Radio transmit and receive in timeslot

Hi,

I am developing a project that includes transmission and reception in particular timeslots. I checked the radio example in nrf5 sdk and copied the trasmission part to my timeslot file. Now first transmission is happening but afer that transmission is not working. I think its getting stuck in this while loop.   while (NRF_RADIO->EVENTS_DISABLED == 0U) 

Please have look at the below code

nrf_radio_signal_callback_return_param_t *radio_callback(uint8_t signal_type) {
  //printf("\n signal = %d",signal_type);
  switch (signal_type) {
  case NRF_RADIO_CALLBACK_SIGNAL_TYPE_START:
    //Start of the timeslot - set up timer interrupt
    signal_callback_return_param.params.request.p_next = NULL;
    signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE;

    NRF_TIMER0->INTENSET = TIMER_INTENSET_COMPARE0_Msk;
    NRF_TIMER0->CC[0] = m_slot_length - 1000;
    NVIC_EnableIRQ(TIMER0_IRQn);

    nrf_gpio_pin_toggle(20); //Toggle LED4
    adv_flag = 1;
    break;

  case NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO:
    signal_callback_return_param.params.request.p_next = NULL;
    signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE;
    break;

  //case NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0:
  //  //Timer interrupt - attempt to increase timeslot length
  //  signal_callback_return_param.params.extend.length_us = m_slot_length;
  //  signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND;
  //  break;
  //case NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED:
  //  //Extension succeeded, reset timer(configurations still valid since slot length is the same)
  //  NRF_TIMER0->TASKS_CLEAR = 1;
  //  break;
  case NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0:
    //Timer interrupt - do graceful shutdown - schedule next timeslot
    configure_next_event_normal();
    signal_callback_return_param.params.request.p_next = &m_timeslot_request;
    signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END;
    adv_flag = 0;
    break;
  case NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED:
    //No implementation needed
    break;
  case NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED:
    //Try scheduling a new timeslot
    configure_next_event_earliest();
    signal_callback_return_param.params.request.p_next = &m_timeslot_request;
    signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END;
    break;
  default:
    //No implementation needed
    break;
  }
  return (&signal_callback_return_param);
}
void send_packet() {
  // send the packet:
  NRF_RADIO->PACKETPTR = (uint32_t)&packet;

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

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

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

  uint32_t err_code = bsp_indication_set(BSP_INDICATE_SENT_OK);
  NRF_LOG_INFO("The packet was sent");
  APP_ERROR_CHECK(err_code);

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

  while (NRF_RADIO->EVENTS_DISABLED == 0U) {
    // wait
  }
}
void clock_initialization() {
  /* Start 16 MHz crystal oscillator */
  NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
  NRF_CLOCK->TASKS_HFCLKSTART = 1;

  /* Wait for the external oscillator to start up */
  while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0) {
    // Do nothing.
  }

  /* Start low frequency crystal oscillator for app_timer(used by bsp)*/
  NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_Xtal << CLOCK_LFCLKSRC_SRC_Pos);
  NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
  NRF_CLOCK->TASKS_LFCLKSTART = 1;

  while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0) {
    // Do nothing.
  }
}
  int main(void) {
  clock_initialization();
  ble_stack_init();
  timeslot_sd_init();
  for (;;) {

    // idle_state_handle();

    if (adv_flag == 1) {
      radio_configure();
      adv_flag = 0;
      packet = 4;
      send_packet();
      printf("\nw");
      packet = 0;
      NRF_LOG_FLUSH();

    } else {

    }
    __WFE();
  }

  • /**@brief Request next timeslot event in earliest configuration
     */
    uint32_t request_next_event_earliest(void) {
      m_slot_length = 50000;
      m_timeslot_request.request_type = NRF_RADIO_REQ_TYPE_EARLIEST;
      m_timeslot_request.params.earliest.hfclk = NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED;
      m_timeslot_request.params.earliest.priority = NRF_RADIO_PRIORITY_NORMAL;
      m_timeslot_request.params.earliest.length_us = m_slot_length;
      m_timeslot_request.params.earliest.timeout_us = 1000000;
      return sd_radio_request(&m_timeslot_request);
    }
    
    /**@brief Configure next timeslot event in earliest configuration
     */
    void configure_next_event_earliest(void) {
      m_slot_length = 50000;
      m_timeslot_request.request_type = NRF_RADIO_REQ_TYPE_EARLIEST;
      m_timeslot_request.params.earliest.hfclk = NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED;
      m_timeslot_request.params.earliest.priority = NRF_RADIO_PRIORITY_NORMAL;
      m_timeslot_request.params.earliest.length_us = m_slot_length;
      m_timeslot_request.params.earliest.timeout_us = 1000000;
    }
    
    /**@brief Configure next timeslot event in normal configuration
     */
    void configure_next_event_normal(void) {
      m_slot_length = 50000;
      m_timeslot_request.request_type = NRF_RADIO_REQ_TYPE_NORMAL;
      m_timeslot_request.params.normal.hfclk = NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED;
      m_timeslot_request.params.normal.priority = NRF_RADIO_PRIORITY_HIGH;
      m_timeslot_request.params.normal.distance_us = 1000000;
      m_timeslot_request.params.normal.length_us = m_slot_length;
    }
    
    /**@brief Timeslot signal handler
     */
    void nrf_evt_signal_handler(uint32_t evt_id) {
      uint32_t err_code;
    
      switch (evt_id) {
      case NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN:
        //No implementation needed
        break;
      case NRF_EVT_RADIO_SESSION_IDLE:
        //No implementation needed
        break;
      case NRF_EVT_RADIO_SESSION_CLOSED:
        //No implementation needed, session ended
        break;
      case NRF_EVT_RADIO_BLOCKED:
        //Fall through
      case NRF_EVT_RADIO_CANCELED:
        err_code = request_next_event_earliest();
        APP_ERROR_CHECK(err_code);
        break;
      default:
        break;
      }
    }
    uint32_t timeslot_sd_init(void) {
      uint32_t err_code;
    
      err_code = sd_radio_session_open(radio_callback);
      if (err_code != NRF_SUCCESS) {
        return err_code;
      }
    
      err_code = request_next_event_earliest();
      if (err_code != NRF_SUCCESS) {
        (void)sd_radio_session_close();
        return err_code;
      }
      return NRF_SUCCESS;
    }

  • Do you see this error if you keep all the low-level radio code but remove the SoftDevice and timeslot related code, so that you always have full access to the radio etc? If not (or in any case), can you check if this issue also happens if you do everything in a single timeslot?

  • hi,

    I got the code working by resetting radio register in radio callback case.

        // Disable and enable the Radio to reset the RADIO registers, needed from S1xx v8.x
        NRF_RADIO->POWER = ((RADIO_POWER_POWER_Disabled << RADIO_POWER_POWER_Pos) & RADIO_POWER_POWER_Msk);
        NRF_RADIO->POWER = ((RADIO_POWER_POWER_Enabled << RADIO_POWER_POWER_Pos) & RADIO_POWER_POWER_Msk);
    thanks for your support and timely responses.

Related