You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
SAMD51 crystalless boards never enable USB clock recovery for DFLL48M #403
Found while working on #389 (closed-loop DFLL on SAMD51 crystal boards, #386). Pre-existing code that #389 does not change; it affects only crystalless boards.
Related: #386 — same DFLL setup in SystemInit, but for crystal boards.
Problem
On SAMD51 crystalless boards, cores/arduino/startup.c:113-145 (the #ifdef CRYSTALLESS block, identical at master a1efcca) writes DFLLCTRLB = WAITLOCK | CCDIS | USBCRM without MODE, with DFLLMUL CSTEP=1, FSTEP=1, MUL=0. Nothing else in cores/, libraries/ or variants/ writes DFLLCTRLB.
Checked against SAM D5x/E5x datasheet DS60001507N and errata DS80000748T:
p720, USB Clock Recovery Mode: it is enabled by writing 1 to both DFLLCTRLB.USBCRM and DFLLCTRLB.MODE. MUL should be 0xBB80 (48000 for the 1 kHz SOF). USBCRM must not be set if USB is disabled.
Table 54-68 (p1902), note 1: in USB recovery mode the fine step must be 0xA. The table marks DFLL48M open loop as not a recommended USB device clock source.
Table 54-50 (p1884): open-loop output is 45.8-49.3 MHz over temperature, against USB FS's ±0.25%.
The SAMD21 crystalless path does set MODE | USBCRM (startup.c:~502-505).
So the SAMD51 DFLL stays open loop, and what USBCRM does without MODE is undocumented. Field impact is unproven: these boards enumerate in practice.
Remaining work
Keep the open-loop setup in SystemInit with USBCRM cleared. Setting MODE there would hang boot under WAITLOCK, since no SOF arrives before USB is enabled.
After the USB peripheral is enabled, write DFLLMUL MUL=0xBB80, FSTEP=0xA and a small CSTEP, then DFLLCTRLB = MODE | USBCRM | CCDIS without WAITLOCK, with the GCLK_DFLL48M_REF channel disabled.
Both USB stacks need it. The TinyUSB part goes upstream in adafruit/Adafruit_TinyUSB_Arduino.
Hardware check on a crystalless SAMD51 board (ItsyBitsy M4, PyPortal): read OSCCTRL->DFLLVAL over SWD repeatedly (FINE never moving means recovery is off), or measure GCLK_USB on a pin.
Why deferred
Outside #389's scope (crystal boards only), and no crystalless SAMD51 board is on the HIL farm, so this is unvalidated on hardware.
Activity