X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;ds=sidebyside;f=bertos%2Fcpu%2Favr%2Fdrv%2Ftimer_xmega.h;fp=bertos%2Fcpu%2Favr%2Fdrv%2Ftimer_xmega.h;h=092cb4c4e0e0888afe2dc6b5f23143d05bfe06ba;hb=7af1283ce327bfe58eae21e167d20a47acf5bbd0;hp=0000000000000000000000000000000000000000;hpb=4c9e017d1b5cad3501d8d93aef46ec513bb03fd0;p=bertos.git diff --git a/bertos/cpu/avr/drv/timer_xmega.h b/bertos/cpu/avr/drv/timer_xmega.h new file mode 100644 index 00000000..092cb4c4 --- /dev/null +++ b/bertos/cpu/avr/drv/timer_xmega.h @@ -0,0 +1,134 @@ +/** + * \file + * + * + * \brief Low-level timer module for AVR XMEGA (interface). + * + * This file is heavily inspired by the AVR implementation for BeRTOS, + * but uses a different approach for implementing the different debug + * ports, by using the timer structs. + * + * \author Onno + * + */ + +#ifndef DRV_TIMER_XMEGA_H +#define DRV_TIMER_XMEGA_H + +#include /* CPU_FREQ */ + +#include "cfg/cfg_timer.h" /* CONFIG_TIMER */ +#include /* uint8_t */ +#include /* DIV_ROUND */ + +#include +#include + +/* + * \name Values for CONFIG_TIMER. + * + * Select which hardware timer interrupt to use for system clock and softtimers. + * $WIZ$ timer_select = "TIMER_USE_TCC0", "TIMER_USE_TCC1", "TIMER_USE_TCD0", "TIMER_USE_TCE0", "TIMER_USE_TCD1", "TIMER_DEFAULT" + */ +#define TIMER_USE_TCC0 1 +#define TIMER_USE_TCC1 2 +#define TIMER_USE_TCD0 3 +#define TIMER_USE_TCE0 4 +// The XMEGA A Family has one extra timer +#ifdef CPU_AVR_XMEGA_A + #define TIMER_USE_TCD1 5 +#endif + +#define TIMER_DEFAULT TIMER_USE_TCC1 ///< Default system timer + +/* + * Hardware dependent timer initialization. + */ +#if (CONFIG_TIMER == TIMER_USE_TCC0) + #define TIMER_OVF_VECT TCC0_OVF_vect + #define TIMERCOUNTER TCC0 +#elif (CONFIG_TIMER == TIMER_USE_TCC1) + #define TIMER_OVF_VECT TCC1_OVF_vect + #define TIMERCOUNTER TCC1 +#elif (CONFIG_TIMER == TIMER_USE_TCD0) + #define TIMER_OVF_VECT TCD0_OVF_vect + #define TIMERCOUNTER TCD0 +#elif (CONFIG_TIMER == TIMER_USE_TCE0) + #define TIMER_OVF_VECT TCE0_OVF_vect + #define TIMERCOUNTER TCE0 +#elif (CONFIG_TIMER == TIMER_USE_TCD1) + #define TIMER_OVF_VECT TCD1_OVF_vect + #define TIMERCOUNTER TCD1 +#else + #error Unimplemented value for CONFIG_TIMER +#endif /* CONFIG_TIMER */ + +//define the Interrupt Service Routine for this Timer Mode +#define DEFINE_TIMER_ISR DECLARE_ISR_CONTEXT_SWITCH(TIMER_OVF_VECT) +//define the Ticks per second we want +#define TIMER_TICKS_PER_SEC 1000 +//define the Prescaler to use, which is dependend on the amount +//of ticks per second, the maximum value for the TOP value of the +//timer (0xFFFF) and the clock frequency. +//The maximum clock frequency is 32Mhz, so as long as the TIMER_TICKS_PER_SEC +//is larger then (about) 500 no prescaler is required. +#define TIMER_PRESCALER 1 +//define the TOP/PERIOD value +#define TIMER_PERIOD_VALUE DIV_ROUND(DIV_ROUND(CPU_FREQ, TIMER_PRESCALER), TIMER_TICKS_PER_SEC) +//check if the TIMER_PRESCALER is large enough to accomate for the TIMER_TICKS_PER_SEC +#if TIMER_PERIOD_VALUE > 0xFFFF + #error Timer cannot generate the required Ticks per second, please adjust TIMER_PRESCALER +#endif +//define TIMER_HW_CNT it is used by the timer.c module to determine the 'edge' of the hardware counter +#define TIMER_HW_CNT TIMER_PERIOD_VALUE +/** Frequency of the hardware high precision timer. */ +#define TIMER_HW_HPTICKS_PER_SEC DIV_ROUND(CPU_FREQ, TIMER_PRESCALER) + +// Type of time expressed in ticks of the hardware high-precision timer +typedef uint16_t hptime_t; +#define SIZEOF_HPTIME_T 2 + +INLINE hptime_t timer_hw_hpread(void) +{ + return (TIMERCOUNTER).CNT; +} + +/* Not needed, IRQ timer flag cleared automatically */ +#define timer_hw_irq() do {} while (0) + +/* Not needed, timer IRQ handler called only for timer source */ +#define timer_hw_triggered() (true) + +void timer_hw_init(void); + +#endif /* DRV_TIMER_XMEGA_H */