Skip to content

48Mhz clock not very accurate (round off error in startup.c?) #223

Closed
@joverbee

Description

@joverbee

I think found a minor issue in producing the 48Mhz clock from 32.768Khz in startup.c
Leading to a small offset of the nominal 48Mhz towards 47.972Mhz (546ppm off). This is probably not important in most cases, but it is to me in a timing critical application.

I think there is an easy fix which brings the frequency to 48.005Mhz (136ppm) which is already a factor 4 better. I measured it with a 5 digit frequency meter and the above seems confirmed in practice.

I think the culprit is the following line of code in startup.c
SYSCTRL->DFLLMUL.reg = SYSCTRL_DFLLMUL_CSTEP( 31 ) | // Coarse step is 31, half of the max value SYSCTRL_DFLLMUL_FSTEP( 511 ) | // Fine step is 511, half of the max value SYSCTRL_DFLLMUL_MUL( (VARIANT_MCK/VARIANT_MAINOSC) ) ; // External 32KHz is the reference }

The multiplier is loaded with (VARIANT_MCK/VARIANT_MAINOSC) which is a division of 2 unsigned longs being 48000000/32768=1464 (I assume)

A floating division should give 1464.8 which should then get rounded to 1465.

I am not entirely sure what it is the best syntax to get this in a nice way...I am thinking along something like
uint(double(VARIANT_MCK)/double(VARIANT_MAINOSC)) but need to check the correct syntax to get it.

Note that the error can be much more significant for lower frequencies and is on average 0.5/MUL, so fixing this seemingly minor issue could be very helpful for others working at much lower frequencies and requiring accuracy of the main clock.(after all, we have a nice accurate crystal, so lets not downgrade it in software)

An even more accurate solution would be to divide the XOSC32K by 4 and then using the same corrected rounding leading to an accuracy of 68ppm, or dividing by 8 gives 21 ppm accuracy which starts to be on the same size of the accuracy of the 32.768Khz crystal itself (similar crystals state between 10-100 ppm, don't have exact datasheet for the one mounted on the M0 pro board). But this might have more side-effects?

Note that including correct rounding leads to a 48.005 Mhz frequency which is slightly above the maximum allowed 48Mhz and strictly speaking brings us out of spec. As the deviation in in the few 100ppm range I really don't expect issues, but one never knows if you built a life-supporting application (you probably aren't using Arduino in the first place then).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions