The software solution p#9 , p#3 seems to work okay - against fixed single test incoming pin rise ...
With 10X freq of 500 Hz to 2000 toggles and the printing gets in the way {bottom}, but the jitter is only +/- 6 clock cycles even then : so 6 parts in 600,000,000 isn't much.
Doing only output on the second (except when CYCCNT misses the mark) and with 20,000 output toggles { 100X more} loop count went up to 6.5M without excess debug output: Loops per second is 6561838
Code:
#define OUTPUT_RATE 20000
#define DEMO_RATE 5000
There is rare jitter with toggle every 30,000 cycles - possibly from the two interrupts of same priority hitting at the same time:
Code:
toggle was 30000 apart. { 20000 Hz is 30000 )
Loops per second is 6561838 )
toggle was 30000 apart. { 20000 Hz is 30000 )
Loops per second is 6561838 )
...
toggle was 29994 .vs. 30000 )
toggle was 30006 .vs. 30000 )
Loops per second is 6561665 )
After running 12926 seconds a total of 263 misses - the odd one is on startup with prior CYCCNT unset
Code:
And the rest are paired:
59 at toggle was 29994 .vs. 30000 )
59 at toggle was 30006 .vs. 30000 )
48 at toggle was 30001 .vs. 30000 )
48 at toggle was 29999 .vs. 30000 )
24 at toggle was 30002 .vs. 30000 )
24 at toggle was 29998 .vs. 30000 )
This code did the above - wire with p#14 to #15 and output on #16:
Code:
// https://forum.pjrc.com/threads/68503-Jitter-free-square-wave-doubler-with-TeensyTimerTool?p=291678&viewfull=1#post291678
IntervalTimer myTimer;
bool pinActive = false;
volatile uint32_t nextToggle;
volatile uint32_t debugToggle = 0;
#define OUTPUT_RATE 20000
#define DEMO_RATE 5000
#define PRIOR2TICK 1000 // prior tick ready for tiggle time for 1 MHz _isr()
void isrPin() {
uint32_t myCYCCNT = ARM_DWT_CYCCNT;
if ( !pinActive ) {
// Could average some 8 to get 'measured' cycles from the input before doing pinActive
// External clock not likely to match the hardcoded "F_CPU_ACTUAL / (OUTPUT_RATE)"
digitalWriteFast( 16, 1 );
pinActive = true;
myTimer.begin(isrTimer, 1); // adjust PRIOR2TICK
nextToggle = myCYCCNT + F_CPU_ACTUAL / (OUTPUT_RATE) - PRIOR2TICK;
}
// add check and update to nextToggle here if 48 Hz can slip
}
void isrTimer() {
uint32_t myCYCCNT = ARM_DWT_CYCCNT;
if ( myCYCCNT - nextToggle < PRIOR2TICK ) {
// Wait until toggle needed
myCYCCNT += PRIOR2TICK;
while ( ARM_DWT_CYCCNT < PRIOR2TICK );
digitalToggleFast( 16 );
nextToggle += F_CPU_ACTUAL / (OUTPUT_RATE);
debugToggle = myCYCCNT;
}
}
elapsedMicros showCount;
void setup() {
Serial.begin(115200);
Serial.println("\n" __FILE__ " " __DATE__ " " __TIME__);
pinMode( 15, INPUT );
pinMode( 16, OUTPUT );
attachInterrupt(15, isrPin, RISING);
// DEMO input for testing wire pin 14 to 15
analogWriteFrequency( A0, DEMO_RATE ); // A0 is p#14
analogWriteResolution(12); // 0-4095
analogWrite( A0, 2048 );
showCount = 0;
}
uint32_t myDebugToggle = 0;
uint32_t loopCnt = 0;
void loop() {
loopCnt++;
if ( debugToggle != myDebugToggle ) {
if ( showCount > 1000000 ) {
Serial.printf( "\tLoops per second is %lu )\n", loopCnt );
Serial.printf( "\ntoggle was %lu apart. { %u Hz is %lu )\n", debugToggle - myDebugToggle, OUTPUT_RATE, F_CPU_ACTUAL / OUTPUT_RATE );
showCount -= 1000000;
loopCnt = 0;
}
if ( debugToggle - myDebugToggle != F_CPU_ACTUAL / OUTPUT_RATE )
Serial.printf( "toggle was %lu .vs. %lu )\n", debugToggle - myDebugToggle, F_CPU_ACTUAL / OUTPUT_RATE );
/* else {
Serial.print( "." );
if ( !(loopCnt % 100) ) {
Serial.printf( "\ntoggle was %lu apart. { %u Hz is %lu )\n", debugToggle - myDebugToggle, OUTPUT_RATE, F_CPU_ACTUAL / OUTPUT_RATE );
//Serial.println( );
}
}
*/
myDebugToggle = debugToggle;
}
}
Before string output was shortened the 6 cycle jitter was the same (each '.' dot is response on the expected cycle) - but the loop count went down from 3.5M before: Loops per second is 3166258
Code:
toggle was 300000 apart. { 2000 Hz is 300000 )
......................................................
toggle was 300000 apart. { 2000 Hz is 300000 )
toggle was 300006 .vs. 300000 )
toggle was 299994 .vs. 300000 )
..................................................
toggle was 300000 apart. { 2000 Hz is 300000 )
toggle was 300006 .vs. 300000 )
toggle was 299994 .vs. 300000 )
.................................................................. Loops per second is 3166258 )
..........
toggle was 300000 apart. { 2000 Hz is 300000 )
.......................................................................................................................
toggle was 300000 apart. { 2000 Hz is 300000 )
toggle was 300006 .vs. 300000 )
toggle was 299994 .vs. 300000 )
.........................
toggle was 300000 apart. { 2000 Hz is 300000 )
toggle was 300006 .vs. 300000 )
toggle was 299994 .vs. 300000 )
..................................................