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
--- /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;
+}
--- /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
+
--- /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();
+}
+
--- /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);
--- /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);
+}
--- /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);