00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef _TIMER_DEFINITIONS_H_
00023 #define _TIMER_DEFINITIONS_H_
00024
00025
00026 #include <aversive/parts.h>
00027
00028 #define DEFINE_TIMER_START_STOP(x) \
00029 \
00030 \
00031 void timer##x##_start(void) \
00032 { \
00033 TCNT##x = 0; \
00034 CS##x##0_REG = __timer##x##_div_to_reg(TIMER##x##_PRESCALER_DIV) << CS##x##0 ; \
00035 } \
00036 \
00037 \
00038 void timer##x##_stop(void) \
00039 { \
00040 CS##x##0_REG = 0; \
00041 TCNT##x = 0; \
00042 }
00043
00044
00045
00046 #define DEFINE_TIMER_GET_SET(x) \
00047 \
00048 uint16_t timer##x##_get(void) \
00049 { \
00050 return TCNT##x ; \
00051 } \
00052 \
00053 void timer##x##_set(uint16_t t) \
00054 { \
00055 TCNT##x = t; \
00056 }
00057
00058
00059 #define DEFINE_OV_INTR(x) \
00060 SIGNAL(x) \
00061 { \
00062 if(timer_OV_callback_table[x##_NUM]) \
00063 timer_OV_callback_table[x##_NUM](); \
00064 }
00065
00066
00067 #define DEFINE_OC_INTR(x) \
00068 SIGNAL(x) \
00069 { \
00070 if(timer_OC_callback_table[x##_NUM]) \
00071 timer_OC_callback_table[x##_NUM](); \
00072 }
00073
00074
00075 #define DEFINE_REGISTER_OV_INTR(x) \
00076 \
00077 void timer##x##_register_OV_intr(void (*func)(void)) \
00078 { \
00079 uint8_t flags; \
00080 \
00081 IRQ_LOCK(flags); \
00082 timer_OV_callback_table[SIG_OVERFLOW##x##_NUM] = func; \
00083 if (func) { \
00084 TOIE##x##_REG |= (1<<TOIE##x); \
00085 } \
00086 else { \
00087 TOIE##x##_REG &= (uint8_t)(~(1<<TOIE##x)); \
00088 } \
00089 IRQ_UNLOCK(flags); \
00090 }
00091
00092
00093 #define DEFINE_REGISTER_OC_INTR_AT_TICS(x) \
00094 \
00095 void timer##x##_register_OC_intr_at_tics(void (*func)(void), uint16_t t) \
00096 { \
00097 uint8_t flags; \
00098 \
00099 IRQ_LOCK(flags); \
00100 timer_OC_callback_table[SIG_OUTPUT_COMPARE##x##_NUM] = func; \
00101 if (func) { \
00102 OCIE##x##_REG |= (1<<OCIE##x); \
00103 OCR##x = t; \
00104 } \
00105 else { \
00106 OCIE##x##_REG &= (uint8_t)(~(1<<OCIE##x)); \
00107 } \
00108 IRQ_UNLOCK(flags); \
00109 }
00110
00111
00112 #define DEFINE_REGISTER_OC_INTR_IN_US(x,y) \
00113 \
00114 int8_t timer##y##_register_OC_intr_in_us(void (*func)(void), uint16_t t) \
00115 { \
00116 uint8_t flags; \
00117 float tics; \
00118 \
00119 IRQ_LOCK(flags); \
00120 if (! func) { \
00121 timer_OC_callback_table[SIG_OUTPUT_COMPARE##y##_NUM] = func; \
00122 OCIE##y##_REG &= (uint8_t)(~(1<<OCIE##y)); \
00123 IRQ_UNLOCK(flags); \
00124 return 0; \
00125 } \
00126 \
00127 tics = timer##x##_us_to_tics(t); \
00128 if ( tics > 0xFFFF ) { \
00129 IRQ_UNLOCK(flags); \
00130 return -1; \
00131 } \
00132 \
00133 OCR##y = TCNT##x + tics; \
00134 timer_OC_callback_table[SIG_OUTPUT_COMPARE##y##_NUM] = func; \
00135 OCIE##y##_REG |= (1<<OCIE##y); \
00136 IRQ_UNLOCK(flags); \
00137 return 0; \
00138 }
00139
00140
00141 #define DEFINE_DYNAMIC_PRESCALER_FUNCS(x) \
00142 \
00143 int16_t timer##x##_div_to_reg(uint16_t div) \
00144 { \
00145 return __timer##x##_div_to_reg(div); \
00146 } \
00147 \
00148 int16_t timer##x##_reg_to_div(uint8_t reg) \
00149 { \
00150 return __timer##x##_reg_to_div(reg); \
00151 } \
00152 \
00153 uint16_t timer##x##_get_prescaler_div(void) \
00154 { \
00155 return __timer##x##_reg_to_div(CS##x##0_REG >> CS##x##0); \
00156 } \
00157 \
00158 void timer##x##_set_prescaler_div(uint16_t div) \
00159 { \
00160 CS##x##0_REG = __timer##x##_div_to_reg(div) << CS##x##0 ; \
00161 }
00162
00163
00164 #define DEFINE_STATIC_PRESCALER_FUNCS(x) \
00165 \
00166 int16_t timer##x##_div_to_reg(uint16_t div) \
00167 { \
00168 return __timer##x##_div_to_reg(TIMER##x##_PRESCALER_DIV); \
00169 } \
00170 \
00171 uint16_t timer##x##_get_prescaler_div(void) \
00172 { \
00173 return TIMER##x##_PRESCALER_DIV; \
00174 }
00175
00176 #define DEFINE_TIMER_US_CONVERSIONS(x) \
00177 \
00178 static inline float timer##x##_us_to_tics(float us) \
00179 { \
00180 return ((float)CONFIG_QUARTZ / \
00181 ((float)MHz * timer##x##_get_prescaler_div()) ) * us; \
00182 } \
00183 \
00184 static inline float timer##x##_tics_to_us(float t) \
00185 { \
00186 return t / ((float)CONFIG_QUARTZ / \
00187 ((float)MHz * timer##x##_get_prescaler_div()) ); \
00188 }
00189
00190 #endif