Graphic demonstration of remote clock sync2011/02/03
So I’ve been perfecting the method I use in my current project to sync up the two clocks. In a previous post I explained the generation method, which consists of using a master-generated reference pulse on the data bus to drive a PID that pushes the slave’s crystal frequency around to get them to line up.
Originally I’d maintained a local difference between the master and slave clocks, and any request for the clock would be adjusted by that. However, I realized it would be very useful for the actual hardware timers to line up with the same values, and it turned out to be almost a trivial change. Instead of just taking the offset and storing it, I pause the timers and reset them with a value that’s adjusted by the offset (plus a fudge factor for the time it takes to actually change the timers). Any slight deviation left over can be handled by the I and D of the PID controller.
The main cycle counter is actually two daisy-chained 16-bit timers, and the daisy-chain mechanism is what on Xmega is called an “event”. If I select the right event channel (0 out of 0..7) and flip a few config bits, I can output the 16th bit of the cycle counter to a pin, which I can then connect my scope to. I hooked up my scope to this output on both the master and slave event outputs, and set it to trigger off the master’s pulse.
Initially there is only a master trace (channel 1) visible, with the slave (on channel 3) somewhere entirely else along the 488.3KHz cycle period (32MHz / 16 bits). Halfway through the video I hit the key that triggers the sync protocol, and you can immediately see the slave’s clock trace show up and home in on a lock.
A quick eye-ball measurement of the jitter and delay gives me about a 1 cycle average delay (32MHz cycle) or about 31nS, and a worst-case jitter of about +-2 cycles or about 62nS. I’m betting some of this has to do with the tuning of my PID, as I can clearly see some periodic overshoot in the crystal adjustment parameter. My goal was supposed to be around 25,000nS if I remember right, so I think I’ve managed fairly well ;-)
Next step is to trigger a single pulse at another time and use that to start the ADC’s conversion clock…