Add timer support for ATmega1281 (only for ther out on copare 0/2).
[bertos.git] / bertos / cpu / avr / drv / timer_avr.c
index b6771a92da8984b5d2985ac79ec4ff4f075d2480..b224a902016e6775c4b8557d315aaab41834394c 100644 (file)
@@ -37,7 +37,7 @@
  *
  * \brief Low-level timer module for AVR (implementation).
  *
- * This module is automatically included so no need to include 
+ * This module is automatically included so no need to include
  * in test list.
  * notest: avr
  */
        #define REG_TIMSK0 TIMSK0
        #define REG_TIMSK2 TIMSK2
 
+       #define REG_TCCR0A TCCR0A
+       #define REG_TCCR0B TCCR0B
+
        #define REG_TCCR2A TCCR2A
        #define REG_TCCR2B TCCR2B
 
+       #define REG_OCR0A  OCR0A
        #define REG_OCR2A  OCR2A
 
        #define BIT_OCF0A  OCF0A
        #define REG_TIMSK0 TIMSK
        #define REG_TIMSK2 TIMSK
 
+       #define REG_TCCR2A TCCR0
+       #define REG_TCCR2B TCCR0
+
        #define REG_TCCR2A TCCR2
        #define REG_TCCR2B TCCR2
 
+       #define REG_OCR0A  OCR0
        #define REG_OCR2A  OCR2
 
        #define BIT_OCF0A  OCF0
        #define BIT_OCIE2A OCIE2
 #endif
 
+#if CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA103
+    /* These ATMega have different prescaler options. */
+    #define TIMER0_PRESCALER_64 BV(CS02)
+    #define TIMER2_PRESCALER_64 (BV(CS21) | BV(CS20))
+#else
+    #define TIMER0_PRESCALER_64 (BV(CS01) | BV(CS00))
+    #define TIMER2_PRESCALER_64 BV(CS22)
+#endif
 
 /** HW dependent timer initialization  */
 #if (CONFIG_TIMER == TIMER_ON_OUTPUT_COMPARE0)
 
        static void timer_hw_init(void)
        {
-               cpuflags_t flags;
+               cpu_flags_t flags;
                IRQ_SAVE_DISABLE(flags);
 
                /* Reset Timer flags */
 
                /* Setup Timer/Counter interrupt */
                ASSR = 0x00;                  /* Internal system clock */
-               TCCR0 = BV(WGM01)             /* Clear on Compare match */
+
+               REG_TCCR0A = 0; // TCCR2 reg could be separate or a unique register with both A & B values, this is needed to
+               REG_TCCR0B = 0;
+
+               REG_TCCR0A = BV(WGM01);             /* Clear on Compare match */
                        #if TIMER_PRESCALER == 64
-                               | BV(CS02)
+                       REG_TCCR0B |= TIMER0_PRESCALER_64;
                        #else
                                #error Unsupported value of TIMER_PRESCALER
                        #endif
                ;
                TCNT0 = 0x00;                 /* Initialization of Timer/Counter */
-               OCR0 = OCR_DIVISOR;           /* Timer/Counter Output Compare Register */
+               REG_OCR0A = OCR_DIVISOR;           /* Timer/Counter Output Compare Register */
 
                /* Enable timer interrupts: Timer/Counter2 Output Compare (OCIE2) */
                REG_TIMSK0 &= ~BV(TOIE0);
-               REG_TIMSK0 |= BV(OCIE0);
+               REG_TIMSK0 |= BV(OCIE0A);
 
                IRQ_RESTORE(flags);
        }
 
        static void timer_hw_init(void)
        {
-               cpuflags_t flags;
+               cpu_flags_t flags;
                IRQ_SAVE_DISABLE(flags);
 
                /* Reset Timer overflow flag */
-               TIFR |= BV(TOV1);
+               REG_TIFR0 |= BV(TOV1);
 
                /* Fast PWM mode, 9 bit, 24 kHz, no prescaling. */
                #if (TIMER_PRESCALER == 1) && (TIMER_HW_BITS == 9)
                TCNT1 = 0x00;         /* initialization of Timer/Counter */
 
                /* Enable timer interrupt: Timer/Counter1 Overflow */
-               TIMSK |= BV(TOIE1);
+               REG_TIMSK0 |= BV(TOIE1);
 
                IRQ_RESTORE(flags);
        }
 #elif (CONFIG_TIMER == TIMER_ON_OUTPUT_COMPARE2)
        static void timer_hw_init(void)
        {
-               cpuflags_t flags;
+               cpu_flags_t flags;
                IRQ_SAVE_DISABLE(flags);
 
                /* Reset Timer flags */
 
                REG_TCCR2A = BV(WGM21);
                #if TIMER_PRESCALER == 64
-               #if CPU_AVR_ATMEGA1281 || CPU_AVR_ATMEGA168
-                       // ATMega1281 & ATMega168 have undocumented differences in timer2 prescaler!
-                       REG_TCCR2B |= BV(CS22);
-               #else
-                       REG_TCCR2B |= BV(CS21) | BV(CS20);
-               #endif
+                       REG_TCCR2B |= TIMER2_PRESCALER_64;
                #else
                        #error Unsupported value of TIMER_PRESCALER
                #endif
 
        static void timer_hw_init(void)
        {
-               cpuflags_t flags;
+               cpu_flags_t flags;
                IRQ_SAVE_DISABLE(flags);
 
                /* Reset Timer overflow flag */