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

current consumption increases after first GPIOTE interrupt

I have a problem with some current consumption I cannot explain. I first thought it had something to do with floating pins or something, but that does not seem to be the case.

The problem boils down to this: after startup, I configure pins, and. among other things, I configure the GPIOTE, to generate a port interrupt, and enable 2 pins which are connected to a switch. When I then go to low power, all is fine, current consumption is about 20 uA (I have some peripherals on my board, so the 20 uA is as expected).

However, when I receive a first GPIOTE interrupt, when pressing a button, my current consumption increases to about 600 uA. I really cannot figure out what I am doing wrong. The only thing is that, when I disable the GPIOTE interrupt, but still operate everything else, like timers and such, the sleep mode current stays at around 20 uA.

Is there something in a GPIOTE interrupt that keeps something awake in the chip? Can anyone give me a hint of what might be wrong?

BTW: I am not using the app_gpiote library, I wrote my own, much more limited version. Maybe I need to reset something in my interrupt routine, I do not know. Any ideas are welcome.

Parents
  • I use the port interrupt, not a pin interrupt, like this:

    Init function:

    void gpiote_init(app_sched_event_handler_t handler)
    {
        gpiote_interrupt_callback = handler;
        // Initialize GPIOTE interrupt (will not be enabled until app_gpiote_user_enable() is called).
        NRF_GPIOTE->INTENCLR = 0xFFFFFFFF;
        NVIC_ClearPendingIRQ(GPIOTE_IRQn);
        NVIC_SetPriority(GPIOTE_IRQn, APP_IRQ_PRIORITY_HIGH);
        NVIC_EnableIRQ(GPIOTE_IRQn);
    }
    

    And then enable:

    void gpiote_enable_pin(uint32_t pin,bool rising_edge)
    {
        NRF_GPIOTE->EVENTS_PORT = 0;
        NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_PORT_Msk;
        NRF_GPIO->PIN_CNF[pin] &= ~GPIO_PIN_CNF_SENSE_Msk;
        if (rising_edge) NRF_GPIO->PIN_CNF[pin] |= GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos;
        else NRF_GPIO->PIN_CNF[pin] |= GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos;
    }
    

    And then turning on the actual interrupt:

    void gpiote_enable_port_interrupt()
    {
        NRF_GPIOTE->EVENTS_PORT = 0;
        NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_PORT_Msk;
    }
    

    And interrupt service routine:

    void GPIOTE_IRQHandler(void) {
        gpiote_disable_port_interrupt();
    
        static uint32_t pins_state;
        pins_state = NRF_GPIO->IN;
    
        // Clear event.
        NRF_GPIOTE->EVENTS_PORT = 0;
        if (gpiote_interrupt_callback != NULL)
        {
            uint32_t retval =    app_sched_event_put(&pins_state, sizeof(pins_state), gpiote_interrupt_callback);
            if (retval != NRF_SUCCESS)
            DBG(0,"GPIOTEIRQ: scheduled handler with reval %d\n",retval);
        } }
    
Reply
  • I use the port interrupt, not a pin interrupt, like this:

    Init function:

    void gpiote_init(app_sched_event_handler_t handler)
    {
        gpiote_interrupt_callback = handler;
        // Initialize GPIOTE interrupt (will not be enabled until app_gpiote_user_enable() is called).
        NRF_GPIOTE->INTENCLR = 0xFFFFFFFF;
        NVIC_ClearPendingIRQ(GPIOTE_IRQn);
        NVIC_SetPriority(GPIOTE_IRQn, APP_IRQ_PRIORITY_HIGH);
        NVIC_EnableIRQ(GPIOTE_IRQn);
    }
    

    And then enable:

    void gpiote_enable_pin(uint32_t pin,bool rising_edge)
    {
        NRF_GPIOTE->EVENTS_PORT = 0;
        NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_PORT_Msk;
        NRF_GPIO->PIN_CNF[pin] &= ~GPIO_PIN_CNF_SENSE_Msk;
        if (rising_edge) NRF_GPIO->PIN_CNF[pin] |= GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos;
        else NRF_GPIO->PIN_CNF[pin] |= GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos;
    }
    

    And then turning on the actual interrupt:

    void gpiote_enable_port_interrupt()
    {
        NRF_GPIOTE->EVENTS_PORT = 0;
        NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_PORT_Msk;
    }
    

    And interrupt service routine:

    void GPIOTE_IRQHandler(void) {
        gpiote_disable_port_interrupt();
    
        static uint32_t pins_state;
        pins_state = NRF_GPIO->IN;
    
        // Clear event.
        NRF_GPIOTE->EVENTS_PORT = 0;
        if (gpiote_interrupt_callback != NULL)
        {
            uint32_t retval =    app_sched_event_put(&pins_state, sizeof(pins_state), gpiote_interrupt_callback);
            if (retval != NRF_SUCCESS)
            DBG(0,"GPIOTEIRQ: scheduled handler with reval %d\n",retval);
        } }
    
Children
No Data
Related