Testing the stability of a XOSC32K used for SAMD21 RTC


I devised a set-up to measure the [EDIT]external 32 kHz crystal (XOSC32K) characteristics, i.e. frequency and clock jitter. [EDIT note: I confused my Adafruit Trinket M0 with my Feather M0, the latter has an external 32.768 kHz crystal, I should do the same test with the crystal-less Trinket soon...]

First I calibrated the clock of an audio recorder with a GPS time signal to find out it was sampling at exactly 47998.519 Hz. I then recorded for almost an hour each one of the second tics the SAMD21 produced (a few tics are plotted below):

The recording was processed with python + numpy and the results are quite adequate for my project:

  • Frequency discrepancy: the events had a frequency of 1.0000257 Hz (each digit is significant); that's a drift of 26 ppm (on par with my cameras and audio recorders drift).
  • Clock jitter: each 2700 second had the same (slightly off) duration within ± 21 microseconds, i.e. all the "1 sec" events were timed and NO tics were nearer than 47996 nor farther than 47998 audio samples apart.

The air temperature was 20C, it should be interesting to take the same measurements at really cold and really hot chip temp.

I merged two programs found on the net to produce a 0.5 Hz square wave using the RTCZero lib:

#include <RTCZero.h>

/* Create an rtc object */
RTCZero rtc;
bool pinState;
void setup()
  rtc.begin(); // initialize RTC 24H format
  rtc.setAlarmTime(0, 0, 1);
  pinMode(A0, OUTPUT);
  pinState = true;

void loop() {}

void setAlarmNextSecond()
  RTC->MODE2.Mode2Alarm[0].ALARM.bit.SECOND =
    (RTC->MODE2.Mode2Alarm[0].ALARM.bit.SECOND + 1) % 60;

void alarmMatch()
  digitalWrite(A0, pinState);
  pinState = not pinState;