BeRTOS
|
00001 00047 #include <drv/timer_xmega.h> 00048 #include <cfg/macros.h> // BV() 00049 00050 #include <cpu/types.h> 00051 #include <cpu/irq.h> 00052 00053 #include <avr/io.h> 00054 00055 /* Helper MACROS taken from the Atmel examples and altered 00056 * 00057 * The AVR XMEGA has different structures for TC0 and TC1, 00058 * however these only differ in the amount of compare/capture 00059 * channels, so for this purpose they can be used exactly the same 00060 */ 00061 00062 //check if the bitvalues of the TC0 and TC1 Timer/Counters are really the same 00063 #if TC0_CLKSEL_gm != TC1_CLKSEL_gm || TC0_WGMODE_gm != TC1_WGMODE_gm || TC0_OVFINTLVL_gm != TC1_OVFINTLVL_gm 00064 #error TC0 and TC1 Timer/Counters cannot be configured with the same bitvalues 00065 #endif 00066 00067 #define TIMER_CONFIG_CLOCK_SOURCE(_clkSel)\ 00068 ((TIMERCOUNTER).CTRLA = ((TIMERCOUNTER).CTRLA & ~TC0_CLKSEL_gm) | _clkSel) 00069 00070 #define TIMER_CLEAR_FLAGS() ((TIMERCOUNTER).INTFLAGS = 0xFF) 00071 00072 #define TIMER_SET_PERIOD( _period ) ( (TIMERCOUNTER).PER = (_period) ) 00073 00074 #define TIMER_SET_OVERFLOW_INTERRUPT_LEVEL( _interruptLevel )\ 00075 ((TIMERCOUNTER).INTCTRLA = ( (TIMERCOUNTER).INTCTRLA & ~TC0_OVFINTLVL_gm ) | _interruptLevel) 00076 00077 #define TIMER_CONFIG_WGM(_wgm)\ 00078 ((TIMERCOUNTER).CTRLB = ( (TIMERCOUNTER).CTRLB & ~TC0_WGMODE_gm ) | _wgm) 00079 00080 #define TIMER_RESET() ( (TIMERCOUNTER).CTRLFSET = TC_CMD_RESET_gc ) 00081 00082 //Define TIMER_PRESCALE_REG_VALUE bases on the provided 00083 //TIMER_PRESCALER value 00084 #if TIMER_PRESCALER == 0 00085 #define TIMER_CLKSEL_gc TC_CLKSEL_OFF_gc 00086 #elif TIMER_PRESCALER == 1 00087 #define TIMER_CLKSEL_gc TC_CLKSEL_DIV1_gc 00088 #elif TIMER_PRESCALER == 2 00089 #define TIMER_CLKSEL_gc TC_CLKSEL_DIV2_gc 00090 #elif TIMER_PRESCALER == 4 00091 #define TIMER_CLKSEL_gc TC_CLKSEL_DIV4_gc 00092 #elif TIMER_PRESCALER == 16 00093 #define TIMER_CLKSEL_gc TC_CLKSEL_DIV16_gc 00094 #elif TIMER_PRESCALER == 64 00095 #define TIMER_CLKSEL_gc TC_CLKSEL_DIV64_gc 00096 #elif TIMER_PRESCALER == 256 00097 #define TIMER_CLKSEL_gc TC_CLKSEL_DIV256_gc 00098 #elif TIMER_PRESCALER == 1024 00099 #define TIMER_CLKSEL_gc TC_CLKSEL_DIV1024_gc 00100 #else 00101 #error Invalid value for TIMER_PRESCALER has been defined! Using default of 1 00102 #define TIMER_CLKSEL_gc TC_CLKSEL_DIV1_gc 00103 #endif 00104 00105 void timer_hw_init(void) 00106 { 00107 //Save and disable IRQ 00108 cpu_flags_t flags; 00109 IRQ_SAVE_DISABLE(flags); 00110 //disable the timer 00111 TIMER_CONFIG_CLOCK_SOURCE(TC_CLKSEL_OFF_gc); 00112 //clear all flags 00113 TIMER_CLEAR_FLAGS(); 00114 //setup the Periode register value 00115 //CNT register will be reset to 0 when CNT == PER 00116 TIMER_SET_PERIOD(TIMER_PERIOD_VALUE); 00117 //set the Waveform Generation Mode to Normal 00118 TIMER_CONFIG_WGM(TC_WGMODE_NORMAL_gc); 00119 //enable the overflow interrupt 00120 //use the highest priority 00121 TIMER_SET_OVERFLOW_INTERRUPT_LEVEL(TC_OVFINTLVL_HI_gc); 00122 //enable timer by setting the correct prescaler/clock 00123 TIMER_CONFIG_CLOCK_SOURCE(TIMER_CLKSEL_gc); 00124 //Restore IRQ 00125 IRQ_RESTORE(flags); 00126 }