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, committed 2014-07-24
- Comitter:
- stefangun
- Date:
- Thu Jul 24 14:14:40 2014 +0000
- Commit message:
- Driver for Maxim DS2482 1Wire-to-I2C bridge IC.; Includes interface functions for DS1820 temperature sensors.; Offers HAL (Hardware Abstraction Layer) for easy porting to other hardware environment.
Changed in this revision
diff -r 000000000000 -r 39243a42bc87 ds2482.cpp --- /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; +}
diff -r 000000000000 -r 39243a42bc87 ds2482.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ds2482.h Thu Jul 24 14:14:40 2014 +0000 @@ -0,0 +1,209 @@ +#include "i2c_api.h" +#include "wait_api.h" + +/* Driver Object Definition */ +struct sDS2482_t +{ + uint32_t u32Flags; + uint8_t u8Addr; + + uint8_t u8RomNr[8]; + int16_t i16LastDiscrepancy; + int16_t i16LastFamilyDiscrepancy; + int16_t i16LastDeviceFlag; + uint8_t u8CRC8; +} ; + +/* DS2482 Low-Level-Interface */ +int8_t i8DS2482Reset (struct sDS2482_t *dev); +int16_t i16DS2482GetStatus (struct sDS2482_t *dev); +int8_t i8DS2482SetControlBits (struct sDS2482_t *dev, uint8_t u8Flags); +// TODO: extract basic write/read function from higher-level functions below + +/* 1Wire Interface Functions */ +int8_t i8DS2482_OWWait (struct sDS2482_t *dev); +int8_t i8DS2482_OWReset (struct sDS2482_t *dev); +int8_t i8DS2482_OWTouchBit (struct sDS2482_t *dev, uint8_t sendbit); +int8_t i8DS2482_OWReadBit (struct sDS2482_t *dev); +int8_t i8DS2482_OWWriteBit (struct sDS2482_t *dev, uint8_t sendbit); +int8_t i8DS2482_OWWriteByte (struct sDS2482_t *dev, uint8_t sendbyte); +int16_t i16DS2482_OWReadByte (struct sDS2482_t *dev); +int8_t i8DS2482_OWBlock (struct sDS2482_t *dev, uint8_t *tran_buf, uint8_t tran_len); +int16_t i16DS2482_OWTouchByte (struct sDS2482_t *dev, uint8_t sendbyte); +int16_t i16DS2482_OWFirst (struct sDS2482_t *dev); +int16_t i16DS2482_OWNext (struct sDS2482_t *dev); +int16_t i16DS2482_OWSearch (struct sDS2482_t *dev); +int16_t i16DS2482_search_triplet (struct sDS2482_t *dev, int search_direction); +int8_t i8DS2482_OWSelectDevice (struct sDS2482_t *dev, uint8_t *u8SN); +int8_t i8DS2482_OWCheckDeviceReady (struct sDS2482_t *dev); + +/* DS1820-Specific High-Level-Functions */ +int8_t i8DS2482_OWStartAllDS1820 (struct sDS2482_t *dev, uint8_t u8WaitForCompletion); +int16_t i16DS2482_OWReadDS1820 (struct sDS2482_t *dev, uint8_t *u8SN, uint8_t u8ManualStart); +int8_t i8DS2482_OWReadDS1820Precise(struct sDS2482_t *dev, uint8_t *u8SN, uint8_t u8ManualStart, int16_t *i16Temperature); + +/* Helper Function */ +uint8_t calc_crc8 (uint8_t *data_in, int number_of_bytes_to_read); + +/* =============== USAGE EXAMPLE =============== +#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"); + } + } +} +*/ + +/* HW Setup */ +#define DS2482_ADDR1 0x30 +#define DS2482_ADDR2 0x32 + +#define POLL_LIMIT 50 + +#define ACK 1 +#define NAK 0 + +/* DS2482 Status Register Bit Definitions */ +#define STATUS_1WB (1<<0) +#define STATUS_PPD (1<<1) +#define STATUS_SD (1<<2) +#define STATUS_LL (1<<3) +#define STATUS_RST (1<<4) +#define STATUS_SBR (1<<5) +#define STATUS_TSB (1<<6) +#define STATUS_DIR (1<<7) + +/* DS2482 Config Register Definitions */ +#define APU 0x1 // active pullup +#define SPU 0x4 // strong pullup +#define OWS 0x8 // 1wire speed + +/* Flag Definition */ +#define FLAG_SHORT 0x00000001 + +/* Error Codes */ +#define DS2482_ERR_NOPRESENCE 2 +#define DS2482_ERR_TIMEOUT 3 +#define DS2482_ERR_I2CWRITE 4 +#define DS2482_ERR_I2CREAD 5 +#define DS2482_ERR_CONFIGMISSMATCH 6 +#define DS2482_ERR_CHECKSUM 7 + +/* DS2482 Commands */ +#define DRST 0xF0 +#define SRP 0xE1 +#define WCFG 0xD2 +#define OWRS 0xB4 +#define OWSB 0x87 +#define OWWB 0xA5 +#define OWRB 0x96 +#define OWT 0x78 + +/* 1Wire CRC Definitions */ +#define CRC8INIT 0x00 +#define CRC8POLY 0x18 +
diff -r 000000000000 -r 39243a42bc87 i2c_api.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/i2c_api.cpp Thu Jul 24 14:14:40 2014 +0000 @@ -0,0 +1,44 @@ +/* ============== Platform-specific API ===================*/ +/* ( HAL - Hardware Abstraction Layer Implementation ) */ +/* These functions have to be implemented in actual system */ + +#include "i2c_api.h" + +I2C *mbed_i2c; + +// returns 0 on ACK +int8_t _i8I2CWrite(uint8_t u8Cmd, uint8_t *u8Data, uint8_t u8Size) +{ + return mbed_i2c->write(u8Cmd, (const char*) u8Data, u8Size); +} + +// returns 0 on ACK +int8_t _i8I2CWriteByte(uint8_t u8Data) +{ + return !mbed_i2c->write(u8Data); // this sucker returns 1 on ACK so invert it +} + +// return 0 on ACK +// NAK ("stop") last byte if u8Repeated == 0 +int8_t _i8I2CRead (uint8_t u8Cmd, uint8_t *u8Data, uint8_t u8Size, uint8_t u8Repeated) +{ + return mbed_i2c->read(u8Cmd, (char*)u8Data, u8Size, u8Repeated); +} + +// returns read data +// sends acknowledge if u8Ack == 1 +int8_t _i8I2CReadByte (uint8_t u8Ack) +{ + return mbed_i2c->read(u8Ack); +} + +void _vI2CStart (void) +{ + mbed_i2c->start(); +} + +void _vI2CStop (void) +{ + mbed_i2c->stop(); +} +
diff -r 000000000000 -r 39243a42bc87 i2c_api.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/i2c_api.h Thu Jul 24 14:14:40 2014 +0000 @@ -0,0 +1,10 @@ +/* Hardware API (HAL) For I2C Peripheral Access */ +#include "mbed.h" // peripheral access library +extern I2C *mbed_i2c; // global i2c peripheral object + +int8_t _i8I2CWrite (uint8_t u8Cmd, uint8_t *u8Data, uint8_t u8Size); +int8_t _i8I2CWriteByte (uint8_t u8Cmd); +int8_t _i8I2CRead (uint8_t u8Cmd, uint8_t *u8Data, uint8_t u8Size, uint8_t u8Ack); +int8_t _i8I2CReadByte (uint8_t u8Ack); +void _vI2CStart (void); +void _vI2CStop (void);
diff -r 000000000000 -r 39243a42bc87 wait_api.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wait_api.cpp Thu Jul 24 14:14:40 2014 +0000 @@ -0,0 +1,6 @@ +#include "wait_api.h" + +void _vWait_ms(uint32_t u32MS) +{ + wait_us(1000*u32MS); +}
diff -r 000000000000 -r 39243a42bc87 wait_api.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/wait_api.h Thu Jul 24 14:14:40 2014 +0000 @@ -0,0 +1,4 @@ +/* Hardware API For Wait Function */ +#include "mbed.h" // peripheral access library + +void _vWait_ms (uint32_t u32MS);