This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Reduce GPIO current draw

Hi there, 

We are currently developing and testing on the nRF5340. We are using our own OS (not Zephyr).

We measure power on the devkit by connecting the PPK2 as a source meter to the external supply, and then switching SW10 (VEXT->NRF) switch to on. 

With the above setup, we measure a current of 2uA when the device goes into System Off mode, and about 11uA in System On Low power mode. The only peripherals running are the RTC and the watchdog.

However when we use the GPIO peripheral, the current draw shoots up to 270uA when the device goes into System On Low Power mode. This seems extremely high, and we are not able to get this current down. This is the steps we performed on the GPIO peripheral:

1) Set LED1 pin as output

2) Set button1 as input and enable the interrupt for it

3) The interrupt service routine then toggles the LED.

NRF_P0_S->PIN_CNF[28] = (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos) | //Set LED1
                                   (GPIO_PIN_CNF_DRIVE_S0S1 << GPIO_PIN_CNF_DRIVE_Pos) |
                                   (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) |
                                   (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos) |
                                   (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos);
    
NRF_P0_S->PIN_CNF[23] = (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | // Configure Button 1 dev kit as input with pull-up resistor enabled.
                                   (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_Disabled << GPIO_PIN_CNF_SENSE_Pos);
      
NRF_GPIOTE0_S->CONFIG[0] =    (GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos) |
                                            (23 << GPIOTE_CONFIG_PSEL_Pos) |
                                            (GPIOTE_PORT << GPIOTE_CONFIG_PORT_Pos) |
                                            (GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos);
    
NRF_GPIOTE0_S->INTENSET = GPIOTE_INTENSET_IN0_Set << GPIOTE_INTENSET_IN0_Pos;
    
NVIC_SetPriority(GPIOTE0_IRQn, (uint32_t) ISR_PRIORITY_RAIL);
NVIC_EnableIRQ(GPIOTE0_IRQn);

void GPIOTE0_IRQHandler(void)
{
    if(NRF_GPIOTE0_S->EVENTS_IN[0])
    {
      NRF_GPIOTE0_S->EVENTS_IN[0] = 0;
      
      if(NRF_P0_S->OUT & (1 << LED1_PIN))
      {
        NRF_P0_S->OUTCLR = (1UL << LED1_PIN);
      }
      else      
      {
        NRF_P0_S->OUTSET = (1UL << LED1_PIN);
      }
    }
}

This works as expected, however current draw is 270uA in System On Low Power mode, regardless of the state of the LED, which seems extremely high. How can we reduce the current draw? We execute the following to allow the processor to go into low power:

    NRF_POWER_S->TASKS_LOWPWR = 1U;     //Enable low power mode
    
    __DSB();
    __WFE();

Kind regards,

Frikkie

  • Hi Stian,

    Thanks for your response. Understood that the using the PORT interrupt will use less current. 

    Could you please respond with the following on the case which Hung is handling.

    1) Is it specified somewhere that the IN event will add current while the PORT event will not?

    2) When using the PORT event, and there are 2 inputs on the same GPIO port, how would one know which input triggered the interrupt?

    3) How exactly are you measuring current on the DK? Could you please describe your exact hardware setup

    Looking forward to your response!

    Regards,

    Frikkie

  • Cause of issue was that we were using the GPIOTE IN interrupt instead of the PORT interrupt.

Related