In the past I've built a simple Clapp oscillator to measure the inductance of unknown coils, by measuring the oscillation frequency with a frequency counter and doing some math. Recently I realized that a Teensy or Arduino can do that just as well and can additionally print the correct uH value directly. Your FreqCount library was ideally suited for this task.
While studying how FreqCount actually worked, I noticed a few areas for improvement. One thing led to another and before I knew it, I was knee-deep in the timer hardware specs and AVR assembly!
The original code uses the difference between two ever-increasing counters (previous total and current total) to calculate the actual count during the current gate interval. But given enough time and a high enough frequency, count_msw, count or count_prev can overflow, because count_msw is never decreased. This could cause subtle bugs which only occur after a certain amount of time. To avoid that scenario, I've added a "counter_reset" instruction to the hardware abstraction layer. FreqCount now simply measures the frequency, reports it and resets for the next round -- no need to deal with the previous count anymore. I don't have a Teensy 3 so I haven't been able to test my counter_reset() implementation for the Freescale MCU. From the reference manual I gather that it suffices to toggle the Timer Enable bit, but you'd have to test it in practice.
I've also added some documentation in a few places and eliminated variables "length" (redundant, equal to gate_length), "index" (gate_index is sufficient; it's incremented before the if so the effect is the same) and "count" (can directly use count_output).
The new code is smaller, more reliable and a bit easier to understand. Accuracy is identical: for a frequency of 87420 Hz, as measured by my frequency counter, the Arduino reads only about 3 to 4 Hz less for either version. Not bad at all!
While studying how FreqCount actually worked, I noticed a few areas for improvement. One thing led to another and before I knew it, I was knee-deep in the timer hardware specs and AVR assembly!
The original code uses the difference between two ever-increasing counters (previous total and current total) to calculate the actual count during the current gate interval. But given enough time and a high enough frequency, count_msw, count or count_prev can overflow, because count_msw is never decreased. This could cause subtle bugs which only occur after a certain amount of time. To avoid that scenario, I've added a "counter_reset" instruction to the hardware abstraction layer. FreqCount now simply measures the frequency, reports it and resets for the next round -- no need to deal with the previous count anymore. I don't have a Teensy 3 so I haven't been able to test my counter_reset() implementation for the Freescale MCU. From the reference manual I gather that it suffices to toggle the Timer Enable bit, but you'd have to test it in practice.
I've also added some documentation in a few places and eliminated variables "length" (redundant, equal to gate_length), "index" (gate_index is sufficient; it's incremented before the if so the effect is the same) and "count" (can directly use count_output).
The new code is smaller, more reliable and a bit easier to understand. Accuracy is identical: for a frequency of 87420 Hz, as measured by my frequency counter, the Arduino reads only about 3 to 4 Hz less for either version. Not bad at all!