Mercurial > ~darius > hgwebdir.cgi > avr
comparison 1wire.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 | 0aa6bf4b98ae |
children | efd44dc40934 |
comparison
equal
deleted
inserted
replaced
40:1061fdbdc44f | 41:5898fba6593c |
---|---|
40 #include <avr/io.h> | 40 #include <avr/io.h> |
41 #include <avr/pgmspace.h> | 41 #include <avr/pgmspace.h> |
42 #include <util/delay.h> | 42 #include <util/delay.h> |
43 #include "1wire.h" | 43 #include "1wire.h" |
44 #include "1wire-config.h" | 44 #include "1wire-config.h" |
45 #include "cons.h" | |
45 | 46 |
46 static uint8_t OW_LastDevice = 0; | 47 static uint8_t OW_LastDevice = 0; |
47 static uint8_t OW_LastDiscrepancy = 0; | 48 static uint8_t OW_LastDiscrepancy = 0; |
48 static uint8_t OW_LastFamilyDiscrepancy = 0; | 49 static uint8_t OW_LastFamilyDiscrepancy = 0; |
49 | 50 |
241 if (!OW_LastDevice) { | 242 if (!OW_LastDevice) { |
242 /* check if reset first is requested */ | 243 /* check if reset first is requested */ |
243 if (do_reset) { | 244 if (do_reset) { |
244 /* reset the 1-wire | 245 /* reset the 1-wire |
245 * if there are no parts on 1-wire, return 0 */ | 246 * if there are no parts on 1-wire, return 0 */ |
246 OWPUTSP(PSTR("Resetting\n\r")); | 247 OWPUTSP(PSTR("Resetting\r\n")); |
247 switch (OWTouchReset()) { | 248 switch (OWTouchReset()) { |
248 case 0: | 249 case 0: |
249 break; | 250 break; |
250 | 251 |
251 case 1: | 252 case 1: |
252 /* reset the search */ | 253 /* reset the search */ |
253 OW_LastDiscrepancy = 0; | 254 OW_LastDiscrepancy = 0; |
254 OW_LastFamilyDiscrepancy = 0; | 255 OW_LastFamilyDiscrepancy = 0; |
255 OWPUTSP(PSTR("No devices on bus\n\r")); | 256 OWPUTSP(PSTR("No devices on bus\r\n")); |
256 return OW_NOPRESENCE; | 257 return OW_NOPRESENCE; |
257 break; | 258 break; |
258 | 259 |
259 case 2: | 260 case 2: |
260 /* reset the search */ | 261 /* reset the search */ |
261 OW_LastDiscrepancy = 0; | 262 OW_LastDiscrepancy = 0; |
262 OW_LastFamilyDiscrepancy = 0; | 263 OW_LastFamilyDiscrepancy = 0; |
263 OWPUTSP(PSTR("Bus appears to be being held low\n\r")); | 264 OWPUTSP(PSTR("Bus appears to be being held low\r\n")); |
264 return OW_BADWIRE; | 265 return OW_BADWIRE; |
265 break; | 266 break; |
266 | 267 |
267 } | 268 } |
268 } | 269 } |
282 do { | 283 do { |
283 /* read a bit and its compliment */ | 284 /* read a bit and its compliment */ |
284 bit_test = OWReadBit() << 1; | 285 bit_test = OWReadBit() << 1; |
285 bit_test |= OWReadBit(); | 286 bit_test |= OWReadBit(); |
286 | 287 |
287 #if OW_DEBUG | 288 OWPRINTFP(PSTR("bit_test = %d\r\n"), bit_test); |
288 sprintf_P(errstr, PSTR("bit_test = %d\n\r"), bit_test); | |
289 OWPUTSP(errstr); | |
290 #endif | |
291 | 289 |
292 /* check for no devices on 1-wire */ | 290 /* check for no devices on 1-wire */ |
293 if (bit_test == 3) { | 291 if (bit_test == 3) { |
294 #if OW_DEBUG | 292 OWPRINTFP(PSTR("bit_test = %d\r\n"), bit_test); |
295 sprintf_P(errstr, PSTR("bit_test = %d\n\r"), bit_test); | |
296 OWPUTSP(errstr); | |
297 #endif | |
298 return(OW_BADWIRE); | 293 return(OW_BADWIRE); |
299 } | 294 } |
300 else { | 295 else { |
301 /* all devices coupled have 0 or 1 */ | 296 /* all devices coupled have 0 or 1 */ |
302 if (bit_test > 0) | 297 if (bit_test > 0) |
348 } while (rom_byte_number < 8); /* loop until through all ROM bytes 0-7 */ | 343 } while (rom_byte_number < 8); /* loop until through all ROM bytes 0-7 */ |
349 | 344 |
350 /* if the search was successful then */ | 345 /* if the search was successful then */ |
351 if (!(bit_number < 65) || lastcrc8) { | 346 if (!(bit_number < 65) || lastcrc8) { |
352 if (lastcrc8) { | 347 if (lastcrc8) { |
353 #if OW_DEBUG | 348 OWPRINTFP(PSTR("Bad CRC (%d)\r\n"), lastcrc8); |
354 sprintf_P(errstr, PSTR("Bad CRC (%d)\n\r"), lastcrc8); | |
355 OWPUTSP(errstr); | |
356 #endif | |
357 next_result = OW_BADCRC; | 349 next_result = OW_BADCRC; |
358 } else { | 350 } else { |
359 /* search successful so set LastDiscrepancy,LastDevice,next_result */ | 351 /* search successful so set LastDiscrepancy,LastDevice,next_result */ |
360 OW_LastDiscrepancy = last_zero; | 352 OW_LastDiscrepancy = last_zero; |
361 OW_LastDevice = (OW_LastDiscrepancy == 0); | 353 OW_LastDevice = (OW_LastDiscrepancy == 0); |
362 #if OW_DEBUG | 354 OWPRINTFP(PSTR("Last device = %d\r\n"), OW_LastDevice); |
363 sprintf_P(errstr, PSTR("Last device = %d\n\r"), OW_LastDevice); | |
364 OWPUTSP(errstr); | |
365 #endif | |
366 next_result = OW_FOUND; | 355 next_result = OW_FOUND; |
367 } | 356 } |
368 } | 357 } |
369 } | 358 } |
370 | 359 |
447 if (len < 1) | 436 if (len < 1) |
448 return(2); | 437 return(2); |
449 | 438 |
450 OWDELAY_I; | 439 OWDELAY_I; |
451 if (OWTouchReset() != 0) { | 440 if (OWTouchReset() != 0) { |
452 uart_putsP(PSTR("No presence pulse\n\r")); | 441 cons_putsP(PSTR("No presence pulse\r\n")); |
453 return(3); | 442 return(3); |
454 } | 443 } |
455 | 444 |
456 crc = 0; | 445 crc = 0; |
457 | 446 |
472 | 461 |
473 OWWriteByte(0x00); | 462 OWWriteByte(0x00); |
474 OWCRC(0x00, &crc); | 463 OWCRC(0x00, &crc); |
475 | 464 |
476 for (i = 0; i < len; i++) { | 465 for (i = 0; i < len; i++) { |
477 uart_putsP(PSTR("Programming ")); | 466 cons_putsP(PSTR("Programming ")); |
478 uart_puts_hex(data[i]); | 467 cons_puts_hex(data[i]); |
479 uart_putsP(PSTR(" to ")); | 468 cons_putsP(PSTR(" to ")); |
480 uart_puts_hex(start + i); | 469 cons_puts_hex(start + i); |
481 uart_putsP(PSTR("\n\r")); | 470 cons_putsP(PSTR("\r\n")); |
482 | 471 |
483 OWWriteByte(data[i]); | 472 OWWriteByte(data[i]); |
484 OWCRC(data[i], &crc); | 473 OWCRC(data[i], &crc); |
485 | 474 |
486 tmp = OWReadByte(); | 475 tmp = OWReadByte(); |
487 | 476 |
488 if (crc != tmp) { | 477 if (crc != tmp) { |
489 uart_putsP(PSTR("CRC mismatch ")); | 478 cons_putsP(PSTR("CRC mismatch ")); |
490 uart_puts_hex(crc); | 479 cons_puts_hex(crc); |
491 uart_putsP(PSTR(" vs ")); | 480 cons_putsP(PSTR(" vs ")); |
492 uart_puts_hex(tmp); | 481 cons_puts_hex(tmp); |
493 uart_putsP(PSTR("\n\r")); | 482 cons_putsP(PSTR("\r\n")); |
494 | 483 |
495 OWTouchReset(); | 484 OWTouchReset(); |
496 return(3); | 485 return(3); |
497 } | 486 } |
498 | 487 |
507 for (i = 0; i < 8; i++) | 496 for (i = 0; i < 8; i++) |
508 if (!(data[i] & 1 << i) && (tmp & 1 << i)) | 497 if (!(data[i] & 1 << i) && (tmp & 1 << i)) |
509 return(-3); | 498 return(-3); |
510 */ | 499 */ |
511 if ((!data[i] & tmp) != 0) { | 500 if ((!data[i] & tmp) != 0) { |
512 uart_putsP(PSTR("Readback mismatch ")); | 501 cons_putsP(PSTR("Readback mismatch ")); |
513 uart_puts_hex(data[i]); | 502 cons_puts_hex(data[i]); |
514 uart_putsP(PSTR(" vs ")); | 503 cons_putsP(PSTR(" vs ")); |
515 uart_puts_hex(data[i]); | 504 cons_puts_hex(data[i]); |
516 uart_putsP(PSTR("\n\r")); | 505 cons_putsP(PSTR("\r\n")); |
517 | 506 |
518 OWTouchReset(); | 507 OWTouchReset(); |
519 return(3); | 508 return(3); |
520 } | 509 } |
521 | 510 |
529 #else | 518 #else |
530 return(1); | 519 return(1); |
531 #endif | 520 #endif |
532 } | 521 } |
533 | 522 |
523 /* | |
524 * OWGetTemp | |
525 * | |
526 * Get the temperature from a 1wire bus module | |
527 * | |
528 * Returns temperature in hundredths of a degree or OW_TEMP_xxx on | |
529 * error. | |
530 */ | |
531 int16_t | |
532 OWGetTemp(uint8_t *ROM) { | |
533 int8_t i; | |
534 uint8_t crc, buf[9]; | |
535 int16_t temp; | |
536 int16_t tfrac; | |
537 | |
538 if (ROM[0] != OW_FAMILY_TEMP) | |
539 return OW_TEMP_WRONG_FAM; | |
540 | |
541 OWSendCmd(ROM, OW_CONVERTT_CMD); | |
542 | |
543 i = 0; | |
544 | |
545 /* Wait for the conversion */ | |
546 while (OWReadBit() == 0) | |
547 i = 1; | |
548 | |
549 /* Check that we talked to a module and it did something */ | |
550 if (i == 0) { | |
551 return OW_TEMP_NO_ROM; | |
552 } | |
553 | |
554 OWSendCmd(ROM, OW_RD_SCR_CMD); | |
555 crc = 0; | |
556 for (i = 0; i < 8; i++) { | |
557 buf[i] = OWReadByte(); | |
558 OWCRC(buf[i], &crc); | |
559 } | |
560 buf[i] = OWReadByte(); | |
561 if (crc != buf[8]) | |
562 return OW_TEMP_CRC_ERR; | |
563 temp = buf[0]; | |
564 if (buf[1] & 0x80) | |
565 temp -= 256; | |
566 | |
567 /* Chop off 0.5 degree bit */ | |
568 temp >>= 1; | |
569 | |
570 /* Calulate the fractional remainder */ | |
571 tfrac = buf[7] - buf[6]; | |
572 | |
573 /* Work in 100'th of degreess to save on floats */ | |
574 tfrac *= (int16_t)100; | |
575 | |
576 /* Divide by count */ | |
577 tfrac /= buf[7]; | |
578 | |
579 /* Subtract 0.25 deg from temp */ | |
580 tfrac += 75; | |
581 if (tfrac < 100) | |
582 temp--; | |
583 else | |
584 tfrac -= 100; | |
585 | |
586 i = temp; | |
587 temp *= 100; | |
588 temp += tfrac; | |
589 | |
590 return(temp); | |
591 } |