add ballboard commands on mainboard
[aversive.git] / modules / hardware / timer / timer_definitions.h
1 /*  
2  *  Copyright Droids Corporation, Microb Technology, Eirbot (2006)
3  * 
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  *
18  *  Revision : $Id: timer_definitions.h,v 1.1.2.5 2009-04-07 20:00:46 zer0 Exp $
19  *
20  */
21
22 #ifndef _TIMER_DEFINITIONS_H_
23 #define _TIMER_DEFINITIONS_H_
24
25 /* needed by nearly all .c */
26 #include <aversive/parts.h>
27
28 #define DEFINE_TIMER_START_STOP(x)                                                       \
29                                                                                          \
30 /** start the timer */                                                                   \
31 void timer##x##_start(void)                                                              \
32 {                                                                                        \
33         TCNT##x = 0;                                                                     \
34         CS##x##0_REG = __timer##x##_div_to_reg(TIMER##x##_PRESCALER_DIV) << CS##x##0 ;   \
35 }                                                                                        \
36                                                                                          \
37 /** stop the timer */                                                                    \
38 void timer##x##_stop(void)                                                               \
39 {                                                                                        \
40         CS##x##0_REG = 0;                                                                \
41         TCNT##x = 0;                                                                     \
42 }
43
44
45
46 #define DEFINE_TIMER_GET_SET(x)                                                          \
47                                                                                          \
48 uint16_t timer##x##_get(void)                                                            \
49 {                                                                                        \
50         return TCNT##x ;                                                                 \
51 }                                                                                        \
52                                                                                          \
53 void timer##x##_set(uint16_t t)                                                          \
54 {                                                                                        \
55         TCNT##x = t;                                                                     \
56 }
57
58
59 #define DEFINE_OV_INTR(x)                               \
60 SIGNAL(x)                                               \
61 {                                                       \
62         if(timer_OV_callback_table[x##_NUM])            \
63                 timer_OV_callback_table[x##_NUM]();     \
64 }
65
66
67 #define DEFINE_OC_INTR(x)                               \
68 SIGNAL(x)                                               \
69 {                                                       \
70         if(timer_OC_callback_table[x##_NUM])            \
71                 timer_OC_callback_table[x##_NUM]();     \
72 }
73
74
75 #define DEFINE_REGISTER_OV_INTR(x)                                  \
76                                                                     \
77 void timer##x##_register_OV_intr(void (*func)(void))                \
78 {                                                                   \
79         uint8_t flags;                                              \
80                                                                     \
81         IRQ_LOCK(flags);                                            \
82         timer_OV_callback_table[SIG_OVERFLOW##x##_NUM] = func;      \
83         if (func) {                                                 \
84                 TOIE##x##_REG |= (1<<TOIE##x);                      \
85         }                                                           \
86         else {                                                      \
87                 TOIE##x##_REG &= (uint8_t)(~(1<<TOIE##x));          \
88         }                                                           \
89         IRQ_UNLOCK(flags);                                          \
90 }
91
92
93 #define DEFINE_REGISTER_OC_INTR_AT_TICS(x)                                      \
94                                                                                 \
95 void timer##x##_register_OC_intr_at_tics(void (*func)(void), uint16_t t)        \
96 {                                                                               \
97         uint8_t flags;                                                          \
98                                                                                 \
99         IRQ_LOCK(flags);                                                        \
100         timer_OC_callback_table[SIG_OUTPUT_COMPARE##x##_NUM] = func;            \
101         if (func) {                                                             \
102                 OCIE##x##_REG |= (1<<OCIE##x);                                  \
103                 OCR##x = t;                                                     \
104         }                                                                       \
105         else {                                                                  \
106                 OCIE##x##_REG &= (uint8_t)(~(1<<OCIE##x));                      \
107         }                                                                       \
108         IRQ_UNLOCK(flags);                                                      \
109 }
110
111
112 #define DEFINE_REGISTER_OC_INTR_IN_US(x,y)                                      \
113                                                                                 \
114 int8_t timer##y##_register_OC_intr_in_us(void (*func)(void), uint16_t t)        \
115 {                                                                               \
116         uint8_t flags;                                                          \
117         float tics;                                                             \
118                                                                                 \
119         IRQ_LOCK(flags);                                                        \
120         if (! func) {                                                           \
121                 timer_OC_callback_table[SIG_OUTPUT_COMPARE##y##_NUM] = func;    \
122                 OCIE##y##_REG &= (uint8_t)(~(1<<OCIE##y));                      \
123                 IRQ_UNLOCK(flags);                                              \
124                 return 0;                                                       \
125         }                                                                       \
126                                                                                 \
127         tics = timer##x##_us_to_tics(t);                                        \
128         if ( tics > 0xFFFF ) {  /* XXX use MAX_TIMER */                         \
129                 IRQ_UNLOCK(flags);                                              \
130                 return -1;                                                      \
131         }                                                                       \
132                                                                                 \
133         OCR##y = TCNT##x + tics;                                                \
134         timer_OC_callback_table[SIG_OUTPUT_COMPARE##y##_NUM] = func;            \
135         OCIE##y##_REG |= (1<<OCIE##y);                                          \
136         IRQ_UNLOCK(flags);                                                      \
137         return 0;                                                               \
138 }
139
140
141 #define DEFINE_DYNAMIC_PRESCALER_FUNCS(x)                           \
142                                                                     \
143 int16_t timer##x##_div_to_reg(uint16_t div)                         \
144 {                                                                   \
145         return __timer##x##_div_to_reg(div);                        \
146 }                                                                   \
147                                                                     \
148 int16_t timer##x##_reg_to_div(uint8_t reg)                          \
149 {                                                                   \
150         return __timer##x##_reg_to_div(reg);                        \
151 }                                                                   \
152                                                                     \
153 uint16_t timer##x##_get_prescaler_div(void)                         \
154 {                                                                   \
155         return __timer##x##_reg_to_div(CS##x##0_REG >> CS##x##0);   \
156 }                                                                   \
157                                                                     \
158 void timer##x##_set_prescaler_div(uint16_t div)                     \
159 {                                                                   \
160         CS##x##0_REG = __timer##x##_div_to_reg(div) << CS##x##0 ;   \
161 }
162
163
164 #define DEFINE_STATIC_PRESCALER_FUNCS(x)                            \
165                                                                     \
166 int16_t timer##x##_div_to_reg(__attribute__((unused)) uint16_t div)                         \
167 {                                                                   \
168         return __timer##x##_div_to_reg(TIMER##x##_PRESCALER_DIV);   \
169 }                                                                   \
170                                                                     \
171 uint16_t timer##x##_get_prescaler_div(void)                         \
172 {                                                                   \
173         return TIMER##x##_PRESCALER_DIV;                            \
174 }
175
176 #define DEFINE_TIMER_US_CONVERSIONS(x)                                   \
177                                                                          \
178 static inline float timer##x##_us_to_tics(float us)                      \
179 {                                                                        \
180         return ((float)CONFIG_QUARTZ /                                   \
181                 ((float)MHz * timer##x##_get_prescaler_div()) ) * us;    \
182 }                                                                        \
183                                                                          \
184 static inline float timer##x##_tics_to_us(float t)                       \
185 {                                                                        \
186         return t / ((float)CONFIG_QUARTZ /                               \
187                 ((float)MHz * timer##x##_get_prescaler_div()) );         \
188 }
189
190 #endif