//timer02.c // use atmega timer2 as main system timer instead of timer0 // timer0 is used for fast pwm (OC0B output) // original OVF handler is disabled #include #include #include "Arduino.h" #include "io_atmega2560.h" #define BEEPER 84 uint8_t timer02_pwm0 = 0; void timer02_set_pwm0(uint8_t pwm0) { if (timer02_pwm0 == pwm0) return; if (pwm0) { TCCR0A |= (2 << COM0B0); OCR0B = pwm0 - 1; } else { TCCR0A &= ~(2 << COM0B0); OCR0B = 0; } timer02_pwm0 = pwm0; } void timer02_init(void) { //save sreg uint8_t _sreg = SREG; //disable interrupts for sure cli(); //mask timer0 interrupts - disable all TIMSK0 &= ~(1<> 3) #define FRACT_MAX (1000 >> 3) //extern volatile unsigned long timer0_overflow_count; //extern volatile unsigned long timer0_millis; //unsigned char timer0_fract = 0; volatile unsigned long timer2_overflow_count; volatile unsigned long timer2_millis; unsigned char timer2_fract = 0; ISR(TIMER2_OVF_vect) { // copy these to local variables so they can be stored in registers // (volatile variables must be read from memory on every access) unsigned long m = timer2_millis; unsigned char f = timer2_fract; m += MILLIS_INC; f += FRACT_INC; if (f >= FRACT_MAX) { f -= FRACT_MAX; m += 1; } timer2_fract = f; timer2_millis = m; timer2_overflow_count++; } unsigned long millis2(void) { unsigned long m; uint8_t oldSREG = SREG; // disable interrupts while we read timer0_millis or we might get an // inconsistent value (e.g. in the middle of a write to timer0_millis) cli(); m = timer2_millis; SREG = oldSREG; return m; } unsigned long micros2(void) { unsigned long m; uint8_t oldSREG = SREG, t; cli(); m = timer2_overflow_count; #if defined(TCNT2) t = TCNT2; #elif defined(TCNT2L) t = TCNT2L; #else #error TIMER 2 not defined #endif #ifdef TIFR2 if ((TIFR2 & _BV(TOV2)) && (t < 255)) m++; #else if ((TIFR & _BV(TOV2)) && (t < 255)) m++; #endif SREG = oldSREG; return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond()); } void delay2(unsigned long ms) { uint32_t start = micros2(); while (ms > 0) { yield(); while ( ms > 0 && (micros2() - start) >= 1000) { ms--; start += 1000; } } } void tone2(__attribute__((unused)) uint8_t _pin, __attribute__((unused)) unsigned int frequency/*, unsigned long duration*/) { PIN_SET(BEEPER); } void noTone2(__attribute__((unused)) uint8_t _pin) { PIN_CLR(BEEPER); }