AnasSarkiz/rp2040-usb-c-single-axis-dm542t-motion-controller--01a0e89c
A USB‑C RP2040 controller board with external QSPI flash, crystal clock, regulated 3.3/1.1/5 V power, boost-converted motor-driver supply, protected USB and limit inputs, status LEDs, reset/boot switches, and AO3400A MOSFET outputs for stepper-control signals.
- Version
- 0.1.0-prototype.19
- License
- unset
- Stars
- 0
firmware/usb_sleep.c
#include "usb_sleep.h"
#include "tusb.h"
#include "hardware/clocks.h"
#include "hardware/sync.h"
#include "hardware/structs/scb.h"
void usb_sleep_until_resume(void) {
uint32_t original_sleep0 = clocks_hw->sleep_en0;
uint32_t original_sleep1 = clocks_hw->sleep_en1;
uint32_t original_scr = scb_hw->scr;
// XOSC and USB PLL remain on so USB can detect host resume/reset.
// set_sys_clock_48mhz() has already disabled the unused system PLL.
clock_configure(clk_sys, CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX,
CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB,
48000000, 12000000);
clocks_hw->sleep_en0 = 0;
clocks_hw->sleep_en1 = CLOCKS_SLEEP_EN1_CLK_USB_USBCTRL_BITS |
CLOCKS_SLEEP_EN1_CLK_SYS_USBCTRL_BITS;
hw_set_bits(&scb_hw->scr, M0PLUS_SCR_SLEEPDEEP_BITS);
while (tud_suspended()) {
tud_task_ext(0, false);
// A pending interrupt wakes WFI even with PRIMASK set. Hold PRIMASK
// between testing the queue and WFI so a just-arrived resume cannot
// be consumed by the ISR before we go to sleep (lost-wakeup race).
uint32_t irq = save_and_disable_interrupts();
if (tud_suspended() && !tud_task_event_ready()) {
__dsb();
__wfi();
}
restore_interrupts(irq);
}
scb_hw->scr = original_scr;
clocks_hw->sleep_en0 = original_sleep0;
clocks_hw->sleep_en1 = original_sleep1;
set_sys_clock_48mhz();
}