atsamd
atsamd copied to clipboard
Support DFLL USB clock recovery on SAMD21
This is partially taken from my comment here: https://github.com/atsamd-rs/atsamd/pull/155#issuecomment-993080854
USB clock recovery (USBCRM) allows the 1 kHz USB start-of-frame (SOF) signal to control the DFLL in closed-loop mode, allowing accurate clocking as a USB device without an external crystal. This feature was disabled in #155 because it was causing problems with USB support.
These problems occur because DFLLMUL.MUL needs to be set to 48000 (48 MHz / 1k Hz), rather than 1464 (48 MHz / 32768 Hz). When USBCRM is enabled, the 32 kHz reference clock is ignored. If USB is connected, the DFLL runs in closed-loop mode using the 1 kHz SOF signal, otherwise it runs in open loop mode. This is described in section 16.6.7.2 (Atmel datasheet) or 17.6.7.2.2 (Microchip datasheet) of the datasheet.
I tested various configurations on my ItsyBitsy M0. The frequencies I measured depend on many external factors, but they may still give some insights. Enabling USBCRM with the current multiplier results in a frequency of around 52 Mhz, which explains why things didn't work. With the correct multiplier, I get a frequency of 47.98 MHz. In open loop mode (USB disconnected), I measured 46.50 Mhz. In closed loop mode with the 32 kHz oscillator, I measured 47.12 MHz.
In the short term, we probably want to fix the multiplier and always enable USBCRM. This may improve USB stability and only seems to result in a small change in clock accuracy for users not using USB. This would also bring it in line with the thumbv7em clock driver, which sets the multiplier correctly and enables USBCRM.
There do seem to be some small tradeoffs between running the DFLL in closed-loop mode with the internal oscillator vs open-loop mode, so in the longer term we probably want an API to choose between these modes, possibly as part of #450 (and its equivalent for thumbv6m).
cc @bradleyharden @vccggorski @vcchtjader
Thanks for the very clear write-up. This will come in handy
Is this resolved by https://github.com/atsamd-rs/atsamd/pull/625?
Yes