Skip to content

SAMD51 crystalless boards never enable USB clock recovery for DFLL48M #403

Open

Description

@hathach

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions