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

nRF52840 DK- Softdevice events handling

Hello :

I come from STM32 programming and I am new to Nordic device programming.

for nRF52840 DK, I am looking at the ble-blinking example and try to understand Softdevice event handling process flow.

I understand when a Softdevice has an event, it will trigger an interrupt and the interrupt service routine will execute the 

 nrf_sdh_evts_poll().

 However,

I am not sure how the above  evts-poll function will call the    -- ble_evt_handler     and the            ble_lbs_on_ble_evt ?  ( LED control) 

How does the nrf_sdh_evts_poll() know the address of  ble_evt_handler          and the             ble_lbs_on_ble_evt ? ( LED control) 

There are some discussion saying the event handles are registered , so nrf_sdh_evts_poll()  will know which handle to execute ?

Could you explain it in details ?  ( event handling registration  process ,  etc?)

I would like to understand how the Softdevice event handling  works.

Thanks a lot !

 

ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)

 ble_lbs_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)

void nrf_sdh_evts_poll(void)
{
nrf_section_iter_t iter;

// Notify observers about pending SoftDevice event.
for (nrf_section_iter_init(&iter, &sdh_stack_observers);
nrf_section_iter_get(&iter) != NULL;
nrf_section_iter_next(&iter))
{
nrf_sdh_stack_observer_t * p_observer;
nrf_sdh_stack_evt_handler_t handler;

p_observer = (nrf_sdh_stack_observer_t *) nrf_section_iter_get(&iter);
handler = p_observer->handler;

handler(p_observer->p_context);
}
}

Parents
  • Another thread question:  Button notification

    for the same example code:

    nRF5SDK160098a08e2\examples\ble_peripheral\ble_app_blinky\pca10056\s140\ses 

    Button notification:   

    Could you explain how button_event_handler () get called ?

    Looks like when button is pressed, GPIO interrupt is triggered and serviced, but how does the GPIO interrupt service trigger button_event_handler ()  ?  My guess is that is done somehow by function pointer ?

    Could you explain?

    Thanks a lot !

     

  • Yes, the event handler is passed to app_button_init as a the button_handler member of the app_button_cfg_t struct in the buttons array. The buttons array of type app_button_cfg_t is saved to an internal variable, mp_buttons, in app_button.c. 

    When ever a pin in the buttons array is pressed the app_button module will start an application timer that acts as a debounce timer, i,e, the pin is check when the interrupt is triggered, then you wait for a short period for the voltage level to stabilize on the pin before you check the state of the pin again. In app_button.c the last step is done in detection_delay_timeout_handler() where you see that the mp_buttons array, which is identical to the buttons array passed to app_button_init, is traversed and the evt_handle() is called if there is a state change. 

    In evt_handle the state is processed and the usr_event() function is called which looks up the configuration for the given pin and then calls the button_handler() function, which is the function pointer to button_event_handler.

    /* Find configuration structure for given pin. */
    static app_button_cfg_t const * button_get(uint8_t pin)
    {
        for (int i = 0; i < m_button_count; i++)
        {
            app_button_cfg_t const * p_btn = &mp_buttons[i];
            if (pin == p_btn->pin_no) {
                return p_btn;
            }
        }
    
        /* If button is not found then configuration is wrong. */
        ASSERT(false);
        return NULL;
    }
    
    static void usr_event(uint8_t pin, uint8_t type)
    {
        app_button_cfg_t const * p_btn = button_get(pin);
    
        if (p_btn && p_btn->button_handler)
        {
            NRF_LOG_DEBUG("Pin %d %s", pin, (type == APP_BUTTON_PUSH) ? "pressed" : "released");
            p_btn->button_handler(pin, type);
        }
    }

  • Yes, its a tad complicated with the debounce timer and function pointer being passed around. However, from a top level the app_button module is quite easy to use and understand :) 

Reply Children
No Data
Related