BCM20736S "wake on GPIO" is calling interrupt handler instead of normal wake cycle

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

On the BCM20736S, we are trying to wake on various GPIOs, For the most part, this is working fine. But about 20% of the time we see the BCM20736S wake into the registered GPIO callback instead of going through the normal wake cycle.

Any ideas one why this might be happening?

Thanks in advance,

     Aaron

5 Replies
BoonT_56
Employee
Employee
500 likes received 250 likes received 100 likes received

Is this happening on your own board or the tag3? The i2c_temperature_sensor app is the classic example of "wake on gpio".

Check out Arvind's reply in the below thread.

How can I wake BCM20737S up by using GPIO interrupt?

Anonymous
Not applicable

Thanks boont

The code is running on our own board, and the "wake on GPIO" is already functioning, just not reliably. It goes to sleep and I see less than 200 microamps power draw. However, a change to a GPIO pin (a button press in this case) will sometimes cause the BCM20736S to wake normally and other times it wakes into the GPIO interrupt handler instead. We need it to wake reliably.

In order to get it to sleep in the first place we call:

void goto_sleep()

{

    ble_trace0("Entering DEEP SLEEP");

    bleprofile_KillTimer();

    // One more time to avoid keyscan issue, as seen on forums

    gpio_configurePin(0,0,GPIO_INPUT_DISABLE | GPIO_OUTPUT_DISABLE,0);

    devLpmConfig.disconnectedLowPowerMode = DEV_LPM_DISC_LOW_POWER_MODES_HID_OFF;

    devLpmConfig.wakeFromHidoffInMs = HID_OFF_WAKEUP_TIME_NONE;

   // This spec's the wait time after entering deep sleep before giving up

    // and calling HID_ABORT callback

    miaDriverConfig.delayAfterEnteringHidOffInUs = 100000;

    devLpmConfig.wakeFromHidoffRefClk = HID_OFF_TIMED_WAKE_CLK_SRC_128KHZ;

    // One more time to avoid keyscan issue, as seen on forums

    gpio_configurePin(0,0,GPIO_INPUT_DISABLE | GPIO_OUTPUT_DISABLE,0);

    // Final clear of GPIO interrupt states

    gpio_clearPinInterruptStatus(GPIO_PORT0, GPIO_PORT0_P2);

    gpio_clearPinInterruptStatus(GPIO_PORT0, GPIO_PORT0_P8);

   gpio_clearPinInterruptStatus(GPIO_PORT0, GPIO_PORT0_P11);

    mia_enterHidOff(0, HID_OFF_TIMED_WAKE_CLK_SRC_128KHZ);

}

Then since it sometimes exits mia_enterHidOff(), we also register for these callbacks:

The second of these will retry sleep entry.

    bleprofile_regAppEvtHandler(BLECM_APP_EVT_ENTERING_HIDOFF, (BLECM_NO_PARAM_FUNC)app_enter_hidoff);

    bleprofile_regAppEvtHandler(BLECM_APP_EVT_ABORTING_HIDOFF,(BLECM_NO_PARAM_FUNC)app_abort_hidoff);

void app_enter_hidoff(void)

{

  // Do nothing.

}

void app_abort_hidoff(void)

{

  // If sleep is aborted, try again...

  gpio_clearPinInterruptStatus(GPIO_PORT0, GPIO_PORT0_P2);

  gpio_clearPinInterruptStatus(GPIO_PORT0, GPIO_PORT0_P8);

  gpio_clearPinInterruptStatus(GPIO_PORT0, GPIO_PORT0_P11);

  mia_enterHidOff(0, HID_OFF_TIMED_WAKE_CLK_SRC_128KHZ);

}

0 Likes
Anonymous
Not applicable

Ok, I think I have a work around.

It appears it has something to do with the BCM20736S not making it into a 100% healthy sleep mode. If I do the following it appears to force the issue and I no longer get the calls to my GPIO handler from wake.

while (1) {

     // Final clear of GPIO interrupt states

    gpio_clearPinInterruptStatus(GPIO_PORT0, GPIO_PORT0_P2);

    gpio_clearPinInterruptStatus(GPIO_PORT0, GPIO_PORT0_P8);

   gpio_clearPinInterruptStatus(GPIO_PORT0, GPIO_PORT0_P11);

    mia_enterHidOff(0, HID_OFF_TIMED_WAKE_CLK_SRC_128KHZ);

}

However, this has the side effect of putting the BCM20736S into a sleep mode with 3mA current draw!

My final work around is to reset it (using the code below) and my wake-up code will put it to sleep if POR is detected.

mia_enterHidOff(0, HID_OFF_TIMED_WAKE_CLK_SRC_128KHZ);

// If mia_enterHidOff(), we force a reset so that we can wake and then get a reliable sleep mode

wdog_configure(TRUE);

bleappfwu_watchdogExpired();

while (1) {} // Hang

This seems to be working reliably to avoid both the calls to my GPIO handler from wake and the 3mS sleep condition. It is a hack, but gets me reliable operation.

-Aaron

0 Likes
Anonymous
Not applicable

Perhaps you already have your answer, as I see an answer marked correct.  But I notice a couple of things that I would do.

  1. Increase the time here so you have a better chance of operations finishing before HIDOFF is attempted: miaDriverConfig.delayAfterEnteringHidOffInUs = 100000;  I had to increase this to 3000000 with our firmware.
  2. Add some ble_trace calls to your enter and abort HIDOFF callbacks to see if that might be an issue.  If you see an abort hidoff trace message, increase the delay or fix other issues until you do this reliably.
Anonymous
Not applicable

Actually, boont marked the answer correct as soon as it was posted, but it wasn't actually what I needed.

Thanks for the tip.  I tried the longer timeout, but then it blocks me from seeing GPIO changes until it is complete. The full reset after 1/10th second is a hack, but gets the device ready faster for the next user input.

Thanks,

       Aaron

0 Likes