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

HVX notification crashes when called from peripheral handler

So as part of my system I have something much like the Nordic UART service in that I need to send a notification when something arrives from the UART. Mine is a little bit different from NUS as it doesn't wait for a newline before sending to BLE, instead the notification is triggered either by a buffer full or a timeout so is called from either the UART handler or timer handler.

The notification itself is packaged into a separate routine, which I tested by calling it in my main loop along with a 1 second delay - works absolutely fine.

BUT - if I try to call the same routine from either the UART handler or timer handler the system crashes. No debug or anything, just a complete crash.

The only real difference I can see between my code and NUS code is that I'm not using the link context storage, instead I'm just using the stored connection & attribute handles.

Can you offer any ideas? This is the actual notify code:

uint32_t uartrx_notify(uint8_t * p_data,uint16_t *p_length)
{
  if(m_conn_handle != BLE_CONN_HANDLE_INVALID)
  {
    NRF_LOG_INFO("Sending UART notify: handles %d, %d",m_conn_handle,m_bushub_service.uartrx_char_handles.value_handle);
    ble_gatts_hvx_params_t params;
    memset(&params, 0, sizeof(params));
    params.type   = BLE_GATT_HVX_NOTIFICATION;
    params.handle = m_bushub_service.uartrx_char_handles.value_handle; 
    params.p_data = p_data;
    params.p_len  = p_length;
    return sd_ble_gatts_hvx(m_conn_handle, &params);
  }
  else
  {
    NRF_LOG_INFO("UART notify - not connected");
  }
}

Parents
  • Hello,

    What's the interrupt priority of your UART handler and timer handler? It should be fine to call the HVX function from these if you are using the default priority which is '6'. 

  • Hi Thanks for the quick reply..

    I think I do have an IRQ issue. The  UART was set to level 6 but was overridden when calling APP_UART_FIFO_INIT. I've reset it to 6 and the UART event handler works as expected.

    For the timer, I'm currently not using the nrf drivers as the timer code was culled from an example ages ago (this project started out as a Manchester decoder) so it is setting registers directly.

    Is there an easy way to set the IRQ priority for timer4? I think my next task should be to rewrite the timer routines...

      NRF_TIMER4->TASKS_CLEAR   = 1;
      NRF_TIMER4->BITMODE =     TIMER_BITMODE_BITMODE_32Bit;
      NRF_TIMER4->CC[0]         = 1000;
      NRF_TIMER4->SHORTS        = TIMER_SHORTS_COMPARE0_CLEAR_Msk;
      NRF_TIMER4->INTENSET      = (TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos);
      NVIC_EnableIRQ(TIMER4_IRQn);
      NRF_TIMER4->TASKS_START = 1;
      

    Thanks

Reply
  • Hi Thanks for the quick reply..

    I think I do have an IRQ issue. The  UART was set to level 6 but was overridden when calling APP_UART_FIFO_INIT. I've reset it to 6 and the UART event handler works as expected.

    For the timer, I'm currently not using the nrf drivers as the timer code was culled from an example ages ago (this project started out as a Manchester decoder) so it is setting registers directly.

    Is there an easy way to set the IRQ priority for timer4? I think my next task should be to rewrite the timer routines...

      NRF_TIMER4->TASKS_CLEAR   = 1;
      NRF_TIMER4->BITMODE =     TIMER_BITMODE_BITMODE_32Bit;
      NRF_TIMER4->CC[0]         = 1000;
      NRF_TIMER4->SHORTS        = TIMER_SHORTS_COMPARE0_CLEAR_Msk;
      NRF_TIMER4->INTENSET      = (TIMER_INTENSET_COMPARE0_Enabled << TIMER_INTENSET_COMPARE0_Pos);
      NVIC_EnableIRQ(TIMER4_IRQn);
      NRF_TIMER4->TASKS_START = 1;
      

    Thanks

Children
Related