Ok, found a solution on my own ![]()
First, code has been correct, nothing to correct on. BUT, after debugging (see Little Helper on Debugging: Arduinotrace (not mine)), I was a little surprised why TCB2.CTRLA had not desired value of 3, but 7 or 17 ...
![]()
Well, it seems as control registers are not properly resetted at start up. Documentation states that register shall be 0x00000000 at reset, but obviously there aren't.
After adding a line TCB2.CTRLA = 0, every thing is working fine.
Here my code (with two ISRs):
#define ARDUINOTRACE_ENABLE 1
#include <ArduinoTrace.h>
void setup() {
Serial.begin(115200);
cli();
// Configure TBC1, ISR shall be called every 500us
TCB1.CTRLA = 0;
TCB1.CTRLA |= TCB_CLKSEL_CLKDIV2_gc; // Divider 2 from CLK_PER ( = 1/16MHz )
TCB1.CTRLA |= TCB_ENABLE_bm; // Enable Timer
TCB1.CTRLB = 0; // Periodic Interrupt mode, waveform output disabled
TCB1.INTCTRL = 0x00000001; // Enable interrupt on capture
TCB1.CCMP = 4000; // @16Mhz it is 500us ( = 4000 /(16MHz/2) )
TCB1.CNT = 0; // Make sure to start time at zero
// Configure TCB2, ISR shall be called every 5ms
TCB2.CTRLA = 0;
TCB2.CTRLA |= TCB_CLKSEL_CLKDIV2_gc; // Divider 2 from CLK_PER ( = 1/16MHz )
TCB2.CTRLA |= TCB_ENABLE_bm; // Enable Timer
TCB2.CTRLB = 0; // Periodic Interrupt mode, waveform output disabled
TCB2.INTCTRL = 0x00000001; // Enable interrupt on capture
TCB2.CCMP = 40000; // @16Mhz it is 5ms ( = 40000 /(16MHz/2) )
TCB2.CNT = 0; // Make sure to start time at zero
// Output to check proper function of ISR
pinMode(14, OUTPUT);
digitalWrite(14, LOW);
pinMode(21, OUTPUT);
digitalWrite(21, LOW);
sei();
// Just another LED to show that something is alive
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
// Some Debugging
DUMP(TCB1.CTRLA)
DUMP(TCB2.CTRLA)
DUMP(TCB_CLKSEL_CLKDIV2_gc)
DUMP(TCB_ENABLE_bm)
int myVariable = 10;
DUMP(myVariable)
TRACE()
}
ISR(TCB1_INT_vect) { // called every 500us
static boolean on = false;
if (on) {
digitalWrite(14, LOW);
on = false;
}
else {
digitalWrite(14, HIGH);
on = true;
}
TCB1.INTFLAGS |= 0x00000001; // Clear interupt flag
}
ISR(TCB2_INT_vect) { // called every 500us
static boolean on = false;
if (on) {
digitalWrite(21, LOW);
on = false;
}
else {
digitalWrite(21, HIGH);
on = true;
}
TCB2.INTFLAGS |= 0x00000001; // Clear interupt flag
}
void loop() {
digitalWrite(LED_BUILTIN, HIGH);
delay(500);
digitalWrite(LED_BUILTIN, LOW);
delay(500);
}