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!