Summary
This article describes how to configure a Texas Instruments CC2543 or CC2544 radio to receive traffic from a NRF24L01+ chipset.
Tools
- TI CC2543/CC2544 development kit
- 2x Arduino Uno
- 2x Nordic Semiconductor NRF24L01+ from Amazon
- Example code running on Arduino to send a known packet between two NRF24s.
Set up
I used the RF24 library and the included sample to send a known packet between two NRF24L01 nodes. The sample code is linked above. I basically configure it on the network address, address with, data rate as I want to mimic on the TI chips, then send a 10 byte packet with data that’s easy to find in a bitstream (0x55, 0xAA, will be alternating 010101010) since we may not capture the data aligned exactly on a byte level.
Once I had the two NRF24 nodes communicating I set up the CC2543-CC2544 DK with the SmartRF Studio 7 under Packet RX.
The key to get it to capture the NRF24 traffic is in all the register settings, to make it behave like the NRF24 when it comes to sync words, packet format, etc. I’ll list out all the registry settings that are relevant here.
Register settings
Here’s the table with all register settings that match the Arduino sample above.
Register | Value | Description |
---|---|---|
PRF_CHAN | 0x44 | The RF channel. I set this to what match 2447 MHz (channel 0x2F in NRF24), but there’s another register called FREQCTRL, I’m not 100% sure which one is used |
PRF_TASK_CONF.MODE | 0x02 | Operation mode, 0x02 means Auto mode, 9-bit header |
PRF_FIFO_CONF.RX_ADDR_CONF | 0x03 | Just for debugging, shows the received address (1-byte) and config byte in the output. Doesn’t affect how the chipset is actually operating |
PRF_PKT_CONF.ADDR_LEN | 0x01 | Set to 1 to capture the full 5 network address bytes from NRF24 (first 4 are handled by the 32-bit sync word) |
PRF_CRC_LEN | 0x02 | Length of CRC. 2 bytes in my NRF24 sample. Note that the SmartRF tool will still output data that doesn’t pass CRC check, so it’s not critical that you get this right initially |
PRF_CRC_INIT_2 & 3 | 0xFF | Default values of 0xFF. This is just the initial value for the CRC calculation, and the default is correct, but I want to have it listed here for reference. |
BSP_P3 | 0x10 | For CRC calculation |
BSP_P2 | 0x21 | For CRC calculation |
PRF_ADDR_ENTRY_0_0.VARLEN | 0x01 | Bit 4 says VARLEN (variable length), but SmartRF says it’s reserved. I didn’t test a lot with changing this value, but since the NRF24 is configured to use the Enhanced ShockBurst with variable length we should support that |
PRF_ADDR_ENTRY_0_0.ENA0 | 0x01 | Enable primary sync word (default I think) |
PRF_ADDR_ENTRY_0_1.RXLENGTH | 0x20 | Max length to receive. I wasn’t 100% sure this was used since we wanted variable length, but 0x20 showed all my data at least |
PRF_ADDR_ENTRY_0_2 | 0x71 | Address for the 5th byte network id matching |
FRMCTRL0.SW_CRC_MODE | 0x01 | The NRF24 includes the network address in the CRC calculation |
FRMCTRL0.ENDIANNESS | 0x01 | Important setting, the data goes MSB first over the air |
FREQCTRL | 0x44 | This is the setting that seems to be duplicated with PRF_CHAN. I didn’t both figuring out which is used, I just configured both to the same value. |
SW3 | 0xAB | This is the first byte in the network address as configured in the NRF24 chip |
SW2 | 0xCD | This is the second byte in the network address as configured in the NRF24 chip |
SW1 | 0xAB | This is the third byte in the network address as configured in the NRF24 chip |
SW0 | 0xCD | This is the fourth byte in the network address as configured in the NRF24 chip |
MDMCTRL0.MODULATION | 0x07 | 0x07 means GFSK 320 kHz deviation, 2 Mbps data rate |
MDMCTRL0.PHASE_INVERT | 0x00 | Normal operation (default, but I want to have it here for reference) |
MDMCTRL2.SW_BIT_ORDER | 0x01 | The sync word is transmitted MSB to LSB (from SYNC_WORD[31] to SYNC_WORD[0]) |
MDMCTRL2.PREAM_SEL | 0x00 | Preamble is set based on first bit in the sync word |
MDMCTRL2.NUM_PREAM_BYTES | 0x00 | Preamble from NRF24 is always 1 byte (0x00 value) |
MDMCTRL3.SYNC_MODE | 0x01 | Correlation value above threshold and all bits in the sync words match (lots of noise if you don’t select this option, maybe it can be used to grab unknown sync words if you know the rest of the bytes?) |
SW_CONF.SW_LEN | 0x00 | Expect 32-bit sync words (4 bytes) |