5 Replies Latest reply on Apr 21, 2016 11:19 AM by aneedles

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

    aneedles

      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

        • 1. Re: BCM20736S "wake on GPIO" is calling interrupt handler instead of normal wake cycle
          BoonT_56

          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?

          1 of 2 people found this helpful
          • 2. Re: BCM20736S "wake on GPIO" is calling interrupt handler instead of normal wake cycle
            aneedles

            Thanks BoonT_56

             

            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);

            }

            • 3. Re: BCM20736S "wake on GPIO" is calling interrupt handler instead of normal wake cycle
              aneedles

              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

              • 4. Re: BCM20736S "wake on GPIO" is calling interrupt handler instead of normal wake cycle
                cliff@rayman.com

                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.
                2 of 2 people found this helpful
                • 5. Re: BCM20736S "wake on GPIO" is calling interrupt handler instead of normal wake cycle
                  aneedles

                  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