Mercurial > templog
annotate main.c @ 12:3c27bfbd7f3a
Add simple_ds18b20.c etc
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Sat, 19 May 2012 21:47:09 +0800 |
parents | 1bfe28c348dd |
children | 4838bfcb3504 |
rev | line source |
---|---|
0 | 1 /* Name: main.c |
2 * Author: <insert your name here> | |
3 * Copyright: <insert your copyright message here> | |
4 * License: <insert your license reference here> | |
5 */ | |
6 | |
7 #include <stdio.h> | |
8 #include <string.h> | |
1 | 9 #include <avr/io.h> |
10 #include <avr/interrupt.h> | |
11 #include <avr/sleep.h> | |
7 | 12 #include <util/delay.h> |
6 | 13 #include <avr/pgmspace.h> |
0 | 14 #include <util/crc16.h> |
15 | |
12 | 16 // for DWORD of get_fattime() |
3 | 17 #include "integer.h" |
12 | 18 |
19 #include "simple_ds18b20.h" | |
3 | 20 |
0 | 21 // configuration params |
22 // - measurement interval | |
23 // - transmit interval | |
24 // - bluetooth params | |
25 // - number of sensors (and range?) | |
26 | |
1 | 27 // 1 second. we have 1024 prescaler, 32768 crystal. |
2 | 28 #define SLEEP_COMPARE 32 |
4
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
29 #define MEASURE_WAKE 60 |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
30 |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
31 #define COMMS_WAKE 3600 |
2 | 32 |
10 | 33 #define BAUD 19200 |
7 | 34 #define UBRR ((F_CPU)/8/(BAUD)-1) |
35 | |
36 #define PORT_LED PORTC | |
37 #define DDR_LED DDRC | |
38 #define PIN_LED PC4 | |
1 | 39 |
6 | 40 #define NUM_MEASUREMENTS 300 |
41 | |
10 | 42 int uart_putchar(char c, FILE *stream); |
0 | 43 static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, |
44 _FDEV_SETUP_WRITE); | |
45 | |
7 | 46 static uint8_t n_measurements = 0; |
6 | 47 // stored as 1/5 degree above 0 |
48 static uint8_t measurements[NUM_MEASUREMENTS]; | |
49 static uint8_t internal_measurements[NUM_MEASUREMENTS]; | |
0 | 50 |
4
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
51 // boolean flags |
7 | 52 static uint8_t need_measurement = 0; |
53 static uint8_t need_comms = 0; | |
54 static uint8_t comms_done = 0; | |
1 | 55 |
7 | 56 static uint8_t readpos = 0; |
0 | 57 static char readbuf[30]; |
58 | |
7 | 59 static uint8_t measure_count = 0; |
60 static uint16_t comms_count = 0; | |
4
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
61 |
8 | 62 #define DEBUG(str) printf_P(PSTR(str)) |
63 | |
4
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
64 static void deep_sleep(); |
1 | 65 |
0 | 66 static void |
7 | 67 uart_on() |
0 | 68 { |
8 | 69 // Power reduction register |
70 //PRR &= ~_BV(PRUSART0); | |
71 | |
0 | 72 // baud rate |
7 | 73 UBRR0H = (unsigned char)(UBRR >> 8); |
74 UBRR0L = (unsigned char)UBRR; | |
75 // set 2x clock, improves accuracy of UBRR | |
76 UCSR0A |= _BV(U2X0); | |
6 | 77 UCSR0B = _BV(RXCIE0) | _BV(RXEN0) | _BV(TXEN0); |
0 | 78 //8N1 |
7 | 79 UCSR0C = _BV(UCSZ01) | _BV(UCSZ00); |
6 | 80 } |
81 | |
82 static void | |
83 uart_off() | |
84 { | |
85 // Turn of interrupts and disable tx/rx | |
86 UCSR0B = 0; | |
87 | |
88 // Power reduction register | |
8 | 89 //PRR |= _BV(PRUSART0); |
0 | 90 } |
91 | |
10 | 92 int |
0 | 93 uart_putchar(char c, FILE *stream) |
94 { | |
10 | 95 // XXX should sleep in the loop for power. |
8 | 96 if (c == '\n') |
97 { | |
10 | 98 loop_until_bit_is_set(UCSR0A, UDRE0); |
99 UDR0 = '\r';; | |
8 | 100 } |
2 | 101 loop_until_bit_is_set(UCSR0A, UDRE0); |
102 UDR0 = c; | |
10 | 103 if (c == '\r') |
104 { | |
105 loop_until_bit_is_set(UCSR0A, UDRE0); | |
106 UDR0 = '\n';; | |
107 } | |
0 | 108 return 0; |
109 } | |
110 | |
111 static void | |
112 cmd_fetch() | |
113 { | |
114 uint16_t crc = 0; | |
115 int i; | |
6 | 116 printf_P(PSTR("%d measurements\n"), n_measurements); |
0 | 117 for (i = 0; i < n_measurements; i++) |
118 { | |
6 | 119 printf_P(PSTR("%3d : %d\n"), i, measurements[i]); |
1 | 120 crc = _crc_ccitt_update(crc, measurements[i]); |
0 | 121 } |
6 | 122 printf_P(PSTR("CRC : %d\n"), crc); |
0 | 123 } |
124 | |
125 static void | |
126 cmd_clear() | |
127 { | |
7 | 128 n_measurements = 0; |
129 printf_P(PSTR("Cleared\n")); | |
0 | 130 } |
131 | |
132 static void | |
133 cmd_btoff() | |
134 { | |
7 | 135 printf_P(PSTR("Turning off\n")); |
136 _delay_ms(50); | |
4
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
137 comms_done = 1; |
0 | 138 } |
139 | |
140 static void | |
12 | 141 cmd_measure() |
142 { | |
143 printf_P(PSTR("Measuring\n")); | |
144 need_measurement = 1; | |
145 } | |
146 | |
147 static void | |
148 cmd_sensors() | |
149 { | |
150 uint8_t ret = simple_ds18b20_start_meas(NULL); | |
151 printf("All sensors, ret %d, waiting...\n", ret); | |
152 _delay_ms(DS18B20_TCONV_12BIT); | |
153 simple_ds18b20_read_all(); | |
154 } | |
155 | |
156 static void | |
0 | 157 read_handler() |
158 { | |
6 | 159 if (strcmp_P(readbuf, PSTR("fetch")) == 0) |
0 | 160 { |
161 cmd_fetch(); | |
162 } | |
6 | 163 else if (strcmp_P(readbuf, PSTR("clear")) == 0) |
0 | 164 { |
165 cmd_clear(); | |
166 } | |
6 | 167 else if (strcmp_P(readbuf, PSTR("btoff")) == 0) |
0 | 168 { |
169 cmd_btoff(); | |
170 } | |
12 | 171 else if (strcmp_P(readbuf, PSTR("measure")) == 0) |
172 { | |
173 cmd_measure(); | |
174 } | |
175 else if (strcmp_P(readbuf, PSTR("sensors")) == 0) | |
176 { | |
177 cmd_sensors(); | |
178 } | |
0 | 179 else |
180 { | |
6 | 181 printf_P(PSTR("Bad command\n")); |
0 | 182 } |
183 } | |
184 | |
2 | 185 ISR(USART_RX_vect) |
0 | 186 { |
2 | 187 char c = UDR0; |
12 | 188 uart_putchar(c, NULL); |
189 if (c == '\r') | |
0 | 190 { |
191 readbuf[readpos] = '\0'; | |
192 read_handler(); | |
193 readpos = 0; | |
194 } | |
195 else | |
196 { | |
197 readbuf[readpos] = c; | |
198 readpos++; | |
199 if (readpos >= sizeof(readbuf)) | |
200 { | |
201 readpos = 0; | |
202 } | |
203 } | |
204 } | |
205 | |
2 | 206 ISR(TIMER2_COMPA_vect) |
1 | 207 { |
4
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
208 measure_count ++; |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
209 comms_count ++; |
12 | 210 printf("measure_count %d\n", measure_count); |
4
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
211 if (measure_count == MEASURE_WAKE) |
1 | 212 { |
4
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
213 measure_count = 0; |
12 | 214 printf("need_measurement = 1\n"); |
1 | 215 need_measurement = 1; |
216 } | |
4
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
217 |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
218 if (comms_count == COMMS_WAKE) |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
219 { |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
220 comms_count = 0; |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
221 need_comms = 1; |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
222 } |
1 | 223 } |
224 | |
3 | 225 DWORD get_fattime (void) |
226 { | |
227 return 0; | |
228 } | |
229 | |
1 | 230 static void |
231 deep_sleep() | |
232 { | |
233 // p119 of manual | |
2 | 234 OCR2A = SLEEP_COMPARE; |
235 loop_until_bit_is_clear(ASSR, OCR2AUB); | |
1 | 236 |
237 set_sleep_mode(SLEEP_MODE_PWR_SAVE); | |
238 sleep_mode(); | |
239 } | |
240 | |
241 static void | |
4
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
242 idle_sleep() |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
243 { |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
244 set_sleep_mode(SLEEP_MODE_IDLE); |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
245 sleep_mode(); |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
246 } |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
247 |
6 | 248 static void |
249 do_adc_335() | |
250 { | |
8 | 251 //PRR &= ~_BV(PRADC); |
6 | 252 |
253 ADMUX = _BV(ADLAR); | |
254 | |
255 // ADPS2 = /16 prescaler, 62khz at 1mhz clock | |
256 ADCSRA = _BV(ADEN) | _BV(ADPS2); | |
257 | |
258 // measure value | |
259 ADCSRA |= _BV(ADSC); | |
260 loop_until_bit_is_clear(ADCSRA, ADSC); | |
261 uint8_t low = ADCL; | |
262 uint8_t high = ADCH; | |
263 uint16_t f_measure = low + (high << 8); | |
264 | |
265 // set to measure 1.1 reference | |
266 ADMUX = _BV(ADLAR) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1); | |
267 ADCSRA |= _BV(ADSC); | |
268 loop_until_bit_is_clear(ADCSRA, ADSC); | |
269 uint8_t low_11 = ADCL; | |
270 uint8_t high_11 = ADCH; | |
271 uint16_t f_11 = low_11 + (high_11 << 8); | |
272 | |
273 float res_volts = 1.1 * f_measure / f_11; | |
274 | |
275 // 10mV/degree | |
276 // scale to 1/5 degree units above 0C | |
277 int temp = (res_volts - 2.73) * 500; | |
278 measurements[n_measurements] = temp; | |
279 // XXX something if it hits the limit | |
280 | |
281 // measure AVR internal temperature against 1.1 ref. | |
282 ADMUX = _BV(ADLAR) | _BV(MUX3) | _BV(REFS1) | _BV(REFS0); | |
283 ADCSRA |= _BV(ADSC); | |
284 loop_until_bit_is_clear(ADCSRA, ADSC); | |
285 uint16_t res_internal = ADCL; | |
286 res_internal |= ADCH << 8; | |
287 | |
288 float internal_volts = res_internal * (1.1 / 1024.0); | |
289 | |
290 // 1mV/degree | |
291 int internal_temp = (internal_volts - 2.73) * 5000; | |
292 internal_measurements[n_measurements] = internal_temp; | |
293 | |
294 printf_P("measure %d: external %d, internal %d, 1.1 %d\n", | |
295 n_measurements, temp, internal_temp, f_11); | |
296 | |
297 n_measurements++; | |
8 | 298 //PRR |= _BV(PRADC); |
6 | 299 } |
300 | |
4
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
301 static void |
1 | 302 do_measurement() |
303 { | |
12 | 304 printf("do_measurement\n"); |
1 | 305 need_measurement = 0; |
6 | 306 |
12 | 307 //do_adc_335(); |
1 | 308 } |
309 | |
4
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
310 static void |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
311 do_comms() |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
312 { |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
313 need_comms = 0; |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
314 |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
315 // turn on bluetooth |
7 | 316 uart_on(); |
4
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
317 |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
318 // write sd card here? same 3.3v regulator... |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
319 |
12 | 320 printf("ready> \n"); |
321 | |
4
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
322 comms_done = 0; |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
323 for (;;) |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
324 { |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
325 if (comms_done) |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
326 { |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
327 break; |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
328 } |
6 | 329 |
330 if (need_measurement) | |
331 { | |
332 do_measurement(); | |
333 } | |
334 | |
4
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
335 idle_sleep(); |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
336 } |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
337 |
6 | 338 uart_off(); |
339 | |
4
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
340 // turn off bluetooth |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
341 } |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
342 |
7 | 343 static void |
344 blink() | |
345 { | |
346 PORT_LED &= ~_BV(PIN_LED); | |
9 | 347 _delay_ms(1); |
7 | 348 PORT_LED |= _BV(PIN_LED); |
349 } | |
350 | |
351 static void | |
352 long_delay(int ms) | |
353 { | |
354 int iter = ms / 100; | |
355 | |
356 for (int i = 0; i < iter; i++) | |
357 { | |
358 _delay_ms(100); | |
359 } | |
360 } | |
361 | |
8 | 362 ISR(BADISR_vect) |
363 { | |
364 uart_on(); | |
365 printf_P(PSTR("Bad interrupt\n")); | |
366 } | |
367 | |
9 | 368 static void |
369 set_2mhz() | |
370 { | |
371 cli(); | |
372 CLKPR = _BV(CLKPCE); | |
373 // divide by 4 | |
374 CLKPR = _BV(CLKPS1); | |
375 sei(); | |
376 } | |
377 | |
378 static void | |
12 | 379 dump_ds18x20() |
9 | 380 { |
381 } | |
382 | |
0 | 383 int main(void) |
384 { | |
9 | 385 set_2mhz(); |
386 | |
7 | 387 DDR_LED |= _BV(PIN_LED); |
8 | 388 blink(); |
7 | 389 |
6 | 390 stdout = &mystdout; |
7 | 391 uart_on(); |
392 | |
6 | 393 fprintf_P(&mystdout, PSTR("hello %d\n"), 12); |
8 | 394 uart_off(); |
0 | 395 |
6 | 396 // turn off everything except timer2 |
8 | 397 //PRR = _BV(PRTWI) | _BV(PRTIM0) | _BV(PRTIM1) | _BV(PRSPI) | _BV(PRUSART0) | _BV(PRADC); |
398 | |
399 // for testing | |
400 uart_on(); | |
401 | |
12 | 402 sei(); |
8 | 403 |
12 | 404 #if 0 |
1 | 405 // set up counter2. |
406 // COM21 COM20 Set OC2 on Compare Match (p116) | |
407 // WGM21 Clear counter on compare | |
8 | 408 TCCR2A = _BV(COM2A1) | _BV(COM2A0) | _BV(WGM21); |
1 | 409 // CS22 CS21 CS20 clk/1024 |
2 | 410 TCCR2B = _BV(CS22) | _BV(CS21) | _BV(CS20); |
1 | 411 // set async mode |
412 ASSR |= _BV(AS2); | |
8 | 413 // interrupt |
414 TIMSK2 = _BV(OCIE2A); | |
12 | 415 #endif |
0 | 416 |
6 | 417 for (;;) |
418 { | |
12 | 419 do_comms(); |
6 | 420 } |
12 | 421 |
0 | 422 for(;;){ |
423 /* insert your main loop code here */ | |
1 | 424 if (need_measurement) |
425 { | |
426 do_measurement(); | |
4
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
427 continue; |
1 | 428 } |
4
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
429 |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
430 if (need_comms) |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
431 { |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
432 do_comms(); |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
433 continue; |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
434 } |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
435 |
54d369e3d689
Fill out more main.c structure
Matt Johnston <matt@ucc.asn.au>
parents:
3
diff
changeset
|
436 deep_sleep(); |
9 | 437 blink(); |
10 | 438 printf("."); |
0 | 439 } |
12 | 440 |
0 | 441 return 0; /* never reached */ |
442 } |