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
  • Einar, thanks for the reply.

    The goal is, as is it was in my original post. Allow the chip to enter shutdown mode. Wake up from the button press and have the button press event handler run (the handler i registered to the button when initialising the app_button).

    But i've found that this does not happen because the debounce timer is never started. So i am trying to manually start the chain of events that leads to my button handler being run. I am asking about the gpiote event handler because this seems to be the first domino in the chain/ first item in the call stack, that drives the app_button library. So it seemed sensible to start from the top... I tried just calling the contents of my custom app_button handler. But the app_button library, then doesn't "know" that the button has been pushed, subsequently when the button is released, my app_button handler does not run.

    the chain of events i've described, runs my custom event handler, and other functions that tell the app_button library that the button is pressed. I find it odd that i seemingly cant initialised the app_button library in the "already pressed" state... anyway, another approach might be to make sure app_button library to understand that the button is pressed. so that my handler runsproperly when the button is released, that way i could manually run my handler (which is global), once upon startup, to register the press, tell the libary the button is pressed. Then the handler will run just fine when the button is released. This is the equivilent of running all the things that would be triggered by manually calling the GPIOTE event handler as id originally proposed.

    I had considered & tried copying chunks of code from the functions run as a result of the debounce timer etc. But the ones i've tried require access to global variables within the app_button library, so basically the same problem i have with calling functions... (scope!)

    I take your point on not having a dirty hack. I am not a fan of dirty code so would agree here. IMHO altering the SDK counstitutes as a dirty hack (this isn't the only reason i cant change it). But the purpose of this forum post is to see if there is a non-dirty-hack solution that i'm not aware of.

    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. While i appreciate the out-of-the-box idea, it's really not suitable for a peice of firmware being deployed into an active product and makes automation of piplining & deployment very tricky and it could easily result in some serious errors in future, especially when trying to pass the code around multiple developers & use in multiple debugging environments.

    Thanks, sorry for the long reply,

    Sean

Reply
  • Einar, thanks for the reply.

    The goal is, as is it was in my original post. Allow the chip to enter shutdown mode. Wake up from the button press and have the button press event handler run (the handler i registered to the button when initialising the app_button).

    But i've found that this does not happen because the debounce timer is never started. So i am trying to manually start the chain of events that leads to my button handler being run. I am asking about the gpiote event handler because this seems to be the first domino in the chain/ first item in the call stack, that drives the app_button library. So it seemed sensible to start from the top... I tried just calling the contents of my custom app_button handler. But the app_button library, then doesn't "know" that the button has been pushed, subsequently when the button is released, my app_button handler does not run.

    the chain of events i've described, runs my custom event handler, and other functions that tell the app_button library that the button is pressed. I find it odd that i seemingly cant initialised the app_button library in the "already pressed" state... anyway, another approach might be to make sure app_button library to understand that the button is pressed. so that my handler runsproperly when the button is released, that way i could manually run my handler (which is global), once upon startup, to register the press, tell the libary the button is pressed. Then the handler will run just fine when the button is released. This is the equivilent of running all the things that would be triggered by manually calling the GPIOTE event handler as id originally proposed.

    I had considered & tried copying chunks of code from the functions run as a result of the debounce timer etc. But the ones i've tried require access to global variables within the app_button library, so basically the same problem i have with calling functions... (scope!)

    I take your point on not having a dirty hack. I am not a fan of dirty code so would agree here. IMHO altering the SDK counstitutes as a dirty hack (this isn't the only reason i cant change it). But the purpose of this forum post is to see if there is a non-dirty-hack solution that i'm not aware of.

    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. While i appreciate the out-of-the-box idea, it's really not suitable for a peice of firmware being deployed into an active product and makes automation of piplining & deployment very tricky and it could easily result in some serious errors in future, especially when trying to pass the code around multiple developers & use in multiple debugging environments.

    Thanks, sorry for the long reply,

    Sean

Children
No Data
Related