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

Using NRF52 Radio IRQhandler for sending and receiving data

Hello there,

I'd like to send and receive data through NRF Radio's handler. I've been able to configure the handler to receive data. Otherwise, I'm having difficulty on sending data.

Here's my current IRQHandler function:

void RADIO_IRQHandler(void) {
	nrf_gpio_pin_set(RECPIN);
	NRF_RADIO->EVENTS_END = 0U;
	NRF_RADIO->TASKS_START = 1U;
	if (NRF_RADIO->EVENTS_READY && (NRF_RADIO->INTENSET & RADIO_INTENSET_READY_Msk)) {
		NRF_RADIO->EVENTS_READY = 0;
	}

	if (NRF_RADIO->EVENTS_END && (NRF_RADIO->INTENSET & RADIO_INTENSET_END_Msk)) {
		NRF_RADIO->EVENTS_END = 0U;
	}

	if (NRF_RADIO->EVENTS_ADDRESS && (NRF_RADIO->INTENSET & RADIO_INTENSET_ADDRESS_Msk)) {
		NRF_RADIO->EVENTS_ADDRESS = 0;
	}
	NRF_RADIO->EVENTS_DISABLED = 0U;

	if (NRF_RADIO->CRCSTATUS == 1U) {
		receive_packet();
		if (targetID == MyID || targetID == ALL_NODES) {
			if (My_Role == MASTER) {
				communicator();
			} else {
				normal();
			}
		}
	}
	nrf_gpio_pin_clear(RECPIN);
}

And here's my send_packet function:

void send_packet()
{
    // send the packet:
    NRF_RADIO->EVENTS_READY = 0U;
    NRF_RADIO->TASKS_TXEN   = 1;

    while (NRF_RADIO->EVENTS_READY == 0U)
    {
        // wait
    }
    NRF_RADIO->EVENTS_END  = 0U;
    NRF_RADIO->TASKS_START = 1U;

    while (NRF_RADIO->EVENTS_END == 0U)
    {
        // wait
    }

    NRF_RADIO->EVENTS_DISABLED = 0U;
    // Disable radio
    NRF_RADIO->TASKS_DISABLE = 1U;

    while (NRF_RADIO->EVENTS_DISABLED == 0U)
    {
        // wait
    }
}

This function may lead my board to freeze somewhere

And:

void send_packet() {
	// send the radioTxBuffer:
	//	if (radioTxBuffer[1] == COLLECT_REPLY) {
	//		//printf("%d: Transmitting: %x %x %x %x\r\n", __LINE__, radioTxBuffer[0], radioTxBuffer[1], radioTxBuffer[2], radioTxBuffer[3]);
	//		copyThis(radioTxBuffer);
	//	}
	NRF_RADIO->EVENTS_DISABLED = 0;
	NRF_RADIO->TASKS_DISABLE = 1;
	while (!NRF_RADIO->EVENTS_DISABLED);		//wait for radio to be disabled

	NRF_RADIO->EVENTS_READY = 0U;
	NRF_RADIO->TASKS_TXEN	 = 1;

	while (NRF_RADIO->EVENTS_READY == 0U) {	//wait for radio to be in tx mode
		// wait
	}

	NRF_RADIO->PACKETPTR = (uint32_t)&radioTxBuffer;

	NRF_RADIO->EVENTS_END	= 0U;			// clear flag
	NRF_RADIO->TASKS_START = 1U;			// Start sending

	while (NRF_RADIO->EVENTS_END == 0U) {	// wait for radio to finish sending
		// wait
	}

	// Clear event
	NRF_RADIO->EVENTS_DISABLED = 0U;
	NRF_RADIO->EVENTS_END = 0;
	NRF_RADIO->EVENTS_READY = 0;
	// Disable radio
	//NRF_RADIO->TASKS_DISABLE = 1U;


	//	while (NRF_RADIO->EVENTS_DISABLED == 0U)
	//	{
	//		// wait
	//	}
}

This function will return normal as nothing happened, while not sending anything.

I would like some enlightenment on how to implement Radio Send and receive properly. (Proprietary radio, not BLE)

Thank you in advance

Parents
  • Hi, Torbjørn,

    After decided and tried porting nrf_esb from the example code to my project, now I am stuck with changing the content of the payload.

    I changed the payload using:

    for (uint8_t i = 0; i < tx_payload.length; i++) {
    			tx_payload.data[i] += 1;
    //			printf("tx_payload.data[%d]: %x\r\n", i, tx_payload.data[i]);
    		}

    And here's my handler:

    void nrf_esb_event_handler(nrf_esb_evt_t const * p_event) {
    	nrf_gpio_pin_toggle(LED_2);
    	printf("handler\r\n");
    //	NRF_LOG_INFO("Inside handler!");
    //	NRF_LOG_FLUSH();
    	switch (p_event->evt_id) {
    	case NRF_ESB_EVENT_TX_SUCCESS:
    //		NRF_LOG_INFO("Packet sending succeeded!");
    		printf("sent? PID: %x\r\n", tx_payload.pid);
    		nrf_esb_pop_tx();
    		break;
    	case NRF_ESB_EVENT_TX_FAILED:
    		(void) nrf_esb_flush_tx();
    		(void) nrf_esb_start_tx();
    		//NRF_LOG_INFO("Packet sending failed!");
    		break;
    	case NRF_ESB_EVENT_RX_RECEIVED:
    		// Get the most recent element from the RX FIFO.
    		while (nrf_esb_read_rx_payload(&rx_payload) == NRF_SUCCESS) {
    			printf("Received a packet. ID: %x:\r\n", rx_payload.pid);
    			for (uint8_t i = 0; i < rx_payload.length; i++) {
    				printf("rx_payload.data[%d]: %x\r\n", i, rx_payload.data[i]);
    			}
    			// Set LEDs identical to the ones on the PTX.
    //			NRF_LOG_INFO("Packet Received!");
    		}
    		//nrf_esb_flush_rx();
    		break;
    
    	}
    //	NRF_LOG_INFO("Exit!");
    //	NRF_LOG_FLUSH();
    	//nrf_gpio_pin_toggle(LED_2);
    }

    Every time a "send packet command" is fired, it should increment the content inside tx_payload by 1 then send it.

    Upon printing data, it always print the old data. Printing on the receiver will not happen if I did not fire sending on sender. The only way to print a new data is to reset it first.

    Is this the correct way to use nrf_esb? or is it not?

    Thank you,
    Winz

  • Hi Winz

    Do you pass the updated payload to the nrf_esb library by using the nrf_esb_write_tx_payload(..) function after you change the value of the tx_payload struct?

    Also, running nrf_esb_pop_tx() in the TX_SUCCESS callback should not be necessary. The packet will be removed from the TX FIFO automatically once a valid ACK is received. 

    Best regards
    Torbjørn

Reply
  • Hi Winz

    Do you pass the updated payload to the nrf_esb library by using the nrf_esb_write_tx_payload(..) function after you change the value of the tx_payload struct?

    Also, running nrf_esb_pop_tx() in the TX_SUCCESS callback should not be necessary. The packet will be removed from the TX FIFO automatically once a valid ACK is received. 

    Best regards
    Torbjørn

Children
Related