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.