]> git.donarmstrong.com Git - qmk_firmware.git/blobdiff - tmk_core/common/avr/timer.c
Generate API docs from source code comments (#2491)
[qmk_firmware.git] / tmk_core / common / avr / timer.c
index 292b41c3a6c29fca9e4319114a0759473ea3e7e3..b7d4f060ef0993a01d2cd9d2ea84bb17ed8b0019 100644 (file)
@@ -17,6 +17,7 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 #include <avr/io.h>
 #include <avr/interrupt.h>
+#include <util/atomic.h>
 #include <stdint.h>
 #include "timer_avr.h"
 #include "timer.h"
@@ -24,94 +25,128 @@ along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 // counter resolution 1ms
 // NOTE: union { uint32_t timer32; struct { uint16_t dummy; uint16_t timer16; }}
-volatile uint32_t timer_count = 0;
+volatile uint32_t timer_count;
 
+/** \brief timer initialization
+ *
+ * FIXME: needs doc
+ */
 void timer_init(void)
 {
-    // Timer0 CTC mode
-    TCCR0A = 0x02;
-
 #if TIMER_PRESCALER == 1
-    TCCR0B = 0x01;
+    uint8_t prescaler = 0x01;
 #elif TIMER_PRESCALER == 8
-    TCCR0B = 0x02;
+    uint8_t prescaler = 0x02;
 #elif TIMER_PRESCALER == 64
-    TCCR0B = 0x03;
+    uint8_t prescaler = 0x03;
 #elif TIMER_PRESCALER == 256
-    TCCR0B = 0x04;
+    uint8_t prescaler = 0x04;
 #elif TIMER_PRESCALER == 1024
-    TCCR0B = 0x05;
+    uint8_t prescaler = 0x05;
 #else
 #   error "Timer prescaler value is NOT vaild."
 #endif
 
+#ifndef __AVR_ATmega32A__
+    // Timer0 CTC mode
+    TCCR0A = 0x02;
+
+    TCCR0B = prescaler;
+
     OCR0A = TIMER_RAW_TOP;
     TIMSK0 = (1<<OCIE0A);
+#else
+    // Timer0 CTC mode
+    TCCR0 = (1 << WGM01) | prescaler;
+
+    OCR0 = TIMER_RAW_TOP;
+    TIMSK = (1 << OCIE0);
+#endif
 }
 
+/** \brief timer clear
+ *
+ * FIXME: needs doc
+ */
 inline
 void timer_clear(void)
 {
-    uint8_t sreg = SREG;
-    cli();
+  ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
     timer_count = 0;
-    SREG = sreg;
+  }
 }
 
+/** \brief timer read
+ *
+ * FIXME: needs doc
+ */
 inline
 uint16_t timer_read(void)
 {
     uint32_t t;
 
-    uint8_t sreg = SREG;
-    cli();
-    t = timer_count;
-    SREG = sreg;
+    ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
+      t = timer_count;
+    }
 
     return (t & 0xFFFF);
 }
 
+/** \brief timer read32
+ *
+ * FIXME: needs doc
+ */
 inline
 uint32_t timer_read32(void)
 {
     uint32_t t;
 
-    uint8_t sreg = SREG;
-    cli();
-    t = timer_count;
-    SREG = sreg;
+    ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
+      t = timer_count;
+    }
 
     return t;
 }
 
+/** \brief timer elapsed
+ *
+ * FIXME: needs doc
+ */
 inline
 uint16_t timer_elapsed(uint16_t last)
 {
     uint32_t t;
 
-    uint8_t sreg = SREG;
-    cli();
-    t = timer_count;
-    SREG = sreg;
+    ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
+      t = timer_count;
+    }
 
     return TIMER_DIFF_16((t & 0xFFFF), last);
 }
 
+/** \brief timer elapsed32
+ *
+ * FIXME: needs doc
+ */
 inline
 uint32_t timer_elapsed32(uint32_t last)
 {
     uint32_t t;
 
-    uint8_t sreg = SREG;
-    cli();
-    t = timer_count;
-    SREG = sreg;
+    ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
+      t = timer_count;
+    }
 
     return TIMER_DIFF_32(t, last);
 }
 
 // excecuted once per 1ms.(excess for just timer count?)
-ISR(TIMER0_COMPA_vect)
+#ifndef __AVR_ATmega32A__
+#define TIMER_INTERRUPT_VECTOR TIMER0_COMPA_vect
+#else
+#define TIMER_INTERRUPT_VECTOR TIMER0_COMP_vect
+#endif
+ISR(TIMER_INTERRUPT_VECTOR, ISR_NOBLOCK)
 {
     timer_count++;
 }