Mercurial > ~darius > hgwebdir.cgi > avr
annotate testavr.c @ 41:5898fba6593c
Add temperature control.
- Split out console stuff to cons.[ch]. Set up stdio so we can use printf etc.
- Use \r\n as the line terminator consistently.
- Add OWGetTemp to get temperatures from a device.
- Load/save settings in EEPROM, defaults loaded from flash.
Nearly feature complete except you can't edit ROM IDs without a programming tool :)
(To be fixed)
Needs more testing.
author | darius@inchoate.localdomain |
---|---|
date | Sun, 06 Jul 2008 22:19:53 +0930 |
parents | 0a148f362097 |
children | 13a68734348b |
rev | line source |
---|---|
0 | 1 /* |
9
7ed10c59ba06
Supply clock speed via the command line so 1wire-delay.h can use it.
darius
parents:
7
diff
changeset
|
2 * Test various AVR bits and pieces |
7ed10c59ba06
Supply clock speed via the command line so 1wire-delay.h can use it.
darius
parents:
7
diff
changeset
|
3 * |
41 | 4 * Copyright (c) 2008 |
0 | 5 * Daniel O'Connor <darius@dons.net.au>. All rights reserved. |
6 * | |
7 * Redistribution and use in source and binary forms, with or without | |
8 * modification, are permitted provided that the following conditions | |
9 * are met: | |
10 * 1. Redistributions of source code must retain the above copyright | |
11 * notice, this list of conditions and the following disclaimer. | |
12 * 2. Redistributions in binary form must reproduce the above copyright | |
13 * notice, this list of conditions and the following disclaimer in the | |
14 * documentation and/or other materials provided with the distribution. | |
15 * | |
16 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
19 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE | |
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
26 * SUCH DAMAGE. | |
27 */ | |
28 | |
29 #include <avr/io.h> | |
30 #include <avr/interrupt.h> | |
31 #include <avr/pgmspace.h> | |
41 | 32 #include <stdio.h> |
0 | 33 #include <string.h> |
4 | 34 #include <ctype.h> |
13 | 35 #include <stdlib.h> |
24 | 36 #include <util/delay.h> |
0 | 37 |
41 | 38 #include "cons.h" |
0 | 39 #include "1wire.h" |
37 | 40 #ifdef WITHUSB |
24 | 41 #include "usb.h" |
37 | 42 #endif |
41 | 43 #include "tempctrl.h" |
24 | 44 |
45 void process_cmd(void); | |
0 | 46 |
24 | 47 int |
48 main(void) { | |
49 /* Disable interrupts while we frob stuff */ | |
50 cli(); | |
51 | |
41 | 52 #if 0 |
24 | 53 /* Disable JTAG (yes twice) */ |
54 MCUCSR |= _BV(JTD); | |
55 MCUCSR |= _BV(JTD); | |
37 | 56 #endif |
57 | |
58 #ifdef WITHUSB | |
24 | 59 /* USB data bus (7:0) */ |
60 DDRA = 0x00; | |
61 PORTA = 0x00; | |
62 | |
37 | 63 /* USB control (4:0) */ |
64 DDRB = 0x0d; | |
24 | 65 PORTB = 0x00; |
37 | 66 #else |
67 DDRA = 0xff; | |
68 PORTA = 0x00; | |
69 #endif | |
24 | 70 /* GPIO (0:7) */ |
71 DDRC = 0xff; | |
72 PORTC = 0x00; | |
73 | |
37 | 74 /* USART (0:1), IDBus (2:5), 485 (6:6), GPIO (7:7) */ |
75 DDRD = 0xf7; | |
76 PORTD = 0xf7; | |
77 | |
78 /* Set up the one wire stuff */ | |
79 OWInit(); | |
24 | 80 |
81 /* Init UART */ | |
41 | 82 cons_init(); |
24 | 83 |
41 | 84 printf_P(PSTR("\r\n\r\n===============\r\n" |
85 "Inited!\r\n\r\n")); | |
24 | 86 |
41 | 87 tempctrl_init(); |
88 | |
24 | 89 /* Ready to go! */ |
90 sei(); | |
91 | |
37 | 92 #if 0 |
93 DDRA = 0xff; | |
94 DDRC = 0xff; | |
95 while (1) { | |
41 | 96 printf_P(PSTR("1\r\n")); |
37 | 97 PORTA = 0xff; |
41 | 98 printf_P(PSTR("2\r\n")); |
37 | 99 PORTC = 0x00; |
41 | 100 printf_P(PSTR("3\r\n")); |
37 | 101 _delay_us(1); |
41 | 102 printf_P(PSTR("4\r\n")); |
37 | 103 PORTA = 0x80; |
41 | 104 printf_P(PSTR("5\r\n")); |
37 | 105 PORTC = 0xff; |
41 | 106 printf_P(PSTR("6\r\n")); |
37 | 107 } |
108 #endif | |
109 | |
110 #ifdef WITHUSB | |
41 | 111 printf_P(PSTR("Calling usb_init\r\n")); |
24 | 112 usb_init(); |
41 | 113 printf_P(PSTR("done\r\n")); |
114 _delay_us(1000); | |
37 | 115 #endif |
41 | 116 printf_P(PSTR("> ")); |
24 | 117 cmd.state = 0; |
118 | |
119 /* Wait for user input or an "interrupt" */ | |
120 while (1) { | |
41 | 121 tempctrl_update(); |
122 | |
24 | 123 if (cmd.state == 255) { |
124 process_cmd(); | |
41 | 125 printf_P(PSTR("> ")); |
24 | 126 /* Allow new characters to be processed */ |
127 cmd.state = 0; | |
128 } | |
129 | |
37 | 130 #ifdef WITHUSB |
131 if (!(PDICTL & _BV(PDIINT))) | |
24 | 132 usb_intr(); |
37 | 133 #endif |
24 | 134 } |
135 } | |
136 | |
137 void | |
138 process_cmd(void) { | |
139 uint8_t ROM[8]; | |
140 int8_t i, arg; | |
141 uint8_t crc, buf[9]; | |
142 int8_t temp; | |
143 uint16_t tfrac; | |
0 | 144 |
24 | 145 /* User just pressed enter */ |
146 if (cmd.len == 0) | |
147 return; | |
148 | |
149 if (cmd.buf[0] == '?') { | |
41 | 150 printf_P(PSTR("rs Reset and check for presence\r\n" |
151 "sr Search the bus for ROMs\r\n" | |
152 "re Read a bit\r\n" | |
153 "rb Read a byte\r\n" | |
154 "wr bit Write a bit\r\n" | |
155 "wb byte Write a byte (hex)\r\n" | |
156 "wc cmd [ROMID] Write command\r\n" | |
157 "te ROMID Read the temperature from a DS1820\r\n" | |
158 "in port Read from a port\r\n" | |
159 "out port val Write to a port\r\n" | |
160 "ddr port [val] Read/write DDR for a port\r\n" | |
161 "tc ... Temperature control related (tc help for more)\r\n")); | |
162 | |
24 | 163 return; |
164 } | |
165 | |
166 i = strlen((char *)cmd.buf); | |
167 if (cmd.len < 2) | |
168 goto badcmd; | |
169 | |
170 if (cmd.buf[0] == 'r' && cmd.buf[1] == 's') { | |
41 | 171 printf_P(PSTR("Resetting... ")); |
4 | 172 |
24 | 173 if (OWTouchReset() == 1) |
41 | 174 printf_P(PSTR("No presence pulse found\r\n")); |
24 | 175 else |
41 | 176 printf_P(PSTR("Presence pulse found\r\n")); |
24 | 177 } else if (cmd.buf[0] == 'r' && cmd.buf[1] == 'e') { |
178 if (OWReadBit()) | |
41 | 179 printf_P(PSTR("Read a 1\r\n")); |
24 | 180 else |
41 | 181 printf_P(PSTR("Read a 0\r\n")); |
24 | 182 } else if (cmd.buf[0] == 'r' && cmd.buf[1] == 'b') { |
41 | 183 printf_P(PSTR("Read a 0x%02x\r\n"), OWReadByte()); |
24 | 184 } else if (cmd.buf[0] == 'w' && cmd.buf[1] == 'r') { |
185 arg = strtol((char *)cmd.buf + 3, (char **)NULL, 10); | |
186 OWWriteBit(arg); | |
41 | 187 printf_P(PSTR("Wrote a %c\r\n"), arg ? '1' : '0'); |
24 | 188 } else if (cmd.buf[0] == 'w' && cmd.buf[1] == 'b') { |
189 arg = (int)strtol((char *)cmd.buf + 3, (char **)NULL, 16); | |
190 OWWriteByte(arg); | |
37 | 191 } else if (cmd.buf[0] == 'r' && cmd.buf[1] == 't') { |
192 if (cmd.len < 26) { | |
41 | 193 printf_P(PSTR("Unable to parse ROM ID\r\n")); |
37 | 194 return; |
195 } | |
196 | |
197 if (OWTouchReset() != 0) { | |
41 | 198 printf_P(PSTR("No presence\r\n")); |
37 | 199 return; |
200 } | |
201 | |
202 for (i = 0; i < 8; i++) | |
203 ROM[i] = (int)strtol((char *)cmd.buf + 3 * (i + 1), (char **)NULL, 16); | |
204 | |
205 if (ROM[0] != OW_FAMILY_ROM) { | |
41 | 206 printf_P(PSTR("ROM specified isn't a DS2502\r\n")); |
37 | 207 return; |
208 } | |
209 | |
210 if (OWTouchReset() != 0) { | |
41 | 211 printf_P(PSTR("No presence\r\n")); |
37 | 212 return; |
213 } | |
214 | |
215 crc = 0; | |
216 | |
217 OWCRC(OW_READ_STATUS, &crc); | |
218 OWSendCmd(ROM, OW_READ_STATUS); | |
219 | |
220 OWWriteByte(0x00); | |
221 OWCRC(0x00, &crc); | |
222 | |
223 OWWriteByte(0x00); | |
224 OWCRC(0x00, &crc); | |
225 | |
226 if (crc != OWReadByte()) { | |
41 | 227 printf_P(PSTR("CRC mismatch on command & address\r\n")); |
37 | 228 return; |
229 } | |
230 | |
231 crc = 0; | |
232 for (i = 0; i < 8; i++) { | |
233 temp = OWReadByte(); | |
41 | 234 printf_P(PSTR("%02x "), temp); |
37 | 235 OWCRC(temp, &crc); |
236 } | |
41 | 237 printf_P(PSTR("\r\n")); |
37 | 238 if (crc != OWReadByte()) { |
41 | 239 printf_P(PSTR("CRC mismatch on data\r\n")); |
37 | 240 return; |
241 } | |
242 } else if (cmd.buf[0] == 'w' && cmd.buf[1] == 'e') { | |
243 if (cmd.len < 26) { | |
41 | 244 printf_P(PSTR("Unable to parse ROM ID\r\n")); |
37 | 245 return; |
246 } | |
247 | |
248 for (i = 0; i < 8; i++) | |
249 ROM[i] = (int)strtol((char *)cmd.buf + 3 * (i + 1), (char **)NULL, 16); | |
250 | |
251 if (ROM[0] != OW_FAMILY_ROM) { | |
41 | 252 printf_P(PSTR("ROM specified isn't a ROM\r\n")); |
37 | 253 return; |
254 } | |
255 | |
256 buf[0] = (int)strtol((char *)cmd.buf + 27, (char **)NULL, 16); /* Address */ | |
257 buf[1] = (int)strtol((char *)cmd.buf + 30, (char **)NULL, 16); /* Data .. */ | |
258 buf[2] = (int)strtol((char *)cmd.buf + 33, (char **)NULL, 16); | |
259 | |
260 if (OWTouchReset() != 0) { | |
41 | 261 printf_P(PSTR("No presence\r\n")); |
37 | 262 return; |
263 } | |
264 | |
265 i = OWProgROM(ROM, buf[0], 2, &buf[1], 0, 0); | |
41 | 266 printf_P(PSTR("OWProgROM returned %d\r\n"), i); |
37 | 267 } else if (cmd.buf[0] == 'r' && cmd.buf[1] == 'r') { |
268 if (cmd.len < 26) { | |
41 | 269 printf_P(PSTR("Unable to parse ROM ID\r\n")); |
37 | 270 return; |
271 } | |
272 | |
273 for (i = 0; i < 8; i++) | |
274 ROM[i] = (int)strtol((char *)cmd.buf + 3 * (i + 1), (char **)NULL, 16); | |
275 | |
276 if (ROM[0] != OW_FAMILY_ROM) { | |
41 | 277 printf_P(PSTR("ROM specified isn't a ROM\r\n")); |
37 | 278 return; |
279 } | |
280 | |
281 crc = 0; | |
282 OWSendCmd(ROM, OW_READ_MEMORY); | |
283 OWCRC(OW_READ_MEMORY, &crc); | |
284 | |
285 OWWriteByte(0x00); | |
286 OWCRC(0x00, &crc); | |
287 | |
288 OWWriteByte(0x00); | |
289 OWCRC(0x00, &crc); | |
290 | |
291 if (crc != OWReadByte()) { | |
41 | 292 printf_P(PSTR("CRC mismatch on command & address\r\n")); |
37 | 293 return; |
294 } | |
295 | |
296 crc = 0; | |
297 for (buf[0] = 0; buf[0] < 128; buf[0]++) { | |
298 buf[1] = OWReadByte(); | |
299 if (buf[0] > 0) { | |
300 if (buf[0] % 16 != 0) | |
41 | 301 printf_P(PSTR(" ")); |
37 | 302 else |
41 | 303 printf_P(PSTR("\r\n")); |
37 | 304 } |
305 | |
41 | 306 printf_P(PSTR("%02x"), buf[1]); |
37 | 307 OWCRC(buf[1], &crc); |
308 } | |
41 | 309 printf_P(PSTR("\r\n")); |
37 | 310 if (crc != OWReadByte()) { |
41 | 311 printf_P(PSTR("CRC mismatch on data\r\n")); |
37 | 312 return; |
313 } | |
314 | |
24 | 315 } else if (cmd.buf[0] == 'w' && cmd.buf[1] == 'c') { |
316 if (cmd.len < 5) { | |
41 | 317 printf_P(PSTR("No arguments\r\n")); |
24 | 318 return; |
319 } | |
320 | |
321 arg = (int)strtol((char *)cmd.buf + 3, (char **)NULL, 16); | |
322 if (arg == 0) { | |
41 | 323 printf_P(PSTR("Unparseable command\r\n")); |
24 | 324 return; |
325 } | |
13 | 326 |
24 | 327 if (i == 5) { |
328 OWSendCmd(NULL, arg); | |
329 return; | |
330 } | |
4 | 331 |
24 | 332 if (i < 29) { |
41 | 333 printf_P(PSTR("Can't parse ROM ID\r\n")); |
24 | 334 return; |
335 } | |
336 for (i = 0; i < 8; i++) | |
337 ROM[i] = (int)strtol((char *)cmd.buf + 6 + (3 * i), (char **)NULL, 16); | |
338 | |
339 OWSendCmd(ROM, arg); | |
340 } else if (cmd.buf[0] == 't' && cmd.buf[1] == 'e') { | |
341 if (cmd.len < 26) { | |
41 | 342 printf_P(PSTR("Unable to parse ROM ID\r\n")); |
24 | 343 return; |
344 } | |
345 | |
346 for (i = 0; i < 8; i++) | |
347 ROM[i] = (int)strtol((char *)cmd.buf + 3 * (i + 1), (char **)NULL, 16); | |
348 | |
349 if (ROM[0] != OW_FAMILY_TEMP) { | |
41 | 350 printf_P(PSTR("ROM specified isn't a temperature sensor\r\n")); |
24 | 351 return; |
352 } | |
4 | 353 |
24 | 354 OWSendCmd(ROM, OW_CONVERTT_CMD); |
355 i = 0; | |
37 | 356 /* Wait for the conversion */ |
41 | 357 while (OWReadBit() == 0) |
358 i = 1; | |
359 | |
360 | |
24 | 361 OWSendCmd(ROM, OW_RD_SCR_CMD); |
362 crc = 0; | |
363 for (i = 0; i < 9; i++) { | |
364 buf[i] = OWReadByte(); | |
365 if (i < 8) | |
366 OWCRC(buf[i], &crc); | |
367 } | |
368 | |
369 if (crc != buf[8]) { | |
41 | 370 printf_P(PSTR("CRC mismatch\r\n")); |
24 | 371 return; |
372 } | |
4 | 373 |
24 | 374 /* 0 Temperature LSB |
375 * 1 Temperature MSB | |
376 * 2 Th | |
377 * 3 Tl | |
378 * 4 Reserved | |
379 * 5 Reserved | |
380 * 6 Count Remain | |
381 * 7 Count per C | |
382 * 8 CRC | |
383 */ | |
13 | 384 #if 0 |
41 | 385 for (i = 0; i < 9; i++) |
386 printf_P(PSTR("%d\r\n"), buf[i]); | |
13 | 387 #endif |
24 | 388 temp = buf[0]; |
389 if (buf[1] & 0x80) | |
390 temp -= 256; | |
391 temp >>= 1; | |
13 | 392 |
24 | 393 tfrac = buf[7] - buf[6]; |
394 tfrac *= (uint16_t)100; | |
395 tfrac /= buf[7]; | |
396 tfrac += 75; | |
397 if (tfrac < 100) { | |
398 temp--; | |
399 } else { | |
400 tfrac -= 100; | |
401 } | |
13 | 402 |
41 | 403 printf_P(PSTR("%d.%02d\r\n"), temp, tfrac); |
24 | 404 } else if (cmd.buf[0] == 's' && cmd.buf[1] == 'r') { |
405 memset(ROM, 0, 8); | |
10 | 406 |
24 | 407 i = OWFirst(ROM, 1, 0); |
408 do { | |
409 switch (i) { | |
10 | 410 case OW_BADWIRE: |
41 | 411 printf_P(PSTR("Presence pulse, but no module found, bad module/cabling?\r\n")); |
10 | 412 break; |
413 | |
414 case OW_NOPRESENCE: | |
41 | 415 printf_P(PSTR("No presence pulse found\r\n")); |
10 | 416 break; |
417 | |
418 case OW_BADCRC: | |
41 | 419 printf_P(PSTR("Bad CRC\r\n")); |
10 | 420 break; |
421 | |
422 case OW_NOMODULES: | |
423 case OW_FOUND: | |
424 break; | |
425 | |
426 default: | |
41 | 427 printf_P(PSTR("Unknown error from 1 wire library\r\n")); |
10 | 428 break; |
24 | 429 } |
10 | 430 |
24 | 431 if (i != OW_FOUND) |
432 break; | |
13 | 433 |
41 | 434 for (i = 0; i < 8; i++) |
435 printf_P(PSTR("%02x%S"), ROM[i], i == 7 ? PSTR("\r\n") : PSTR(":")); | |
10 | 436 |
24 | 437 i = OWNext(ROM, 1, 0); |
438 } while (1); | |
439 } else if (cmd.buf[0] == 'i' && cmd.buf[1] == 'n') { | |
440 switch (tolower(cmd.buf[3])) { | |
441 case 'a': | |
442 crc = PINA; | |
443 break; | |
444 | |
445 case 'b': | |
446 crc = PINB; | |
447 break; | |
448 | |
449 case 'c': | |
450 crc = PINC; | |
451 break; | |
452 | |
453 case 'd': | |
454 crc = PIND; | |
455 break; | |
456 | |
457 default: | |
41 | 458 printf_P(PSTR("Unknown port\r\n")); |
24 | 459 return; |
0 | 460 } |
41 | 461 printf_P(PSTR("0x%02x\r\n"), crc); |
24 | 462 } else if (cmd.buf[0] == 'o' && cmd.buf[1] == 'u') { |
463 crc = strtol((char *)cmd.buf + 8, (char **)NULL, 16); | |
464 switch (tolower(cmd.buf[4])) { | |
465 case 'a': | |
466 PORTA = crc; | |
467 break; | |
468 | |
469 case 'b': | |
470 PORTB = crc; | |
471 break; | |
472 | |
473 case 'c': | |
474 PORTC = crc; | |
475 break; | |
476 | |
477 case 'd': | |
478 PORTD = crc; | |
479 break; | |
480 | |
481 default: | |
41 | 482 printf_P(PSTR("Unknown port\r\n")); |
24 | 483 return; |
484 } | |
41 | 485 printf_P(PSTR("PORT%c <= 0x%02x\r\n"), toupper(cmd.buf[4]), crc); |
37 | 486 } else if (cmd.buf[0] == 'd' && cmd.buf[1] == 'd') { |
487 crc = strtol((char *)cmd.buf + 8, (char **)NULL, 16); | |
488 switch (tolower(cmd.buf[4])) { | |
489 case 'a': | |
490 DDRA = crc; | |
491 break; | |
492 | |
493 case 'b': | |
494 DDRB = crc; | |
495 break; | |
496 | |
497 case 'c': | |
498 DDRC = crc; | |
499 break; | |
500 | |
501 case 'd': | |
502 DDRD = crc; | |
503 break; | |
504 | |
505 default: | |
41 | 506 printf_P(PSTR("Unknown port\r\n")); |
37 | 507 return; |
508 } | |
41 | 509 printf_P(PSTR("0x%02x\r\n"), crc); |
510 } else if (cmd.buf[0] == 't' && cmd.buf[1] == 'c') { | |
511 tempctrl_cmd((char *)cmd.buf); | |
37 | 512 #ifdef WITHUSB |
24 | 513 } else if (cmd.buf[0] == 'u' && cmd.buf[1] == 's') { |
514 usb_gendata(); | |
37 | 515 #endif |
24 | 516 } else { |
517 badcmd: | |
41 | 518 printf_P(PSTR("Unknown command, ? for a list\r\n")); |
0 | 519 } |
24 | 520 } |
0 | 521 |
522 |