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

GPIOTE freezes on pin value change

I currently have a problem with the gpiote setup. I'm using it to detect an interrupt from mma8652 accelerometer.

here is an annotated version with the key portions of the code.

pin_event_handler()
{
    NRF_LOG_INFO("\r\n PIN 26 triggered \r\n");
    NRF_LOG_FLUSH();
}

static void accel_intrpt_pin_config()
{
    nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_HITOLO(true);
    config.pull = NRF_GPIO_PIN_PULLUP;
    err_code = nrf_drv_gpiote_in_init(26, &config, pin_event_handler);
    APP_ERROR_CHECK(err_code);
    nrf_drv_gpiote_in_event_enable(26, false);
}

main()
{
    // basic inits
    ...
    while (1)
    {
        ...
        // wait for interrupt from accelerometer to trigger pin 26 -- I never get past this
        while(nrf_drv_gpiote_in_is_set(26) == 1)
        {
            nrf_delay_ms(1000); // check every second just to be sure we didn't freeze early
            NRF_LOG_INFO("\r\n PIN 26 value: %u \r\n",nrf_drv_gpiote_in_is_set(26));
            NRF_LOG_FLUSH();
        }
    }
}

this is the ending uart output after which nothing happens

APP:INFO:
PIN 26 value: 1
APP:INFO:
PIN 26 value: 1
APP:INFO:
PIN 26 value: 0

so I see the pin changes but I never get to my trigger comment in the event handler. I'm sure I'm missing something but I haven't really been able to figure out what. When it reached the point in the code where a change was detected, the whole things stops and when I try to flash the code again to restart it, it freezes at the accelerometer register setup and I have to disconnect to remove the power to the MCU and re-connect to get it going again.

I was using the pin_change_int example to structure this. This wasn't a very complicated thing so I figured that was all I needed. then I was looking on other solved question and I saw all these other things on interrupt and priorities. Is that necessary?

  • Two hints:

    • nrf_delay_ms function is blocking MCU with NOP instructions, doesn't really work well if you wait for some asynchronous thing like interrupt. I use it for some quick debugging as well but in your case implementing correct timer (e.g. through RTC based app_timer library) would be much better.
    • Similar with your interrupt handler: doing any time-consuming action or computation might lead to different kind of failures or unexpected behavior. So your UART logging might look short but in some extreme cases you can be running out of time. As you experience some troubles exactly here I would either remove it completely or put some faster debugging indication like simple GPIO LOW/HIGH control of single output PIN and observing it with oscilloscope or better logical analyzer....
  • Hi,

    You need to set the int_enable parameter in nrf_drv_gpiote_in_event_enable() to true to enable the interrupt. If you look in the implementation of the function, you will see that interrupt and handler is only set if this parameter is true.

    Best regards,

    Jørgen

  • That's good to know that some things like uart can be the source. The delay_ms function was my attempt just to do a quick debug on the value coming in and I wanted to verify that I was getting an interrupt from the accelerometer since if I don't have uart I won't see anything. That I can remove. And unfortunately, since I don't own the hardware like an oscilloscope, uart is the easiest option for me to look at the pin output.

    If you have anything like this to point out about my response to Jorgen that would be appreciated. More knowledge or examples is always helpful.

  • This appears to have worked as I can now trigger the statement in pin_event_handler. As a follow-up question, is there something that stops the function form going on after hitting the interrupt? It seems to just stop doing anything in the outermost while loop in function main? I've seen other question that reference NRF_GPIOTE->EVENT_PORT = 0 NRF_GPIOTE->EVENTS_IN[0] but I don't quite understand how these work or if they are related at all to make the code continue.

    I assume this should be fairly common action to code where a sensor sends an interrupt and I want to take take note of that and call a read on the data. I haven't seen any examples but is there anything I can reference for this?

  • Hi Dan, fully understand the constrains, just note that clones of Saleae Logic can be yours for 5USD including shipping...;)

Related