[time-nuts] Input filter for data logger
Tom Van Baak
tvb at LeapSecond.com
Sun Nov 19 22:54:15 EST 2017
> I'll need to experiment with this. I think the drawback cold be for the
> signal with long pulse width (more than one second).
I'm not sure I understand. If you're building some kind of time interval counter or timestamp counter the duration is only limited by how many digits or bits you allocate to your timestamp. Longer than one second should be very easy.
>> That's a software problem for sure. Do you use interrupts? Or some
>> library code for formatting and output?
> STM32 has an internal counter which counting MCU ticks (I clocked my
> stone by 40Mhz. So, it will be 40 mln. ticks per second). I am using
> this ticks number to get microseconds as signal capture event has
That sounds fine.
> My other timer generate interrupt each second. This is used to start
> count the microseconds over again. So, its pretty simple.
This could be trouble. You'll have to check for timing windows in your code. It's usually better to let counters free-run rather than to start / stop / reset them all the time.
> I'll need to dig this issue deeper, since its occurred only when I was
> using DDS generator as a signal source. I know DDS chips sometimes
> generates some spurs. But not sure if this is related.
> If I raise the input freq. to 1Mhz, the STM32 become unresponsive, since
> number "capture" interrupts is too high. The signal capture interrupt
> routine doing nothing more than one assignment : "cur_tick =
Make sure this assignment is atomic (a single load/store pair, not multi-byte or multi-word instruction sequence); very timer and cpu dependent.
You don't want unresponsive. When you get an event, capture the timer, format your output, and do the serial transmit. Only when that's all finished then re-enable for the next event. This avoids lock-up. And it means your CPU saturates at the point where your output rate is a maximum. So it's self regulating. Note if you do all your event processing in the interrupt handler and cur_tick is not used at main level, you don't have to worry about atomic loads and stores either.
Another way around all of this is to use capture/compare registers. Most uC have this feature. This way your precise timing is not at all dependent on interrupt latency or what language you write in.
> has no 32bit timers. Using 40Mhz clock, I can't go low than 610Hz
> without some tricks, like using pre-scaler or cascading the timers. I
> tried those methods but results was not impressive. Probably because of
One solution is to use h/w timers for the low bits and s/w overflow counters for the high bits. For example a 64-bit counter could be made using a 16-bit timer and a 48-bit overflow count. This is an overflow every 1.6 ms, which is easy to deal with using either interrupts or polling.
> my software implementation. I am using DMA and other timer to capture
> 1PPS events. It works OK for me. But in that case I just need one
> number. Which ideally should be 23040 in my case (40000000 % 65536 =
> 23040). I don't care about number of overflows and anything else in this
> case. If I am getting something different from magic number - its time
> to tweak DAC to control OCXO.
Right, if this is just for a GPSDO then you can consider modulus tricks like this. If you're making a more general purpose time interval counter or time stamping counter then you can't rely on that trick. I'm not sure of the context for this thread. It sort of seemed like you were building a counter.
Then again, even if this is a GPSDO I would not want to rely on magic number tricks. What happens if the user decides to change antenna length in order to move the 1PPS by hundreds of us? The magic trick will now cause great trouble. You can avoid that with a FLL instead of PLL version of GPSDO and ignore what look like glitches. But this is now adding hack upon hack. My advise is just implement a 0 to 1.x second TIC. It can't be that hard to do that in a STM32.
More information about the time-nuts