- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Labels:
-
Debug
-
GPIO
-
Recovery
-
Sleep Modes
-
WICED Sense
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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);
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Perhaps you already have your answer, as I see an answer marked correct. But I notice a couple of things that I would do.
- 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.
- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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