I did even more experimenting. After observing for longer times, I did see the Systick interrupt cause the waveform to jitter by about 1 microsecond.
Writing to the SCB_SHPR3 register to lower the Systick priority, and of course IntervalTimer's priority function to make it the highest proirity, solves that.
But still quite a bit of jitter happens. I managed to solve most of it by using FASTRUN on the interrupt routine, and replacing digitalWrite() with digitalWriteFast(). When executing code from flash memory, the timing can vary, because the flash is slow and the timing depends on whatever is in the small cache memory between the flash and processor. The RAM runs without any delays.
There's still a jitter of approx 40 ns, which I believe corresponds to 4 processor cycles at 96 MHz. I still can't figure out exactly what's causing that...
Anyway, here's a copy of the code with the lowest IntervalTimer to digitalWrite jitter.
Code:
#define PIN 9 // output pin
int L = 3; // length of sequence
boolean seq[3] = {1, 0, 1}; // sequence to be played
int Fs = 32768; // sampling rate
IntervalTimer t;
volatile int ind = 0;
FASTRUN void next_digit(){
if (ind<L){
digitalWriteFast(PIN, seq[ind]);
}
else if (ind<=Fs) {
digitalWriteFast(PIN, 0);
}
else {
ind=-1;
}
ind++;
}
void setup() {
SCB_SHPR3 = 0x20200000; // Systick = priority 32 (defaults to zero)
pinMode(PIN, OUTPUT);
t.priority(0);
t.begin(next_digit, 1000000.0/Fs);
t.priority(0);
}
void loop() {
}
Edit: Here's what I see with this code. Notice the time scale is only 20 ns/div