Contiki 3.x
clock-avr.h
1 #ifndef CONTIKI_CLOCK_AVR_H
2 #define CONTIKI_CLOCK_AVR_H
3 
4 #if defined (__AVR_ATmega128__)
5 
6 #define AVR_OUTPUT_COMPARE_INT TIMER0_COMP_vect
7 
8 #define OCRSetup() \
9  /* Select internal clock */ \
10  ASSR = 0x00; \
11 \
12  /* Set counter to zero */ \
13  TCNT0 = 0; \
14 \
15  /* \
16  * Set comparison register: \
17  * Crystal freq. is F_CPU,\
18  * pre-scale factor is 1024, we want CLOCK_CONF_SECOND ticks / sec: \
19  * F_CPU = 1024 * CLOCK_CONF_SECOND * OCR0 \
20  */ \
21  OCR0 = F_CPU/1024UL/CLOCK_CONF_SECOND; \
22 \
23  /* \
24  * Set timer control register: \
25  * - prescale: 1024 (CS00 - CS02) \
26  * - counter reset via comparison register (WGM01) \
27  */ \
28  TCCR0 = _BV(CS00) | _BV(CS01) | _BV(CS02) | _BV(WGM01); \
29 \
30  /* Clear interrupt flag register */ \
31  TIFR = 0x00; \
32 \
33  /* \
34  * Raise interrupt when value in OCR0 is reached. Note that the \
35  * counter value in TCNT0 is cleared automatically. \
36  */ \
37  TIMSK = _BV (OCIE0);
38 
39 #elif defined (__AVR_ATmega128RFA1__) && 0
40 /* Uses the general routine below at present */
41 
42 #define AVR_OUTPUT_COMPARE_INT TIMER0_COMPA_vect
43 #define OCRSetup() \
44  /* Select internal clock */ \
45  ASSR = 0x00; \
46 \
47  /* Set counter to zero */ \
48  TCNT0 = 0; \
49 \
50  /* \
51  * Set comparison register: \
52  * Crystal freq. is F_CPU,\
53  * pre-scale factor is 1024, we want CLOCK_CONF_SECOND ticks / sec: \
54  * F_CPU = 1024 * CLOCK_CONF_SECOND * OCR0A, less 1 for CTC mode \
55  */ \
56  OCR0A = F_CPU/1024/CLOCK_CONF_SECOND - 1; \
57 \
58  /* \
59  * Set timer control register: \
60  * - prescale: 1024 (CS00 - CS02) \
61  * - counter reset via comparison register (WGM01) \
62  */ \
63  TCCR0A = _BV(WGM01); \
64  TCCR0B = _BV(CS00) | _BV(CS02); \
65 \
66  /* Clear interrupt flag register */ \
67  TIFR0 = TIFR0; \
68 \
69  /* \
70  * Raise interrupt when value in OCR0 is reached. Note that the \
71  * counter value in TCNT0 is cleared automatically. \
72  */ \
73  TIMSK0 = _BV (OCIE0A);
74 
75 
76 #elif defined (__AVR_ATmega1284P__) || (__AVR_AT90USB1287__) || (__AVR_ATmega1281__) || defined (__AVR_ATmega128RFA1__)
77 /*
78  The Raven has a 32768Hz watch crystal that can be used to clock the timer
79  while the 1284p is sleeping. The Jackdaw has pads for a crystal. The crystal
80  can be used to clock the 8 bit timer2.
81  The 1284p routine also uses TIMER2 to sleep a variable number of seconds.
82  It restores the values here after a wake.
83 */
84 #if AVR_CONF_USE32KCRYSTAL
85 #define AVR_OUTPUT_COMPARE_INT TIMER2_COMPA_vect
86 #define OCRSetup() \
87  /* Clock from crystal on TOSC0-1 */ \
88  ASSR = _BV(AS2); \
89 \
90  /* Set counter to zero */ \
91  TCNT2 = 0; \
92 \
93  /* \
94  * Set comparison register: \
95  * Crystal freq. is 32768,\
96  * pre-scale factor is 8, we want CLOCK_CONF_SECOND ticks / sec: \
97  * 32768 = 8 * CLOCK_CONF_SECOND * OCR2A, less 1 for CTC mode\
98  */ \
99  OCR2A = 32768/8/CLOCK_CONF_SECOND - 1; \
100 \
101  /* \
102  * Set timer control register: \
103  * - prescale: 8 (CS21) \
104  * - counter reset via comparison register (WGM21) \
105  */ \
106  TCCR2A = _BV(WGM21); \
107  TCCR2B = _BV(CS21); \
108 \
109  /* Clear interrupt flag register */ \
110  TIFR2 = TIFR2; \
111 \
112  /* \
113  * Raise interrupt when value in OCR2 is reached. Note that the \
114  * counter value in TCNT2 is cleared automatically. \
115  */ \
116  TIMSK2 = _BV (OCIE2A);
117 #else /* !AVR_CONF_USE32KCRYSTAL */
118 
119 /* Determine the largest value that can be used with 8 bit timer0 */
120 #ifndef F_CPU
121 #error "Please define CPU clock speed for your platform. #define F_CPU 8000000UL is typical."
122 #endif
123 #if CLOCK_CONF_SECOND == 0
124 #error "Please define timer ticks per second for your platform. #define CLOCK_CONF_SECOND 128 is typical."
125 #endif
126 
127 #ifdef AVR_CONF_TMR0_PRESCALE
128 #elif F_CPU/CLOCK_CONF_SECOND < 256
129  #define AVR_CONF_TMR0_PRESCALE 1
130 #elif F_CPU/CLOCK_CONF_SECOND < 256 * 8
131  #define AVR_CONF_TMR0_PRESCALE 8
132 #elif F_CPU/CLOCK_CONF_SECOND < 256 * 64
133  #define AVR_CONF_TMR0_PRESCALE 64
134 #elif F_CPU/CLOCK_CONF_SECOND < 256 * 256
135  #define AVR_CONF_TMR0_PRESCALE 256
136 #else
137  #define AVR_CONF_TMR0_PRESCALE 1024
138 #endif
139 
140 #if F_CPU/CLOCK_CONF_SECOND/AVR_CONF_TMR0_PRESCALE > 255
141 #error "Can not prescale CPU clock to get specified ticks per second. F_CPU/CLOCK_CONF_SECOND/1024 must be less than 256."
142 #endif
143 
144 #if AVR_CONF_TMR0_PRESCALE == 1
145  #define AVR_TCCR0B_CONF _BV(CS00)
146 #elif AVR_CONF_TMR0_PRESCALE == 8
147  #define AVR_TCCR0B_CONF _BV(CS01)
148 #elif AVR_CONF_TMR0_PRESCALE == 64
149  #define AVR_TCCR0B_CONF _BV(CS01) | _BV(CS00)
150 #elif AVR_CONF_TMR0_PRESCALE == 256
151  #define AVR_TCCR0B_CONF _BV(CS02)
152 #elif AVR_CONF_TMR0_PRESCALE == 1024
153  #define AVR_TCCR0B_CONF _BV(CS02) | _BV(CS00)
154 #else
155 #error "Prescale factor not supported. Allowed values are 1,8,64,256,1024."
156 #endif
157 
158 #define AVR_OUTPUT_COMPARE_INT TIMER0_COMPA_vect
159 
160 #define OCRSetup() \
161  /* Select internal clock */ \
162  ASSR = 0x00; \
163 \
164  /* Set counter to zero */ \
165  TCNT0 = 0; \
166 \
167  /* \
168  * Set comparison register: \
169  * Crystal freq. is F_CPU, prescale is given, \
170  * We want CLOCK_CONF_SECOND ticks / sec: \
171  * F_CPU = AVR_CONF_TMR0_PRESCALE * CLOCK_CONF_SECOND * OCR2A, less 1 for CTC mode \
172  */ \
173  OCR0A = F_CPU/AVR_CONF_TMR0_PRESCALE/CLOCK_CONF_SECOND - 1; \
174 \
175  /* \
176  * Set timer control register: \
177  * - prescale according to AVR_CONF_TMR0_PRESCALE \
178  * - counter reset via comparison register (WGM01) \
179  */ \
180  TCCR0A = _BV(WGM01); \
181  TCCR0B = AVR_TCCR0B_CONF; \
182 \
183  /* Clear interrupt flag register */ \
184  TIFR0 = TIFR0; \
185 \
186  /* \
187  * Raise interrupt when value in OCR0 is reached. Note that the \
188  * counter value in TCNT0 is cleared automatically. \
189  */ \
190  TIMSK0 = _BV (OCIE0A);
191 #endif /* AVR_CONF_USE32KCRYSTAL */
192 
193 #elif defined (__AVR_ATmega644__) || defined (__AVR_ATmega328P__)
194 
195 #define OCRSetup() \
196  /* Set counter to zero */ \
197  TCNT0 = 0; \
198 \
199  /* \
200  * Set comparison register: \
201  * Crystal freq. is F_CPU,\
202  * pre-scale factor is 256, want CLOCK_CONF_SECOND ticks / sec: \
203  */ \
204  OCR0A = F_CPU/256UL/CLOCK_CONF_SECOND - 1; \
205 \
206  /* \
207  * Set timer control register: \
208  * - prescale: 256 (CS02) \
209  * - counter reset via comparison register (WGM01) \
210  */ \
211  TCCR0A = _BV(WGM01); \
212  TCCR0B = _BV(CS02); \
213 \
214  /* Clear interrupt flag register */ \
215  TIFR0 = 0x00; \
216 \
217  /* \
218  * Raise interrupt when value in OCR0 is reached. Note that the \
219  * counter value in TCNT0 is cleared automatically. \
220  */ \
221  TIMSK0 = _BV (OCIE0A);
222 
223 #define AVR_OUTPUT_COMPARE_INT TIMER0_COMPA_vect
224 
225 #elif defined (__AVR_ATmega8515__) || defined (__AVR_ATmega16__) || defined (__AVR_ATmega32__)
226 
227 #define AVR_OUTPUT_COMPARE_INT TIMER0_COMP_vect
228 
229 #define OCRSetup() \
230  /* Set counter to zero */ \
231  TCNT0 = 0; \
232 \
233  /* \
234  * Set comparison register: \
235  * Crystal freq. is F_CPU,\
236  * pre-scale factor is 256, we want CLOCK_CONF_SECOND ticks / sec: \
237  * F_CPU = 256 * CLOCK_CONF_SECOND * OCR0 \
238  */ \
239  OCR0 = F_CPU/256UL/CLOCK_CONF_SECOND; \
240 \
241  /* \
242  * Set timer control register: \
243  * - prescale: 256 (CS02) \
244  * - counter reset via comparison register (WGM01) \
245  */ \
246  TCCR0 = _BV(CS02) | _BV(WGM01); \
247 \
248  /* Clear interrupt flag register */ \
249  TIFR = 0x00; \
250 \
251  /* \
252  * Raise interrupt when value in OCR0 is reached. Note that the \
253  * counter value in TCNT0 is cleared automatically. \
254  */ \
255  TIMSK = _BV (OCIE0);
256 
257 #elif defined (__AVR_ATmega8__)
258 
259 #define AVR_OUTPUT_COMPARE_INT TIMER2_COMP_vect
260 
261 #define OCRSetup() \
262  /* Set counter to zero */ \
263  TCNT2 = 0; \
264 \
265  /* \
266  * Set comparison register: \
267  * Crystal freq. is F_CPU,\
268  * pre-scale factor is 256, we want CLOCK_CONF_SECOND ticks / sec: \
269  * F_CPU = 256 * CLOCK_CONF_SECOND * OCR2 \
270  */ \
271  OCR2 = F_CPU/256UL/CLOCK_CONF_SECOND; \
272 \
273  /* \
274  * Set timer control register: \
275  * - prescale: 256 (CS21 CS22) \
276  * - counter reset via comparison register (WGM21) \
277  */ \
278  TCCR2 = _BV(CS22) | _BV(CS21) | _BV(WGM21); \
279 \
280  /* Clear interrupt flag register */ \
281  TIFR = 0x00; \
282 \
283  /* \
284  * Raise interrupt when value in OCR2 is reached. Note that the \
285  * counter value in TCNT2 is cleared automatically. \
286  */ \
287  TIMSK = _BV (OCIE2);
288 #else
289 #error "Setup CPU in clock-avr.h"
290 #endif
291 
292 #endif //CONTIKI_CLOCK_AVR_H