It sounds a good idea - will investigate later when time allows. In the meantime, I have some very good news to report. I managed to get CH1 working (very simple) as well as CH0 on FTM0 using the system clock. These use Teensy 3.1 pin 23 for CH1 and pin 22 for CH0. I set the modulus for FTM0 at 47999 (appropriate for 48 MHz system clock). I wrote an ISR for rollover, and reset FTM0 COUNT to zero in the ISR as well as resetting the TOF overflow flag. I also incremented a rollover integer variable just to keep check on the number of rollovers (rate should be 1 KHz, like your original idea).
Here is a scope picture to show events... Trace 1 (Yellow) is the edge of a 100 KHz sq wave derived from the 10 MHz OCXO via the 74HC390 dual decade divider (Pin 23 CH1 positive going edge). Trace 2 (Light Blue) is the edge of the RFS 1PPS and also the synch trace (Pin 22 CH0 positive going edge). Trace 3 (Purple) is the 10 MHz OCXO sine wave = locked to Trace 1 sq wave.
I could adjust Trace 1 to lead or lag Trace 2 (very slow, sliding left or right using a manual control of the DAC value). As I did so, the count values for CH0 and CH1 came into close agreement until eventually they were co-incident. The shrinking count difference also agreed precisely with scope display, being one count value difference for every 20 nanoSecs (roughly) of scope Trace 1 versus Trace 2 separation (which agrees with the 48 MHz clock rate).
Typical values (every second) were:
Secs = 1200, CH0 Count = 19714, CH1 Count = 19714
Secs = 1201, CH0 Count = 5771, CH1 Count = 5771
Secs = 1202, CH0 Count = 39998, CH1 Count = 39998
The system clock is not precisely 48 MHz, so I think this is the reason why the readings are drifting in (absolute) value, but the co-incidence was a great pleasure to observe. And as the two traces drifted 20 nanoSecs apart again (Trace 1 moving to the right of Trace 2) then the values again differed by one count.
So I now have a very accurate method of reading the relative phases (difference) of the OCXO sq wave relative to the 1 PPS. Possibly by using some "maths" filtering on the numbers over periods of minutes, then I should be able to get a good control signal to automatically adjust the DAC. We shall see exactly how good. That's the next phase of work.
For anyone reading who is a newbie to "channels", here is my code snippets to enable them (do NOT use "pinMode" to set as inputs):
//initialise Flextimer
FTM0HiCount = 47999;
FTM0_MODE = 0x05; //set write-protect disable (WPDIS) bit to modify other registers
//FAULTIE=0, FAULTM=00, CAPTEST=0, PWMSYNC=0, WPDIS=1, INIT=0, FTMEN=1(no restriction FTM)
FTM0_SC = 0x00; //set status/control to zero = disabled (enabled in main loop)
FTM0_CNT = 0x0000; //reset count to zero
FTM0_MOD = FTM0HiCount; //max modulus = 47999 (gives count = 48,000 on roll-over - 1 KHz)
FTM0_C0SC = 0x04; // CHF=0, CHIE=0 (disable interrupt, use software polling), MSB=0 MSA=0, ELSB=0 ELSA=1 (input capture - rising edge), 0, DMA=0
FTM0_C1SC = 0x04; // CHF=0, CHIE=0 (disable interrupt, use software polling), MSB=0 MSA=0, ELSB=0 ELSA=1 (input capture - rising edge), 0, DMA=0
//Note - not using any channel interrupts - interrupt is from TOF
NVIC_ENABLE_IRQ(IRQ_FTM0); //enable FTM0 interrupt within NVIC table
//configure Teensy input capture channels
PORTC_PCR1 |= 0x400; //MUX = alternative function 4 on Chip Pin 44 (FTM0_CH0) = Teensy Pin 22
PORTC_PCR2 |= 0x400; //MUX = alternative function 4 on Chip Pin 45 (FTM0_CH1) = Teensy Pin 23
//enable system clock (48 MHz), no prescale
FTM0_SC = 0x48; // (Note - FTM0_SC [TOF=0 TOIE=1 CPWMS=0 CLKS=01 (System Clock 48 MHz) PS=000 [no prescale divide])
And the ISR routine:
// ISR routine for FlexTimer0 Module
extern "C" void ftm0_isr(void) {
FTM0_CNT = 0x0000; // reset count value
if ((FTM0_SC & FTM_SC_TOF) != 0) { //read the timer overflow flag (TOF in FTM0_SC)
FTM0_SC &= ~FTM_SC_TOF; //if set, clear overflow flag
}
FTM0CountOVFlow++; //increment overflow counter
}
And to read the channels:
FTM0Ch0CountValue = FTM0_C0V; //current captured count value
if ((FTM0_C0SC&0x80) != 0) { //look for channel event flag
FTM0_C0SC &= ~0x80; //clear channel event flag
FTM0Ch0Flag++;
}
FTM0Ch1CountValue = FTM0_C1V; //current captured count value
if ((FTM0_C1SC&0x80) != 0) { //look for channel event flag
FTM0_C1SC &= ~0x80; //clear channel event flag
FTM0Ch1Flag++;
}
The channel flags were supervisory signals just to show that something was actually happening on each channel (can be removed).