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"); } } }
Diff: ds2482.cpp
- 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; +}