RF Dongle: Schematic

Let’s take a look at the schematic!

Architecture

This really isn’t necessary for this project, but I made the schematic hierarchical. This means that at the top is a schematic that contains blocks, then each block contains a schematic. Hierarchical schematics are really useful for complex boards, and completely overkill for this project, but I wanted to try it to get experience.

All the way to the left is the USB block, which has the USB connector. This connects to the MCU block, providing it with the USB data lines. The MCU block then connects to the RF block, which has the RF transceiver and PA/LNA chip; the interface between them is SPI and some GPIO signals. At the top is the power block, which turns USB’s 5 V into 3.3 V for the various ICs. This block also generates analog and digital signals for the MCU to check the state of the system power.

USB Block

The USB block shows the USB A plug (P1). The bus voltage goes through a ferrite bead and fuse, then to the power block. The data lines go through ESD protection, then to the MCU block; this is a common best-practice. C28 provides decoupling for the bus voltage, while C27 is for EMI purposes; the value of C27 may need to be tweaked.

MCU Block

U1 is the microcontroller I’ll be using, the STM32L072KBU6. This chip has plenty of Flash and RAM, has USB interface built in to it, and doesn’t need a crystal! Handy!

The only two interfaces I’ll be using on the chip are USB, to communicate with my PC, and SPI, to communicate with the RF transceiver. Additionally, I need some GPIO and ADC inputs for digital logic and checking rail voltages. There are a bunch of unused interfaces, and they seem like such a waste to do nothing with them, so I’m going to be bringing out most of them to a header; that way, this board can be used as a USB-to-SPI or USB-to-I2C or any combination of interfaces.

In order to program the board, I plan to use the factory programmed bootloader (DFU) on the chip. When the chip is reset, it reads BOOT0. If it is high during this time, then the MCU prepares to reprogram itself. If it is low, then the MCU runs the regular program it already has. This means that I can reprogram the MCU by holding down SW2, then hitting SW1.

RF Block

U4, the RF transceiver, receives commands and provides information to the MCU through the SPI interface. CE is used to enter and exit receive and transmit mode, and IRQ is used to alert the MCU that something has changed (eg. transmission complete, received a new message, etc.). The state machine inside the chip is shown below:

From NRF24L01P datasheet

The transceiver needs a crystal; mine has a load capacitance of 9 pF, so 15 pF seems good for this purpose. In general, the value of each capacitor should be a couple picofarads less than twice the load capacitance; in this case, the capacitors should be less than 18 pF. The two capacitors are seen as in series from the crystal’s point of view, and then there’s a couple picofarads of stray capacitance on top of that. In this circuit, the crystal sees (15/2) pF + stray capacitance as a load. If the stray capacitance is 2 pF, then the crystal sees 9.5 pF of load capacitance, which is probably close enough.

U3 is the PA/LNA, which amplifies incoming and outgoing RF signals. Besides its input and output RF pins (TXRX and ANT), it has TXEN and RXEN for control:

From RFX2401C datasheet

In the schematic, RXEN is tied to CE, the chip enable for the RF transceiver. CE is high when the transceiver is receiving or transmitting, and low otherwise, which is in accordance with the table shown above. TXEN was tied to VDD_PA in an example circuit I saw, which I didn’t understand, so I did some testing and found the following:

Two Arduinos communicating with each other using NRF24L01P modules
VDD_PA on the transmitter, when two NRF24L01P are communicating
VDD_PA on the receiver, when two NRF24L01P are communicating

The setup shows two Arduinos, each with an NRF24L01P module. One of the modules is transmitting, and the other is receiving. The images above show what VDD_PA looks like on the transmitting and receiving module, when communication is occurring.

Let’s look at the transmitter. The first large pulse, when VDD_PA goes up to around 1.8 V, is when the transmitter is sending a message; 4 bytes in this test. It takes about 160 us. About 100 us after that is a smaller pulse, which comes up to around 800 mV, and lasts for about 120 us. This is the acknowledge from the receiver, which tells the transmitter that the message was transmitted successfully. The second bump is unusually large because the two NRF24L01P modules are very close together; in the setup photo you can see the antennas are almost touching. When the distance between the two modules is increased, or the antennas are out of alignment (no longer parallel to each other), the second pulse becomes much, much smaller. VDD_PA on the receiver is basically the same as on the transmitter, but backwards; the receiver receives the signal (small pulse on the left), and then sends an acknowledgement (larger pulse on the right).

This test shows the following:

  • VDD_PA is low when not receiving or transmitting
  • VDD_PA is 1.8 V when transmitting
  • VDD_PA varies in voltage when receiving. When the antennas are right next to each other, VDD_PA goes up to 800 mV. When the two antennas are 15 cm apart, pulse goes down to 370 mV; at 30 cm apart, pulse goes down to 120 mV

According to the RFX2401C datasheet, a logic high is 1.2 V and higher. This means that it’s unlikely that receiving a signal will cause VDD_PA to become large enough that TXEN will be read as a logic high. Therefore, tying VDD_PA to TXEN should be fine since VDD_PA will only be a logic high when NRF24L01P is transmitting, which is exactly what we want.

Let’s summarize RXEN and TXEN. When nothing is happening, RXEN and TXEN are low since VDD_PA and CE are low. When receiving, RXEN will be high and TXEN will be low, putting U3 in receive mode, since VDD_PA is low, while CE is high. When transmitting, RXEN and TXEN will be high, putting U3 in transmit mode, since VDD_PA is high, and CE is high. This means that the MCU doesn’t need any control signals dedicated solely to the PA/LNA!

Power Block

Finally, the power block. VBUS is the +5V from USB, and VIN is power that can be supplied externally. U2 is a LDO that outputs 3.3 V.

I have voltage dividers to measure or detect VBUS, VIN and VCC. According to USB specification, a pull-up must be attached to one of the USB data signals if the USB device is self-powered (not powered by USB). If the device is powered by USB, then VBUS_DET will be 3 V, or a logic high; if the device is powered by VIN, then VBUS will be 0 V, a logic low. However, it is possible that VBUS has power on it, but VIN is also powered at a higher voltage, so the system is self-powered despite having USB power. To address that case, the MCU must also measure VIN; if VIN is higher than VBUS, the system is self-powered. If VIN is less than VBUS, the system is bus powered. VCC is also measured, but this is for monitoring / self-test purposes.

That should do it for the schematic! Next, let’s look at the layout.

Leave a comment

Design a site like this with WordPress.com
Get started