Hi Bobby -- Thanks so much for the code! That's way more assistance than I was expecting. I really appreciate it.
The external signals that I'm measuring are normally pulse-per-second ticks from electronic clocks of varying type and quality, though there are other applications as well. The complete system has two identical measurement channels, and measures two PPS signals from two independent and hopefully uncorrelated sources, one a device under test, and the other a reference (like a GPS, or a clock of higher quality than the DUT). By looking at changes in the time difference between them over time, we can determine the frequency offset, aging, stability, and other statistics of the DUT compared to the reference. The time interval between the two signals could be anywhere from a few hundred nanoseconds to a few hundred milliseconds.
Again, I'm NOT trying to do a measurement for each cycle of the coarse timer. It's not 1,000 measurements per second, but 1 (or maybe 10 for some configurations). If I could guarantee that the time interval between REF and DUT would be <6ms, I could just use the TDC chip by itself. But I can't -- all I can say is that the time difference is less than the measurement interval. So the coarse clock scheme is intended to extend the measurement range to meet that requirement.
At a high level, here's the program logic:
In setup(), use SPI to send configuration to the TDC7200s on both channels, and then send each the start command. Set up the coarse clock interrupt ISR, so the coarse counter increments on each interrupt.
Within an infinite loop, poll the various hardware pins for flags indicating measurement activity:
-
The channel 0 TDC7200 waits patiently until it detects an incoming edge on its START pin. Then its measurement cycle starts automatically.
-
The incoming edge also starts a 2-bit hardware counter clocked at 10 MHz to generate a pulse after a 300 nanosecond delay. That pulse opens a "gate" (probably a flip-flop, but I'm still working through this part of the design) that passes the next pulse of the coarse clock to the 7200 STOP pin, then closes. The circuit ensures that the selected 1ms clock edge meets the minimum and maximum interval requirements of the 7200. The actual time between START and the gated clock edge could be from 300 nanoseconds to (2ms + 300ns) if we just miss an edge and have to wait for another. (I know there are some additional timing subtleties here, but I'm trying not to get below the weeds.)
-
The gated clock pulse is also routed to an input pin on the Arduino. When the Arduino sees that it's high the current contents of the coarse timer are copied into a variable (call it channel0_coarse for that channel). The pulse 50/50 duty cycle, so there's a reasonable time for the Arduino to catch the signal and copy the counter value before the next increment.
-
The 7200 sets its interrupt pin when its measurement is complete, and when the Arduino catches that that, it initiates SPI communication to grab the data. As soon as that transaction is complete, it sends the "start" message, arming the chip for the next measurement.
-
The Arduino is also polling for the same set of events on channel 1, which is waiting for the other PPS source. Channel 1 is processed the same as channel 0 (into its own set of data variables, of course).
-
When data from both channels is in hand, the Arduino calculates the timestamp for each channel by subtracting its '7200 time interval from its channel_coarse value, and outputs the channel0 and channel1 timestamps, and optionally their difference, via USB.
As long as the loop completes faster than the measurement rate (in this example, once per second), the 7200s will be armed and waiting when the next set of PPS signals arrive. The loop spends most of its time polling the hardware pins for activity, reading the data when needed, and only does calculations after data from both channels is in hand. By this time, both channels are already armed and ready for the next cycle.
Although the master 10 MHz clock and the 1 kHz clock are in fact synchronous, I can't see that's a requirement for this to work. And of course the external PPS signals are asynchronous, because the whole point is to measure their arrival time.
Am I missing something? I hope I'm not just adding to the confusion. (And, thanks again.)