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

Do peripheral events used in shortcuts still generate interrupts?

I have the nrf51 RADIO peripheral set up with the usual set of shortcuts:

NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk | RADIO_SHORTS_DISABLED_RXEN_Msk;

This should automatically transmit a packet when I use the START task, and then transition to receive mode immediately afterward. I also have the RADIO IRQ enabled, with the END task interrupt enabled.

Without the DISABLED-RXEN shortcut set, I correctly get interrupts when the END event is generated. However, if I enable the DISABLED-RXEN shortcut I don't seem to receive END interrupts.

I thought this was perhaps because I am moving to RXEN state and it was preventing me from sending another packet, but the routine that I use to set up the radio for the next transmission makes sure that the radio is in DISABLED state before being configured for TXEN and ultimately START:

static void _disable_radio(void)
{
	NRF_RADIO->EVENTS_DISABLED = 0;
	NRF_RADIO->TASKS_DISABLE = 1;

	while (NRF_RADIO->EVENTS_DISABLED == 0) ;
}

and

static void _setup_radio(void)
{
	uint32_t val;

	_disable_radio();

	NRF_RADIO->MODE = RADIO_MODE_MODE_Nrf_2Mbit << RADIO_MODE_MODE_Pos;
	NRF_RADIO->FREQUENCY = rf_channel;
	NRF_RADIO->TXPOWER = RADIO_TXPOWER_TXPOWER_0dBm << RADIO_TXPOWER_TXPOWER_Pos;

	/* CRC config */
	NRF_RADIO->CRCCNF = RADIO_CRCCNF_LEN_Three << RADIO_CRCCNF_LEN_Pos;
	NRF_RADIO->CRCINIT = 0xFFFFFFUL;
	NRF_RADIO->CRCPOLY = 0x11021UL;

	/*
	 * Packet format:
	 * - No S0, S1 or Length
	 * - No whitening, big endian, 5 byte address, packet length is the sync struct length
	 */

	val = RADIO_PCNF1_ENDIAN_Msk | (4 << RADIO_PCNF1_BALEN_Pos);
	val |= (sizeof(sync_packet) << RADIO_PCNF1_STATLEN_Pos);
	val |= (sizeof(sync_packet) << RADIO_PCNF1_MAXLEN_Pos);

	NRF_RADIO->PCNF0 = (0 << RADIO_PCNF0_S0LEN_Pos) | (0 << RADIO_PCNF0_LFLEN_Pos) | (0 << RADIO_PCNF0_S1LEN_Pos);
	NRF_RADIO->PCNF1 = val;

	/* Radio address config */
	NRF_RADIO->PREFIX0 = PIPE_PREFIX;
	NRF_RADIO->BASE0 = PIPE_BASE;

	/* clear the END event and all interrupts, then set the END event interrupt and enable the radio IRQ */
	NRF_RADIO->EVENTS_END = 0;
	NRF_RADIO->EVENTS_READY = 0;
	NRF_RADIO->INTENCLR = 0xFFFFFFFF;
	NRF_RADIO->INTENSET = RADIO_INTENSET_END_Msk;
	NVIC_EnableIRQ(RADIO_IRQn);
	
	NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk | RADIO_SHORTS_DISABLED_RXEN_Msk;
}

The packet transmission is very straightforward:

	NRF_RADIO->PACKETPTR = (uint32_t)packet_ptr;
	NRF_RADIO->EVENTS_READY = 0;
	NRF_RADIO->TASKS_TXEN = 1;

As you can see, there is not much that can go wrong, yet with that DISABLED-RXEN shortcut enabled my packet transmission breaks and I do not see END interrupts.

Related