Interface Driver for Maxim DS2482 1Wire-to-I2C bridge IC. Includes access functions for DS1820 temperature sensors. Can easily be ported to other hardware by using hardware abstraction layer.

Usage Example - main.cpp

#include "mbed.h"
#include "ds2482.h"

#define MAX_TEMP_SENSORS        16
#define CONNECTED_DS2482_HUBS   2

struct sDS1820_t
{    
    struct sDS2482_t *hub;
    uint8_t u8RomNr[8];
};

struct sDS1820_t sDS1820[MAX_TEMP_SENSORS];
struct sDS2482_t sDS2482[CONNECTED_DS2482_HUBS];

Serial console(USBTX, USBRX);
I2C i2c (p9, p10);

int8_t i8SetupTempSensors(void)
{
    int x=0;    
    
    sDS2482[0].u8Addr = DS2482_ADDR1;     
    sDS2482[1].u8Addr = DS2482_ADDR2;
    
    for(int loop=0; loop<2; loop++)
    {   
        int8_t i8Tmp = i8DS2482Reset(&sDS2482[loop]);
        if(i8Tmp)
            return i8Tmp;
        
        i8Tmp = i8DS2482SetControlBits(&sDS2482[loop], APU | SPU );
        if(i8Tmp)
            return i8Tmp;
        
        i8Tmp = i8DS2482_OWReset(&sDS2482[loop]);        
        if(i8Tmp) 
            return i8Tmp;
            
        while(i16DS2482_OWSearch(&sDS2482[loop]) > 0)
        {            
            sDS1820[x].hub = &sDS2482[loop];
            for(int z=0; z<8; z++)
                sDS1820[x].u8RomNr[z] = sDS2482[loop].u8RomNr[z];                        
            x++;
        }
    }  
    return x;
}

int main(void)
{
    uint8_t u8SensorCount;
    
    mbed_i2c = &i2c; 
    
    console.baud(115200);    
    
    int8_t i8Ret = i8SetupTempSensors();    
    
    if(i8Ret < 0)
    {
        console.printf("Error -i8Ret\n");    
        while(1);       // error occured
    }
    
    u8SensorCount = i8Ret;
    
    while(1)
    {
        // Start Temperature Conversion on all DS1820
        for(uint8_t loop = 0; loop < CONNECTED_DS2482_HUBS; loop++)
        {            
            i8Ret = i8DS2482_OWStartAllDS1820(&sDS2482[loop], 0);
                if(i8Ret) 
                {
                    console.printf("Error %i\n", -i8Ret);
                    while(1);   // error!            
                }
        }
        
        // Wait until all DS1820 have completed the conversion
        for(uint8_t loop = 0; loop < CONNECTED_DS2482_HUBS; loop++)        
            while(!i8DS2482_OWCheckDeviceReady(&sDS2482[loop]));                        
        
        // Get temperature values and display them
        for(uint8_t z=0; z<u8SensorCount; z++)
        {
            int16_t i16Tmp = i16DS2482_OWReadDS1820(sDS1820[z].hub, sDS1820[z].u8RomNr, 0);
            if(i16Tmp < 0)    
            {                
                console.printf("Error %i\n", -i16Tmp);
                while(1);           // error                    
            }
            else
            {
                uint8_t u8Tmp = (i16Tmp-109)/2;
                uint8_t u8Tmp2;
                if((int16_t)u8Tmp*2+109 != i16Tmp)
                    u8Tmp2=5;
                else
                    u8Tmp2=0;
                console.printf("[%02i] %02i", z+1, u8Tmp);         
                console.printf(",%iC | ", u8Tmp2);
            }
            if((z+1)%8==0)
                console.printf("\n");
        }                                        
    }
}
Revision:
0:39243a42bc87
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ds2482.cpp	Thu Jul 24 14:14:40 2014 +0000
@@ -0,0 +1,839 @@
+#include "ds2482.h"
+
+/* ================================================
+   Reads Status Register of given DS2482 IC
+   Parameter:   Pointer to DS2482 object to work on
+   Returns:     register content
+                (negative value on error)
+   ------------------------------------------------ */
+int16_t i16DS2482GetStatus(struct sDS2482_t *dev)
+{
+    uint8_t u8Data[2];
+    u8Data[0] = SRP;
+    u8Data[1] = 0xF0;           // Status register
+    if(_i8I2CWrite(dev->u8Addr, u8Data, 2) != 0)
+        return -1;
+    if(_i8I2CRead(dev->u8Addr, u8Data, 1, 0) != 0)
+        return -1;
+    
+    return u8Data[0];
+}
+
+/* ================================================
+   Issues reset to given DS2482 IC
+   Parameter:   1 Pointer to DS2482 object to work on
+   Returns:     zero
+                (negative value on error)
+   ------------------------------------------------ */
+int8_t i8DS2482Reset(struct sDS2482_t *dev)
+{
+    uint8_t u8Data;
+    u8Data = DRST;           
+    if(_i8I2CWrite(dev->u8Addr, &u8Data, 1) != 0)
+        return -DS2482_ERR_I2CWRITE;
+    
+    return 0;
+}
+
+/* ================================================
+   Writes into Config Register of given DS2482 IC
+   Parameter:   1 Pointer to DS2482 object to work on
+                2 Byte register value
+   Returns:     zero
+                (negative value on error)
+   ------------------------------------------------ */
+int8_t i8DS2482SetControlBits(struct sDS2482_t *dev, uint8_t u8Flags)
+{
+    uint8_t u8Data[2];
+    
+    u8Data[0] = WCFG;
+    u8Data[1] = (~u8Flags)<<4 | u8Flags;           // active pullup
+    if(_i8I2CWrite(dev->u8Addr, u8Data, 2) != 0)
+        return -DS2482_ERR_I2CWRITE;
+                
+    
+    
+    u8Data[0] = SRP;
+    u8Data[1] = 0xC3;           // Config 
+    
+    if(_i8I2CWrite(dev->u8Addr, u8Data, 2) != 0)
+        return -DS2482_ERR_I2CWRITE;
+        
+    if(_i8I2CRead(dev->u8Addr, u8Data, 1, 0) != 0)
+        return -DS2482_ERR_I2CREAD;
+    
+    
+    
+    if(u8Data[0] != u8Flags)
+        return -DS2482_ERR_CONFIGMISSMATCH;
+    
+    return 0;
+}
+
+/* ================================================
+   Issue 1Wire Reset on given DS2482 IC
+   Parameter:   1 Pointer to DS2482 object to work on                
+   Returns:     zero if a device is present
+                (negative value on error)
+   ------------------------------------------------ */
+int8_t i8DS2482_OWReset(struct sDS2482_t *dev)
+{
+   unsigned char status;
+   int poll_count = 0;
+
+   // 1-Wire reset (Case B)
+   //   S AD,0 [A] 1WRS [A] Sr AD,1 [A] [Status] A [Status] A\ P
+   //                                   \--------/
+   //                       Repeat until 1WB bit has changed to 0
+   //  [] indicates from slave
+    uint8_t u8Data[2];
+    u8Data[0] = OWRS;
+   
+    _i8I2CWrite(dev->u8Addr, u8Data, 1);        
+
+    // loop checking 1WB bit for completion of 1-Wire operation
+    // abort if poll limit reached
+    _i8I2CRead(dev->u8Addr, &status, 1, 0);
+    do
+    {
+        _i8I2CRead(dev->u8Addr, &status, 1 ,status & STATUS_1WB);
+    }
+    while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT));
+
+   
+
+   // check for failure due to poll limit reached
+   if (poll_count >= POLL_LIMIT)
+   {
+      // handle error
+      // ...
+        i8DS2482Reset(dev);
+        return -DS2482_ERR_TIMEOUT;
+   }
+
+   // check for short condition
+   if (status & STATUS_SD)
+      dev->u32Flags &= ~FLAG_SHORT;
+   else
+      dev->u32Flags |= FLAG_SHORT;
+
+   // check for presence detect
+   if (status & STATUS_PPD)
+      return 0;
+   else
+      return -DS2482_ERR_NOPRESENCE;
+}
+
+//--------------------------------------------------------------------------
+// Send 1 bit of communication to the 1-Wire Net.
+// The parameter 'sendbit' least significant bit is used.
+//
+// 'sendbit' - 1 bit to send (least significant byte)
+//
+/* ================================================
+   Sends 1 bit to 1Wire network of given DS2482 IC
+   Parameter:   1 Pointer to DS2482 object to work on                
+                2 Information
+   Returns:     zero
+                (negative value on error)
+   ------------------------------------------------ */
+int8_t i8DS2482_OWWriteBit(struct sDS2482_t *dev, uint8_t sendbit)
+{
+   return i8DS2482_OWTouchBit(dev, sendbit);
+}
+
+//--------------------------------------------------------------------------
+// Reads 1 bit of communication from the 1-Wire Net and returns the
+// result
+//
+// Returns:  1 bit read from 1-Wire Net
+//
+/* ================================================
+   Reads one bit from 1Wire network of given DS2482 IC
+   Parameter:   1 Pointer to DS2482 object to work on                
+   Returns:     Information
+                (negative value on error)
+   ------------------------------------------------ */
+int8_t i8DS2482_OWReadBit(struct sDS2482_t *dev)
+{
+   return i8DS2482_OWTouchBit(dev, 0x01);
+}
+
+//--------------------------------------------------------------------------
+// Send 1 bit of communication to the 1-Wire Net and return the
+// result 1 bit read from the 1-Wire Net. The parameter 'sendbit'
+// least significant bit is used and the least significant bit
+// of the result is the return bit.
+//
+// 'sendbit' - the least significant bit is the bit to send
+//
+// Returns: 0:   0 bit read from sendbit
+//          1:   1 bit read from sendbit
+//
+
+int8_t i8DS2482_OWTouchBit(struct sDS2482_t *dev, uint8_t sendbit)
+{
+   uint8_t status;
+   int poll_count = 0;
+
+   // 1-Wire bit (Case B)
+   //   S AD,0 [A] 1WSB [A] BB [A] Sr AD,1 [A] [Status] A [Status] A\ P
+   //                                          \--------/
+   //                           Repeat until 1WB bit has changed to 0
+   //  [] indicates from slave
+   //  BB indicates byte containing bit value in msbit
+
+    uint8_t u8Data[2];
+    u8Data[0] = OWSB;
+    u8Data[1] = sendbit?0x80:0x00;
+    
+    if(_i8I2CWrite(dev->u8Addr, u8Data, 2) != 0)
+        return -DS2482_ERR_I2CWRITE;
+   
+    // loop checking 1WB bit for completion of 1-Wire operation
+    // abort if poll limit reached
+    _i8I2CRead(dev->u8Addr, &status, 1, 0);
+    do
+    {
+        
+        _i8I2CRead(dev->u8Addr, &status, 1, status & STATUS_1WB);
+    }
+    while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT));   
+    
+   // check for failure due to poll limit reached
+   if (poll_count >= POLL_LIMIT)
+   {
+     i8DS2482Reset(dev);
+        return -DS2482_ERR_TIMEOUT;
+   }
+    
+   // return bit state
+   if (status & STATUS_SBR)
+      return 1;
+   else
+      return 0;
+}
+
+/* ================================================
+   Sends 1 byte to 1Wire network of given DS2482 IC
+   Parameter:   1 Pointer to DS2482 object to work on                
+                2 Data
+   Returns:     zero
+                (negative value on error)
+   ------------------------------------------------ */
+int8_t i8DS2482_OWWriteByte(struct sDS2482_t *dev, uint8_t sendbyte)
+{
+   // 1-Wire Write Byte (Case B)
+   //   S AD,0 [A] 1WWB [A] DD [A] Sr AD,1 [A] [Status] A [Status] A\ P
+   //                                          \--------/
+   //                             Repeat until 1WB bit has changed to 0
+   //  [] indicates from slave
+   //  DD data to write
+
+   uint8_t u8Data[2];
+   u8Data[0] = OWWB;
+   u8Data[1] = sendbyte;
+   
+    if(_i8I2CWrite(dev->u8Addr, u8Data, 2) != 0)
+        return -DS2482_ERR_I2CWRITE;          
+   
+    int8_t i8Tmp = i8DS2482_OWWait(dev);
+    if(i8Tmp != 0)
+        return i8Tmp;
+    
+    return 0;           // all went good
+}
+
+/* ================================================
+   Reads 1 byte from 1Wire network of given DS2482 IC
+   Parameter:   1 Pointer to DS2482 object to work on                
+   Returns:     Read byte
+                (negative value on error)
+   ------------------------------------------------ */
+int16_t i16DS2482_OWReadByte(struct sDS2482_t *dev)
+{
+   // 1-Wire Read Bytes (Case C)
+   //   S AD,0 [A] 1WRB [A] Sr AD,1 [A] [Status] A [Status] A\
+   //                                   \--------/
+   //                     Repeat until 1WB bit has changed to 0
+   //   Sr AD,0 [A] SRP [A] E1 [A] Sr AD,1 [A] DD A\ P
+   //
+   //  [] indicates from slave
+   //  DD data read
+    uint8_t u8Data[2];
+    uint8_t data = 0;
+    u8Data[0] = OWRB;
+   
+    if(_i8I2CWrite(dev->u8Addr, u8Data, 1) != 0)
+        return -DS2482_ERR_I2CWRITE;
+    
+    i8DS2482_OWWait(dev);
+    
+    u8Data[0] = SRP;
+    u8Data[1] = 0xE1;
+    
+    if(_i8I2CWrite(dev->u8Addr, u8Data, 2) != 0)
+        return -DS2482_ERR_I2CWRITE;    
+   
+    if(_i8I2CRead(dev->u8Addr, &data, 1, 0) != 0)            
+        return -DS2482_ERR_I2CREAD;           
+       
+    return data;
+}
+
+/* ================================================
+   Write-and-read block of data (byte-alligned)
+   to/from 1Wire network of given DS2482   
+   Parameter:   1 Pointer to DS2482 object to work on                
+                2 Pointer to Data Buffer
+                3 Length (in bytes) of Data Buffer
+   Returns:     zero (Data Buffer now contains read data)
+                (negative value on error)                
+   ------------------------------------------------ */
+int8_t i8DS2482_OWBlock(struct sDS2482_t *dev, uint8_t *tran_buf, uint8_t tran_len)
+{
+    int i;
+    int16_t i16Ret;
+
+    for (i = 0; i < tran_len; i++)
+    {
+        
+        i16Ret = i16DS2482_OWTouchByte(dev, tran_buf[i]);        
+        
+        if(i16Ret >= 0)        
+            tran_buf[i] = (uint8_t)i16Ret;                    
+        else        
+            return i16Ret;                    
+    }
+    return 0;
+}
+
+/* ================================================
+   Waits for 1Wire transmission ends on given DS2482 IC
+   Parameter:   1 Pointer to DS2482 object to work on                
+   Returns:     zero
+                (negative value on error)
+   ------------------------------------------------ */
+int8_t i8DS2482_OWWait(struct sDS2482_t *dev)
+{
+    uint8_t status, poll_count;
+    poll_count = 0;
+    status = 0;
+// loop checking 1WB bit for completion of 1-Wire operation
+    // abort if poll limit reached
+    _i8I2CRead(dev->u8Addr, &status, 1, 0);
+    do
+    {
+        _i8I2CRead(dev->u8Addr, &status, 1 ,status & STATUS_1WB);
+    }
+    while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT));   
+
+    // check for failure due to poll limit reached
+    if (poll_count >= POLL_LIMIT)
+    {
+        i8DS2482Reset(dev);
+            return -DS2482_ERR_TIMEOUT;
+    }
+    return 0;
+}
+
+/* ================================================
+   Write-and-Reads a Byte to/from 1Wire network
+   of given DS2482   
+   Parameter:   1 Pointer to DS2482 object to work on                
+                2 Byte to send
+   Returns:     Read data
+                (negative value on error)
+   ------------------------------------------------ */
+int16_t i16DS2482_OWTouchByte(struct sDS2482_t *dev, uint8_t sendbyte)
+{
+    if (sendbyte == 0xFF)
+    {        
+        return i16DS2482_OWReadByte(dev);
+    }
+    else               
+    {     
+        return i8DS2482_OWWriteByte(dev, sendbyte);    
+    }
+}
+
+//--------------------------------------------------------------------------
+// Find the 'first' devices on the 1-Wire network
+// Return TRUE  : device found, ROM number in ROM_NO buffer
+//        FALSE : no device present
+//
+
+int16_t i16DS2482_OWFirst(struct sDS2482_t *dev)
+{
+   // reset the search state
+   dev->i16LastDiscrepancy = 0;
+   dev->i16LastDeviceFlag = 0;
+   dev->i16LastFamilyDiscrepancy = 0;
+
+   return i16DS2482_OWSearch(dev);
+}
+
+//--------------------------------------------------------------------------
+// Find the 'next' devices on the 1-Wire network
+// Return TRUE  : device found, ROM number in ROM_NO buffer
+//        FALSE : device not found, end of search
+//
+int16_t i16DS2482_OWNext(struct sDS2482_t *dev)
+{
+   // leave the search state alone
+   return i16DS2482_OWSearch(dev);
+}
+
+
+//--------------------------------------------------------------------------
+// The 'OWSearch' function does a general search. This function
+// continues from the previous search state. The search state
+// can be reset by using the 'OWFirst' function.
+// This function contains one parameter 'alarm_only'.
+// When 'alarm_only' is TRUE (1) the find alarm command
+// 0xEC is sent instead of the normal search command 0xF0.
+// Using the find alarm command 0xEC will limit the search to only
+// 1-Wire devices that are in an 'alarm' state.
+//
+// Returns:   TRUE (1) : when a 1-Wire device was found and its
+//                       Serial Number placed in the global ROM
+//            FALSE (0): when no new device was found.  Either the
+//                       last search was the last device or there
+//                       are no devices on the 1-Wire Net.
+//
+int16_t i16DS2482_OWSearch(struct sDS2482_t *dev)
+{
+   int id_bit_number;
+   int last_zero, rom_byte_number, search_result;
+   int id_bit, cmp_id_bit;
+   unsigned char rom_byte_mask, search_direction, status;
+    
+    
+    
+   // initialize for search
+   id_bit_number = 1;
+   last_zero = 0;
+   rom_byte_number = 0;
+   rom_byte_mask = 1;
+   search_result = 0;
+   dev->u8CRC8 = 0;
+
+   // if the last call was not the last one
+   if (!dev->i16LastDeviceFlag)
+   {
+      // 1-Wire reset
+      
+      int8_t i8Ret = i8DS2482_OWReset(dev);
+      if(i8Ret != 0)
+      {
+         // reset the search
+         dev->i16LastDiscrepancy = 0;
+         dev->i16LastDeviceFlag = 0;
+         dev->i16LastFamilyDiscrepancy = 0;
+         return i8Ret;
+      }
+
+      // issue the search command
+      
+      i8Ret = i8DS2482_OWWriteByte(dev, 0xF0);
+      if(i8Ret != 0)
+        return i8Ret;
+
+      // loop to do the search
+      
+      do
+      {
+         
+         // if this discrepancy if before the Last Discrepancy
+         // on a previous next then pick the same as last time
+         if (id_bit_number < dev->i16LastDiscrepancy)
+         {
+            if ((dev->u8RomNr[rom_byte_number] & rom_byte_mask) > 0)
+               search_direction = 1;
+            else
+               search_direction = 0;
+         }
+         else
+         {
+            // if equal to last pick 1, if not then pick 0
+            if (id_bit_number == dev->i16LastDiscrepancy)
+               search_direction = 1;
+            else
+               search_direction = 0;
+         }
+
+         // Perform a triple operation on the DS2482 which will perform
+         // 2 read bits and 1 write bit
+         status = i16DS2482_search_triplet(dev, search_direction);
+        
+         // check bit results in status byte
+         id_bit = ((status & STATUS_SBR) == STATUS_SBR);
+         cmp_id_bit = ((status & STATUS_TSB) == STATUS_TSB);
+         search_direction =
+            ((status & STATUS_DIR) == STATUS_DIR) ? 1 : 0;
+
+         // check for no devices on 1-Wire
+         if ((id_bit) && (cmp_id_bit))
+            break;
+         else
+         {
+            if ((!id_bit) && (!cmp_id_bit) && (search_direction == 0))
+            {
+               last_zero = id_bit_number;
+
+               // check for Last discrepancy in family
+               if (last_zero < 9)
+                  dev->i16LastFamilyDiscrepancy = last_zero;
+            }
+
+            // set or clear the bit in the ROM byte rom_byte_number
+            // with mask rom_byte_mask
+            if (search_direction == 1)
+               dev->u8RomNr[rom_byte_number] |= rom_byte_mask;
+            else
+               dev->u8RomNr[rom_byte_number] &= ~rom_byte_mask;
+
+            // increment the byte counter id_bit_number
+            // and shift the mask rom_byte_mask
+            id_bit_number++;
+            rom_byte_mask <<= 1;
+
+            // if the mask is 0 then go to new SerialNum byte rom_byte_number
+            // and reset mask
+            if (rom_byte_mask == 0)
+            {
+               dev->u8CRC8 += calc_crc8(&dev->u8RomNr[rom_byte_number], 1);  // accumulate the CRC               
+               rom_byte_number++;
+               rom_byte_mask = 1;
+            }
+         }
+      }
+      while(rom_byte_number < 8);  // loop until through all ROM bytes 0-7
+      
+      // do CRC check      
+      dev->u8CRC8 = calc_crc8(dev->u8RomNr, 7);
+      if(dev->u8CRC8 != dev->u8RomNr[7])
+        return -DS2482_ERR_CHECKSUM;
+        
+      
+      if(!(id_bit_number < 65 ))
+      {
+         // search successful so set LastDiscrepancy,LastDeviceFlag
+         // search_result
+         dev->i16LastDiscrepancy = last_zero;
+
+         // check for last device
+         if (dev->i16LastDiscrepancy == 0)
+            dev->i16LastDeviceFlag = 1;
+
+         search_result = 1;
+      }
+      else
+      {
+          return -DS2482_ERR_CHECKSUM;
+      }
+   }
+
+   // if no device found then reset counters so next
+   // 'search' will be like a first
+
+   if (!search_result || (dev->u8RomNr[0] == 0))
+   {
+      dev->i16LastDiscrepancy = 0;
+      dev->i16LastDeviceFlag = 0;
+      dev->i16LastFamilyDiscrepancy = 0;
+      search_result = 0;
+   }
+
+   return search_result;
+}
+
+//--------------------------------------------------------------------------
+// Use the DS2482 help command '1-Wire triplet' to perform one bit of a
+//1-Wire search.
+//This command does two read bits and one write bit. The write bit
+// is either the default direction (all device have same bit) or in case of
+// a discrepancy, the 'search_direction' parameter is used.
+//
+// Returns – The DS2482 status byte result from the triplet command
+//
+int16_t i16DS2482_search_triplet(struct sDS2482_t *dev, int search_direction)
+{
+   unsigned char status;
+   int poll_count = 0;
+
+   // 1-Wire Triplet (Case B)
+   //   S AD,0 [A] 1WT [A] SS [A] Sr AD,1 [A] [Status] A [Status] A\ P
+   //                                         \--------/
+   //                           Repeat until 1WB bit has changed to 0
+   //  [] indicates from slave
+   //  SS indicates byte containing search direction bit value in msbit
+
+   uint8_t u8Data[2];
+   u8Data[0] = OWT;
+   u8Data[1] = search_direction ? 0x80 : 0x00;
+   
+    if(_i8I2CWrite(dev->u8Addr, u8Data, 2) != 0)
+        return -DS2482_ERR_I2CWRITE;
+
+   // loop checking 1WB bit for completion of 1-Wire operation
+    // abort if poll limit reached
+    _i8I2CRead(dev->u8Addr, &status, 1, 0);
+    do
+    {
+        _i8I2CRead(dev->u8Addr, &status, 1 ,status & STATUS_1WB);
+    }
+    while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT));   
+
+    // check for failure due to poll limit reached
+    if (poll_count >= POLL_LIMIT)
+    {
+        i8DS2482Reset(dev);
+            return -DS2482_ERR_TIMEOUT;
+    }
+
+   // return status byte
+   return status;
+}
+
+uint8_t   calc_crc8 ( uint8_t *data_in, int number_of_bytes_to_read )
+{
+    char     crc;
+    int loop_count;
+    char  bit_counter;
+    char  data;
+    char  feedback_bit;
+    
+    crc = CRC8INIT;
+ 
+    for (loop_count = 0; loop_count != number_of_bytes_to_read; loop_count++)
+    {
+        data = data_in[loop_count];
+        
+        bit_counter = 8;
+        do {
+            feedback_bit = (crc ^ data) & 0x01;
+    
+            if ( feedback_bit == 0x01 ) {
+                crc = crc ^ CRC8POLY;
+            }
+            crc = (crc >> 1) & 0x7F;
+            if ( feedback_bit == 0x01 ) {
+                crc = crc | 0x80;
+            }
+        
+            data = data >> 1;
+            bit_counter--;
+        
+        } while (bit_counter > 0);
+    }
+    
+    return crc;
+}
+
+int8_t i8DS2482_OWSelectDevice(struct sDS2482_t *dev, uint8_t *u8SN)
+{
+    int8_t i8Tmp;
+    
+    // 1. reset 1Wire bus
+    i8Tmp = i8DS2482_OWReset(dev);
+    if(i8Tmp != 0)
+        return i8Tmp;
+        
+    // 2. issue command 0x55        
+    i8Tmp = i8DS2482_OWWriteByte(dev, 0x55);
+    //i8Tmp = i8DS2482_OWWriteByte(dev, 0x69);
+    if(i8Tmp != 0)
+        return i8Tmp;    
+    //i8DS2482SetControlBits(dev, APU | OWS );
+    
+    // 3. wait for 1wire transaction
+    i8Tmp = i8DS2482_OWWait(dev);
+    if(i8Tmp != 0)
+        return i8Tmp;    
+    
+    // 4. send rom code to select device
+    for(int x=0; x<8; x++)
+        i8DS2482_OWWriteByte(dev, u8SN[x]);       
+    
+    // 5. wait for 1wire transaction
+    i8Tmp = i8DS2482_OWWait(dev);
+    if(i8Tmp != 0)
+        return i8Tmp;    
+        
+    return 0;    
+}
+
+int8_t i8DS2482_OWWaitForDevice(struct sDS2482_t *dev)
+{
+    int8_t i8Tmp;
+    
+    do                                                  // wait for completion
+    {
+        i8Tmp = i8DS2482_OWReadBit(dev);
+        if(i8Tmp<0)
+            return i8Tmp;
+    } while(i8Tmp == 0);
+    
+    return 0;
+}
+
+int8_t i8DS2482_OWStartAllDS1820(struct sDS2482_t *dev, uint8_t u8WaitForCompletion)
+{
+    int8_t i8Tmp;
+    i8DS2482_OWReset(dev);        
+    
+    i8Tmp = i8DS2482_OWWriteByte(dev, 0xCC);            // skip rom
+    //i8Tmp = i8DS2482_OWWriteByte(dev, 0x3C);            // skip rom
+    if(i8Tmp) return i8Tmp;
+    //i8DS2482SetControlBits(dev, APU | OWS );
+    
+    i8Tmp = i8DS2482_OWWriteByte(dev, 0x44);            // start conversion
+    if(i8Tmp) return i8Tmp;
+    
+    if(u8WaitForCompletion)
+    {
+        i8Tmp = i8DS2482_OWWaitForDevice(dev);              // wait for device
+        if(i8Tmp) return i8Tmp;
+    }
+    
+    return 0;
+}
+
+int8_t i8DS2482_OWCheckDeviceReady(struct sDS2482_t *dev)
+{
+    
+    return i8DS2482_OWReadBit(dev);
+    
+} 
+
+int16_t i16DS2482_OWReadDS1820(struct sDS2482_t *dev, uint8_t *u8SN, uint8_t u8ManualStart)
+{
+    int8_t i8Tmp;
+    int16_t i16Tmp;
+    uint8_t u8Data[9];
+    uint8_t u8CRC8 = 0;
+    
+    if(u8ManualStart)
+    {
+        i8DS2482_OWReset(dev);        
+        
+        i8Tmp = i8DS2482_OWSelectDevice(dev, u8SN);    
+        if(i8Tmp) return i8Tmp;
+        
+        i8Tmp = i8DS2482_OWWriteByte(dev, 0x44);
+        if(i8Tmp) return i8Tmp;
+        
+        do
+        {
+            i8Tmp = i8DS2482_OWReadBit(dev);
+            if(i8Tmp<0)
+                return i8Tmp;
+        } while(i8Tmp == 0);
+    }
+    
+    i8DS2482_OWReset(dev);
+    
+    i8Tmp = i8DS2482_OWSelectDevice(dev, u8SN);    
+    if(i8Tmp) return i8Tmp;
+    
+    i8Tmp = i8DS2482_OWWriteByte(dev, 0xBE);    
+    if(i8Tmp) return i8Tmp;
+    
+    for(int x=0; x<9; x++)
+    {
+        
+        i16Tmp = i16DS2482_OWReadByte(dev);
+        
+        if(i16Tmp<0)
+            return i16Tmp;
+        else
+            u8Data[x] = i16Tmp;
+    }
+    // check CRC
+    u8CRC8 = calc_crc8(u8Data, 8);
+    if(u8CRC8 != u8Data[8])
+        return -DS2482_ERR_CHECKSUM;
+    
+    // calculate temperature
+    // check sign
+    if(u8Data[1])
+        u8Data[0] = ~u8Data[0];
+        
+    i16Tmp = u8Data[0];
+    
+    if(!u8Data[1])
+        i16Tmp+=109;
+    else
+        i16Tmp=110-i16Tmp;
+    
+    return i16Tmp;    
+}
+
+
+int8_t i8DS2482_OWReadDS1820Precise(struct sDS2482_t *dev, uint8_t *u8SN, uint8_t u8ManualStart, int16_t *i16Temperature)
+{
+    int8_t i8Tmp;
+    int16_t i16Tmp;
+    uint8_t u8Data[9];
+    uint8_t u8CRC8 = 0;
+    
+    if(u8ManualStart)
+    {
+        i8DS2482_OWReset(dev);        
+        
+        i8Tmp = i8DS2482_OWSelectDevice(dev, u8SN);    
+        if(i8Tmp) return i8Tmp;
+        
+        i8Tmp = i8DS2482_OWWriteByte(dev, 0x44);
+        if(i8Tmp) return i8Tmp;
+        
+        do
+        {
+            i8Tmp = i8DS2482_OWReadBit(dev);
+            if(i8Tmp<0)
+                return i8Tmp;
+        } while(i8Tmp == 0);
+    }
+    
+    i8DS2482_OWReset(dev);
+    
+    i8Tmp = i8DS2482_OWSelectDevice(dev, u8SN);    
+    if(i8Tmp) return i8Tmp;
+    
+    i8Tmp = i8DS2482_OWWriteByte(dev, 0xBE);    
+    if(i8Tmp) return i8Tmp;
+    
+    for(int x=0; x<9; x++)
+    {
+        
+        i16Tmp = i16DS2482_OWReadByte(dev);
+        
+        if(i16Tmp<0)
+            return i16Tmp;
+        else
+            u8Data[x] = i16Tmp;
+    }
+    // check CRC
+    u8CRC8 = calc_crc8(u8Data, 8);
+    if(u8CRC8 != u8Data[8])
+        return -DS2482_ERR_CHECKSUM;
+    
+    // calculate temperature
+    *i16Temperature = u8Data[0]&0xFE;
+    if(u8Data[1])
+    {
+        *i16Temperature = ~*i16Temperature;
+        *i16Temperature -= 1;
+    }
+    
+    *i16Temperature*=100;
+    *i16Temperature -= 250;
+    int16_t countPerC, countRemain;
+    countPerC = u8Data[7];
+    countRemain = u8Data[6];
+    
+    *i16Temperature += ((100*(countPerC-countRemain)))/countPerC;
+    
+    return 0;    
+}