Mercurial > templog
comparison main.c @ 8:c55321727d02
deep sleep works
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Fri, 18 May 2012 20:38:40 +0800 |
parents | 52cb08a01171 |
children | 7da9a3f23592 |
comparison
equal
deleted
inserted
replaced
7:52cb08a01171 | 8:c55321727d02 |
---|---|
54 static char readbuf[30]; | 54 static char readbuf[30]; |
55 | 55 |
56 static uint8_t measure_count = 0; | 56 static uint8_t measure_count = 0; |
57 static uint16_t comms_count = 0; | 57 static uint16_t comms_count = 0; |
58 | 58 |
59 #define DEBUG(str) printf_P(PSTR(str)) | |
60 | |
59 static void deep_sleep(); | 61 static void deep_sleep(); |
60 | 62 |
61 static void | 63 static void |
62 uart_on() | 64 uart_on() |
63 { | 65 { |
66 // Power reduction register | |
67 //PRR &= ~_BV(PRUSART0); | |
68 | |
64 // baud rate | 69 // baud rate |
65 UBRR0H = (unsigned char)(UBRR >> 8); | 70 UBRR0H = (unsigned char)(UBRR >> 8); |
66 UBRR0L = (unsigned char)UBRR; | 71 UBRR0L = (unsigned char)UBRR; |
67 // set 2x clock, improves accuracy of UBRR | 72 // set 2x clock, improves accuracy of UBRR |
68 UCSR0A |= _BV(U2X0); | 73 UCSR0A |= _BV(U2X0); |
69 UCSR0B = _BV(RXCIE0) | _BV(RXEN0) | _BV(TXEN0); | 74 UCSR0B = _BV(RXCIE0) | _BV(RXEN0) | _BV(TXEN0); |
70 //8N1 | 75 //8N1 |
71 UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); | 76 UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); |
72 | |
73 // Power reduction register | |
74 //PRR &= ~_BV(PRUSART0); | |
75 } | |
76 | |
77 static void | |
78 uart_test() | |
79 { | |
80 | |
81 UDR0 = 'n'; | |
82 _delay_ms(50); | |
83 UDR0 = 'f'; | |
84 _delay_ms(50); | |
85 while ( !( UCSR0A & (1<<UDRE0)) ); | |
86 UDR0 = 'x'; | |
87 loop_until_bit_is_set(UCSR0A, UDRE0); | |
88 UDR0 = 'a'; | |
89 loop_until_bit_is_set(UCSR0A, UDRE0); | |
90 UDR0 = 'b'; | |
91 loop_until_bit_is_set(UCSR0A, UDRE0); | |
92 UDR0 = 'c'; | |
93 loop_until_bit_is_set(UCSR0A, UDRE0); | |
94 UDR0 = '\n'; | |
95 } | 77 } |
96 | 78 |
97 static void | 79 static void |
98 uart_off() | 80 uart_off() |
99 { | 81 { |
100 // Turn of interrupts and disable tx/rx | 82 // Turn of interrupts and disable tx/rx |
101 UCSR0B = 0; | 83 UCSR0B = 0; |
102 | 84 |
103 // Power reduction register | 85 // Power reduction register |
104 PRR |= _BV(PRUSART0); | 86 //PRR |= _BV(PRUSART0); |
105 } | 87 } |
106 | 88 |
107 static int | 89 static int |
108 uart_putchar(char c, FILE *stream) | 90 uart_putchar(char c, FILE *stream) |
109 { | 91 { |
92 if (c == '\n') | |
93 { | |
94 uart_putchar('\r', stream); | |
95 } | |
110 // XXX should sleep in the loop for power. | 96 // XXX should sleep in the loop for power. |
111 loop_until_bit_is_set(UCSR0A, UDRE0); | 97 loop_until_bit_is_set(UCSR0A, UDRE0); |
112 UDR0 = c; | 98 UDR0 = c; |
113 return 0; | 99 return 0; |
114 } | 100 } |
164 } | 150 } |
165 | 151 |
166 ISR(USART_RX_vect) | 152 ISR(USART_RX_vect) |
167 { | 153 { |
168 char c = UDR0; | 154 char c = UDR0; |
155 printf_P(PSTR("wake up '%c'\n"), c); | |
169 if (c == '\n') | 156 if (c == '\n') |
170 { | 157 { |
171 readbuf[readpos] = '\0'; | 158 readbuf[readpos] = '\0'; |
172 read_handler(); | 159 read_handler(); |
173 readpos = 0; | 160 readpos = 0; |
183 } | 170 } |
184 } | 171 } |
185 | 172 |
186 ISR(TIMER2_COMPA_vect) | 173 ISR(TIMER2_COMPA_vect) |
187 { | 174 { |
175 DEBUG("wake up\n"); | |
188 measure_count ++; | 176 measure_count ++; |
189 comms_count ++; | 177 comms_count ++; |
190 if (measure_count == MEASURE_WAKE) | 178 if (measure_count == MEASURE_WAKE) |
191 { | 179 { |
192 measure_count = 0; | 180 measure_count = 0; |
208 } | 196 } |
209 | 197 |
210 static void | 198 static void |
211 deep_sleep() | 199 deep_sleep() |
212 { | 200 { |
201 DEBUG("deep sleep\n"); | |
213 // p119 of manual | 202 // p119 of manual |
214 OCR2A = SLEEP_COMPARE; | 203 OCR2A = SLEEP_COMPARE; |
215 loop_until_bit_is_clear(ASSR, OCR2AUB); | 204 loop_until_bit_is_clear(ASSR, OCR2AUB); |
216 | 205 |
206 DEBUG("really about to\n"); | |
207 | |
217 set_sleep_mode(SLEEP_MODE_PWR_SAVE); | 208 set_sleep_mode(SLEEP_MODE_PWR_SAVE); |
209 DEBUG("done.\n"); | |
218 sleep_mode(); | 210 sleep_mode(); |
219 } | 211 } |
220 | 212 |
221 static void | 213 static void |
222 idle_sleep() | 214 idle_sleep() |
226 } | 218 } |
227 | 219 |
228 static void | 220 static void |
229 do_adc_335() | 221 do_adc_335() |
230 { | 222 { |
231 PRR &= ~_BV(PRADC); | 223 //PRR &= ~_BV(PRADC); |
232 | 224 |
233 ADMUX = _BV(ADLAR); | 225 ADMUX = _BV(ADLAR); |
234 | 226 |
235 // ADPS2 = /16 prescaler, 62khz at 1mhz clock | 227 // ADPS2 = /16 prescaler, 62khz at 1mhz clock |
236 ADCSRA = _BV(ADEN) | _BV(ADPS2); | 228 ADCSRA = _BV(ADEN) | _BV(ADPS2); |
273 | 265 |
274 printf_P("measure %d: external %d, internal %d, 1.1 %d\n", | 266 printf_P("measure %d: external %d, internal %d, 1.1 %d\n", |
275 n_measurements, temp, internal_temp, f_11); | 267 n_measurements, temp, internal_temp, f_11); |
276 | 268 |
277 n_measurements++; | 269 n_measurements++; |
278 PRR |= _BV(PRADC); | 270 //PRR |= _BV(PRADC); |
279 } | 271 } |
280 | 272 |
281 static void | 273 static void |
282 do_measurement() | 274 do_measurement() |
283 { | 275 { |
334 { | 326 { |
335 _delay_ms(100); | 327 _delay_ms(100); |
336 } | 328 } |
337 } | 329 } |
338 | 330 |
331 ISR(BADISR_vect) | |
332 { | |
333 uart_on(); | |
334 printf_P(PSTR("Bad interrupt\n")); | |
335 } | |
336 | |
339 int main(void) | 337 int main(void) |
340 { | 338 { |
341 DDR_LED |= _BV(PIN_LED); | 339 DDR_LED |= _BV(PIN_LED); |
342 | |
343 blink(); | 340 blink(); |
344 long_delay(1000); | 341 |
345 blink(); | |
346 long_delay(500); | |
347 stdout = &mystdout; | 342 stdout = &mystdout; |
348 uart_on(); | 343 uart_on(); |
349 blink(); | |
350 long_delay(200); | |
351 blink(); | |
352 long_delay(200); | |
353 uart_test(); | |
354 | |
355 PORT_LED &= ~_BV(PIN_LED); | |
356 for (int i = 0; i < 10; i++) | |
357 _delay_ms(100); | |
358 PORT_LED |= _BV(PIN_LED); | |
359 | 344 |
360 fprintf_P(&mystdout, PSTR("hello %d\n"), 12); | 345 fprintf_P(&mystdout, PSTR("hello %d\n"), 12); |
361 //uart_off(); | 346 uart_off(); |
362 | 347 |
363 // turn off everything except timer2 | 348 // turn off everything except timer2 |
364 PRR = _BV(PRTWI) | _BV(PRTIM0) | _BV(PRTIM1) | _BV(PRSPI) | _BV(PRUSART0) | _BV(PRADC); | 349 //PRR = _BV(PRTWI) | _BV(PRTIM0) | _BV(PRTIM1) | _BV(PRSPI) | _BV(PRUSART0) | _BV(PRADC); |
350 | |
351 // for testing | |
352 uart_on(); | |
353 | |
354 DEBUG("power off\n"); | |
355 sei(); | |
356 DEBUG("sei done\n"); | |
357 | |
365 | 358 |
366 // set up counter2. | 359 // set up counter2. |
367 // COM21 COM20 Set OC2 on Compare Match (p116) | 360 // COM21 COM20 Set OC2 on Compare Match (p116) |
368 // WGM21 Clear counter on compare | 361 // WGM21 Clear counter on compare |
362 TCCR2A = _BV(COM2A1) | _BV(COM2A0) | _BV(WGM21); | |
369 // CS22 CS21 CS20 clk/1024 | 363 // CS22 CS21 CS20 clk/1024 |
370 TCCR2A = _BV(COM2A1) | _BV(COM2A0) | _BV(WGM21); | |
371 TCCR2B = _BV(CS22) | _BV(CS21) | _BV(CS20); | 364 TCCR2B = _BV(CS22) | _BV(CS21) | _BV(CS20); |
372 // set async mode | 365 // set async mode |
373 ASSR |= _BV(AS2); | 366 ASSR |= _BV(AS2); |
374 | 367 // interrupt |
375 DDR_LED |= _BV(PIN_LED); | 368 TIMSK2 = _BV(OCIE2A); |
376 PORT_LED &= ~_BV(PIN_LED); | 369 |
377 _delay_ms(100); | 370 DEBUG("async setup\n"); |
378 PORT_LED |= _BV(PIN_LED); | |
379 | 371 |
380 #ifdef TEST_MODE | 372 #ifdef TEST_MODE |
381 for (;;) | 373 for (;;) |
382 { | 374 { |
383 do_comms() | 375 do_comms() |