Force GPIOTE event manually.

Using SDK17.1.0, I need to manually force an event handler to run. But the event handler is part of the SDK and is declared static. Key constraint is that i cannot modify the SDK.

I'm using the app_button library. But the handler i registered for the button doesn't run when the chip is wakes up from shutdown mode (following button press). I am aware this is because the debounce timer doesn't start (started in the gpiote event handler).

I tried manually running my local app_button handler, but of course this skips many steps within the app_button library and causes all sorts of problems. So, essentially i need to call a function from further back in the call stack/ chain of events.

But every function that potentially provides a route to triggering the app_button event handler is declared static or is out of scope of my code.

The event handler i'd like to trigger is below: (line 245 app_button.c)

 

static void gpiote_event_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
    app_button_cfg_t const * p_btn = button_get(pin);
    bool is_set = nrf_drv_gpiote_in_is_set(p_btn->pin_no);
    bool is_active = !((p_btn->active_state == APP_BUTTON_ACTIVE_HIGH) ^ is_set);

    /* If event indicates that pin is active and no other pin is active start the timer. All
     * action happens in timeout event.
     */
    if (is_active && (m_pin_active == 0))
    {
        NRF_LOG_DEBUG("First active button, starting periodic timer");
        timer_start();
    }
}

Ideally i could do to find the memory location in which the pointer to the above handler is stored (when it is initialised). i could, for example, do this using the following code:

   nrfx_gpiote_evt_handler_t handler = channel_handler_get((uint32_t)channel_port_get(BTN_PIN));
         handler(BTN_PIN, GPIOTE_CONFIG_POLARITY_HiToLo);       

But again, both of these functions are static.

 

Ideally, i'm looking for suggestions of global functions that can be used to retrieve a pointer to the gpiote event handler (the one in the first extract of code above). Or some other way of manually forcing a button action. Even if i could perhaps manually force the pin's IRQ at register level?

Thanks,

Sean

Parents
  • Hi Sean,

    SeanHowsonTB said:
    IMHO altering the SDK counstitutes as a dirty hack

    You could say that. And I agree that you should try to avoid it . But in reality, the SDK does not cover all use cases even though we try to make it as generic as possible, and also, it is not bug free. So it is not uncommon to have to change the SDK code, even though it is not ideal.

    SeanHowsonTB said:
    If i'm being honest, while i appreciate the solution you've presented it really sounds like a long winded solution for a very simple problem.

    I fully agree. But it was a suggested solution for how to call a static function without changing the code that is static, which is what you describe. I do not like that approach at all, though, as mentioned.

    I see the problem with interpreting the button press when it is a wakeup source. I would consider doing this with a completely different approach, handling the startup case as a special case, and using some dedicated code to handel it without the app_button library. You could still use the app_timer (with a dedicated instance) to do the debouncing. This would involve a bit more code so perhaps not ideal, but you would not have to do any changes in the SDK, and you will not have to do any other dirty hacks.

Reply
  • Hi Sean,

    SeanHowsonTB said:
    IMHO altering the SDK counstitutes as a dirty hack

    You could say that. And I agree that you should try to avoid it . But in reality, the SDK does not cover all use cases even though we try to make it as generic as possible, and also, it is not bug free. So it is not uncommon to have to change the SDK code, even though it is not ideal.

    SeanHowsonTB said:
    If i'm being honest, while i appreciate the solution you've presented it really sounds like a long winded solution for a very simple problem.

    I fully agree. But it was a suggested solution for how to call a static function without changing the code that is static, which is what you describe. I do not like that approach at all, though, as mentioned.

    I see the problem with interpreting the button press when it is a wakeup source. I would consider doing this with a completely different approach, handling the startup case as a special case, and using some dedicated code to handel it without the app_button library. You could still use the app_timer (with a dedicated instance) to do the debouncing. This would involve a bit more code so perhaps not ideal, but you would not have to do any changes in the SDK, and you will not have to do any other dirty hacks.

Children
No Data
Related