one wire driver

Dependents:   09_PT1000 10_PT1000 11_PT1000

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DS2482.cpp Source File

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