Events emitted by radio do not match expected events

Hello,
I am having trouble getting a simple radio application with a transmitter and receiver working. The events emitted by the radio do not seem to make sense, and no packet is ever received by the receiver. I am using the nRF HAL radio driver with an nRF52833 and the zephyr operating system.

I am using the BLE 1 Mbit mode. I have an ISR set up to receive all of the events that the radio emits, with a function to print these events as a string. For transmission these events make sense except for a FRAMESTART event, which should only be emitted in 802.15.4 mode (which I am not using) and also only when receiving, if I'm not mistaken. For reception, the only events received are READY, RXREADY and again FRAMESTART, which I don't think should be emitted for my application.

Here is the code. The same code is running on both the receiver and transmitter, with the only difference being on line 145 (the `mode` variable).

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(mm_radio, LOG_LEVEL_DBG);

#include <zephyr/kernel.h>

#include <zephyr/irq.h>

#include "hal/nrf_radio.h"

enum {
	RECEIVER,
	TRANSMITTER,
};

static uint8_t packet[ 255 ]; // Packet to send

static const char *event_to_str(nrf_radio_event_t event) {
	switch (event) {
	case NRF_RADIO_EVENT_READY:
		return "READY";
	case NRF_RADIO_EVENT_ADDRESS:
		return "ADDRESS";
	case NRF_RADIO_EVENT_PAYLOAD:
		return "PAYLOAD";
	case NRF_RADIO_EVENT_END:
		return "END";
	case NRF_RADIO_EVENT_DISABLED:
		return "DISABLED";
	case NRF_RADIO_EVENT_DEVMATCH:
		return "DEVMATCH";
	case NRF_RADIO_EVENT_DEVMISS:
		return "DEVMISS";
	case NRF_RADIO_EVENT_RSSIEND:
		return "RSSIEND";
	case NRF_RADIO_EVENT_BCMATCH:
		return "BCMATCH";
	case NRF_RADIO_EVENT_CRCOK:
		return "CRCOK";
	case NRF_RADIO_EVENT_CRCERROR:
		return "CRCERROR";
	case NRF_RADIO_EVENT_FRAMESTART:
		return "FRAMESTART";
	case NRF_RADIO_EVENT_EDEND:
		return "EDEND";
	case NRF_RADIO_EVENT_CCAIDLE:
		return "CCIDLE";
	case NRF_RADIO_EVENT_CCABUSY:
		return "CCABUSY";
	case NRF_RADIO_EVENT_CCASTOPPED:
		return "CCASTOPPED";
	case NRF_RADIO_EVENT_RATEBOOST:
		return "RATEBOOST";
	case NRF_RADIO_EVENT_TXREADY:
		return "TXREADY";
	case NRF_RADIO_EVENT_RXREADY:
		return "RXREADY";
	case NRF_RADIO_EVENT_MHRMATCH:
		return "MHRMATCH";
	case NRF_RADIO_EVENT_SYNC:
		return "SYNC";
	case NRF_RADIO_EVENT_PHYEND:
		return "PHYEND";
	case NRF_RADIO_EVENT_CTEPRESENT:
		return "CTEPRESENT";
	default:
		return "???";
	}
}

static void radio_config() {

	nrf_radio_power_set(NRF_RADIO, true);

	nrf_radio_mode_set(NRF_RADIO, RADIO_MODE_MODE_Ble_1Mbit);

	nrf_radio_packet_conf_t config = {
		.lflen		= 0,							// Length on air of LENGTH field in number of bits.
		.s0len		= 0,							// Length on air of S0 field in number of bytes.
		.s1len		= 0,							// Length on air of S1 field in number of bits.
		.s1incl		= RADIO_PCNF0_S1INCL_Automatic, // Include or exclude S1 field in RAM.
		.cilen		= 0,							// Length of code indicator - long range.
		.plen		= RADIO_PCNF0_PLEN_16bit,		// Length of preamble on air. Decision point: TASKS_START task.
		.crcinc		= false,						// Indicates if LENGTH field contains CRC or not.
		.termlen	= 0,							// Length of TERM field in Long Range operation.
		.maxlen		= 60,							// Maximum length of packet payload.
		.statlen	= 60,							// Static length in number of bytes.
		.balen		= 4,							// Base address length in number of bytes.
		.big_endian = false,						// On air endianness of packet.
		.whiteen	= true							// Enable or disable packet whitening.
	};
	nrf_radio_packet_configure(NRF_RADIO, &config);

	nrf_radio_datawhiteiv_set(NRF_RADIO, 0xAB);

	nrf_radio_base0_set(NRF_RADIO, 0x0000FAFE);
	nrf_radio_prefix0_set(NRF_RADIO, 0xBA);

	nrf_radio_txaddress_set(NRF_RADIO, 0);
	nrf_radio_rxaddresses_set(NRF_RADIO, 1);

	nrf_radio_crc_configure(NRF_RADIO, 2, RADIO_CRCCNF_SKIP_ADDR_Skip, 0x000AA0AA);
	nrf_radio_crcinit_set(NRF_RADIO, 0x00005050);

	nrf_radio_fast_ramp_up_enable_set(NRF_RADIO, true);

	nrf_radio_txpower_set(NRF_RADIO, RADIO_TXPOWER_TXPOWER_0dBm);
	nrf_radio_frequency_set(NRF_RADIO, 0);

	nrf_radio_packetptr_set(NRF_RADIO, packet);
}

ISR_DIRECT_DECLARE(radio_isr) {

	__disable_irq();

	LOG_DBG("isr");

	for (int i = 0x100; i <= 0x170; i += 4) {
		if (nrf_radio_event_check(NRF_RADIO, i)) {
			LOG_DBG("NRF_RADIO_EVENT: %12s (%03x)", event_to_str(i), i);
			nrf_radio_event_clear(NRF_RADIO, i);
		}
	}

	__enable_irq();
	return 0;
}

int radio_init() {

	for (int i = 0; i < 255; i++) {
		packet[ i ] = i;
	}

	radio_config();

	nrf_radio_int_enable(NRF_RADIO, 0x1fe5ffe7); // all of them

	IRQ_DIRECT_CONNECT(RADIO_IRQn, 0, radio_isr, 0);
	irq_enable(RADIO_IRQn);

	LOG_DBG("radio state: %d", nrf_radio_state_get(NRF_RADIO));

	uint8_t mode = TRANSMITTER;

	switch (mode) {
	case TRANSMITTER:
		nrf_radio_shorts_set(NRF_RADIO, NRF_RADIO_SHORT_READY_START_MASK);
		NRF_RADIO->TASKS_TXEN = 1;
		for (;;) {
			k_msleep(1000);
			LOG_INF("radio state: %d", nrf_radio_state_get(NRF_RADIO));
			NRF_RADIO->TASKS_START = 1;
		}
		break;
	case RECEIVER:
		nrf_radio_dacnf_set(NRF_RADIO, 1, 1);
		nrf_radio_shorts_set(NRF_RADIO, NRF_RADIO_SHORT_READY_START_MASK | NRF_RADIO_SHORT_END_START_MASK);
		NRF_RADIO->TASKS_RXEN  = 1;
		NRF_RADIO->TASKS_START = 1;
		for (;;) {
			k_msleep(1000);

			LOG_INF("radio state: %d", nrf_radio_state_get(NRF_RADIO));
		}
		break;
	}

	return 0;
}
Here is the output of the transmit node:

[00:00:00.100,646] <dbg> mm_radio: radio_init: radio state: 0
[00:00:00.106,781] <dbg> mm_radio: radio_isr_body: isr
[00:00:00.112,274] <dbg> mm_radio: radio_isr_body: NRF_RADIO_EVENT:        READY (100)
[00:00:00.120,544] <dbg> mm_radio: radio_isr_body: NRF_RADIO_EVENT:      ADDRESS (104)
[00:00:00.128,814] <dbg> mm_radio: radio_isr_body: NRF_RADIO_EVENT:      PAYLOAD (108)
[00:00:00.137,084] <dbg> mm_radio: radio_isr_body: NRF_RADIO_EVENT:          END (10c)
[00:00:00.145,355] <dbg> mm_radio: radio_isr_body: NRF_RADIO_EVENT:   FRAMESTART (138)
[00:00:00.153,625] <dbg> mm_radio: radio_isr_body: NRF_RADIO_EVENT:      TXREADY (154)
[00:00:00.161,895] <dbg> mm_radio: radio_isr_body: NRF_RADIO_EVENT:       PHYEND (16c)
[00:00:01.106,781] <inf> mm_radio: radio state: 10
[00:00:01.111,907] <dbg> mm_radio: radio_isr_body: isr
[00:00:01.117,431] <dbg> mm_radio: radio_isr_body: NRF_RADIO_EVENT:      ADDRESS (104)
[00:00:01.125,701] <dbg> mm_radio: radio_isr_body: NRF_RADIO_EVENT:      PAYLOAD (108)
[00:00:01.133,941] <dbg> mm_radio: radio_isr_body: NRF_RADIO_EVENT:          END (10c)
[00:00:01.142,211] <dbg> mm_radio: radio_isr_body: NRF_RADIO_EVENT:   FRAMESTART (138)
[00:00:01.150,482] <dbg> mm_radio: radio_isr_body: NRF_RADIO_EVENT:       PHYEND (16c)
[00:00:02.158,813] <inf> mm_radio: radio state: 10
[00:00:02.163,940] <dbg> mm_radio: radio_isr_body: isr
[00:00:02.169,464] <dbg> mm_radio: radio_isr_body: NRF_RADIO_EVENT:      ADDRESS (104)
[00:00:02.177,734] <dbg> mm_radio: radio_isr_body: NRF_RADIO_EVENT:      PAYLOAD (108)
[00:00:02.186,004] <dbg> mm_radio: radio_isr_body: NRF_RADIO_EVENT:          END (10c)
[00:00:02.194,274] <dbg> mm_radio: radio_isr_body: NRF_RADIO_EVENT:   FRAMESTART (138)
[00:00:02.202,545] <dbg> mm_radio: radio_isr_body: NRF_RADIO_EVENT:       PHYEND (16c)
[00:00:03.210,845] <inf> mm_radio: radio state: 10
[00:00:03.215,972] <dbg> mm_radio: radio_isr_body: isr
[00:00:03.221,496] <dbg> mm_radio: radio_isr_body: NRF_RADIO_EVENT:      ADDRESS (104)
[00:00:03.229,766] <dbg> mm_radio: radio_isr_body: NRF_RADIO_EVENT:      PAYLOAD (108)
[00:00:03.238,037] <dbg> mm_radio: radio_isr_body: NRF_RADIO_EVENT:          END (10c)
[00:00:03.246,307] <dbg> mm_radio: radio_isr_body: NRF_RADIO_EVENT:   FRAMESTART (138)
[00:00:03.254,577] <dbg> mm_radio: radio_isr_body: NRF_RADIO_EVENT:       PHYEND (16c)

And here is the output of receive node:

[00:00:00.101,287] <dbg> mm_radio: radio_init: radio state: 0
[00:00:00.107,452] <dbg> mm_radio: radio_isr_body: isr
[00:00:00.113,067] <dbg> mm_radio: radio_isr_body: NRF_RADIO_EVENT:        READY (100)
[00:00:00.121,429] <dbg> mm_radio: radio_isr_body: NRF_RADIO_EVENT:   FRAMESTART (138)
[00:00:00.129,821] <dbg> mm_radio: radio_isr_body: NRF_RADIO_EVENT:      RXREADY (158)
[00:00:01.138,244] <inf> mm_radio: radio state: 3
[00:00:02.143,402] <inf> mm_radio: radio state: 3
[00:00:03.148,559] <inf> mm_radio: radio state: 3
[00:00:04.153,717] <inf> mm_radio: radio state: 3
[00:00:05.158,874] <inf> mm_radio: radio state: 3
[00:00:06.164,031] <inf> mm_radio: radio state: 3
[00:00:07.169,189] <inf> mm_radio: radio state: 3
[00:00:08.174,346] <inf> mm_radio: radio state: 3
[00:00:09.179,504] <inf> mm_radio: radio state: 3
[00:00:10.184,661] <inf> mm_radio: radio state: 3
[00:00:11.189,819] <inf> mm_radio: radio state: 3
[00:00:12.194,976] <inf> mm_radio: radio state: 3
[00:00:13.200,134] <inf> mm_radio: radio state: 3
[00:00:14.205,291] <inf> mm_radio: radio state: 3
[00:00:15.210,449] <inf> mm_radio: radio state: 3
[00:00:16.215,606] <inf> mm_radio: radio state: 3

Related