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.