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

RP2 - lightsleep() fails/does not exit when started from inside a thread - solution #14092

Closed
2 tasks done
mungewell opened this issue Mar 14, 2024 · 4 comments
Closed
2 tasks done
Labels

Comments

@mungewell
Copy link
Contributor

Checks

  • I agree to follow the MicroPython Code of Conduct to ensure a safe and respectful space for everyone.

  • I've searched for existing issues matching this bug, and didn't find any.

Port, board and/or hardware

rp2 - official Pico (non-wifi)

MicroPython version

MicroPython v1.22.2 on 2024-02-22; Raspberry Pi Pico with RP2040

Reproduction

Run the attached script...

blink_thread.py.txt

Expected behaviour

When called within (only) a function, lightsleep() correct exits and the rest of the function are run.

MPY: soft reboot
Blink in thread test
CPU Freq 100000000
entering lightsleep
wake from sleep
CPU Freq 125000000

Observed behaviour

The lightsleep() call does not exit....

MPY: soft reboot
Blink in thread test
CPU Freq 100000000
entering lightsleep

...

Additional Information

No, I've provided everything above.

@mungewell mungewell added the bug label Mar 14, 2024
@mungewell
Copy link
Contributor Author

I commented out various bits of the lightsleep() code, and noted that it DOES work from within a thread - if it does NOT call __wfi()

         scb_hw->scr |= M0PLUS_SCR_SLEEPDEEP_BITS;
+#if 0 //SDW
         __wfi();
+#endif //SDW
         scb_hw->scr &= ~M0PLUS_SCR_SLEEPDEEP_BITS;

So does this mean that the (previously set) timer interrupt does not occur, if running from within a thread? And if so, why?

@mungewell
Copy link
Contributor Author

Seems that IRQs are NOT enabled, on the core that the code is running.... if we enable them, then the lightsleep() functions OK.

Patch (mixed in with my other stuff) is something like

@@ -165,18 +233,25 @@ STATIC void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) {
     } else {
         uint32_t sleep_en0 = clocks_hw->sleep_en0;
         uint32_t sleep_en1 = clocks_hw->sleep_en1;
-        clocks_hw->sleep_en0 = CLOCKS_SLEEP_EN0_CLK_RTC_RTC_BITS;
+        bool timer3_enabled = irq_is_enabled(3);
+        clocks_hw->sleep_en0 = req_sleep_en0 | CLOCKS_SLEEP_EN0_CLK_RTC_RTC_BITS;
         if (use_timer_alarm) {
             // Use timer alarm to wake.
-            clocks_hw->sleep_en1 = CLOCKS_SLEEP_EN1_CLK_SYS_TIMER_BITS;
+            clocks_hw->sleep_en1 = req_sleep_en1 | CLOCKS_SLEEP_EN1_CLK_SYS_TIMER_BITS;
+           // Make sure ALARM3/IRQ is enabled on _this_ core
+            timer_hw->inte |= 1 << 3;
+           if (timer3_enabled == false)
+               irq_set_enabled(3, true);
             timer_hw->alarm[3] = timer_hw->timerawl + delay_ms * 1000;
         } else {
             // TODO: Use RTC alarm to wake.
-            clocks_hw->sleep_en1 = 0;
+            clocks_hw->sleep_en1 = req_sleep_en1;
         }
         scb_hw->scr |= M0PLUS_SCR_SLEEPDEEP_BITS;
         __wfi();
         scb_hw->scr &= ~M0PLUS_SCR_SLEEPDEEP_BITS;
+       if (timer3_enabled == false)
+           irq_set_enabled(3, false);
         clocks_hw->sleep_en0 = sleep_en0;
         clocks_hw->sleep_en1 = sleep_en1;

@mungewell mungewell changed the title RP2 - lightsleep() fails/does not exit when started from inside a thread RP2 - lightsleep() fails/does not exit when started from inside a thread - solution Mar 27, 2024
@mungewell
Copy link
Contributor Author

BTW I have PR with the Pico SDK for keeping some of the clocks running:
raspberrypi/pico-sdk#1672

mungewell added a commit to mungewell/micropython that referenced this issue Mar 28, 2024
As per Bug micropython#14092 when called from within a thread the interrupts
may not be enabled on current core, and thus the call to
`lightsleep()` never completes.

Signed-off-by: Simon Wood <[email protected]>
mungewell added a commit to mungewell/micropython that referenced this issue Mar 28, 2024
As per Bug micropython#14092 when called from within a thread the interrupts
may not be enabled on current core, and thus the call to
`lightsleep()` never completes.

Signed-off-by: Simon Wood <[email protected]>
dpgeorge pushed a commit to mungewell/micropython that referenced this issue Apr 22, 2024
When `lightsleep()` is called from within a thread the interrupts may not
be enabled on current core, and thus the call to `lightsleep()` never
completes.

Fixes issue micropython#14092.

Signed-off-by: Simon Wood <[email protected]>
@dpgeorge
Copy link
Member

Fixed in 19844b4

graeme-winter pushed a commit to winter-special-projects/micropython that referenced this issue Sep 21, 2024
When `lightsleep()` is called from within a thread the interrupts may not
be enabled on current core, and thus the call to `lightsleep()` never
completes.

Fixes issue micropython#14092.

Signed-off-by: Simon Wood <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
2 participants