Skip to content

Commit d6986d6

Browse files
committed
rp2: Selectively leave the USB clocks enabled in light sleep.
Without this change going to lightsleep stops the USB peripheral clock, and can lead to either the device going into a weird state or the host deciding to issue a bus reset. This change only keeps the USB peripheral clocks enabled if the USB device is currently active and a host has configured the device. Otherwise USB clocks are disabled same as before. Increases power consumption in light sleep (measured at the USB port for a PICO board as 12-13mA without this change, and 34-35mA with this change). I think can argue that if you have a working active USB host connection, an extra 20mA is unlikely to be significant. As discussed at https://github.com/orgs/micropython/discussions/14401 This work was funded through GitHub Sponsors. Signed-off-by: Angus Gratton <angus@redyak.com.au>
1 parent a196468 commit d6986d6

File tree

1 file changed

+21
-3
lines changed

1 file changed

+21
-3
lines changed

ports/rp2/modmachine.c

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
// extmod/modmachine.c via MICROPY_PY_MACHINE_INCLUDEFILE.
2929

3030
#include "py/mphal.h"
31+
#include "mp_usbd.h"
3132
#include "modmachine.h"
3233
#include "uart.h"
3334
#include "hardware/clocks.h"
@@ -134,8 +135,17 @@ static void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) {
134135
return;
135136
}
136137
#endif
137-
// Disable USB and ADC clocks.
138-
clock_stop(clk_usb);
138+
139+
#if MICROPY_HW_ENABLE_USBDEV
140+
// Only disable the USB clock if a USB host has not configured the device
141+
bool disable_usb = !tud_mounted();
142+
#else
143+
bool disable_usb = true;
144+
#endif
145+
if (disable_usb) {
146+
clock_stop(clk_usb);
147+
}
148+
139149
clock_stop(clk_adc);
140150

141151
// CLK_REF = XOSC
@@ -152,7 +162,9 @@ static void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) {
152162

153163
// Disable PLLs.
154164
pll_deinit(pll_sys);
155-
pll_deinit(pll_usb);
165+
if (disable_usb) {
166+
pll_deinit(pll_usb);
167+
}
156168

157169
// Disable ROSC.
158170
rosc_hw->ctrl = ROSC_CTRL_ENABLE_VALUE_DISABLE << ROSC_CTRL_ENABLE_LSB;
@@ -181,6 +193,12 @@ static void mp_machine_lightsleep(size_t n_args, const mp_obj_t *args) {
181193
// TODO: Use RTC alarm to wake.
182194
clocks_hw->sleep_en1 = 0;
183195
}
196+
197+
if (!disable_usb) {
198+
clocks_hw->sleep_en0 |= CLOCKS_SLEEP_EN0_CLK_SYS_PLL_USB_BITS;
199+
clocks_hw->sleep_en1 |= CLOCKS_SLEEP_EN1_CLK_USB_USBCTRL_BITS;
200+
}
201+
184202
scb_hw->scr |= M0PLUS_SCR_SLEEPDEEP_BITS;
185203
__wfi();
186204
scb_hw->scr &= ~M0PLUS_SCR_SLEEPDEEP_BITS;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy