Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes the issue that gen3 devices cannot be woken up by RTC. #2134

Merged
merged 2 commits into from
Jul 2, 2020

Conversation

XuGuohui
Copy link
Member

Problem

System.sleep(SystemSleepConfiguration().mode(SystemSleepMode::STOP).duration(3s)); doesn't work on Gen3 platforms.

Solution

This issue is caused by not clearing RTC event in its interrupt handler. After device being woken up in hal_sleep_enter(), it will repeat entering the RTC interrupt handler.

Steps to Test

  • Build and flash the example below
  • Build and flash the test application in user/tests/wiring/sleep20

Example App

#include "Particle.h"

SYSTEM_MODE(MANUAL);

void setup() {
    delay(1000);
    System.sleep(SystemSleepConfiguration().mode(SystemSleepMode::STOP).duration(3s));
}

void loop() {
}

Completeness

  • User is totes amazing for contributing!
  • Contributor has signed CLA (Info here)
  • Problem and Solution clearly stated
  • Run unit/integration/application tests on device
  • Added documentation
  • Added to CHANGELOG.md after merging (add links to docs and issues)

@XuGuohui XuGuohui added this to the 2.0.0 milestone Jun 19, 2020
@XuGuohui XuGuohui requested a review from avtolstoy June 19, 2020 18:45
@@ -284,6 +285,16 @@ extern "C" void RTC_IRQ_HANDLER(void) {
sTimerMicrosAtLastOverflow = getCurrentTime();
sTickCountAtLastOverflow = DWT->CYCCNT;
__set_PRIMASK(pri);
} else if (nrf_rtc_event_pending(RTC_INSTANCE, NRF_RTC_EVENT_TICK)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we know which event in particular causes this? While it is fine to just clear everything in the handler, we should have been able to do that in hal_timer_init() after waking up from sleep and enable only what is required.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We make use of the NRF_RTC_EVENT_COMPARE_0 event. Clearing events in hal_timer_init() doesn't work after waking up from sleep, as the interrupt handler is executed immediately following __enable_irq();, which is before hal_timer_init() being executed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That should not be happening though, right? We unbump the priority level of both the GPIOTE and RTC interrupts right before calling __enable_irq(). If they do get triggered that's a bug in the sleep code. This has also been working previously just fine for quite a while. This is not new code.

Copy link
Member

@avtolstoy avtolstoy Jun 22, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to clarify: I meant that calling __enable_irq() at that point in sleep code does not unblock interrupts with priorities >= 2 because we are still under effect of BASEPRI. We do re-enable interrupts with priority >= 5 while waiting for SoftDevice to do certain things, but that should also not apply to RTC as it's configured normally at 6.

@XuGuohui XuGuohui requested a review from avtolstoy June 23, 2020 17:15
@avtolstoy avtolstoy added ready to merge PR has been reviewed and tested and removed needs review labels Jun 25, 2020
@avtolstoy avtolstoy merged commit f294177 into develop Jul 2, 2020
@avtolstoy avtolstoy deleted the fix/rtc_wakeup branch July 2, 2020 12:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug ready to merge PR has been reviewed and tested
Projects
None yet
2 participants