one wire driver
Dependents: 09_PT1000 10_PT1000 11_PT1000
DS2482.cpp
00001 00002 00003 #include "mbed.h" 00004 #include "DS2482.h" 00005 #include "monitor.h" 00006 00007 extern Serial pc; 00008 00009 //----------------------------------------------------------------------------- 00010 // CRC = X^8 + X^5 + X^4 + 1 00011 00012 #define CRC_TABLE_ITEMS 256 00013 00014 const uint8_t crc_table[CRC_TABLE_ITEMS] = 00015 { 00016 0 , 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65, 00017 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220, 00018 35 ,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98, 00019 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255, 00020 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7, 00021 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154, 00022 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36, 00023 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185, 00024 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205, 00025 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80, 00026 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238, 00027 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115, 00028 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139, 00029 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22, 00030 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168, 00031 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53 00032 }; 00033 00034 00035 //========================================================================== 00036 // destructor 00037 00038 DS2482::DS2482(PinName sda, PinName scl, int address) : i2c(sda, scl) 00039 { 00040 addr = address; 00041 i2c.frequency(100000); 00042 } 00043 00044 //----------------------------------------------------------------------------- 00045 // Calculate the CRC8 of the byte value provided with the current 00046 // global 'crc8' value. 00047 // Returns current global crc8 value 00048 // 00049 uint8_t DS2482::crc_calc(uint8_t x) 00050 { 00051 crc_value = crc_table[crc_value ^ x]; 00052 return crc_value; 00053 } 00054 00055 uint8_t DS2482::crc_calc_buffer(uint8_t *pbuffer, uint8_t count) 00056 { 00057 uint8_t n; 00058 00059 crc_value = 0; 00060 00061 for (n = 0; n < count; n++) 00062 { 00063 crc_value = crc_table[crc_value ^ *pbuffer++]; 00064 } 00065 00066 return crc_value; 00067 } 00068 00069 //========================================================================== 00070 // I2C DS2482 00071 // 00072 //-------------------------------------------------------------------------- 00073 // DS2482 Detect routine that sets the I2C address and then performs a 00074 // device reset followed by writing the configuration byte to default values: 00075 // 1-Wire speed (c1WS) = standard (0) 00076 // Strong pullup (cSPU) = off (0) 00077 // Presence pulse masking (cPPM) = off (0) 00078 // Active pullup (cAPU) = on (CONFIG_APU = 0x01) 00079 // 00080 // Returns: TRUE if device was detected and written 00081 // FALSE device not detected or failure to write configuration byte 00082 //uint8_t DS2482_detect(unsigned char addr) 00083 // 00084 uint8_t DS2482::detect(void) 00085 { 00086 00087 if (!reset()) // reset the DS2482 ON selected address 00088 { 00089 #if OW_MASTER_START 00090 pc.printf("\r\n--- DS2482 bus0 reset not executed \n"); 00091 wait(0.1); 00092 #endif 00093 00094 return false; 00095 } 00096 00097 // default configuration 00098 c1WS = 0; 00099 cSPU = 0; 00100 cPPM = 0; 00101 cAPU = DS2482_CFG_APU; 00102 00103 // write the default configuration setup 00104 if (!write_config(c1WS | cSPU | cPPM | cAPU)) 00105 { 00106 #if OW_MASTER_START 00107 pc.printf("\r\n--- DS2482 configuration failure \n"); 00108 wait(0.1); 00109 #endif 00110 00111 return false; 00112 } 00113 00114 #if OW_MASTER_START 00115 pc.printf("\r\n*** DS2482 detect OK \n"); 00116 wait(0.1); 00117 #endif 00118 00119 return true; 00120 } 00121 00122 //-------------------------------------------------------------------------- 00123 // Perform a device reset on the DS2482 00124 // 00125 // Returns: TRUE if device was reset 00126 // FALSE device not detected or failure to perform reset 00127 // 00128 int DS2482::reset(void) 00129 { 00130 char cmd[2]; 00131 00132 cmd[0] = DS2482_CMD_DRST; 00133 // pc.printf("\nreset write"); 00134 i2c.write(addr, cmd, 1); 00135 // pc.printf("\nreset read"); 00136 i2c.read(addr, cmd, 1); 00137 // pc.printf(" cmd = %02x \n",cmd[0]); 00138 wait(0.1); 00139 return ((cmd[0] & 0xF7) == 0x10); 00140 } 00141 00142 //-------------------------------------------------------------------------- 00143 // Write the configuration register in the DS2482. The configuration 00144 // options are provided in the lower nibble of the provided config byte. 00145 // The uppper nibble in bitwise inverted when written to the DS2482. 00146 // 00147 // Returns: TRUE: config written and response correct 00148 // FALSE: response incorrect 00149 // 00150 uint8_t DS2482::write_config(uint8_t config) 00151 { 00152 char cmd[2]; 00153 char read_config; 00154 00155 cmd[0] = DS2482_CMD_WCFG; 00156 cmd[1] = config | (~config << 4); 00157 i2c.write(addr, cmd, 2); 00158 00159 i2c.read(addr, cmd, 1); 00160 read_config = cmd[0]; 00161 00162 if (config != read_config) // check for failure due to incorrect read back 00163 { 00164 // handle error 00165 // ... 00166 #if OW_MASTER_START 00167 pc.printf("\r\n---check for failure due to incorrect config read back"); 00168 #endif 00169 00170 reset(); 00171 return false; 00172 } 00173 return true; 00174 00175 } 00176 00177 //-------------------------------------------------------------------------- 00178 // DS2482 1-Wire Operations 00179 //-------------------------------------------------------------------------- 00180 // 00181 //OWReset 00182 //-------------------------------------------------------------------------- 00183 // Reset all of the devices on the 1-Wire Net and return the result. 00184 // 00185 // Returns: TRUE(1): presence pulse(s) detected, device(s) reset 00186 // FALSE(0): no presence pulses detected 00187 // 00188 uint8_t DS2482::OWReset(void) 00189 { 00190 uint8_t poll_count = 0; 00191 char cmd[2]; 00192 00193 cmd[0] = DS2482_CMD_1WRS; 00194 i2c.write(addr,cmd,1); 00195 00196 #if OW_MASTER_DEBUG 00197 pc.printf("\r\n*** Reset all devices on the 1-Wire Net\r\n"); 00198 #endif 00199 00200 do 00201 { 00202 i2c.read(addr,cmd,1); 00203 // pc.printf("\n read %04x",cmd[0]); 00204 } 00205 while ((cmd[0] & DS2482_STATUS_1WB) && (poll_count++ < POLL_LIMIT)); 00206 00207 // check for failure due to poll limit reached 00208 if (poll_count >= POLL_LIMIT) 00209 { 00210 // handle error 00211 // ... 00212 #if OW_MASTER_DEBUG 00213 pc.printf("\r\n---poll limit reached"); 00214 #endif 00215 00216 reset(); 00217 return false; 00218 } 00219 00220 // check for short condition 00221 if (cmd[0] & DS2482_STATUS_SD) 00222 { 00223 #if OW_MASTER_DEBUG 00224 pc.printf("\r\n---1-Wire Net short detected %04x",cmd[0]); 00225 #endif 00226 00227 short_detected = true; 00228 } 00229 else 00230 { 00231 #if OW_MASTER_DEBUG 00232 pc.printf("\r\n*** 1-Wire electrical net is OK"); 00233 #endif 00234 00235 short_detected = false; 00236 } 00237 00238 // check for presence detect 00239 if (cmd[0] & DS2482_STATUS_PPD) 00240 { 00241 #if OW_MASTER_DEBUG 00242 pc.printf("\r\n*** 1-Wire Device detected"); 00243 #endif 00244 00245 return true; 00246 } 00247 else 00248 { 00249 #if OW_MASTER_DEBUG 00250 pc.printf("\r\n---No Device detected"); 00251 #endif 00252 00253 return false; 00254 } 00255 } 00256 00257 //-------------------------------------------------------------------------- 00258 // Send 1 bit of communication to the 1-Wire Net. 00259 // The parameter 'sendbit' least significant bit is used. 00260 // 00261 // 'sendbit' - 1 bit to send (least significant byte) 00262 // 00263 void DS2482::OWWriteBit(uint8_t sendbit) 00264 { 00265 OWTouchBit(sendbit); 00266 } 00267 00268 //-------------------------------------------------------------------------- 00269 // Reads 1 bit of communication from the 1-Wire Net and returns the 00270 // result 00271 // 00272 // Returns: 1 bit read from 1-Wire Net 00273 // 00274 uint8_t DS2482::OWReadBit(void) 00275 { 00276 return OWTouchBit(0x01); 00277 } 00278 00279 //-------------------------------------------------------------------------- 00280 // Send 1 bit of communication to the 1-Wire Net and return the 00281 // result 1 bit read from the 1-Wire Net. The parameter 'sendbit' 00282 // least significant bit is used and the least significant bit 00283 // of the result is the return bit. 00284 // 00285 // 'sendbit' - the least significant bit is the bit to send 00286 // 00287 // Returns: 0: 0 bit read from sendbit 00288 // 1: 1 bit read from sendbit 00289 // 00290 uint8_t DS2482::OWTouchBit(uint8_t sendbit) 00291 { 00292 char cmd[2]; 00293 uint8_t poll_count = 0; 00294 00295 cmd[0] = DS2482_CMD_1WSB; 00296 cmd[1] = sendbit ? 0x80 : 0x00; 00297 i2c.write(addr, cmd, 2); 00298 00299 // loop checking 1WB bit for completion of 1-Wire operation 00300 // abort if poll limit reached 00301 00302 do 00303 { 00304 i2c.read(addr, cmd, 1); 00305 } 00306 while ((cmd[0] & DS2482_STATUS_1WB) && (poll_count++ < POLL_LIMIT)); 00307 00308 #if OW_MASTER_DEBUG 00309 pc.printf("\r\n*** Send 1 bit to the 1-Wire Net"); 00310 #endif 00311 00312 // check for failure due to poll limit reached 00313 if (poll_count >= POLL_LIMIT) 00314 { 00315 // handle error 00316 // ... 00317 #if OW_MASTER_DEBUG 00318 pc.printf("\r\n---handle error OW Write Bit"); 00319 #endif 00320 00321 reset(); 00322 return 0; 00323 } 00324 00325 // return bit state 00326 if (cmd[0] & DS2482_STATUS_SBR) 00327 { 00328 return 1; 00329 } 00330 else 00331 { 00332 return 0; 00333 } 00334 } 00335 00336 //-------------------------------------------------------------------------- 00337 // Send 8 bits of communication to the 1-Wire Net and verify that the 00338 // 8 bits read from the 1-Wire Net are the same (write operation). 00339 // The parameter 'sendbyte' least significant 8 bits are used. 00340 // 00341 // 'sendbyte' - 8 bits to send (least significant byte) 00342 // 00343 // Returns: TRUE: bytes written and echo was the same 00344 // FALSE: echo was not the same 00345 // 00346 void DS2482::OWWriteByte(uint8_t sendbyte) 00347 { 00348 char cmd[2]; 00349 uint8_t poll_count = 0; 00350 00351 #if OW_MASTER_DEBUG 00352 pc.printf("\r\n*** Send 8 bits of WRITE to the 1-Wire Net"); 00353 #endif 00354 00355 cmd[0] = DS2482_CMD_1WWB; 00356 cmd[1] = sendbyte; 00357 00358 i2c.write(addr, cmd, 2); 00359 00360 // loop checking 1WB bit for completion of 1-Wire operation 00361 // abort if poll limit reached 00362 00363 do 00364 { 00365 i2c.read(addr, cmd, 1); 00366 } 00367 while ((cmd[0] & DS2482_STATUS_1WB) && (poll_count++ < POLL_LIMIT)); 00368 00369 // check for failure due to poll limit reached 00370 if (poll_count >= POLL_LIMIT) 00371 { 00372 // handle error 00373 // ... 00374 #if OW_MASTER_DEBUG 00375 pc.printf("\r\n---handle error OW Write Byte"); 00376 #endif 00377 00378 reset(); 00379 } 00380 00381 #if OW_MASTER_DEBUG 00382 pc.printf(" done"); 00383 #endif 00384 } 00385 00386 //-------------------------------------------------------------------------- 00387 // Send 8 bits of read communication to the 1-Wire Net and return the 00388 // result 8 bits read from the 1-Wire Net. 00389 // 00390 // Returns: 8 bits read from 1-Wire Net 00391 // 00392 uint8_t DS2482::OWReadByte(void) 00393 { 00394 uint8_t poll_count = 0; 00395 char cmd[2]; 00396 00397 #if OW_MASTER_DEBUG 00398 pc.printf("\r\n*** Read 8 bits from the 1-Wire Net"); 00399 #endif 00400 00401 cmd[0] = DS2482_CMD_1WRB; // DS2482 1-Wire Read Byte 00402 i2c.write(addr, cmd, 1); 00403 00404 // loop checking 1WB bit for completion of 1-Wire operation 00405 // abort if poll limit reached 00406 00407 do 00408 { 00409 i2c.read(addr, cmd, 1); 00410 } 00411 while ((cmd[0] & DS2482_STATUS_1WB) && (poll_count++ < POLL_LIMIT)); 00412 00413 // check for failure due to poll limit reached 00414 if (poll_count >= POLL_LIMIT) 00415 { 00416 // handle error 00417 // ... 00418 #if OW_MASTER_DEBUG 00419 pc.printf("\r\n---handle error OW Read Byte"); 00420 #endif 00421 00422 reset(); 00423 return 0; 00424 } 00425 00426 cmd[0] = DS2482_CMD_SRP; // DS2482 Set Read Pointer 00427 cmd[1] = DS2482_READPTR_RDR; // DS2482 Read Data Register 00428 i2c.write(addr, cmd, 2); 00429 00430 i2c.read(addr, cmd, 1); 00431 00432 return cmd[0]; 00433 } 00434 00435 //-------------------------------------------------------------------------- 00436 // The 'OWBlock' transfers a block of data to and from the 00437 // 1-Wire Net. The result is returned in the same buffer. 00438 // 00439 // 'tran_buf' - pointer to a block of unsigned 00440 // chars of length 'tran_len' that will be sent 00441 // to the 1-Wire Net 00442 // 'tran_len' - length in bytes to transfer 00443 // 00444 void DS2482::OWBlock(uint8_t *tran_buf, uint8_t tran_len) 00445 { 00446 uint8_t i; 00447 00448 for (i = 0; i < tran_len; i++) 00449 { 00450 tran_buf[i] = OWTouchByte(tran_buf[i]); 00451 } 00452 } 00453 00454 //-------------------------------------------------------------------------- 00455 // Send 8 bits of communication to the 1-Wire Net and return the 00456 // result 8 bits read from the 1-Wire Net. The parameter 'sendbyte' 00457 // least significant 8 bits are used and the least significant 8 bits 00458 // of the result are the return byte. 00459 // 00460 // 'sendbyte' - 8 bits to send (least significant byte) 00461 // 00462 // Returns: 8 bits read from sendbyte 00463 // 00464 uint8_t DS2482::OWTouchByte(uint8_t sendbyte) 00465 { 00466 if (sendbyte == 0xFF) 00467 { 00468 return OWReadByte(); 00469 } 00470 else 00471 { 00472 OWWriteByte(sendbyte); 00473 return sendbyte; 00474 } 00475 } 00476 00477 //-------------------------------------------------------------------------- 00478 // Search state 00479 //-------------------------------------------------------------------------- 00480 // Find the 'first' devices on the 1-Wire network 00481 // Return TRUE : device found, ROM number in ROM_NO buffer 00482 // FALSE : no device present 00483 // 00484 uint8_t DS2482::OWFirst(void) 00485 { 00486 // reset the search state 00487 LastDiscrepancy = 0; 00488 LastDeviceFlag = FALSE; 00489 LastFamilyDiscrepancy = 0; 00490 00491 #if OW_MASTER_DEBUG 00492 pc.printf("\r\n*** Find the 'first' device on the 1-Wire network"); 00493 #endif 00494 00495 return OWSearch(); 00496 } 00497 00498 //-------------------------------------------------------------------------- 00499 // Find the 'next' devices on the 1-Wire network 00500 // Return TRUE : device found, ROM number in ROM_NO buffer 00501 // FALSE : device not found, end of search 00502 // 00503 uint8_t DS2482::OWNext(void) 00504 { 00505 #if OW_MASTER_DEBUG 00506 pc.printf("\r\n*** Find the 'next' device on the 1-Wire network"); 00507 #endif 00508 00509 // leave the search state alone 00510 return OWSearch(); 00511 } 00512 00513 //-------------------------------------------------------------------------- 00514 // Verify the device with the ROM number in ROM_NO buffer is present. 00515 // Return TRUE : device present 00516 // FALSE : device not present 00517 // 00518 int DS2482::OWVerify(void) 00519 { 00520 uint8_t rom_backup[8], status; 00521 int i,ld_backup,ldf_backup,lfd_backup; 00522 00523 // keep a backup copy of the current state 00524 for (i = 0; i < 8; i++) 00525 { 00526 rom_backup[i] = ROM_NO[i]; 00527 } 00528 00529 ld_backup = LastDiscrepancy; 00530 ldf_backup = LastDeviceFlag; 00531 lfd_backup = LastFamilyDiscrepancy; 00532 00533 // set search to find the same device 00534 LastDiscrepancy = 64; 00535 LastDeviceFlag = FALSE; 00536 00537 if (OWSearch()) 00538 { 00539 // check if same device found 00540 status = TRUE; 00541 00542 for (i = 0; i < 8; i++) 00543 { 00544 if (rom_backup[i] != ROM_NO[i]) 00545 { 00546 status = FALSE; 00547 break; 00548 } 00549 } 00550 } 00551 else 00552 { 00553 status = FALSE; 00554 } 00555 00556 // restore the search state 00557 for (i = 0; i < 8; i++) 00558 { 00559 ROM_NO[i] = rom_backup[i]; 00560 } 00561 LastDiscrepancy = ld_backup; 00562 LastDeviceFlag = ldf_backup; 00563 LastFamilyDiscrepancy = lfd_backup; 00564 00565 // return the result of the verify 00566 #if OW_MASTER_DEBUG 00567 pc.printf("\r\n*** 1-Wire Verify device with the ROM number in ROM_NO"); 00568 #endif 00569 00570 return status; 00571 } 00572 00573 //-------------------------------------------------------------------------- 00574 // Setup the search to find the device type 'family_code' on the next call 00575 // to OWNext() if it is present. 00576 // 00577 void DS2482::OWTargetSetup(uint8_t family_code) 00578 { 00579 uint8_t i; 00580 00581 // set the search state to find SearchFamily type devices 00582 ROM_NO[0] = family_code; 00583 00584 for (i = 1; i < 8; i++) 00585 { 00586 ROM_NO[i] = 0; 00587 } 00588 00589 LastDiscrepancy = 64; 00590 LastFamilyDiscrepancy = 0; 00591 LastDeviceFlag = FALSE; 00592 } 00593 00594 //-------------------------------------------------------------------------- 00595 // Setup the search to skip the current device type on the next call 00596 // to OWNext(). 00597 // 00598 void DS2482::OWFamilySkipSetup(void) 00599 { 00600 // set the Last discrepancy to last family discrepancy 00601 LastDiscrepancy = LastFamilyDiscrepancy; 00602 00603 // clear the last family discrpepancy 00604 LastFamilyDiscrepancy = 0; 00605 00606 // check for end of list 00607 if (LastDiscrepancy == 0) 00608 { 00609 LastDeviceFlag = TRUE; 00610 } 00611 } 00612 00613 //-------------------------------------------------------------------------- 00614 // The 'OWSearch' function does a general search. This function 00615 // continues from the previous search state. The search state 00616 // can be reset by using the 'OWFirst' function. 00617 // This function contains one parameter 'alarm_only'. 00618 // When 'alarm_only' is TRUE (1) the find alarm command 00619 // 0xEC is sent instead of the normal search command 0xF0. 00620 // Using the find alarm command 0xEC will limit the search to only 00621 // 1-Wire devices that are in an 'alarm' state. 00622 // 00623 // Returns: TRUE (1) : when a 1-Wire device was found and its 00624 // Serial Number placed in the global ROM 00625 // FALSE (0): when no new device was found. Either the 00626 // last search was the last device or there 00627 // are no devices on the 1-Wire Net. 00628 // 00629 uint8_t DS2482::OWSearch() 00630 { 00631 int id_bit_number; 00632 int last_zero, rom_byte_number, search_result; 00633 int id_bit, cmp_id_bit; 00634 uint8_t rom_byte_mask, search_direction, status; 00635 00636 // initialize for search 00637 id_bit_number = 1; 00638 last_zero = 0; 00639 rom_byte_number = 0; 00640 rom_byte_mask = 1; 00641 search_result = FALSE; 00642 crc_value = 0; 00643 00644 #if OW_MASTER_DEBUG 00645 pc.printf("\r\n*** one wire search"); 00646 #endif 00647 00648 if (!LastDeviceFlag) // if the last call was not the last one 00649 { 00650 // 1-Wire reset 00651 if (!OWReset()) 00652 { 00653 // reset the search 00654 LastDiscrepancy = 0; 00655 LastDeviceFlag = FALSE; 00656 LastFamilyDiscrepancy = 0; 00657 return FALSE; 00658 } 00659 00660 // issue the search command 00661 OWWriteByte(OW_SEARCH_ROM); 00662 00663 // loop to do the search 00664 do 00665 { 00666 // if this discrepancy if before the Last Discrepancy 00667 // on a previous next then pick the same as last time 00668 if (id_bit_number < LastDiscrepancy) 00669 { 00670 if ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0) 00671 search_direction = 1; 00672 else 00673 search_direction = 0; 00674 } 00675 else 00676 { 00677 // if equal to last pick 1, if not then pick 0 00678 if (id_bit_number == LastDiscrepancy) 00679 search_direction = 1; 00680 else 00681 search_direction = 0; 00682 } 00683 00684 // Perform a triple operation on the DS2482 which will perform 2 read bits and 1 write bit 00685 //pc.printf("\n *** preform triplet operation "); 00686 status = search_triplet(search_direction); 00687 //pc.printf("%04x",status); 00688 00689 // check bit results in status byte 00690 id_bit = ((status & DS2482_STATUS_SBR) == DS2482_STATUS_SBR); 00691 cmp_id_bit = ((status & DS2482_STATUS_TSB) == DS2482_STATUS_TSB); 00692 search_direction = ((status & DS2482_STATUS_DIR) == DS2482_STATUS_DIR) ? 1 : 0; 00693 00694 // check for no devices on 1-Wire 00695 if ((id_bit) && (cmp_id_bit)) 00696 { 00697 break; 00698 } 00699 else 00700 { 00701 if ((!id_bit) && (!cmp_id_bit) && (search_direction == 0)) 00702 { 00703 last_zero = id_bit_number; 00704 00705 // check for Last discrepancy in family 00706 if (last_zero < 9) 00707 { 00708 LastFamilyDiscrepancy = last_zero; 00709 } 00710 } 00711 00712 // set or clear the bit in the ROM byte rom_byte_number 00713 // with mask rom_byte_mask 00714 if (search_direction == 1) 00715 { 00716 ROM_NO[rom_byte_number] |= rom_byte_mask; 00717 } 00718 else 00719 { 00720 ROM_NO[rom_byte_number] &= ~rom_byte_mask; 00721 } 00722 00723 // increment the byte counter id_bit_number 00724 // and shift the mask rom_byte_mask 00725 id_bit_number++; 00726 rom_byte_mask <<= 1; 00727 00728 // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask 00729 if (rom_byte_mask == 0) 00730 { 00731 crc_calc(ROM_NO[rom_byte_number]); // accumulate the CRC 00732 rom_byte_number++; 00733 rom_byte_mask = 1; 00734 } 00735 } 00736 } 00737 while(rom_byte_number < 8); // loop until through all ROM bytes 0-7 00738 00739 // if the search was successful then 00740 if (!((id_bit_number < 65) || (crc_value != 0))) 00741 { 00742 // search successful so set LastDiscrepancy,LastDeviceFlag,search_result 00743 LastDiscrepancy = last_zero; 00744 00745 // check for last device 00746 if (LastDiscrepancy == 0) 00747 { 00748 LastDeviceFlag = TRUE; 00749 } 00750 00751 search_result = TRUE; 00752 } 00753 } 00754 00755 // if no device found then reset counters so next 'search' will be like a first 00756 if (!search_result || (ROM_NO[0] == 0)) 00757 { 00758 LastDiscrepancy = 0; 00759 LastDeviceFlag = FALSE; 00760 LastFamilyDiscrepancy = 0; 00761 search_result = FALSE; 00762 } 00763 00764 #if OW_MASTER_DEBUG 00765 pc.printf(" pass "); 00766 #endif 00767 00768 return search_result; 00769 } 00770 00771 //-------------------------------------------------------------------------- 00772 // Use the DS2482 help command '1-Wire triplet' to perform one bit of a 00773 // 1-Wire search. 00774 // This command does two read bits and one write bit. The write bit 00775 // is either the default direction (all device have same bit) or in case of 00776 // a discrepancy, the 'search_direction' parameter is used. 00777 // 00778 // Returns – The DS2482 status byte result from the triplet command 00779 // 00780 uint8_t DS2482::search_triplet(uint8_t search_direction) 00781 { 00782 char cmd[2]; 00783 uint8_t status, poll_count = 0; 00784 00785 cmd[0] = DS2482_CMD_1WT; 00786 cmd[1] = (search_direction ? 0x80 : 0x00); 00787 i2c.write(addr,cmd,2); 00788 00789 do 00790 { 00791 i2c.read(addr,cmd,1); 00792 status = cmd[0]; 00793 } 00794 while ((status & DS2482_STATUS_1WB) && (poll_count++ < POLL_LIMIT)); 00795 00796 // check for failure due to poll limit reached 00797 if (poll_count >= POLL_LIMIT) 00798 { 00799 // handle error 00800 // ... 00801 reset(); 00802 return 0; 00803 } 00804 // return status byte 00805 return status; 00806 } 00807 00808 //-------------------------------------------------------------------------- 00809 // Set the 1-Wire Net communication speed. 00810 // 00811 // 'new_speed' - new speed defined as 00812 // MODE_STANDARD 0x00 00813 // MODE_OVERDRIVE 0x01 00814 // 00815 // Returns: current 1-Wire Net speed 00816 // 00817 uint8_t DS2482::OWSpeed(uint8_t new_speed) 00818 { 00819 // set the speed 00820 if (new_speed == MODE_OVERDRIVE) 00821 { 00822 c1WS = DS2482_CFG_1WS; 00823 } 00824 else 00825 { 00826 c1WS = FALSE; 00827 } 00828 00829 // write the new config 00830 write_config(c1WS | cSPU | cPPM | cAPU); 00831 00832 00833 return new_speed; 00834 } 00835 00836 //-------------------------------------------------------------------------- 00837 // Set the 1-Wire Net line level pullup to normal. The DS2482 only 00838 // allows enabling strong pullup on a bit or byte event. 00839 // Consequently this function only allows the MODE_STANDARD argument. 00840 // To enable strong pullup 00841 // use OWWriteBytePower or OWReadBitPower. 00842 // 00843 // 'new_level' - new level defined as 00844 // MODE_STANDARD 0x00 00845 // 00846 // Returns: current 1-Wire Net level 00847 // 00848 uint8_t DS2482::OWLevel(uint8_t new_level) 00849 { 00850 // function only will turn back to non-strong pullup 00851 if (new_level != MODE_STANDARD) 00852 { 00853 return MODE_STRONG; 00854 } 00855 00856 // clear the strong pullup bit in the global config state 00857 cSPU = FALSE; 00858 00859 // write the new config 00860 write_config(c1WS | cSPU | cPPM | cAPU); 00861 00862 00863 return MODE_STANDARD; 00864 } 00865 00866 //-------------------------------------------------------------------------- 00867 // Send 1 bit of communication to the 1-Wire Net and verify that the 00868 // response matches the 'applyPowerResponse' bit and apply power delivery 00869 // to the 1-Wire net. Note that some implementations may apply the power 00870 // first and then turn it off if the response is incorrect. 00871 // 00872 // 'applyPowerResponse' - 1 bit response to check, if correct then start 00873 // power delivery 00874 // 00875 // Returns: TRUE: bit written and response correct, strong pullup now on 00876 // FALSE: response incorrect 00877 // 00878 uint8_t DS2482::OWReadBitPower(uint8_t applyPowerResponse) 00879 { 00880 uint8_t rdbit; 00881 00882 // set strong pullup enable 00883 cSPU = DS2482_CFG_SPU; 00884 00885 // write the new config 00886 if (!write_config(c1WS | cSPU | cPPM | cAPU)) 00887 { 00888 return FALSE; 00889 } 00890 00891 // perform read bit 00892 rdbit = OWReadBit(); 00893 00894 // check if response was correct, if not then turn off strong pullup 00895 if (rdbit != applyPowerResponse) 00896 { 00897 OWLevel(MODE_STANDARD); 00898 return FALSE; 00899 } 00900 00901 return TRUE; 00902 } 00903 00904 //-------------------------------------------------------------------------- 00905 // Send 8 bits of communication to the 1-Wire Net and verify that the 00906 // 8 bits read from the 1-Wire Net are the same (write operation). 00907 // The parameter 'sendbyte' least significant 8 bits are used. After the 00908 // 8 bits are sent change the level of the 1-Wire net. 00909 // 00910 // 'sendbyte' - 8 bits to send (least significant bit) 00911 // 00912 // Returns: TRUE: bytes written and echo was the same, strong pullup now on 00913 // FALSE: echo was not the same 00914 // 00915 uint8_t DS2482::OWWriteBytePower(uint8_t sendbyte) 00916 { 00917 // set strong pullup enable 00918 cSPU = DS2482_CFG_SPU; 00919 00920 // write the new config 00921 if (!write_config(c1WS | cSPU | cPPM | cAPU)) 00922 { 00923 #if OW_MASTER_DEBUG 00924 pc.printf("\r\nSPU off"); 00925 #endif 00926 00927 return FALSE; 00928 } 00929 00930 // perform write byte 00931 OWWriteByte(sendbyte); 00932 00933 return TRUE; 00934 } 00935 00936 00937 // end I2C DS2482 00938 //====================================================================== 00939 00940 //--------------------------------------------------------------------------- 00941 //-------------------------DS18XX OPERATIONS--------------------------------- 00942 //--------------------------------------------------------------------------- 00943 // find ALL devices on bus 1 00944 // 00945 void DS2482::DS18XX_Read_Address(void) 00946 { 00947 uint8_t status, i, j; 00948 00949 //-------------------------------------------------------------- 00950 // Device Tabele für bus 1 und bus 2 löschen 00951 00952 for (i = 0; i < OW_MAX_DEVICES; i++) 00953 { 00954 for (j = 0; j < 8; j++) 00955 { 00956 ow.device_table[i].rom[j] = 0; 00957 } 00958 } 00959 00960 // pc.printf("\n --- DS18xx_Read_Address --- "); 00961 // wait(0.1); 00962 00963 ow.devices = 0; 00964 00965 //-------------------------------------------------------------- 00966 // die Bausteine am Bus suchen 00967 00968 //pc.printf("\n -- detect -- \n"); 00969 //wait(0.5); 00970 detect(); // reset and init the 1-wire master 00971 00972 //pc.printf("\n -- OWFirst --\n"); 00973 //wait(0.1); 00974 status = OWFirst(); 00975 00976 if(status == 0) 00977 { 00978 #if OW_MASTER_START 00979 pc.printf("\r\nno 1-Wire slaves found"); 00980 #endif 00981 } 00982 00983 while(status) 00984 { 00985 // TODO hier ins eeprom schreiben 00986 #if OW_MASTER_START 00987 pc.printf("\n*** #%02d ROM_NO= ",ow.devices); 00988 wait(0.1); 00989 #endif 00990 00991 for (uint8_t i = 0; i < 8; i++) 00992 { 00993 ow.device_table[ow.devices].rom[i] = ROM_NO[i]; 00994 00995 #if OW_MASTER_START 00996 pc.printf(" 0x%02x",ROM_NO[i]); 00997 wait (0.1); 00998 #endif 00999 } 01000 ow.device_table[ow.devices].status = 0x01; // Wandler gefunden 01001 01002 status = OWNext(); 01003 ow.devices++; // Zeiger auf den nächsten freien Baustein 01004 01005 // maximal 16 Bausteine 01006 if (ow.devices >= OW_MAX_DEVICES) 01007 { 01008 ow.devices--; // zeiget auf den letzten gültigen Baustein 01009 return; 01010 } 01011 } 01012 01013 #if OW_MASTER_START 01014 pc.printf("\r\n"); 01015 #endif 01016 01017 return; 01018 } 01019 01020 //--------------------------------------------------------------------------- 01021 // 01022 void DS2482::start_conversion(void) 01023 { 01024 //-------------------------------------------------------------- 01025 // alle Bausteine an bus 0 starten 01026 01027 // find a DS18S20 01028 OWFirst(); 01029 OWReset(); 01030 01031 // address all devices 01032 OWWriteByte(OW_SKIP_ROM); 01033 01034 // Start Conversion and Config Strong Pull-Up 01035 if (!OWWriteBytePower(OW_CONVERT_TEMP)) 01036 { 01037 #if OW_MASTER_DEBUG 01038 pc.printf("Fail convert command\r\n"); 01039 #endif 01040 } 01041 01042 //-------------------------------------------------------------- 01043 // alle Bausteine an bus 1 starten 01044 01045 // find a DS18S20 01046 OWFirst(); 01047 OWReset(); 01048 01049 // address all devices 01050 OWWriteByte(OW_SKIP_ROM); 01051 01052 // Start Conversion and Config Strong Pull-Up 01053 if (!OWWriteBytePower(OW_CONVERT_TEMP)) 01054 { 01055 #if OW_MASTER_DEBUG 01056 pc.printf("Fail convert command\r\n"); 01057 #endif 01058 } 01059 01060 } 01061 01062 //----------------------------------------------------------------------------- 01063 01064 bool DS2482::ow_read_rom(void) 01065 { 01066 uint8_t n; 01067 01068 // Write Read ROM Code command 01069 OWWriteByte(OW_CMD_READ_ROM); 01070 01071 // Read 8 bytes of ROM code 01072 for (n = 0; n < 8; n++) 01073 { 01074 ow_rom_code[n] = OWReadByte(); 01075 } 01076 01077 // Do Cyclic Redundancy Check 01078 if (crc_calc_buffer(&ow_rom_code[0],7) != ow_rom_code[7]) 01079 { 01080 ow_flags |= OW_CRC_ERROR; 01081 01082 return false; 01083 } 01084 01085 return true; 01086 } 01087 01088 //----------------------------------------------------------------------------- 01089 01090 bool DS2482::ow_read_scratchpad(void) 01091 { 01092 uint8_t i, crc; 01093 01094 ow_flags = 0; 01095 01096 if (!OWReset()) return false; 01097 01098 // select the device 01099 // den Baustein wird über den ROM Code adressiert 01100 OWWriteByte(OW_CMD_MATCH_ROM); // 0x55 match command 01101 01102 for (i = 0; i < 8; i++) 01103 { 01104 OWWriteByte(ow.device_table[ow.device_table_index].rom[i]); 01105 } 01106 01107 OWWriteByte(OW_CMD_READ_SCRATCHPAD); // Read Scratch pad 0xBE 01108 01109 // Read 9 bytes of scratchpad memory 01110 for (i = 0; i < OW_SCRATCHPAD_BYTES; i++) 01111 { 01112 crc = OWReadByte(); 01113 ow_scratchpad[i] = crc; 01114 } 01115 01116 #if OW_MASTER_DEBUG 01117 01118 pc.printf("\n*** Scratch_Val "); 01119 01120 for (i = 1; i < OW_SCRATCHPAD_BYTES; i++) 01121 { 01122 pc.printf(":0x%02x",ow_scratchpad[i]); 01123 } 01124 01125 pc.printf("\r\n"); 01126 01127 #endif 01128 01129 01130 return true; 01131 } 01132 01133 //----------------------------------------------------------------------------- 01134 01135 bool DS2482::ow_read_scratchpad_ds2438(uint8_t page) 01136 { 01137 uint8_t n, crc; 01138 01139 ow_flags = 0; 01140 01141 if (!OWReset()) return false; 01142 01143 // select the device 01144 // den Baustein wird über den ROM Code adressiert 01145 OWWriteByte(OW_CMD_MATCH_ROM); // 0x55 match command 01146 01147 for (n = 0; n < 8; n++) 01148 { 01149 OWWriteByte(ow.device_table[ow.device_table_index].rom[n]); 01150 } 01151 01152 // Write command to read scratchpad memory 01153 OWWriteByte(0xbe); // 0xBE 01154 OWWriteByte(page); // 0x03 01155 01156 // Read 9 bytes of scratchpad memory 01157 for (n = 0; n < OW_SCRATCHPAD_BYTES; n++) 01158 { 01159 crc = OWReadByte(); 01160 ow_scratchpad[n] = crc; 01161 // printf_P(PSTR("%02x "),crc); 01162 } 01163 01164 crc = crc_calc_buffer(ow_scratchpad,8); 01165 01166 // Calculate CRC 01167 if (crc != ow_scratchpad[8]) 01168 { 01169 ow_flags |= OW_CRC_ERROR; 01170 // Read 9 bytes of scratchpad memory 01171 pc.printf("\now_read_scratchpad: "); 01172 for (n = 0; n < OW_SCRATCHPAD_BYTES; n++) 01173 { 01174 pc.printf("%02x ",ow_scratchpad[n]); 01175 } 01176 pc.printf(": CRC error %02x",crc); 01177 return false; 01178 } 01179 return true; 01180 } 01181 01182 //---------------------------------------------------------------------------- 01183 01184 bool DS2482::ow_write_scratchpad_ds18x20 (uint8_t th, uint8_t tl) 01185 { 01186 uint8_t i; 01187 01188 // Do bus reset 01189 if (!OWReset()) return false; 01190 01191 // select the device 01192 // den Baustein wird über den ROM Code adressiert 01193 OWWriteByte(OW_CMD_MATCH_ROM); // 0x55 match command 01194 01195 for (i = 0; i < 8; i++) 01196 { 01197 OWWriteByte(ow.device_table[ow.device_table_index].rom[i]); 01198 } 01199 01200 01201 // Write command to read scratchpad memory 01202 OWWriteByte(OW_CMD_WRITE_SCRATCHPAD); 01203 01204 // Write 1 byte at scratchpad memory 01205 OWWriteByte(th); // Th 01206 wait_us(8); // ist für das Timing der 8 MHZ CPU notwendig 01207 01208 // Write 1 byte at scratchpad memory 01209 OWWriteByte(tl); // Th 01210 wait_us(8); // ist für das Timing der 8 MHZ CPU notwendig 01211 01212 // Write 1 byte at scratchpad memory 01213 OWWriteByte(0x7F); // 12 Bit Auflösung 01214 wait_us(8); // ist für das Timing der 8 MHZ CPU notwendig 01215 01216 return true; 01217 } 01218 01219 //---------------------------------------------------------------------------- 01220 bool DS2482::ow_write_scratchpad_ds2438 (uint8_t th, uint8_t tl) 01221 { 01222 01223 uint8_t i; 01224 01225 // Do bus reset 01226 if (!OWReset()) return false; 01227 01228 // select the device 01229 // den Baustein wird über den ROM Code adressiert 01230 OWWriteByte(OW_CMD_MATCH_ROM); // 0x55 match command 01231 01232 for (i = 0; i < 8; i++) 01233 { 01234 OWWriteByte(ow.device_table[ow.device_table_index].rom[i]); 01235 } 01236 01237 // Write command to read scratchpad memory 01238 OWWriteByte(0x4E); 01239 OWWriteByte(0x03); 01240 01241 // Write 3 bytes to scratchpad memory 01242 OWWriteByte(th); // Th 01243 wait_us(8); 01244 01245 OWWriteByte(tl); // Tl 01246 wait_us(8); 01247 01248 return true; 01249 } 01250 01251 //---------------------------------------------------------------------------- 01252 bool DS2482::ow_write_eeprom_ds18x20 (void) 01253 { 01254 01255 uint8_t i; 01256 01257 // Do bus reset 01258 if (!OWReset()) return false; 01259 01260 // select the device 01261 // den Baustein wird über den ROM Code adressiert 01262 OWWriteByte(OW_CMD_MATCH_ROM); // 0x55 match command 01263 01264 for (i = 0; i < 8; i++) 01265 { 01266 OWWriteByte(ow.device_table[ow.device_table_index].rom[i]); 01267 } 01268 01269 // Write command to write eeprom 01270 OWWriteByte(0x48); 01271 01272 return true; 01273 01274 } 01275 01276 //---------------------------------------------------------------------------- 01277 bool DS2482::ow_write_eeprom_ds2438 (void) 01278 { 01279 uint8_t i; 01280 01281 // Do bus reset 01282 if (!OWReset()) return false; 01283 01284 // select the device 01285 // den Baustein wird über den ROM Code adressiert 01286 OWWriteByte(OW_CMD_MATCH_ROM); // 0x55 match command 01287 01288 for (i = 0; i < 8; i++) 01289 { 01290 OWWriteByte(ow.device_table[ow.device_table_index].rom[i]); 01291 } 01292 01293 // Write command to read scratchpad memory 01294 OWWriteByte(0x48); 01295 OWWriteByte(0x03); 01296 01297 return true; 01298 } 01299 01300 01301 //---------------------------------------------------------------------------- 01302 01303 void DS2482::ow_read_address (void) 01304 { 01305 uint8_t n; 01306 01307 // ow Adressen aus den Bausteinen lesen 01308 for (n = 0; n < OW_MAX_DEVICES; n++) 01309 { 01310 if ((ow.device_table[n].status & 0x0f) == 1) 01311 { 01312 // printf_P(PSTR("\n device table %d"),n); 01313 ow.device_table_index = n; 01314 01315 if ((ow.device_table[n].rom[0] == 0x10) || (ow.device_table[n].rom[0] == 0x28)) 01316 { 01317 if (ow_read_scratchpad()) 01318 { 01319 if(ow_scratchpad[2] == ow_scratchpad[3]) ow.device_table[n].adr = ow_scratchpad[3]; 01320 } 01321 } 01322 01323 if ((ow.device_table[n].rom[0] == 0xa6) || (ow.device_table[n].rom[0] == 0x26)) 01324 { 01325 if (ow_read_scratchpad_ds2438(0x03)) 01326 { 01327 if(ow_scratchpad[0] == ow_scratchpad[1]) ow.device_table[n].adr = ow_scratchpad[0]; 01328 01329 } 01330 } 01331 01332 } 01333 01334 } // end for(... 01335 } 01336 01337 //----------------------------------------------------------------------------- 01338 01339 bool DS2482::ds1820_start_conversion(uint8_t command) 01340 { 01341 uint8_t i; 01342 01343 // Do bus reset 01344 if (!OWReset()) return false; 01345 01346 // Check if a match ROM code must be done or just skip ROM code (0xFF) 01347 if (command > 0xFE) 01348 { 01349 OWWriteByte(OW_CMD_SKIP_ROM); // Send Skip ROM Code command 01350 } 01351 else 01352 { 01353 // select the device 01354 // den Baustein wird über den ROM Code adressiert 01355 OWWriteByte(OW_CMD_MATCH_ROM); // 0x55 match command 01356 01357 for (i = 0; i < 8; i++) 01358 { 01359 OWWriteByte(ow.device_table[ow.device_table_index].rom[i]); 01360 } 01361 } 01362 01363 // Send the "Convert T" command to start conversion 01364 OWWriteByte(OW_CMD_CONVERT_T); 01365 01366 // Set flag to mark a measurement in progress 01367 ds1820_request_pending = true; 01368 01369 return TRUE; 01370 } 01371 01372 01373 //----------------------------------------------------------------------------- 01374 01375 bool DS2482::ds18B20_read_hrtemp(void) 01376 { 01377 01378 union ds18B20_temp_union 01379 { 01380 int16_t word; 01381 uint8_t byte[2]; 01382 } ds18B20_temp; 01383 01384 // uint8_t temp_lo; 01385 // uint8_t temp_hi; 01386 // int8_t digit; 01387 float ds1820_float_result; 01388 01389 // Preset float result to zero in case of function termination (return false) 01390 //ds1820_float_result = 0.0; 01391 ow.device_table[ow.device_table_index].result = 0; 01392 01393 // Return false if reading scratchpad memory fails 01394 if (!ow_read_scratchpad()) 01395 { 01396 ow.device_table[ow.device_table_index].status &= 0xf0; 01397 ow.device_table[ow.device_table_index].status |= 4; 01398 return FALSE; 01399 } 01400 01401 ds18B20_temp.byte[0] = ow_scratchpad[DS1820_LSB]; 01402 ds18B20_temp.byte[1] = ow_scratchpad[DS1820_MSB]; 01403 01404 //ds18B20_temp.word <<= 4; // Vorzeichenbit auf MSB Bit schieben 01405 //ds18B20_temp.word /= 16; // die letzten 4 Stellen wieder löschen 01406 01407 ds1820_float_result = ds18B20_temp.word * 0.0625; 01408 01409 //pc.printf("\nDS18B20 T-Kanal: %d = %2.2f ",ow.device_table_index,ds1820_float_result); 01410 01411 ow.device_table[ow.device_table_index].result = (int16_t)(ds1820_float_result * 100); 01412 01413 // Clear flag to mark that no measurement is in progress 01414 ds1820_request_pending = false; 01415 01416 // Flag für erfolgreiches Lesen setzen 01417 ow.device_table[ow.device_table_index].status &= 0xf0; 01418 ow.device_table[ow.device_table_index].status |= 3; 01419 01420 return true; 01421 } 01422 01423 01424 //----------------------------------------------------------------------------- 01425
Generated on Wed Jul 13 2022 07:09:37 by 1.7.2