Timer Interrupts and delay(nnn) or Serial.print("xxx")

I have a question about why the timer interrupts fail when I use a delay(1000) or a Serial.print("Anything") in the loop();

I put together a small test program that reads from and writes to flash, while a variable PWM output on Pin13 is controlled by a timer.

In the Loop, the code reads from Flash, prints the contents out the Serial port, then modifies a string and writes to Flash and has a delay of 1 second.

I see timer start up function called and implemented, but the interrupt handler is called twice only and the output on pin 13 doesn't toggle.

When I comment out the Serial.print and the delay(1000), leaving in the flash reads and writes, I get my expected signal out pin 13. If I leave either one un-commented out, it fails as well.

Why does the timer fail with delay(1000) and Serial.print(" "); ? Any clues.

I've tried timer TC1 channel 0 (timer 3) and TC2 channel 1 (timer 7). Same result.

I'll post the code later.

Thanks,
-j

I just used the DueFlashStorage library and added a timer interrupt routine:
GitHub - sebnil/DueFlashStorage: DueFlashStorage saves non-volatile data for Arduino Due. The library is made to be similar to the EEPROM library. GitHub - sebnil/DueFlashStorage: DueFlashStorage saves non-volatile data for Arduino Due. The library is made to be similar to the EEPROM library.

I wanted to exercise a Flash read and write while being interrupted by a timer to output a pulse.

Here's the code:

/* This example will write a struct to memory which is a very convinient way of storing configuration parameters.
Try resetting the Arduino Due or unplug the power to it. The values will stay stored. */
#include <stdio.h>
#include <DueFlashStorage.h>
DueFlashStorage dueFlashStorage;

// Digital Output Pin Assignments
#define injectorPWM 13 //Output D23 Injector PWM

// The struct of the configuration.
struct Configuration {
uint8_t a;
uint8_t b;
int32_t bigInteger;
char* message;
char c;
};

// initialize one struct
Configuration configuration;

//Injector Timer Variables
int pulse = 0;
float TC = 32800; // This sets the frequency to 20Hz
float TCH = 0.0; // TCH and TCL are used to control the high and low duration of the injector pulse
float TCL = 0.0;
//
/
Timer Setup /
/
/
void startTimer(Tc *tc, uint32_t channel, IRQn_Type irq, uint32_t frequency)
{
pmc_set_writeprotect(false);
pmc_enable_periph_clk((uint32_t)irq);

TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK4);
uint32_t rc = VARIANT_MCK/128/frequency; //128 because we selected TIMER_CLOCK4 above

TC_SetRC(tc, channel, rc);
TC_Start(tc, channel);

tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS;
tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS;

NVIC_EnableIRQ(irq);
}

//
/
Setup() /
/
/
void setup() {
Serial.begin(115200);
delay(500);

/* Flash is erased every time new code is uploaded. Write the default configuration to flash if first time /
// running for the first time?
uint8_t codeRunningForTheFirstTime = dueFlashStorage.read(0); // flash bytes will be 255 at first run
Serial.print("codeRunningForTheFirstTime: ");
if (codeRunningForTheFirstTime) {
Serial.println("yes");
/
OK first time running, set defaults */
configuration.a = 1;
configuration.b = 0;
configuration.bigInteger = 1147483647; // my lucky number
configuration.message = "Hello world!";
configuration.c = 's';

// write configuration struct to flash at adress 4
byte b2[sizeof(Configuration)]; // create byte array to store the struct
memcpy(b2, &configuration, sizeof(Configuration)); // copy the struct to the byte array
dueFlashStorage.write(4, b2, sizeof(Configuration)); // write byte array to flash

// write 0 to address 0 to indicate that it is not the first time running anymore
dueFlashStorage.write(0, 0);
}
else {
Serial.println("no");
}
startTimer(TC2, 1, TC7_IRQn, TC);

}

void loop() {
/* read configuration struct from flash /
byte
b = dueFlashStorage.readAddress(4); // byte array which is read from flash at adress 4
Configuration configurationFromFlash; // create a temporary struct
memcpy(&configurationFromFlash, b, sizeof(Configuration)); // copy byte array to temporary struct

// print the content
/*
Serial.print("a:");
/* Serial.print(configurationFromFlash.a);
/*
Serial.print(" b:");
Serial.print(configurationFromFlash.b);

Serial.print(" bigInteger:");
Serial.print(configurationFromFlash.bigInteger);

Serial.print(" message:");
Serial.print(configurationFromFlash.message);

Serial.print(" c:");
Serial.print(configurationFromFlash.c);
Serial.println();
Serial.println();
/
/
change some values in the struct and write them back */
// increment b by 1 (modulus 100 to start over at 0 when 100 is reached)
configurationFromFlash.b = (configurationFromFlash.b+1) % 100;

// change the message
String message = configurationFromFlash.message;
if (configurationFromFlash.message == "Hello world!")
configurationFromFlash.message = "Hello Arduino Due!";
else
configurationFromFlash.message = "Hello world!";

// write configuration struct to flash at adress 4
byte b2[sizeof(Configuration)]; // create byte array to store the struct
memcpy(b2, &configurationFromFlash, sizeof(Configuration)); // copy the struct to the byte array
// dueFlashStorage.write(4, b2, sizeof(Configuration)); // write byte array to flash

// delay(100);

TCH = 0.75 * TC;
TCL = TC - TCH;
} //end Loop

//
/* INTERRUPT HANDLER */
/
/
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// INTERRUPT HANDLERS
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void TC7_Handler()
{
TC_GetStatus(TC2, 1);

pulse = !pulse; // are we flashing S or O

if( pulse ) // set time till next interrupt
{
TC_SetRC(TC2, 1, TCH);
}
else
{
TC_SetRC(TC2, 1, TCL);
}
digitalWrite(injectorPWM, pulse);
}

From the code, you can see I've commented out the Serial.print(); lines.

Hmm,

Thanks for any input,
-j

I have the Serial.print()s and delay() commented out in the code shown, that's the only way I get pin 13 to toggle. If they are not commented out, timer doesn't work and pin 13 doesn't toggle.

Any idea why not. The code is pretty straight forward.

Thanks,
-j