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");
        }                                        
    }
}

ds2482.cpp

Committer:
stefangun
Date:
2014-07-24
Revision:
0:39243a42bc87

File content as of revision 0:39243a42bc87:

#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;    
}