This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Receiving BLE advertising packets without SoftDevice

As a simple experiment, I'm trying to write some code to receive a standard BLE advertising packet by directly programming the radio in the nRF52840. I *think* I'm doing things right, and I can receive packets, but no matter what happens the CRCSTATUS always shows the checksum is bad.

My environment:

Hardware: Nordic nRF52840-DK board (PCA10056 rev 1.0.0)

Silicon variant: AAC0

Compiler: GCC 9.1.0

Host OS: FreeBSD/amd64 12.0-RELEASE

I'm building this code for a project that does not use the Nordic SDK. I compiled my own GCC 9.1.0 cross-compiler and I use OpenOCD to flash the board. Note that this environment works fine when using the SoftDevice and all the other code in the project.

However since I know that Nordic support is unlikely to want to build my entire code base, I created a simple test program based on the SDK which duplicates my problem. The source code is here:

http://people.freebsd.org/~wpaul/w00t/nordic_test/main.c

I based this code on the example in examples/peripheral/bsp in the SDK. To build it, I do the following:

- Copy main.c to examples/peripheral/bsp

- cd to examples/peripheral/bsp/pca10056/blank/armgcc

- set GNU_INSTALL_ROOT to the path of my GCC installation

- run make

From here I can use OpenOCD to flash the sample program to the board.

What I usually get when I run it is:

<info> app: BSP example started.
<info> app: Force disable...
<info> app: Radio initialized...
<info> app: Starting receiver...
<info> app: Got a packet...
<info> app: CRC IS BAD

Note that the example saves the packet data into a buffer called rxpkt. I can dump this using GDB via the J-Link debugger.

I added the functions radioReset(), radioInit() and radioRx(), which are invoked from main(). The radio is set to 2402MHz (channel 37) and I enable the receiver to scan for packets. I'm using what I believe is the correct access address for BLE advertisement packets, and this does seem to allow the radio to receive frames.

Before anyone asks, yes I've searched through the forum, but while I found several topics about using the radio directly, it didn't look like any of them directly related to receiving standard BLE packets. It seems you need to program the PCONF0 and PCONF1 registers correctly in order for the radio to correctly parse the packets, and I'm pretty sure I'm using the right settings, but the CRC is always wrong. I'm using what I believe are the correct CRC polynomial and initial values, and CRCCNF settings.

What confuses me the most is that if I run the board using the SoftDevice, which seems to receive advertisements just fine, and then halt it with the debugger and examine the NRF_RADIO registers, the settings look identical to what I'm using, but for me the same values just don't work.

I'm hoping someone can explain to me just what it is I'm doing wrong. I tried to make the source code as readable as possible.

-Bill

Related