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

nRF 51822 radio receive running error

I'm using nRF 51822 to develop a proprietary wireless protocol.

At Rx side, every 500ms have a listening window with 10ms to listen if there is package to receive. So 10ms is the time out of radio receive, if there is no package received, disable radio, wait 500ms, listen again. the radio receive function is as (wait_time_out_ms=10ms)

   /********************************************************************************/
uint32_t rx_radio_config_parameter(uint8_t *rx_packet, uint32_t frequency, 
	uint32_t logical_address, uint32_t wait_time_out_ms)
{
  uint32_t time_out = 0;
  uint32_t radio_mode = RADIO_MODE;
  uint32_t initial_timer;
	
  /* re-load watch dog request register */
  NRF_WDT->RR[0] = 0x6E524635;

  /* get the initial real time counter */
  initial_timer = NRF_RTC0->COUNTER;
	
  /* Set radio mode */
  radio_mode_set(radio_mode);
  /* Set Frequency bin */
  NRF_RADIO->FREQUENCY = frequency; 
  /* Enable device address to use which receiving */
  NRF_RADIO->RXADDRESSES = logical_address;
	
  /* Set payload pointer */
  NRF_RADIO->PACKETPTR = (uint32_t)rx_packet;
	
  NRF_RADIO->EVENTS_READY = 0U;
  /* Enable radio and wait for ready */
  NRF_RADIO->TASKS_RXEN = 1U;		
  while(NRF_RADIO->EVENTS_READY == 0U)
  {	
    /* radio enable time out */	
    if (((NRF_RTC0->COUNTER - initial_timer) > wait_time_out_ms) || (NRF_RTC0->COUNTER < initial_timer))
    {		
      NRF_RADIO->TASKS_RXEN = 0U;		
      return(1);
    }
  }
	
  NRF_RADIO->EVENTS_END = 0U;
  /* Start listening and wait for address received event */
  NRF_RADIO->TASKS_START = 1U;	
  /* Wait for end of packet */
  while(NRF_RADIO->EVENTS_END == 0U)
  {
    /* radio receive time out */	
    if (((NRF_RTC0->COUNTER - initial_timer) > wait_time_out_ms) || (NRF_RTC0->COUNTER < initial_timer))
    {		
      time_out = 1;
      break;
    }
  }	
	
  NRF_RADIO->EVENTS_DISABLED = 0U;
  /* Disable radio */
  NRF_RADIO->TASKS_DISABLE = 1U;
  while(NRF_RADIO->EVENTS_DISABLED == 0U)
  {
  }

  /* 1: time out, 0: packet recceived */ 
  return (time_out);
}

In most cases, this function works well, but randomly, after several hours, the program stopped inside this function and watch-dog time out (2 seconds) reset (I want radio receive function running at most 10ms).

would you please help to point out the bug inside this function? or any suggetions to better code implementation of radio receive with time out?

Thanks a lot.

  • @JiachengWang: If you don't use watchdog, in which loop would the program stuck in this function ? I don't see any reason it should be stuck here.

  • Thanks a lot for your comment.

    With more debug, it seems the problem is in the "while" loop of radio disable. with following update of radio disable code:

      NRF_RADIO->EVENTS_DISABLED = 0U;
      /* Disable radio */
      NRF_RADIO->TASKS_DISABLE = 1U;
      while(NRF_RADIO->EVENTS_DISABLED == 0U)
      {
    	  /* radio disable time out */	
    		if (((NRF_RTC0->COUNTER - initial_timer) > (wait_time_out_ms + 1)) || (NRF_RTC0->COUNTER < initial_timer))
    		{		
    #if (IF_PRINT_LOG)
          printf("..................Radio disable time out in Rx..................\r\n" );
    #endif
          /* system reset */
          NVIC_SystemReset( );
        }
      }
    

    some time the radio disable is running time out. Because I have another function have higher priority than radio Rx listening, if the radio is interupted while it is listening, the radio disable has problem.

  • @Jiacheng: How long is the timeout ?

    If you have an interrupt that can interrupt between the time you assign initial_timer and the while loop code, then you can easily get a timeout, depend on how much time that interrupt handler uses. Also if you are receiving something, I don't think you will have the RADIO disabled immediately.

    I suggest you to put the assign initial_timer = NRF_RTC0->COUNTER; right above the while loop. And maybe increase the timeout so that it should be OK when the code is preempted by the interrupt.

  • The timeout is 10ms.

    Thanks a lot for your suggestion, I'll try more.

Related