FreqCount used only as a counter

nitrojam

Member
Hi everyone,

I have a Teensy 3.5 using FTM1 (like in this thread https://forum.pjrc.com/threads/45413-ISR-latency-Teensy-3-1-and-3-6?p=148851&viewfull=1#post148851) to count the pulses of a 10 MHz TCXO, which seems to work OK (without interval, juste count the pulse until a decided number and then reset the counter) !

However, I went a bit deeper int the FreqCount library and I think it would possible to modify to get the same result : my try is below but it doesn't seem to count perfectly (as it should increment 1 every second and I have a drift over a quite short period of time)

--> Modified FreqCount.ccp
Code:
uint32_t FreqCountClass::read(void)
{
	uint32_t count;
	uint8_t status;

	status = SREG;
	cli();
	//count = count_output;
	count = counter;
	count_ready = 0;
	SREG = status;
	return count;
}

void FreqCountClass::end(void)
{
	timer_shutdown();
	counter_shutdown();
}


ISR(TIMER_ISR_VECTOR)
{
	uint16_t count_lsw;
	uint32_t count;
	uint16_t index, length;

	count_lsw = counter_read();
	if (counter_overflow()) {
		counter_overflow_reset();
		count_msw++;
		if ((count_msw << 16) >= 9999999)
		{
			count_msw=0;
			counter++;
			count_ready = 1;
		}
	}
	/*index = gate_index + 1;
	length = gate_length;
	if (index >= length) {
		gate_index = 0;
		count = ((uint32_t)count_msw << 16) + count_lsw;
		count_output = count - count_prev;
		count_prev = count;
		count_ready = 1;
		restore_other_interrupts();
	} else {
		if (index == length - 1) disable_other_interrupts();
		gate_index = index;
	}*/
}

I therefore have to questions :
1. What is the advantage of using FTM1 over LPTMR in order to count pulses ?
2. Is there a better (right?) way to modify the Freqcount library to get the expected result (just a counter that reset itself after a decided amount of pulses and triggering an action)?

Thanks for your help !
 
Not, quite the contrary : I woul like to count the number of pulses (from 10 000 000 to 10 000) in order to derive a very precise interval (from 1 second to 1 millisecond) which will enable me to trigger events.
I basically want to use my external clock (here a TXCO but also a RB standard) to get precise timings (better than the teensy clock).

In fact, it woul be like using IntervalTimer but with an external clock !
 
The level of timing precision you're talking about is probably in the realm of custom digital logic like a FPGA or CPLD rather than using a microcontroller. But it does depend on what is meant by "trigger events".

in order to derive a very precise interval (from 1 second to 1 millisecond) which will enable me to trigger events.

In a microcontroller, you're looking at several types of variable timing from an external clock edge (from your highly accurate TXCO) to actually doing something. Latency is at least a dozen clocks, and several factors can cause it to vary by multiple clock cycles.

The worst is interrupt latency. Even if you configure for the highest interrupt priority and no other code ever disables interrupts (as the USB code does), and even if your interrupt code and all variables are in tightly coupled RAM so you never have cache misses to worry about, you're still looking at variability in timing depending on which instruction is executing at the moment your hardware triggers the interrupt.

The next worse is bus access latency, which is one of the components of interrupt latency, and comes up if you have hardware which uses DMA to do its work. Again, less of an issue with tightly coupled memory, but still possibly a factor depending on what is happening on the buses inside the chip at the moment of the hardware event.

Even if you can somehow arrange for a hardware timer to do everything (unlikely), for this level of precision you may also need to consider that nearly all external inputs are synchronized to one of the internal clocks before they're actually used. So if you arrange for a timer to somehow do everything involved in the event (or at least all the timing critical stuff), your nearly perfect clock gets sync'd to the timer clock, which adds an unpredictable latency of 0 to ~7ns (assuming a timer running from the 150 MHz peripheral clock in Teensy 4).

To use an accurate external to truly process an event at extremely precise intervals (under 1ns error) you will probably need to build dedicated digital logic which clocks directly from that accurate clock without the sorts of resynchronization to an internal clock which is present on the input paths of pretty much all pins of a microcontroller.
 
Many thanks for this answer : indeed, the latency of the triggering is not the main goal in my case.
The most important is that I must be sure that I don't miss any of the pulses of my TXCO of 10MHz and I don't know if the hardware counter can be this reliable ?

Then, when my counter reach the desired amount (in my case, it will be minimum 1000 pulses and can go up to 10000 pulses), the counter is reseted and an event is triggered (light a led or increment a software counter for example).

As a consequence, what would be the most reliable way to count these pulses with a teensy 3.5 (and in a near future, a teensy 4.1) ?

Again, big thanks for your support !
 
the latency of the triggering is not the main goal in my case. The most important is that I must be sure that I don't miss any of the pulses of my TXCO of 10MHz and I don't know if the hardware counter can be this reliable?

I think you can assume that you can reliably count edges of your 10 MHz external clock. If your TXCO is 10 MHz, and you set your match value in the range 1000 to 10000, you will get interrupts that are nominally 100 us to 1 ms apart. Let's say you are using 10000 clocks, so your interrupt period is 1 ms, and assume you don't miss any edges, you will get interrupts at 1 kHz. As Paul explains, because of latency issues, this does not mean interrupts will occur at exact 1 ms intervals, but to the extent your TXCO frequency is "exactly" 10 MHz, you will get very close to "exactly" 1000 interrupts per second. Is that what you want?
 
The most important is that I must be sure that I don't miss any of the pulses of my TXCO of 10MHz and I don't know if the hardware counter can be this reliable ?

Yes, it's reliable.

If a pulse rising edge occurs right at end of the gate interval, that pulse will be properly counted. It's unpredictable whether that last count will be in the just-ended interval or whether it will be counted in the next interval, but you can be sure the total of both will be correct.
 
Back
Top