8000 rp2: Fix USB PLL glitch during wake from light sleep. · micropython/micropython@068d9bf · GitHub
[go: up one dir, main page]

Skip to content

Commit 068d9bf

Browse files
committed
rp2: Fix USB PLL glitch during wake from light sleep.
Follow-up to a84c7a0, this commit works most of the time but has an intermittent bug where USB doesn't resume as expected after waking from light sleep. Turns out waking calls clocks_init() which will re-initialise the USB PLL. Most of the time this is OK but occasionally it seems like the clock glitches the USB peripheral and it stops working until the next hard reset. Adds a machine.lightsleep() test that consistently hangs in the first two dozen iterations on rp2 without this fix. Passed over 100 times in a row with this fix. The test is currently rp2-only as it seems similar lightsleep USB issues exist on other ports (both pyboard and ESP32-S3 native USB don't send any data to the host after waking, until they receive something from the host first.) This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
1 parent 5dcffb5 commit 068d9bf

File tree

3 files changed

+35
-2
lines changed

3 files changed

+35
-2
lines changed

ports/rp2/modmachine.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
#include "mp_usbd.h"
3232
#include "modmachine.h"
3333
#include "uart.h"
34-
#include "hardware/clocks.h"
34+
#include "clocks_extra.h"
3535
#include "hardware/pll.h"
3636
#include "hardware/structs/rosc.h"
3737
#include "hardware/structs/scb.h"
@@ -213,7 +213,7 @@ static void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) {
213213
rosc_hw->ctrl = ROSC_CTRL_ENABLE_VALUE_ENABLE << ROSC_CTRL_ENABLE_LSB;
214214

215215
// Bring back all clocks.
216-
clocks_init();
216+
clocks_init_optional_usb(disable_usb);
217217
MICROPY_END_ATOMIC_SECTION(my_interrupts);
218218
}
219219

tests/ports/rp2/rp2_lightsleep.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# This test is mostly intended for ensuring USB serial stays stable over
2+
# lightsleep, but can double as a general lightsleep test.
3+
#
4+
# In theory this should run on any port, but native USB REPL doesn't currently
5+
# recover automatically on all ports. On pyboard and ESP32-S3 the host needs to
6+
# send something to the port before it responds again. Possibly the same for other
7+
# ports with native USB.
8+
#
9+
# A range of sleep periods (1 to 512ms) are tested. The total nominal sleep time
10+
# is 10.23 seconds, but on most ports this will finish much earlier as interrupts
11+
# happen before each timeout expires.
12+
try:
13+
from machine import lightsleep, Pin
14+
except ImportError:
15+
print("SKIP")
16+
raise SystemExit
17+
18+
from sys import stdout, platform
19+
20+
try:
21+
led = Pin(Pin.board.LED, Pin.OUT)
22+
except AttributeError:
23+
led = None
24+
25+
for n in range(100):
26+
if led:
27+
led.toggle()
28+
stdout.write(chr(ord("a") + (n % 26)))
29+
lightsleep(2 ** (n % 10))
30+
31+
print("\nDONE")

tests/ports/rp2/rp2_lightsleep.py.exp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuv
2+
DONE

0 commit comments

Comments
 (0)
0