Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

attachInterrupt() current consumption #754

Open
muhdRiz07 opened this issue Dec 9, 2022 · 3 comments
Open

attachInterrupt() current consumption #754

muhdRiz07 opened this issue Dec 9, 2022 · 3 comments
Labels

Comments

@muhdRiz07
Copy link

Operating System

Linux

IDE version

PlatformIO 3.4.3

Board

adafruit_feather_nrf52832

BSP version

1.3.0

Sketch

`#include <Arduino.h>

#define INT_PIN 14
#define LED 17
uint8_t sleepTime = 0;
uint8_t sleepDuration = 100000;

void irqHandler()
{
Serial.print("interrupt activated");
}

void setup() {
Serial.begin(9600);
Serial.print("led ON");
Serial.end();
pinMode(LED, OUTPUT);
digitalWrite(LED, HIGH);

pinMode(INT_PIN, INPUT_PULLUP_SENSE);
attachInterrupt(INT_PIN, irqHandler, FALLING);
}

void loop()
{
sleepTime = 0;
digitalWrite(LED, HIGH);
delay(1000);
digitalWrite(LED, LOW);
delay(5000);
Serial.begin(9600);
Serial.println("sleep mode");
Serial.end();
while(sleepTime < sleepDuration){
__WFI(); //sleep mode//
sleepTime ++;
}
}`

What happened ?

Hi, here I am facing issue regarding current consumption in sleep mode.It is drawing 13uA in sleep mode when interrupt is enabled and 1uA when interrupt is disabled. Is there any way to reduce the current in sleep mode without disabling interrupt.

How to reproduce ?

Check the above code with attachInterrupt() and without attachInterrupt()

Debug Log

No response

Screenshots

No response

@muhdRiz07 muhdRiz07 added the Bug label Dec 9, 2022
@jgartrel
Copy link
Contributor

jgartrel commented Feb 1, 2023

@muhdRiz07 I use nrf_gpio_cfg_sense_input to leverage the GPIO DETECT signal and generate a Port Event instead of attachInterrupt. This only adds 100nA-200nA more current consumption.

See similar issue in: #165 (comment)

@ericlangel
Copy link

@jgartrel Could you give us an example please?

@jgartrel
Copy link
Contributor

@ericlangel The below code has some untested changes to decode the proper pin position in the latch registers, but I think it should work for both the nrf52832 (single GPIO port) and nrf52840 (dual GPIO port).

You should ensure that whatever code or framework that you use this with does not also use the NRF_EGU3 user defined Event Generation Unit or you will have issues.

Please let me know if this code works for you.

#include <Arduino.h>
#include <bluefruit.h>
#include <WInterrupts.h>

#define INT_PIN 15

volatile unsigned long ms = 25;

extern "C" void SWI3_EGU3_IRQHandler(void)
{
  noInterrupts();
  #if CFG_SYSVIEW
  SEGGER_SYSVIEW_RecordEnterISR();
  #endif

  /* Do something here */
  ms = 2000;

  /* Clear event register and re-arm the event pipeline */
  NRF_EGU3->EVENTS_TRIGGERED[0] = 0;
  NRF_GPIOTE->EVENTS_PORT = 0;

  #if CFG_SYSVIEW
  SEGGER_SYSVIEW_RecordExitISR();
  #endif
  interrupts();
}

void ppi_interrupt_init()
{
    /* 6 is the default int. priority used in SDK drivers */
    NVIC_SetPriority(SWI3_EGU3_IRQn, 6);
    NVIC_ClearPendingIRQ(SWI3_EGU3_IRQn);
    NVIC_EnableIRQ(SWI3_EGU3_IRQn);

    NRF_EGU3->INTENSET = EGU_INTEN_TRIGGERED0_Msk;

    NRF_PPI->CH[0].EEP = (uint32_t) &NRF_GPIOTE->EVENTS_PORT;
    NRF_PPI->CH[0].TEP = (uint32_t) &NRF_EGU3->TASKS_TRIGGER[0];

    NRF_PPI->CHENSET = PPI_CHENSET_CH0_Msk;
}

void setup() {
  Bluefruit.begin();
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, !LED_STATE_ON);

  /* Use PPI to route the Port Event signal to a custom interrupt handler */
  ppi_interrupt_init();

  /* Generate a Port Event signal when INT_PIN goes LOW */
  nrf_gpio_cfg_sense_input(INT_PIN, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
}

void loop() 
{
  digitalWrite(LED_BUILTIN, LED_STATE_ON);
  delay(ms);
  digitalWrite(LED_BUILTIN, !LED_STATE_ON);

  /* Acknowledge the interrupt */
  uint32_t latchStatus[GPIO_COUNT] = {0};
  nrf_gpio_latches_read_and_clear(0, GPIO_COUNT, latchStatus);

  /* Decode the proper pin position in the latch registers */
  uint32_t intPin = g_ADigitalPinMap[INT_PIN];
  uint32_t intPort = (intPin < P0_PIN_NUM) ? 0 : 1;
  uint32_t intMask = (1UL << (intPin - P0_PIN_NUM * intPort));

  /* Reset delay ms if INT was caused by INT_PIN */
  if ( latchStatus[intPort] & intMask ) {
    ms = 25;
  }

  delay(20000);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants