Code using ISR breaks millis(), time library

Hello, I am working on a harddrive clock of my own utilizing the excellent firmware from Giles F. Hall as a starting point. I am integrating the clock functionality into the arduino, whereas Giles had the arduino read the colours to be drawn and the position from a serial port at 115200 baud.

However, I have encountered a problem with Giles’s ISR code breaking millis() and the Time library which I need. I have a hunch that the Giles’s ISR timing on timer #2 (which I have trouble grasping) is breaking millis(), which Time is reliant upon.

Here is a simplified version of the relevant code which sets ISR timing:

//---at the top of the program:-----
#ifndef F_CPU
#define F_CPU           16000000UL  // 16 MHz
#endif

#include                <stdlib.h>
#include                <avr/io.h>
#include                <avr/interrupt.h>
#include                <Time.h>  
#include                <buttons.h>  //debouncing library
#undef int
#include                <stdio.h>
#define DIVISIONS       0xFF
#define RGB(R,G,B)      (R << RED | G << GRN | B << BLU)
#define FREQ_DIV_8      (F_CPU / 8)
#define MILLITICK       (FREQ_DIV_8 * .001)
#define SPURIOUS_INT    (2 * MILLITICK)
#define bitset(var,bitno) ((var) |= (1 << (bitno)))
#define bitclr(var,bitno) ((var) &= ~(1 << (bitno)))
#define bittst(var,bitno) (var& (1 << (bitno)))
#define DEBOUNCETIME    50

//----in the setup:-----

  cli();     // disable global interrupts
  TCCR0A = 0;  // setup timer0 - 8bit for timing the LEDs
  TCCR0B = 0;  
  bitset(TCCR0A, WGM01); // select CTC mode
  bitset(TCCR0B, CS01);  // select prescaler clk / 8
  bitset(TIMSK0, OCIE0A); // enable compare interrupt
  TCCR1B = 0; // setup timer1 - 16bit  for timing the rotation of the platter
  TCCR1A = 0; 
  bitset(TCCR1B, CS11); // select prescaler clk / 8
  TCNT1 = 0;   // reset timer
  bitset(TIMSK1, TOIE1); // enable overflow interrupt
  EICRA = _BV(ISC01); // configure the platter interrupt PIN
  EIMSK |= _BV(INT0); // Enable the hardware interrupt.
  period = 0;  // set the rotational period to 0
  init_pages();
  sei();  // enable global interrupts

//----after the void loop():-----

ISR(INT0_vect) // This interrupt is called on every pulse of the sensor
{
  // Capture the 16bit count on timer1, this represents one revolution
  period = TCNT1;
  if(period < SPURIOUS_INT)
  {
    return;
  }
 // Reset timer1 and timer 0 for next revolution and for light painting
  TCNT1 = 0;
  TCNT0 = 0;
  flip_to_next_page();
  PORTD = FrameBuffer[page_visible][0];  // Write out the LED value to the Frame Buffer
  OCR0A = (period / divisions);
  current_slice = 1;
}

// This interrupt is called every time timer0 counts up to the 8bit value
// stored in the register "ORC0A", which is configured in INT0 interrupt.
ISR(TIMER0_COMPA_vect) {
  PORTD = FrameBuffer[page_visible][current_slice];
  current_slice = ((current_slice + 1) % divisions);
}
// If the platter spin time overflows timer1, this is called
ISR(TIMER1_OVF_vect) {
}

Any help greatly appreciated!

Your theory is correct. The code will certainly interfere with millis. You just guessed the wrong timer (millis runs on timer 0).

any help greatly appreciated

What type of help are you seeking?

[quote author=Coding Badly link=topic=56085.msg402023#msg402023 date=1300748053] What type of help are you seeking? [/quote] Sorry about the ambiguity,

I am looking for a method to keep time on the arduino like the Time library provides, this way I don't need to have a computer connected to the device all the time. At the moment it is looking like I may have to invest in a Real Time Clock chip, but a software solution would make my day!

Well, the ATmega328 processor has three timers. The code you posted uses two timers. You may be able to move the timer 0 code to timer 3. That would resurrect millis.

Have you contacted Giles F. Hall? Asked him why he uses timer 0?

http://www.dipmicro.com/store/DS1307N This won't break the bank, will it? Small package too.

Or surface mount http://www.dipmicro.com/store/DS1307.SO8

CrossRoads: http://www.dipmicro.com/store/DS1307N This won't break the bank, will it? Small package too.

Wow! I've been buying from digikey which charges me $8 shipping to Ontario, that is much cheaper. Thanks!

[quote author=Coding Badly link=topic=56085.msg402039#msg402039 date=1300749127] Well, the ATmega328 processor has three timers. The code you posted uses two timers. You may be able to move the timer 0 code to timer 3. That would resurrect millis.

Have you contacted Giles F. Hall? Asked him why he uses timer 0?

[/quote]

Ok, I am going to try moving the functionality from timer 0 -> timer 2, I also sent an email asking that exact question, the code was written for either the Diecimila or the Duemilanove (I own the latter), likely it's because he was working sequentially without regard for a millis(). I previously thought that there were only two timers, oops!

I will post back with an update as to functionality after migration, hopefully nothing stops me from moving the timer.