Hello.
When using arduino nano 33 IOT and doing serial.print while toggling the LEDs with the timer interrupt, in very rare cases, the result of serial.print may be corrupted. (This does not happen when timer processing is not used.)
Is there any special processing required when using interrupts?
#include <Arduino.h>
#include "Adafruit_ZeroTimer.h"
// This example can have just about any frequency for the callback
// automatically calculated!
float freq = 500000; //
// timer tester
Adafruit_ZeroTimer zerotimer = Adafruit_ZeroTimer(3);
void TC3_Handler() {
Adafruit_ZeroTimer::timerHandler(3);
}
// the timer callback
volatile bool togglepin = false;
void TimerCallback0(void)
{
digitalWrite(LED_BUILTIN, togglepin);
togglepin = !togglepin;
}
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
Serial.begin(115200);
while (!Serial) {
delay(10);
}
Serial.println("Timer callback tester");
Serial.print("Desired freq (Hz):");
Serial.println(freq);
// Set up the flexible divider/compare
uint16_t divider = 1;
uint16_t compare = 0;
tc_clock_prescaler prescaler = TC_CLOCK_PRESCALER_DIV1;
if ((freq < 24000000) && (freq > 800)) {
divider = 1;
prescaler = TC_CLOCK_PRESCALER_DIV1;
compare = 48000000/freq;
} else if (freq > 400) {
divider = 2;
prescaler = TC_CLOCK_PRESCALER_DIV2;
compare = (48000000/2)/freq;
} else if (freq > 200) {
divider = 4;
prescaler = TC_CLOCK_PRESCALER_DIV4;
compare = (48000000/4)/freq;
} else if (freq > 100) {
divider = 8;
prescaler = TC_CLOCK_PRESCALER_DIV8;
compare = (48000000/8)/freq;
} else if (freq > 50) {
divider = 16;
prescaler = TC_CLOCK_PRESCALER_DIV16;
compare = (48000000/16)/freq;
} else if (freq > 12) {
divider = 64;
prescaler = TC_CLOCK_PRESCALER_DIV64;
compare = (48000000/64)/freq;
} else if (freq > 3) {
divider = 256;
prescaler = TC_CLOCK_PRESCALER_DIV256;
compare = (48000000/256)/freq;
} else if (freq >= 0.75) {
divider = 1024;
prescaler = TC_CLOCK_PRESCALER_DIV1024;
compare = (48000000/1024)/freq;
} else {
Serial.println("Invalid frequency");
while (1) delay(10);
}
Serial.print("Divider:"); Serial.println(divider);
Serial.print("Compare:"); Serial.println(compare);
Serial.print("Final freq:"); Serial.println((int)(48000000/compare));
zerotimer.enable(false);
zerotimer.configure(prescaler, // prescaler
TC_COUNTER_SIZE_16BIT, // bit width of timer/counter
TC_WAVE_GENERATION_MATCH_PWM // frequency or PWM mode
);
zerotimer.setCompare(0, compare);
zerotimer.setCallback(true, TC_CALLBACK_CC_CHANNEL0, TimerCallback0);
zerotimer.enable(true);
}
int i=0;
int j=65535;
void loop() {
Serial.print(i++);
Serial.print(" ");
Serial.println(j-i);
//delay(1);
}
There are the following patterns of data corruption.
-
New-line code is not sent.
455640 -390106
455641 -390107455642 -390108
455643 -390109 -
Spaces are not printed
473543 -408009
473544-408010
473545 -408011