Hi all,
I've got a small program that I'm running on a MEGA2560. It's simply an ISR which reads from PROGMEM at intervals and sends the data to an output (PORTK).
The sound sample is about 235K bytes, so what I do is first load the program itself, then load the sound data as a separate .HEX file with an offset of 0x1000.
It works fine, but once in a while (maybe once out of 2 or 3 plays) the sound stops in the middle and restarts at the beginning (acts like RESET was pressed).
I'm sure the code is right... my only guess is that there's something "non-atomic" happening that I am not accounting for. Please take a look at the code and see if you can find my mistake (if any). It's small enough that it should be easy to go through. Thanks!!!
#include <inttypes.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#define SAMPLERATE 8000
volatile uint8_t busy;
volatile uint32_t timer;
volatile uint32_t bytes;
volatile uint32_t addr;
ISR (TIMER1_COMPA_vect) // timer 1 (16 bit)
{
if (timer) { // if there is a count
timer--; // decrement it
} else { // else
busy = 0; // flag not busy anymore
}
if (bytes) { // if bytes to play
PORTK = pgm_read_byte_far (addr++); // push byte to DAC
bytes--; // decrement count
}
}
void delayMsec (uint32_t msec)
{
cli(); // interrupts off
busy = 1; // flag ISR busy
timer = (msec * (SAMPLERATE / 1000)); // count for 1 millisecond (atomic write)
sei(); // interrupts on
while (busy); // wait while busy
}
void initISR (void)
{
cli(); // interrupts off
// set timer 1 to CTC mode
TCCR1A = 0x00; // mode 4 (CTC) OCR1A = top
TCCR1B = (_BV(WGM12) | _BV(CS10)); // set prescale
OCR1A = (F_CPU / SAMPLERATE); // audio sample rate
TIMSK1 = _BV(OCIE1A); // start timer
sei(); // interrupts on
}
int main (void)
{
initISR (); // setup the ISR
DDRK = 0xFF; // all PORTK bits = OUTPUT
while (1) {
cli(); // interrupts off
addr = 0x1000; // set start address of audio
bytes = 234893; // audio byte count
sei(); // interrupts on
while (bytes); // wait while playing audio
delayMsec (3000); // 3 seconds between plays
}
}