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

Workaround for Errata 97

Hi,

As per the Errata 97, there is increase in current consumption if GPIOTE is used in Input mode. We are working on low power device and cannot afford increase in current consumption.

My question is how can we get interrupts on the PORT without using GPIOTE?

The workaround for this erratum says "Use Port event to detect transitions on inputs instead of GPIOTE input mode". Can you guide us to the example code to use port events for interrupts?

Will there be any fix for this erratum from nordic side in near future?

Thanks,

Justin

  • Hi,

    If you are using the GPIOTE driver, you can use PORT mode by setting the hi_accuracy parameter in the config to 0. If you are writing the registers directly, it should be sufficient to configure the GPIO with SENSE enabled and enable interrupts for the EVENTS_PORT event.

    This errata has been inherited from nRF52832 engineering A revision, I do not expect it to be fixed in any potential future spin of this chip. It seems to be fixed in never nRF52 series chips.

    Best regards,
    Jørgen

  • Hi Jorgen,

    I am writing to the registers directly. Following is my code.

    void GPIOTE_IRQHandler()
    {

        gpiote->events_in0 = 0;
        wake_spis0(); // This function enables the spi communication
       
    }

    void gpiote_init()
    {
        gpiote->config0 = (1 << 16)          // Polarity ... LoToHi
                       | (15 << 8)           // PSEL ....... P0.15
                      | (1 << 0);           // MODE ....... Event
         gpiote->intenset = (1 << 0);     // enable interrupt for config0
        *(uint32_t *)0xE000E100 = (1 << 6);  // enable GPIOTE interrupt at NVIC
           
    }
    I tried enabling SENSE and EVENTS_PORT but nothing worked out for me.
    Can you please advice me in above code how can I configure GPIO interrupt and take care of Errata 97?
  • Hi,

    This is a simple example for configuring and enabling interrupts for GPIOTE PORT event:

    #include "nrf.h"
    #include "nrf_gpio.h"
    #include "boards.h"
    
    
    void GPIOTE_IRQHandler()
    {
        if(NRF_GPIOTE->EVENTS_PORT == 1)
        {
            nrf_gpio_pin_toggle(LED_1); // Toggle LED1 when BUTTON1 is pressed
            NRF_GPIOTE->EVENTS_PORT = 0;
        }
    }
    
    /**
     * @brief Function for application main entry.
     */
    int main(void)
    {
        // Configure the GPIO pin for LED 1 on the nRF52832 dev kit
        // and turn off led
        nrf_gpio_cfg_output(LED_1);
        nrf_gpio_pin_clear(LED_1);
    
        // Configure the GPIO pin for Button 1 on the nRF52832 dev kit
        // as input with pull-up resistor enabled and low-sensing.
        NRF_GPIO->PIN_CNF[BUTTON_1] = (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) |
                                         (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) |
                                         (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) |
                                         (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) |
                                         (GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos);
        
        NRF_GPIOTE->EVENTS_PORT = 0;
        
        //Enable interrupts for PORT event
        NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_PORT_Enabled << GPIOTE_INTENSET_PORT_Pos;
        NVIC_SetPriority(GPIOTE_IRQn, 7);
        NVIC_EnableIRQ(GPIOTE_IRQn);
    
        while (true)
        {
            __WFE();
        }
    }
    

    Best regards,
    Jørgen

  • This is a simple example for configuring and enabling interrupts for GPIOTE PORT event:

    Hi,

    I want to use registers directly instead of GPIOTE driver. Using following piece of code to configure to enable interrupts for the EVENTS_PORT.

    void GPIOTE_IRQHandler()
    {
        gpiote->events_port = 0;
        wake_spis0();   // Application logic
    }

    void gpiote_init()
    {
        gpiote->events_port = 0;
        gpio->latch = 0;
        gpio->pin_cnf13 = (uint32_t)(2 << 16) ; // sense high
        gpiote->intenset |= (uint32_t)(1 << 31);        // enable interrupt for INTENSET
        *(uint32_t *)0xE000E100 |= (1 << 6);    // enable GPIOTE interrupt at NVIC
    }
    Is this the right way to use port events to receive the interrupt and work it around the Errata 97?
  • Yes, it seems like this should work. It is very similar to my code (which also writes to the registers, it is not using the driver).

Related