Sleep Issue with Timer and GPIO

Hi there,

In a LoRa (not LoRaWAN) app, I want to set the device to sleep for some time or until an Interrupt on a pin occurs. I have the following code:

static volatile bool lowpower = false;
static volatile uint8_t wakeUpInterrupt1 = INVALID_INTERRUPT_NUM;
static volatile uint8_t wakeUpInterrupt2 = INVALID_INTERRUPT_NUM;
static volatile int8_t wakeUpReason = INVALID_INTERRUPT_NUM;
static TimerEvent_t wakeUp;

void onTimerWakeup()
{
    lowpower = false;
    wakeUpReason = MY_WAKE_UP_BY_TIMER;
}

void onInterrupt1Wakeup()
{
    lowpower = false;
    wakeUpReason = wakeUpInterrupt1;
    ClearPinInterrupt(wakeUpInterrupt1);
    delay(10);
};

void onInterrupt2Wakeup()
{
    lowpower = false;
    wakeUpReason = wakeUpInterrupt2;
    ClearPinInterrupt(wakeUpInterrupt2);
    delay(10);
};

int8_t hwSleep(uint32_t ms)
{
    wakeUpReason = INVALID_INTERRUPT_NUM;
    lowpower = true;
    wakeUp.Callback = onTimerWakeup;
    if (ms > 0)
    {
        TimerReset(&wakeUp);
        TimerSetValue(&wakeUp, ms);
        TimerStart(&wakeUp);
    }

    while (lowpower)
    {
        lowPowerHandler;
    }

    return wakeUpReason;
}

int8_t hwSleep(const uint8_t interrupt, const uint8_t mode, uint32_t ms)
{
    wakeUpReason = INVALID_INTERRUPT_NUM;
    lowpower = true;
    wakeUpInterrupt1 = interrupt;
    attachInterrupt(wakeUpInterrupt1, onInterrupt1Wakeup, (IrqModes)mode);
    wakeUp.Callback = onTimerWakeup;
    if (ms > 0)
    {
        TimerReset(&wakeUp);
        TimerSetValue(&wakeUp, ms);
        TimerStart(&wakeUp);
    }

    while (lowpower)
    {
        lowPowerHandler;
    }
    //TimerStop(&wakeUp);
    detachInterrupt(interrupt);
    return wakeUpReason;
}

void setup() {
    boardInitMcu();
    Serial.begin(115200);
}

void loop() {
    Serial.println("Entering sleep");
    uint8_t wakeReason = hwSleep(5000);
    Serial.printf("Woken up by %d", wakeReason);
    delay(5000);
}

hwSleep(5000); works perfect. But if I do a hwSleep(5000, USER_KEY, BOTH); the CubeCell crashes after wakeup, no matter if woken by timer or button. I then have to manually reset it bevore I can upload something.

Any Ideas?

Thanks, Edi

Have you tried removing the delay(10) in in the onInterruptxWakeup routine, it is never a good idea to wait like this in a ISR.

I’ll try and report back

Nope, does not work. It works if I don’t detach the interrupts… Which is not desirable in my app… maybe void them helps, I’ll try…

hwSleep(5000, USER_KEY, BOTH)

int8_t hwSleep(const uint8_t interrupt, const uint8_t mode, uint32_t ms)

This looks funny, I assume 5000 is the wait time in ms, but that should be the last parameter …

hwSleep(USER_KEY, CHANGE,5000);

detachInterupt -> it is recommended to use like this detachInterrupt(digitalPinToInterrupt(pin))`

You are right, I mixed it up there.

I tried it, same result.

Report it looks like a bug … i tried a detach after 5 interrupts all is just fine until the fifth time i call detachInterrupt and no more interrupts occur …

I can confirm it is a bug, have implemented a work-around, to get you going, needs cleaning up will be shared later.

Thank you very much!

There has been an update which deals with attach and detachInterrupt, have not tested it yet but is should should solve your problem.

Is it only in Arduino IDE or also in the Platform.io framework?

Github is updated, I suggest you follow instruction on how to upgrade your environment.

Thanks a lot. Do you know how to do this on platform.io? If I try to update, it tells me that it’s already up to date:

Platform ASR Microelectronics ASR605x
--------
Updating asrmicro650x                    @ 1.0.0          [Up-to-date]
Updating toolchain-gccarmnoneeabi        @ 1.90201.191206 [Up-to-date]
Updating framework-arduinoasrmicro650x   @ 1.0.0          [Up-to-date]
Updating tool-cubecellelftool            @ 0.0.1          [Up-to-date]
Updating tool-cubecellflash              @ 0.0.1          [Up-to-date]