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@0:39243a42bc87, 2014-07-24 (annotated)
- Committer:
- stefangun
- Date:
- Thu Jul 24 14:14:40 2014 +0000
- Revision:
- 0:39243a42bc87
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.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
stefangun | 0:39243a42bc87 | 1 | #include "ds2482.h" |
stefangun | 0:39243a42bc87 | 2 | |
stefangun | 0:39243a42bc87 | 3 | /* ================================================ |
stefangun | 0:39243a42bc87 | 4 | Reads Status Register of given DS2482 IC |
stefangun | 0:39243a42bc87 | 5 | Parameter: Pointer to DS2482 object to work on |
stefangun | 0:39243a42bc87 | 6 | Returns: register content |
stefangun | 0:39243a42bc87 | 7 | (negative value on error) |
stefangun | 0:39243a42bc87 | 8 | ------------------------------------------------ */ |
stefangun | 0:39243a42bc87 | 9 | int16_t i16DS2482GetStatus(struct sDS2482_t *dev) |
stefangun | 0:39243a42bc87 | 10 | { |
stefangun | 0:39243a42bc87 | 11 | uint8_t u8Data[2]; |
stefangun | 0:39243a42bc87 | 12 | u8Data[0] = SRP; |
stefangun | 0:39243a42bc87 | 13 | u8Data[1] = 0xF0; // Status register |
stefangun | 0:39243a42bc87 | 14 | if(_i8I2CWrite(dev->u8Addr, u8Data, 2) != 0) |
stefangun | 0:39243a42bc87 | 15 | return -1; |
stefangun | 0:39243a42bc87 | 16 | if(_i8I2CRead(dev->u8Addr, u8Data, 1, 0) != 0) |
stefangun | 0:39243a42bc87 | 17 | return -1; |
stefangun | 0:39243a42bc87 | 18 | |
stefangun | 0:39243a42bc87 | 19 | return u8Data[0]; |
stefangun | 0:39243a42bc87 | 20 | } |
stefangun | 0:39243a42bc87 | 21 | |
stefangun | 0:39243a42bc87 | 22 | /* ================================================ |
stefangun | 0:39243a42bc87 | 23 | Issues reset to given DS2482 IC |
stefangun | 0:39243a42bc87 | 24 | Parameter: 1 Pointer to DS2482 object to work on |
stefangun | 0:39243a42bc87 | 25 | Returns: zero |
stefangun | 0:39243a42bc87 | 26 | (negative value on error) |
stefangun | 0:39243a42bc87 | 27 | ------------------------------------------------ */ |
stefangun | 0:39243a42bc87 | 28 | int8_t i8DS2482Reset(struct sDS2482_t *dev) |
stefangun | 0:39243a42bc87 | 29 | { |
stefangun | 0:39243a42bc87 | 30 | uint8_t u8Data; |
stefangun | 0:39243a42bc87 | 31 | u8Data = DRST; |
stefangun | 0:39243a42bc87 | 32 | if(_i8I2CWrite(dev->u8Addr, &u8Data, 1) != 0) |
stefangun | 0:39243a42bc87 | 33 | return -DS2482_ERR_I2CWRITE; |
stefangun | 0:39243a42bc87 | 34 | |
stefangun | 0:39243a42bc87 | 35 | return 0; |
stefangun | 0:39243a42bc87 | 36 | } |
stefangun | 0:39243a42bc87 | 37 | |
stefangun | 0:39243a42bc87 | 38 | /* ================================================ |
stefangun | 0:39243a42bc87 | 39 | Writes into Config Register of given DS2482 IC |
stefangun | 0:39243a42bc87 | 40 | Parameter: 1 Pointer to DS2482 object to work on |
stefangun | 0:39243a42bc87 | 41 | 2 Byte register value |
stefangun | 0:39243a42bc87 | 42 | Returns: zero |
stefangun | 0:39243a42bc87 | 43 | (negative value on error) |
stefangun | 0:39243a42bc87 | 44 | ------------------------------------------------ */ |
stefangun | 0:39243a42bc87 | 45 | int8_t i8DS2482SetControlBits(struct sDS2482_t *dev, uint8_t u8Flags) |
stefangun | 0:39243a42bc87 | 46 | { |
stefangun | 0:39243a42bc87 | 47 | uint8_t u8Data[2]; |
stefangun | 0:39243a42bc87 | 48 | |
stefangun | 0:39243a42bc87 | 49 | u8Data[0] = WCFG; |
stefangun | 0:39243a42bc87 | 50 | u8Data[1] = (~u8Flags)<<4 | u8Flags; // active pullup |
stefangun | 0:39243a42bc87 | 51 | if(_i8I2CWrite(dev->u8Addr, u8Data, 2) != 0) |
stefangun | 0:39243a42bc87 | 52 | return -DS2482_ERR_I2CWRITE; |
stefangun | 0:39243a42bc87 | 53 | |
stefangun | 0:39243a42bc87 | 54 | |
stefangun | 0:39243a42bc87 | 55 | |
stefangun | 0:39243a42bc87 | 56 | u8Data[0] = SRP; |
stefangun | 0:39243a42bc87 | 57 | u8Data[1] = 0xC3; // Config |
stefangun | 0:39243a42bc87 | 58 | |
stefangun | 0:39243a42bc87 | 59 | if(_i8I2CWrite(dev->u8Addr, u8Data, 2) != 0) |
stefangun | 0:39243a42bc87 | 60 | return -DS2482_ERR_I2CWRITE; |
stefangun | 0:39243a42bc87 | 61 | |
stefangun | 0:39243a42bc87 | 62 | if(_i8I2CRead(dev->u8Addr, u8Data, 1, 0) != 0) |
stefangun | 0:39243a42bc87 | 63 | return -DS2482_ERR_I2CREAD; |
stefangun | 0:39243a42bc87 | 64 | |
stefangun | 0:39243a42bc87 | 65 | |
stefangun | 0:39243a42bc87 | 66 | |
stefangun | 0:39243a42bc87 | 67 | if(u8Data[0] != u8Flags) |
stefangun | 0:39243a42bc87 | 68 | return -DS2482_ERR_CONFIGMISSMATCH; |
stefangun | 0:39243a42bc87 | 69 | |
stefangun | 0:39243a42bc87 | 70 | return 0; |
stefangun | 0:39243a42bc87 | 71 | } |
stefangun | 0:39243a42bc87 | 72 | |
stefangun | 0:39243a42bc87 | 73 | /* ================================================ |
stefangun | 0:39243a42bc87 | 74 | Issue 1Wire Reset on given DS2482 IC |
stefangun | 0:39243a42bc87 | 75 | Parameter: 1 Pointer to DS2482 object to work on |
stefangun | 0:39243a42bc87 | 76 | Returns: zero if a device is present |
stefangun | 0:39243a42bc87 | 77 | (negative value on error) |
stefangun | 0:39243a42bc87 | 78 | ------------------------------------------------ */ |
stefangun | 0:39243a42bc87 | 79 | int8_t i8DS2482_OWReset(struct sDS2482_t *dev) |
stefangun | 0:39243a42bc87 | 80 | { |
stefangun | 0:39243a42bc87 | 81 | unsigned char status; |
stefangun | 0:39243a42bc87 | 82 | int poll_count = 0; |
stefangun | 0:39243a42bc87 | 83 | |
stefangun | 0:39243a42bc87 | 84 | // 1-Wire reset (Case B) |
stefangun | 0:39243a42bc87 | 85 | // S AD,0 [A] 1WRS [A] Sr AD,1 [A] [Status] A [Status] A\ P |
stefangun | 0:39243a42bc87 | 86 | // \--------/ |
stefangun | 0:39243a42bc87 | 87 | // Repeat until 1WB bit has changed to 0 |
stefangun | 0:39243a42bc87 | 88 | // [] indicates from slave |
stefangun | 0:39243a42bc87 | 89 | uint8_t u8Data[2]; |
stefangun | 0:39243a42bc87 | 90 | u8Data[0] = OWRS; |
stefangun | 0:39243a42bc87 | 91 | |
stefangun | 0:39243a42bc87 | 92 | _i8I2CWrite(dev->u8Addr, u8Data, 1); |
stefangun | 0:39243a42bc87 | 93 | |
stefangun | 0:39243a42bc87 | 94 | // loop checking 1WB bit for completion of 1-Wire operation |
stefangun | 0:39243a42bc87 | 95 | // abort if poll limit reached |
stefangun | 0:39243a42bc87 | 96 | _i8I2CRead(dev->u8Addr, &status, 1, 0); |
stefangun | 0:39243a42bc87 | 97 | do |
stefangun | 0:39243a42bc87 | 98 | { |
stefangun | 0:39243a42bc87 | 99 | _i8I2CRead(dev->u8Addr, &status, 1 ,status & STATUS_1WB); |
stefangun | 0:39243a42bc87 | 100 | } |
stefangun | 0:39243a42bc87 | 101 | while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT)); |
stefangun | 0:39243a42bc87 | 102 | |
stefangun | 0:39243a42bc87 | 103 | |
stefangun | 0:39243a42bc87 | 104 | |
stefangun | 0:39243a42bc87 | 105 | // check for failure due to poll limit reached |
stefangun | 0:39243a42bc87 | 106 | if (poll_count >= POLL_LIMIT) |
stefangun | 0:39243a42bc87 | 107 | { |
stefangun | 0:39243a42bc87 | 108 | // handle error |
stefangun | 0:39243a42bc87 | 109 | // ... |
stefangun | 0:39243a42bc87 | 110 | i8DS2482Reset(dev); |
stefangun | 0:39243a42bc87 | 111 | return -DS2482_ERR_TIMEOUT; |
stefangun | 0:39243a42bc87 | 112 | } |
stefangun | 0:39243a42bc87 | 113 | |
stefangun | 0:39243a42bc87 | 114 | // check for short condition |
stefangun | 0:39243a42bc87 | 115 | if (status & STATUS_SD) |
stefangun | 0:39243a42bc87 | 116 | dev->u32Flags &= ~FLAG_SHORT; |
stefangun | 0:39243a42bc87 | 117 | else |
stefangun | 0:39243a42bc87 | 118 | dev->u32Flags |= FLAG_SHORT; |
stefangun | 0:39243a42bc87 | 119 | |
stefangun | 0:39243a42bc87 | 120 | // check for presence detect |
stefangun | 0:39243a42bc87 | 121 | if (status & STATUS_PPD) |
stefangun | 0:39243a42bc87 | 122 | return 0; |
stefangun | 0:39243a42bc87 | 123 | else |
stefangun | 0:39243a42bc87 | 124 | return -DS2482_ERR_NOPRESENCE; |
stefangun | 0:39243a42bc87 | 125 | } |
stefangun | 0:39243a42bc87 | 126 | |
stefangun | 0:39243a42bc87 | 127 | //-------------------------------------------------------------------------- |
stefangun | 0:39243a42bc87 | 128 | // Send 1 bit of communication to the 1-Wire Net. |
stefangun | 0:39243a42bc87 | 129 | // The parameter 'sendbit' least significant bit is used. |
stefangun | 0:39243a42bc87 | 130 | // |
stefangun | 0:39243a42bc87 | 131 | // 'sendbit' - 1 bit to send (least significant byte) |
stefangun | 0:39243a42bc87 | 132 | // |
stefangun | 0:39243a42bc87 | 133 | /* ================================================ |
stefangun | 0:39243a42bc87 | 134 | Sends 1 bit to 1Wire network of given DS2482 IC |
stefangun | 0:39243a42bc87 | 135 | Parameter: 1 Pointer to DS2482 object to work on |
stefangun | 0:39243a42bc87 | 136 | 2 Information |
stefangun | 0:39243a42bc87 | 137 | Returns: zero |
stefangun | 0:39243a42bc87 | 138 | (negative value on error) |
stefangun | 0:39243a42bc87 | 139 | ------------------------------------------------ */ |
stefangun | 0:39243a42bc87 | 140 | int8_t i8DS2482_OWWriteBit(struct sDS2482_t *dev, uint8_t sendbit) |
stefangun | 0:39243a42bc87 | 141 | { |
stefangun | 0:39243a42bc87 | 142 | return i8DS2482_OWTouchBit(dev, sendbit); |
stefangun | 0:39243a42bc87 | 143 | } |
stefangun | 0:39243a42bc87 | 144 | |
stefangun | 0:39243a42bc87 | 145 | //-------------------------------------------------------------------------- |
stefangun | 0:39243a42bc87 | 146 | // Reads 1 bit of communication from the 1-Wire Net and returns the |
stefangun | 0:39243a42bc87 | 147 | // result |
stefangun | 0:39243a42bc87 | 148 | // |
stefangun | 0:39243a42bc87 | 149 | // Returns: 1 bit read from 1-Wire Net |
stefangun | 0:39243a42bc87 | 150 | // |
stefangun | 0:39243a42bc87 | 151 | /* ================================================ |
stefangun | 0:39243a42bc87 | 152 | Reads one bit from 1Wire network of given DS2482 IC |
stefangun | 0:39243a42bc87 | 153 | Parameter: 1 Pointer to DS2482 object to work on |
stefangun | 0:39243a42bc87 | 154 | Returns: Information |
stefangun | 0:39243a42bc87 | 155 | (negative value on error) |
stefangun | 0:39243a42bc87 | 156 | ------------------------------------------------ */ |
stefangun | 0:39243a42bc87 | 157 | int8_t i8DS2482_OWReadBit(struct sDS2482_t *dev) |
stefangun | 0:39243a42bc87 | 158 | { |
stefangun | 0:39243a42bc87 | 159 | return i8DS2482_OWTouchBit(dev, 0x01); |
stefangun | 0:39243a42bc87 | 160 | } |
stefangun | 0:39243a42bc87 | 161 | |
stefangun | 0:39243a42bc87 | 162 | //-------------------------------------------------------------------------- |
stefangun | 0:39243a42bc87 | 163 | // Send 1 bit of communication to the 1-Wire Net and return the |
stefangun | 0:39243a42bc87 | 164 | // result 1 bit read from the 1-Wire Net. The parameter 'sendbit' |
stefangun | 0:39243a42bc87 | 165 | // least significant bit is used and the least significant bit |
stefangun | 0:39243a42bc87 | 166 | // of the result is the return bit. |
stefangun | 0:39243a42bc87 | 167 | // |
stefangun | 0:39243a42bc87 | 168 | // 'sendbit' - the least significant bit is the bit to send |
stefangun | 0:39243a42bc87 | 169 | // |
stefangun | 0:39243a42bc87 | 170 | // Returns: 0: 0 bit read from sendbit |
stefangun | 0:39243a42bc87 | 171 | // 1: 1 bit read from sendbit |
stefangun | 0:39243a42bc87 | 172 | // |
stefangun | 0:39243a42bc87 | 173 | |
stefangun | 0:39243a42bc87 | 174 | int8_t i8DS2482_OWTouchBit(struct sDS2482_t *dev, uint8_t sendbit) |
stefangun | 0:39243a42bc87 | 175 | { |
stefangun | 0:39243a42bc87 | 176 | uint8_t status; |
stefangun | 0:39243a42bc87 | 177 | int poll_count = 0; |
stefangun | 0:39243a42bc87 | 178 | |
stefangun | 0:39243a42bc87 | 179 | // 1-Wire bit (Case B) |
stefangun | 0:39243a42bc87 | 180 | // S AD,0 [A] 1WSB [A] BB [A] Sr AD,1 [A] [Status] A [Status] A\ P |
stefangun | 0:39243a42bc87 | 181 | // \--------/ |
stefangun | 0:39243a42bc87 | 182 | // Repeat until 1WB bit has changed to 0 |
stefangun | 0:39243a42bc87 | 183 | // [] indicates from slave |
stefangun | 0:39243a42bc87 | 184 | // BB indicates byte containing bit value in msbit |
stefangun | 0:39243a42bc87 | 185 | |
stefangun | 0:39243a42bc87 | 186 | uint8_t u8Data[2]; |
stefangun | 0:39243a42bc87 | 187 | u8Data[0] = OWSB; |
stefangun | 0:39243a42bc87 | 188 | u8Data[1] = sendbit?0x80:0x00; |
stefangun | 0:39243a42bc87 | 189 | |
stefangun | 0:39243a42bc87 | 190 | if(_i8I2CWrite(dev->u8Addr, u8Data, 2) != 0) |
stefangun | 0:39243a42bc87 | 191 | return -DS2482_ERR_I2CWRITE; |
stefangun | 0:39243a42bc87 | 192 | |
stefangun | 0:39243a42bc87 | 193 | // loop checking 1WB bit for completion of 1-Wire operation |
stefangun | 0:39243a42bc87 | 194 | // abort if poll limit reached |
stefangun | 0:39243a42bc87 | 195 | _i8I2CRead(dev->u8Addr, &status, 1, 0); |
stefangun | 0:39243a42bc87 | 196 | do |
stefangun | 0:39243a42bc87 | 197 | { |
stefangun | 0:39243a42bc87 | 198 | |
stefangun | 0:39243a42bc87 | 199 | _i8I2CRead(dev->u8Addr, &status, 1, status & STATUS_1WB); |
stefangun | 0:39243a42bc87 | 200 | } |
stefangun | 0:39243a42bc87 | 201 | while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT)); |
stefangun | 0:39243a42bc87 | 202 | |
stefangun | 0:39243a42bc87 | 203 | // check for failure due to poll limit reached |
stefangun | 0:39243a42bc87 | 204 | if (poll_count >= POLL_LIMIT) |
stefangun | 0:39243a42bc87 | 205 | { |
stefangun | 0:39243a42bc87 | 206 | i8DS2482Reset(dev); |
stefangun | 0:39243a42bc87 | 207 | return -DS2482_ERR_TIMEOUT; |
stefangun | 0:39243a42bc87 | 208 | } |
stefangun | 0:39243a42bc87 | 209 | |
stefangun | 0:39243a42bc87 | 210 | // return bit state |
stefangun | 0:39243a42bc87 | 211 | if (status & STATUS_SBR) |
stefangun | 0:39243a42bc87 | 212 | return 1; |
stefangun | 0:39243a42bc87 | 213 | else |
stefangun | 0:39243a42bc87 | 214 | return 0; |
stefangun | 0:39243a42bc87 | 215 | } |
stefangun | 0:39243a42bc87 | 216 | |
stefangun | 0:39243a42bc87 | 217 | /* ================================================ |
stefangun | 0:39243a42bc87 | 218 | Sends 1 byte to 1Wire network of given DS2482 IC |
stefangun | 0:39243a42bc87 | 219 | Parameter: 1 Pointer to DS2482 object to work on |
stefangun | 0:39243a42bc87 | 220 | 2 Data |
stefangun | 0:39243a42bc87 | 221 | Returns: zero |
stefangun | 0:39243a42bc87 | 222 | (negative value on error) |
stefangun | 0:39243a42bc87 | 223 | ------------------------------------------------ */ |
stefangun | 0:39243a42bc87 | 224 | int8_t i8DS2482_OWWriteByte(struct sDS2482_t *dev, uint8_t sendbyte) |
stefangun | 0:39243a42bc87 | 225 | { |
stefangun | 0:39243a42bc87 | 226 | // 1-Wire Write Byte (Case B) |
stefangun | 0:39243a42bc87 | 227 | // S AD,0 [A] 1WWB [A] DD [A] Sr AD,1 [A] [Status] A [Status] A\ P |
stefangun | 0:39243a42bc87 | 228 | // \--------/ |
stefangun | 0:39243a42bc87 | 229 | // Repeat until 1WB bit has changed to 0 |
stefangun | 0:39243a42bc87 | 230 | // [] indicates from slave |
stefangun | 0:39243a42bc87 | 231 | // DD data to write |
stefangun | 0:39243a42bc87 | 232 | |
stefangun | 0:39243a42bc87 | 233 | uint8_t u8Data[2]; |
stefangun | 0:39243a42bc87 | 234 | u8Data[0] = OWWB; |
stefangun | 0:39243a42bc87 | 235 | u8Data[1] = sendbyte; |
stefangun | 0:39243a42bc87 | 236 | |
stefangun | 0:39243a42bc87 | 237 | if(_i8I2CWrite(dev->u8Addr, u8Data, 2) != 0) |
stefangun | 0:39243a42bc87 | 238 | return -DS2482_ERR_I2CWRITE; |
stefangun | 0:39243a42bc87 | 239 | |
stefangun | 0:39243a42bc87 | 240 | int8_t i8Tmp = i8DS2482_OWWait(dev); |
stefangun | 0:39243a42bc87 | 241 | if(i8Tmp != 0) |
stefangun | 0:39243a42bc87 | 242 | return i8Tmp; |
stefangun | 0:39243a42bc87 | 243 | |
stefangun | 0:39243a42bc87 | 244 | return 0; // all went good |
stefangun | 0:39243a42bc87 | 245 | } |
stefangun | 0:39243a42bc87 | 246 | |
stefangun | 0:39243a42bc87 | 247 | /* ================================================ |
stefangun | 0:39243a42bc87 | 248 | Reads 1 byte from 1Wire network of given DS2482 IC |
stefangun | 0:39243a42bc87 | 249 | Parameter: 1 Pointer to DS2482 object to work on |
stefangun | 0:39243a42bc87 | 250 | Returns: Read byte |
stefangun | 0:39243a42bc87 | 251 | (negative value on error) |
stefangun | 0:39243a42bc87 | 252 | ------------------------------------------------ */ |
stefangun | 0:39243a42bc87 | 253 | int16_t i16DS2482_OWReadByte(struct sDS2482_t *dev) |
stefangun | 0:39243a42bc87 | 254 | { |
stefangun | 0:39243a42bc87 | 255 | // 1-Wire Read Bytes (Case C) |
stefangun | 0:39243a42bc87 | 256 | // S AD,0 [A] 1WRB [A] Sr AD,1 [A] [Status] A [Status] A\ |
stefangun | 0:39243a42bc87 | 257 | // \--------/ |
stefangun | 0:39243a42bc87 | 258 | // Repeat until 1WB bit has changed to 0 |
stefangun | 0:39243a42bc87 | 259 | // Sr AD,0 [A] SRP [A] E1 [A] Sr AD,1 [A] DD A\ P |
stefangun | 0:39243a42bc87 | 260 | // |
stefangun | 0:39243a42bc87 | 261 | // [] indicates from slave |
stefangun | 0:39243a42bc87 | 262 | // DD data read |
stefangun | 0:39243a42bc87 | 263 | uint8_t u8Data[2]; |
stefangun | 0:39243a42bc87 | 264 | uint8_t data = 0; |
stefangun | 0:39243a42bc87 | 265 | u8Data[0] = OWRB; |
stefangun | 0:39243a42bc87 | 266 | |
stefangun | 0:39243a42bc87 | 267 | if(_i8I2CWrite(dev->u8Addr, u8Data, 1) != 0) |
stefangun | 0:39243a42bc87 | 268 | return -DS2482_ERR_I2CWRITE; |
stefangun | 0:39243a42bc87 | 269 | |
stefangun | 0:39243a42bc87 | 270 | i8DS2482_OWWait(dev); |
stefangun | 0:39243a42bc87 | 271 | |
stefangun | 0:39243a42bc87 | 272 | u8Data[0] = SRP; |
stefangun | 0:39243a42bc87 | 273 | u8Data[1] = 0xE1; |
stefangun | 0:39243a42bc87 | 274 | |
stefangun | 0:39243a42bc87 | 275 | if(_i8I2CWrite(dev->u8Addr, u8Data, 2) != 0) |
stefangun | 0:39243a42bc87 | 276 | return -DS2482_ERR_I2CWRITE; |
stefangun | 0:39243a42bc87 | 277 | |
stefangun | 0:39243a42bc87 | 278 | if(_i8I2CRead(dev->u8Addr, &data, 1, 0) != 0) |
stefangun | 0:39243a42bc87 | 279 | return -DS2482_ERR_I2CREAD; |
stefangun | 0:39243a42bc87 | 280 | |
stefangun | 0:39243a42bc87 | 281 | return data; |
stefangun | 0:39243a42bc87 | 282 | } |
stefangun | 0:39243a42bc87 | 283 | |
stefangun | 0:39243a42bc87 | 284 | /* ================================================ |
stefangun | 0:39243a42bc87 | 285 | Write-and-read block of data (byte-alligned) |
stefangun | 0:39243a42bc87 | 286 | to/from 1Wire network of given DS2482 |
stefangun | 0:39243a42bc87 | 287 | Parameter: 1 Pointer to DS2482 object to work on |
stefangun | 0:39243a42bc87 | 288 | 2 Pointer to Data Buffer |
stefangun | 0:39243a42bc87 | 289 | 3 Length (in bytes) of Data Buffer |
stefangun | 0:39243a42bc87 | 290 | Returns: zero (Data Buffer now contains read data) |
stefangun | 0:39243a42bc87 | 291 | (negative value on error) |
stefangun | 0:39243a42bc87 | 292 | ------------------------------------------------ */ |
stefangun | 0:39243a42bc87 | 293 | int8_t i8DS2482_OWBlock(struct sDS2482_t *dev, uint8_t *tran_buf, uint8_t tran_len) |
stefangun | 0:39243a42bc87 | 294 | { |
stefangun | 0:39243a42bc87 | 295 | int i; |
stefangun | 0:39243a42bc87 | 296 | int16_t i16Ret; |
stefangun | 0:39243a42bc87 | 297 | |
stefangun | 0:39243a42bc87 | 298 | for (i = 0; i < tran_len; i++) |
stefangun | 0:39243a42bc87 | 299 | { |
stefangun | 0:39243a42bc87 | 300 | |
stefangun | 0:39243a42bc87 | 301 | i16Ret = i16DS2482_OWTouchByte(dev, tran_buf[i]); |
stefangun | 0:39243a42bc87 | 302 | |
stefangun | 0:39243a42bc87 | 303 | if(i16Ret >= 0) |
stefangun | 0:39243a42bc87 | 304 | tran_buf[i] = (uint8_t)i16Ret; |
stefangun | 0:39243a42bc87 | 305 | else |
stefangun | 0:39243a42bc87 | 306 | return i16Ret; |
stefangun | 0:39243a42bc87 | 307 | } |
stefangun | 0:39243a42bc87 | 308 | return 0; |
stefangun | 0:39243a42bc87 | 309 | } |
stefangun | 0:39243a42bc87 | 310 | |
stefangun | 0:39243a42bc87 | 311 | /* ================================================ |
stefangun | 0:39243a42bc87 | 312 | Waits for 1Wire transmission ends on given DS2482 IC |
stefangun | 0:39243a42bc87 | 313 | Parameter: 1 Pointer to DS2482 object to work on |
stefangun | 0:39243a42bc87 | 314 | Returns: zero |
stefangun | 0:39243a42bc87 | 315 | (negative value on error) |
stefangun | 0:39243a42bc87 | 316 | ------------------------------------------------ */ |
stefangun | 0:39243a42bc87 | 317 | int8_t i8DS2482_OWWait(struct sDS2482_t *dev) |
stefangun | 0:39243a42bc87 | 318 | { |
stefangun | 0:39243a42bc87 | 319 | uint8_t status, poll_count; |
stefangun | 0:39243a42bc87 | 320 | poll_count = 0; |
stefangun | 0:39243a42bc87 | 321 | status = 0; |
stefangun | 0:39243a42bc87 | 322 | // loop checking 1WB bit for completion of 1-Wire operation |
stefangun | 0:39243a42bc87 | 323 | // abort if poll limit reached |
stefangun | 0:39243a42bc87 | 324 | _i8I2CRead(dev->u8Addr, &status, 1, 0); |
stefangun | 0:39243a42bc87 | 325 | do |
stefangun | 0:39243a42bc87 | 326 | { |
stefangun | 0:39243a42bc87 | 327 | _i8I2CRead(dev->u8Addr, &status, 1 ,status & STATUS_1WB); |
stefangun | 0:39243a42bc87 | 328 | } |
stefangun | 0:39243a42bc87 | 329 | while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT)); |
stefangun | 0:39243a42bc87 | 330 | |
stefangun | 0:39243a42bc87 | 331 | // check for failure due to poll limit reached |
stefangun | 0:39243a42bc87 | 332 | if (poll_count >= POLL_LIMIT) |
stefangun | 0:39243a42bc87 | 333 | { |
stefangun | 0:39243a42bc87 | 334 | i8DS2482Reset(dev); |
stefangun | 0:39243a42bc87 | 335 | return -DS2482_ERR_TIMEOUT; |
stefangun | 0:39243a42bc87 | 336 | } |
stefangun | 0:39243a42bc87 | 337 | return 0; |
stefangun | 0:39243a42bc87 | 338 | } |
stefangun | 0:39243a42bc87 | 339 | |
stefangun | 0:39243a42bc87 | 340 | /* ================================================ |
stefangun | 0:39243a42bc87 | 341 | Write-and-Reads a Byte to/from 1Wire network |
stefangun | 0:39243a42bc87 | 342 | of given DS2482 |
stefangun | 0:39243a42bc87 | 343 | Parameter: 1 Pointer to DS2482 object to work on |
stefangun | 0:39243a42bc87 | 344 | 2 Byte to send |
stefangun | 0:39243a42bc87 | 345 | Returns: Read data |
stefangun | 0:39243a42bc87 | 346 | (negative value on error) |
stefangun | 0:39243a42bc87 | 347 | ------------------------------------------------ */ |
stefangun | 0:39243a42bc87 | 348 | int16_t i16DS2482_OWTouchByte(struct sDS2482_t *dev, uint8_t sendbyte) |
stefangun | 0:39243a42bc87 | 349 | { |
stefangun | 0:39243a42bc87 | 350 | if (sendbyte == 0xFF) |
stefangun | 0:39243a42bc87 | 351 | { |
stefangun | 0:39243a42bc87 | 352 | return i16DS2482_OWReadByte(dev); |
stefangun | 0:39243a42bc87 | 353 | } |
stefangun | 0:39243a42bc87 | 354 | else |
stefangun | 0:39243a42bc87 | 355 | { |
stefangun | 0:39243a42bc87 | 356 | return i8DS2482_OWWriteByte(dev, sendbyte); |
stefangun | 0:39243a42bc87 | 357 | } |
stefangun | 0:39243a42bc87 | 358 | } |
stefangun | 0:39243a42bc87 | 359 | |
stefangun | 0:39243a42bc87 | 360 | //-------------------------------------------------------------------------- |
stefangun | 0:39243a42bc87 | 361 | // Find the 'first' devices on the 1-Wire network |
stefangun | 0:39243a42bc87 | 362 | // Return TRUE : device found, ROM number in ROM_NO buffer |
stefangun | 0:39243a42bc87 | 363 | // FALSE : no device present |
stefangun | 0:39243a42bc87 | 364 | // |
stefangun | 0:39243a42bc87 | 365 | |
stefangun | 0:39243a42bc87 | 366 | int16_t i16DS2482_OWFirst(struct sDS2482_t *dev) |
stefangun | 0:39243a42bc87 | 367 | { |
stefangun | 0:39243a42bc87 | 368 | // reset the search state |
stefangun | 0:39243a42bc87 | 369 | dev->i16LastDiscrepancy = 0; |
stefangun | 0:39243a42bc87 | 370 | dev->i16LastDeviceFlag = 0; |
stefangun | 0:39243a42bc87 | 371 | dev->i16LastFamilyDiscrepancy = 0; |
stefangun | 0:39243a42bc87 | 372 | |
stefangun | 0:39243a42bc87 | 373 | return i16DS2482_OWSearch(dev); |
stefangun | 0:39243a42bc87 | 374 | } |
stefangun | 0:39243a42bc87 | 375 | |
stefangun | 0:39243a42bc87 | 376 | //-------------------------------------------------------------------------- |
stefangun | 0:39243a42bc87 | 377 | // Find the 'next' devices on the 1-Wire network |
stefangun | 0:39243a42bc87 | 378 | // Return TRUE : device found, ROM number in ROM_NO buffer |
stefangun | 0:39243a42bc87 | 379 | // FALSE : device not found, end of search |
stefangun | 0:39243a42bc87 | 380 | // |
stefangun | 0:39243a42bc87 | 381 | int16_t i16DS2482_OWNext(struct sDS2482_t *dev) |
stefangun | 0:39243a42bc87 | 382 | { |
stefangun | 0:39243a42bc87 | 383 | // leave the search state alone |
stefangun | 0:39243a42bc87 | 384 | return i16DS2482_OWSearch(dev); |
stefangun | 0:39243a42bc87 | 385 | } |
stefangun | 0:39243a42bc87 | 386 | |
stefangun | 0:39243a42bc87 | 387 | |
stefangun | 0:39243a42bc87 | 388 | //-------------------------------------------------------------------------- |
stefangun | 0:39243a42bc87 | 389 | // The 'OWSearch' function does a general search. This function |
stefangun | 0:39243a42bc87 | 390 | // continues from the previous search state. The search state |
stefangun | 0:39243a42bc87 | 391 | // can be reset by using the 'OWFirst' function. |
stefangun | 0:39243a42bc87 | 392 | // This function contains one parameter 'alarm_only'. |
stefangun | 0:39243a42bc87 | 393 | // When 'alarm_only' is TRUE (1) the find alarm command |
stefangun | 0:39243a42bc87 | 394 | // 0xEC is sent instead of the normal search command 0xF0. |
stefangun | 0:39243a42bc87 | 395 | // Using the find alarm command 0xEC will limit the search to only |
stefangun | 0:39243a42bc87 | 396 | // 1-Wire devices that are in an 'alarm' state. |
stefangun | 0:39243a42bc87 | 397 | // |
stefangun | 0:39243a42bc87 | 398 | // Returns: TRUE (1) : when a 1-Wire device was found and its |
stefangun | 0:39243a42bc87 | 399 | // Serial Number placed in the global ROM |
stefangun | 0:39243a42bc87 | 400 | // FALSE (0): when no new device was found. Either the |
stefangun | 0:39243a42bc87 | 401 | // last search was the last device or there |
stefangun | 0:39243a42bc87 | 402 | // are no devices on the 1-Wire Net. |
stefangun | 0:39243a42bc87 | 403 | // |
stefangun | 0:39243a42bc87 | 404 | int16_t i16DS2482_OWSearch(struct sDS2482_t *dev) |
stefangun | 0:39243a42bc87 | 405 | { |
stefangun | 0:39243a42bc87 | 406 | int id_bit_number; |
stefangun | 0:39243a42bc87 | 407 | int last_zero, rom_byte_number, search_result; |
stefangun | 0:39243a42bc87 | 408 | int id_bit, cmp_id_bit; |
stefangun | 0:39243a42bc87 | 409 | unsigned char rom_byte_mask, search_direction, status; |
stefangun | 0:39243a42bc87 | 410 | |
stefangun | 0:39243a42bc87 | 411 | |
stefangun | 0:39243a42bc87 | 412 | |
stefangun | 0:39243a42bc87 | 413 | // initialize for search |
stefangun | 0:39243a42bc87 | 414 | id_bit_number = 1; |
stefangun | 0:39243a42bc87 | 415 | last_zero = 0; |
stefangun | 0:39243a42bc87 | 416 | rom_byte_number = 0; |
stefangun | 0:39243a42bc87 | 417 | rom_byte_mask = 1; |
stefangun | 0:39243a42bc87 | 418 | search_result = 0; |
stefangun | 0:39243a42bc87 | 419 | dev->u8CRC8 = 0; |
stefangun | 0:39243a42bc87 | 420 | |
stefangun | 0:39243a42bc87 | 421 | // if the last call was not the last one |
stefangun | 0:39243a42bc87 | 422 | if (!dev->i16LastDeviceFlag) |
stefangun | 0:39243a42bc87 | 423 | { |
stefangun | 0:39243a42bc87 | 424 | // 1-Wire reset |
stefangun | 0:39243a42bc87 | 425 | |
stefangun | 0:39243a42bc87 | 426 | int8_t i8Ret = i8DS2482_OWReset(dev); |
stefangun | 0:39243a42bc87 | 427 | if(i8Ret != 0) |
stefangun | 0:39243a42bc87 | 428 | { |
stefangun | 0:39243a42bc87 | 429 | // reset the search |
stefangun | 0:39243a42bc87 | 430 | dev->i16LastDiscrepancy = 0; |
stefangun | 0:39243a42bc87 | 431 | dev->i16LastDeviceFlag = 0; |
stefangun | 0:39243a42bc87 | 432 | dev->i16LastFamilyDiscrepancy = 0; |
stefangun | 0:39243a42bc87 | 433 | return i8Ret; |
stefangun | 0:39243a42bc87 | 434 | } |
stefangun | 0:39243a42bc87 | 435 | |
stefangun | 0:39243a42bc87 | 436 | // issue the search command |
stefangun | 0:39243a42bc87 | 437 | |
stefangun | 0:39243a42bc87 | 438 | i8Ret = i8DS2482_OWWriteByte(dev, 0xF0); |
stefangun | 0:39243a42bc87 | 439 | if(i8Ret != 0) |
stefangun | 0:39243a42bc87 | 440 | return i8Ret; |
stefangun | 0:39243a42bc87 | 441 | |
stefangun | 0:39243a42bc87 | 442 | // loop to do the search |
stefangun | 0:39243a42bc87 | 443 | |
stefangun | 0:39243a42bc87 | 444 | do |
stefangun | 0:39243a42bc87 | 445 | { |
stefangun | 0:39243a42bc87 | 446 | |
stefangun | 0:39243a42bc87 | 447 | // if this discrepancy if before the Last Discrepancy |
stefangun | 0:39243a42bc87 | 448 | // on a previous next then pick the same as last time |
stefangun | 0:39243a42bc87 | 449 | if (id_bit_number < dev->i16LastDiscrepancy) |
stefangun | 0:39243a42bc87 | 450 | { |
stefangun | 0:39243a42bc87 | 451 | if ((dev->u8RomNr[rom_byte_number] & rom_byte_mask) > 0) |
stefangun | 0:39243a42bc87 | 452 | search_direction = 1; |
stefangun | 0:39243a42bc87 | 453 | else |
stefangun | 0:39243a42bc87 | 454 | search_direction = 0; |
stefangun | 0:39243a42bc87 | 455 | } |
stefangun | 0:39243a42bc87 | 456 | else |
stefangun | 0:39243a42bc87 | 457 | { |
stefangun | 0:39243a42bc87 | 458 | // if equal to last pick 1, if not then pick 0 |
stefangun | 0:39243a42bc87 | 459 | if (id_bit_number == dev->i16LastDiscrepancy) |
stefangun | 0:39243a42bc87 | 460 | search_direction = 1; |
stefangun | 0:39243a42bc87 | 461 | else |
stefangun | 0:39243a42bc87 | 462 | search_direction = 0; |
stefangun | 0:39243a42bc87 | 463 | } |
stefangun | 0:39243a42bc87 | 464 | |
stefangun | 0:39243a42bc87 | 465 | // Perform a triple operation on the DS2482 which will perform |
stefangun | 0:39243a42bc87 | 466 | // 2 read bits and 1 write bit |
stefangun | 0:39243a42bc87 | 467 | status = i16DS2482_search_triplet(dev, search_direction); |
stefangun | 0:39243a42bc87 | 468 | |
stefangun | 0:39243a42bc87 | 469 | // check bit results in status byte |
stefangun | 0:39243a42bc87 | 470 | id_bit = ((status & STATUS_SBR) == STATUS_SBR); |
stefangun | 0:39243a42bc87 | 471 | cmp_id_bit = ((status & STATUS_TSB) == STATUS_TSB); |
stefangun | 0:39243a42bc87 | 472 | search_direction = |
stefangun | 0:39243a42bc87 | 473 | ((status & STATUS_DIR) == STATUS_DIR) ? 1 : 0; |
stefangun | 0:39243a42bc87 | 474 | |
stefangun | 0:39243a42bc87 | 475 | // check for no devices on 1-Wire |
stefangun | 0:39243a42bc87 | 476 | if ((id_bit) && (cmp_id_bit)) |
stefangun | 0:39243a42bc87 | 477 | break; |
stefangun | 0:39243a42bc87 | 478 | else |
stefangun | 0:39243a42bc87 | 479 | { |
stefangun | 0:39243a42bc87 | 480 | if ((!id_bit) && (!cmp_id_bit) && (search_direction == 0)) |
stefangun | 0:39243a42bc87 | 481 | { |
stefangun | 0:39243a42bc87 | 482 | last_zero = id_bit_number; |
stefangun | 0:39243a42bc87 | 483 | |
stefangun | 0:39243a42bc87 | 484 | // check for Last discrepancy in family |
stefangun | 0:39243a42bc87 | 485 | if (last_zero < 9) |
stefangun | 0:39243a42bc87 | 486 | dev->i16LastFamilyDiscrepancy = last_zero; |
stefangun | 0:39243a42bc87 | 487 | } |
stefangun | 0:39243a42bc87 | 488 | |
stefangun | 0:39243a42bc87 | 489 | // set or clear the bit in the ROM byte rom_byte_number |
stefangun | 0:39243a42bc87 | 490 | // with mask rom_byte_mask |
stefangun | 0:39243a42bc87 | 491 | if (search_direction == 1) |
stefangun | 0:39243a42bc87 | 492 | dev->u8RomNr[rom_byte_number] |= rom_byte_mask; |
stefangun | 0:39243a42bc87 | 493 | else |
stefangun | 0:39243a42bc87 | 494 | dev->u8RomNr[rom_byte_number] &= ~rom_byte_mask; |
stefangun | 0:39243a42bc87 | 495 | |
stefangun | 0:39243a42bc87 | 496 | // increment the byte counter id_bit_number |
stefangun | 0:39243a42bc87 | 497 | // and shift the mask rom_byte_mask |
stefangun | 0:39243a42bc87 | 498 | id_bit_number++; |
stefangun | 0:39243a42bc87 | 499 | rom_byte_mask <<= 1; |
stefangun | 0:39243a42bc87 | 500 | |
stefangun | 0:39243a42bc87 | 501 | // if the mask is 0 then go to new SerialNum byte rom_byte_number |
stefangun | 0:39243a42bc87 | 502 | // and reset mask |
stefangun | 0:39243a42bc87 | 503 | if (rom_byte_mask == 0) |
stefangun | 0:39243a42bc87 | 504 | { |
stefangun | 0:39243a42bc87 | 505 | dev->u8CRC8 += calc_crc8(&dev->u8RomNr[rom_byte_number], 1); // accumulate the CRC |
stefangun | 0:39243a42bc87 | 506 | rom_byte_number++; |
stefangun | 0:39243a42bc87 | 507 | rom_byte_mask = 1; |
stefangun | 0:39243a42bc87 | 508 | } |
stefangun | 0:39243a42bc87 | 509 | } |
stefangun | 0:39243a42bc87 | 510 | } |
stefangun | 0:39243a42bc87 | 511 | while(rom_byte_number < 8); // loop until through all ROM bytes 0-7 |
stefangun | 0:39243a42bc87 | 512 | |
stefangun | 0:39243a42bc87 | 513 | // do CRC check |
stefangun | 0:39243a42bc87 | 514 | dev->u8CRC8 = calc_crc8(dev->u8RomNr, 7); |
stefangun | 0:39243a42bc87 | 515 | if(dev->u8CRC8 != dev->u8RomNr[7]) |
stefangun | 0:39243a42bc87 | 516 | return -DS2482_ERR_CHECKSUM; |
stefangun | 0:39243a42bc87 | 517 | |
stefangun | 0:39243a42bc87 | 518 | |
stefangun | 0:39243a42bc87 | 519 | if(!(id_bit_number < 65 )) |
stefangun | 0:39243a42bc87 | 520 | { |
stefangun | 0:39243a42bc87 | 521 | // search successful so set LastDiscrepancy,LastDeviceFlag |
stefangun | 0:39243a42bc87 | 522 | // search_result |
stefangun | 0:39243a42bc87 | 523 | dev->i16LastDiscrepancy = last_zero; |
stefangun | 0:39243a42bc87 | 524 | |
stefangun | 0:39243a42bc87 | 525 | // check for last device |
stefangun | 0:39243a42bc87 | 526 | if (dev->i16LastDiscrepancy == 0) |
stefangun | 0:39243a42bc87 | 527 | dev->i16LastDeviceFlag = 1; |
stefangun | 0:39243a42bc87 | 528 | |
stefangun | 0:39243a42bc87 | 529 | search_result = 1; |
stefangun | 0:39243a42bc87 | 530 | } |
stefangun | 0:39243a42bc87 | 531 | else |
stefangun | 0:39243a42bc87 | 532 | { |
stefangun | 0:39243a42bc87 | 533 | return -DS2482_ERR_CHECKSUM; |
stefangun | 0:39243a42bc87 | 534 | } |
stefangun | 0:39243a42bc87 | 535 | } |
stefangun | 0:39243a42bc87 | 536 | |
stefangun | 0:39243a42bc87 | 537 | // if no device found then reset counters so next |
stefangun | 0:39243a42bc87 | 538 | // 'search' will be like a first |
stefangun | 0:39243a42bc87 | 539 | |
stefangun | 0:39243a42bc87 | 540 | if (!search_result || (dev->u8RomNr[0] == 0)) |
stefangun | 0:39243a42bc87 | 541 | { |
stefangun | 0:39243a42bc87 | 542 | dev->i16LastDiscrepancy = 0; |
stefangun | 0:39243a42bc87 | 543 | dev->i16LastDeviceFlag = 0; |
stefangun | 0:39243a42bc87 | 544 | dev->i16LastFamilyDiscrepancy = 0; |
stefangun | 0:39243a42bc87 | 545 | search_result = 0; |
stefangun | 0:39243a42bc87 | 546 | } |
stefangun | 0:39243a42bc87 | 547 | |
stefangun | 0:39243a42bc87 | 548 | return search_result; |
stefangun | 0:39243a42bc87 | 549 | } |
stefangun | 0:39243a42bc87 | 550 | |
stefangun | 0:39243a42bc87 | 551 | //-------------------------------------------------------------------------- |
stefangun | 0:39243a42bc87 | 552 | // Use the DS2482 help command '1-Wire triplet' to perform one bit of a |
stefangun | 0:39243a42bc87 | 553 | //1-Wire search. |
stefangun | 0:39243a42bc87 | 554 | //This command does two read bits and one write bit. The write bit |
stefangun | 0:39243a42bc87 | 555 | // is either the default direction (all device have same bit) or in case of |
stefangun | 0:39243a42bc87 | 556 | // a discrepancy, the 'search_direction' parameter is used. |
stefangun | 0:39243a42bc87 | 557 | // |
stefangun | 0:39243a42bc87 | 558 | // Returns – The DS2482 status byte result from the triplet command |
stefangun | 0:39243a42bc87 | 559 | // |
stefangun | 0:39243a42bc87 | 560 | int16_t i16DS2482_search_triplet(struct sDS2482_t *dev, int search_direction) |
stefangun | 0:39243a42bc87 | 561 | { |
stefangun | 0:39243a42bc87 | 562 | unsigned char status; |
stefangun | 0:39243a42bc87 | 563 | int poll_count = 0; |
stefangun | 0:39243a42bc87 | 564 | |
stefangun | 0:39243a42bc87 | 565 | // 1-Wire Triplet (Case B) |
stefangun | 0:39243a42bc87 | 566 | // S AD,0 [A] 1WT [A] SS [A] Sr AD,1 [A] [Status] A [Status] A\ P |
stefangun | 0:39243a42bc87 | 567 | // \--------/ |
stefangun | 0:39243a42bc87 | 568 | // Repeat until 1WB bit has changed to 0 |
stefangun | 0:39243a42bc87 | 569 | // [] indicates from slave |
stefangun | 0:39243a42bc87 | 570 | // SS indicates byte containing search direction bit value in msbit |
stefangun | 0:39243a42bc87 | 571 | |
stefangun | 0:39243a42bc87 | 572 | uint8_t u8Data[2]; |
stefangun | 0:39243a42bc87 | 573 | u8Data[0] = OWT; |
stefangun | 0:39243a42bc87 | 574 | u8Data[1] = search_direction ? 0x80 : 0x00; |
stefangun | 0:39243a42bc87 | 575 | |
stefangun | 0:39243a42bc87 | 576 | if(_i8I2CWrite(dev->u8Addr, u8Data, 2) != 0) |
stefangun | 0:39243a42bc87 | 577 | return -DS2482_ERR_I2CWRITE; |
stefangun | 0:39243a42bc87 | 578 | |
stefangun | 0:39243a42bc87 | 579 | // loop checking 1WB bit for completion of 1-Wire operation |
stefangun | 0:39243a42bc87 | 580 | // abort if poll limit reached |
stefangun | 0:39243a42bc87 | 581 | _i8I2CRead(dev->u8Addr, &status, 1, 0); |
stefangun | 0:39243a42bc87 | 582 | do |
stefangun | 0:39243a42bc87 | 583 | { |
stefangun | 0:39243a42bc87 | 584 | _i8I2CRead(dev->u8Addr, &status, 1 ,status & STATUS_1WB); |
stefangun | 0:39243a42bc87 | 585 | } |
stefangun | 0:39243a42bc87 | 586 | while ((status & STATUS_1WB) && (poll_count++ < POLL_LIMIT)); |
stefangun | 0:39243a42bc87 | 587 | |
stefangun | 0:39243a42bc87 | 588 | // check for failure due to poll limit reached |
stefangun | 0:39243a42bc87 | 589 | if (poll_count >= POLL_LIMIT) |
stefangun | 0:39243a42bc87 | 590 | { |
stefangun | 0:39243a42bc87 | 591 | i8DS2482Reset(dev); |
stefangun | 0:39243a42bc87 | 592 | return -DS2482_ERR_TIMEOUT; |
stefangun | 0:39243a42bc87 | 593 | } |
stefangun | 0:39243a42bc87 | 594 | |
stefangun | 0:39243a42bc87 | 595 | // return status byte |
stefangun | 0:39243a42bc87 | 596 | return status; |
stefangun | 0:39243a42bc87 | 597 | } |
stefangun | 0:39243a42bc87 | 598 | |
stefangun | 0:39243a42bc87 | 599 | uint8_t calc_crc8 ( uint8_t *data_in, int number_of_bytes_to_read ) |
stefangun | 0:39243a42bc87 | 600 | { |
stefangun | 0:39243a42bc87 | 601 | char crc; |
stefangun | 0:39243a42bc87 | 602 | int loop_count; |
stefangun | 0:39243a42bc87 | 603 | char bit_counter; |
stefangun | 0:39243a42bc87 | 604 | char data; |
stefangun | 0:39243a42bc87 | 605 | char feedback_bit; |
stefangun | 0:39243a42bc87 | 606 | |
stefangun | 0:39243a42bc87 | 607 | crc = CRC8INIT; |
stefangun | 0:39243a42bc87 | 608 | |
stefangun | 0:39243a42bc87 | 609 | for (loop_count = 0; loop_count != number_of_bytes_to_read; loop_count++) |
stefangun | 0:39243a42bc87 | 610 | { |
stefangun | 0:39243a42bc87 | 611 | data = data_in[loop_count]; |
stefangun | 0:39243a42bc87 | 612 | |
stefangun | 0:39243a42bc87 | 613 | bit_counter = 8; |
stefangun | 0:39243a42bc87 | 614 | do { |
stefangun | 0:39243a42bc87 | 615 | feedback_bit = (crc ^ data) & 0x01; |
stefangun | 0:39243a42bc87 | 616 | |
stefangun | 0:39243a42bc87 | 617 | if ( feedback_bit == 0x01 ) { |
stefangun | 0:39243a42bc87 | 618 | crc = crc ^ CRC8POLY; |
stefangun | 0:39243a42bc87 | 619 | } |
stefangun | 0:39243a42bc87 | 620 | crc = (crc >> 1) & 0x7F; |
stefangun | 0:39243a42bc87 | 621 | if ( feedback_bit == 0x01 ) { |
stefangun | 0:39243a42bc87 | 622 | crc = crc | 0x80; |
stefangun | 0:39243a42bc87 | 623 | } |
stefangun | 0:39243a42bc87 | 624 | |
stefangun | 0:39243a42bc87 | 625 | data = data >> 1; |
stefangun | 0:39243a42bc87 | 626 | bit_counter--; |
stefangun | 0:39243a42bc87 | 627 | |
stefangun | 0:39243a42bc87 | 628 | } while (bit_counter > 0); |
stefangun | 0:39243a42bc87 | 629 | } |
stefangun | 0:39243a42bc87 | 630 | |
stefangun | 0:39243a42bc87 | 631 | return crc; |
stefangun | 0:39243a42bc87 | 632 | } |
stefangun | 0:39243a42bc87 | 633 | |
stefangun | 0:39243a42bc87 | 634 | int8_t i8DS2482_OWSelectDevice(struct sDS2482_t *dev, uint8_t *u8SN) |
stefangun | 0:39243a42bc87 | 635 | { |
stefangun | 0:39243a42bc87 | 636 | int8_t i8Tmp; |
stefangun | 0:39243a42bc87 | 637 | |
stefangun | 0:39243a42bc87 | 638 | // 1. reset 1Wire bus |
stefangun | 0:39243a42bc87 | 639 | i8Tmp = i8DS2482_OWReset(dev); |
stefangun | 0:39243a42bc87 | 640 | if(i8Tmp != 0) |
stefangun | 0:39243a42bc87 | 641 | return i8Tmp; |
stefangun | 0:39243a42bc87 | 642 | |
stefangun | 0:39243a42bc87 | 643 | // 2. issue command 0x55 |
stefangun | 0:39243a42bc87 | 644 | i8Tmp = i8DS2482_OWWriteByte(dev, 0x55); |
stefangun | 0:39243a42bc87 | 645 | //i8Tmp = i8DS2482_OWWriteByte(dev, 0x69); |
stefangun | 0:39243a42bc87 | 646 | if(i8Tmp != 0) |
stefangun | 0:39243a42bc87 | 647 | return i8Tmp; |
stefangun | 0:39243a42bc87 | 648 | //i8DS2482SetControlBits(dev, APU | OWS ); |
stefangun | 0:39243a42bc87 | 649 | |
stefangun | 0:39243a42bc87 | 650 | // 3. wait for 1wire transaction |
stefangun | 0:39243a42bc87 | 651 | i8Tmp = i8DS2482_OWWait(dev); |
stefangun | 0:39243a42bc87 | 652 | if(i8Tmp != 0) |
stefangun | 0:39243a42bc87 | 653 | return i8Tmp; |
stefangun | 0:39243a42bc87 | 654 | |
stefangun | 0:39243a42bc87 | 655 | // 4. send rom code to select device |
stefangun | 0:39243a42bc87 | 656 | for(int x=0; x<8; x++) |
stefangun | 0:39243a42bc87 | 657 | i8DS2482_OWWriteByte(dev, u8SN[x]); |
stefangun | 0:39243a42bc87 | 658 | |
stefangun | 0:39243a42bc87 | 659 | // 5. wait for 1wire transaction |
stefangun | 0:39243a42bc87 | 660 | i8Tmp = i8DS2482_OWWait(dev); |
stefangun | 0:39243a42bc87 | 661 | if(i8Tmp != 0) |
stefangun | 0:39243a42bc87 | 662 | return i8Tmp; |
stefangun | 0:39243a42bc87 | 663 | |
stefangun | 0:39243a42bc87 | 664 | return 0; |
stefangun | 0:39243a42bc87 | 665 | } |
stefangun | 0:39243a42bc87 | 666 | |
stefangun | 0:39243a42bc87 | 667 | int8_t i8DS2482_OWWaitForDevice(struct sDS2482_t *dev) |
stefangun | 0:39243a42bc87 | 668 | { |
stefangun | 0:39243a42bc87 | 669 | int8_t i8Tmp; |
stefangun | 0:39243a42bc87 | 670 | |
stefangun | 0:39243a42bc87 | 671 | do // wait for completion |
stefangun | 0:39243a42bc87 | 672 | { |
stefangun | 0:39243a42bc87 | 673 | i8Tmp = i8DS2482_OWReadBit(dev); |
stefangun | 0:39243a42bc87 | 674 | if(i8Tmp<0) |
stefangun | 0:39243a42bc87 | 675 | return i8Tmp; |
stefangun | 0:39243a42bc87 | 676 | } while(i8Tmp == 0); |
stefangun | 0:39243a42bc87 | 677 | |
stefangun | 0:39243a42bc87 | 678 | return 0; |
stefangun | 0:39243a42bc87 | 679 | } |
stefangun | 0:39243a42bc87 | 680 | |
stefangun | 0:39243a42bc87 | 681 | int8_t i8DS2482_OWStartAllDS1820(struct sDS2482_t *dev, uint8_t u8WaitForCompletion) |
stefangun | 0:39243a42bc87 | 682 | { |
stefangun | 0:39243a42bc87 | 683 | int8_t i8Tmp; |
stefangun | 0:39243a42bc87 | 684 | i8DS2482_OWReset(dev); |
stefangun | 0:39243a42bc87 | 685 | |
stefangun | 0:39243a42bc87 | 686 | i8Tmp = i8DS2482_OWWriteByte(dev, 0xCC); // skip rom |
stefangun | 0:39243a42bc87 | 687 | //i8Tmp = i8DS2482_OWWriteByte(dev, 0x3C); // skip rom |
stefangun | 0:39243a42bc87 | 688 | if(i8Tmp) return i8Tmp; |
stefangun | 0:39243a42bc87 | 689 | //i8DS2482SetControlBits(dev, APU | OWS ); |
stefangun | 0:39243a42bc87 | 690 | |
stefangun | 0:39243a42bc87 | 691 | i8Tmp = i8DS2482_OWWriteByte(dev, 0x44); // start conversion |
stefangun | 0:39243a42bc87 | 692 | if(i8Tmp) return i8Tmp; |
stefangun | 0:39243a42bc87 | 693 | |
stefangun | 0:39243a42bc87 | 694 | if(u8WaitForCompletion) |
stefangun | 0:39243a42bc87 | 695 | { |
stefangun | 0:39243a42bc87 | 696 | i8Tmp = i8DS2482_OWWaitForDevice(dev); // wait for device |
stefangun | 0:39243a42bc87 | 697 | if(i8Tmp) return i8Tmp; |
stefangun | 0:39243a42bc87 | 698 | } |
stefangun | 0:39243a42bc87 | 699 | |
stefangun | 0:39243a42bc87 | 700 | return 0; |
stefangun | 0:39243a42bc87 | 701 | } |
stefangun | 0:39243a42bc87 | 702 | |
stefangun | 0:39243a42bc87 | 703 | int8_t i8DS2482_OWCheckDeviceReady(struct sDS2482_t *dev) |
stefangun | 0:39243a42bc87 | 704 | { |
stefangun | 0:39243a42bc87 | 705 | |
stefangun | 0:39243a42bc87 | 706 | return i8DS2482_OWReadBit(dev); |
stefangun | 0:39243a42bc87 | 707 | |
stefangun | 0:39243a42bc87 | 708 | } |
stefangun | 0:39243a42bc87 | 709 | |
stefangun | 0:39243a42bc87 | 710 | int16_t i16DS2482_OWReadDS1820(struct sDS2482_t *dev, uint8_t *u8SN, uint8_t u8ManualStart) |
stefangun | 0:39243a42bc87 | 711 | { |
stefangun | 0:39243a42bc87 | 712 | int8_t i8Tmp; |
stefangun | 0:39243a42bc87 | 713 | int16_t i16Tmp; |
stefangun | 0:39243a42bc87 | 714 | uint8_t u8Data[9]; |
stefangun | 0:39243a42bc87 | 715 | uint8_t u8CRC8 = 0; |
stefangun | 0:39243a42bc87 | 716 | |
stefangun | 0:39243a42bc87 | 717 | if(u8ManualStart) |
stefangun | 0:39243a42bc87 | 718 | { |
stefangun | 0:39243a42bc87 | 719 | i8DS2482_OWReset(dev); |
stefangun | 0:39243a42bc87 | 720 | |
stefangun | 0:39243a42bc87 | 721 | i8Tmp = i8DS2482_OWSelectDevice(dev, u8SN); |
stefangun | 0:39243a42bc87 | 722 | if(i8Tmp) return i8Tmp; |
stefangun | 0:39243a42bc87 | 723 | |
stefangun | 0:39243a42bc87 | 724 | i8Tmp = i8DS2482_OWWriteByte(dev, 0x44); |
stefangun | 0:39243a42bc87 | 725 | if(i8Tmp) return i8Tmp; |
stefangun | 0:39243a42bc87 | 726 | |
stefangun | 0:39243a42bc87 | 727 | do |
stefangun | 0:39243a42bc87 | 728 | { |
stefangun | 0:39243a42bc87 | 729 | i8Tmp = i8DS2482_OWReadBit(dev); |
stefangun | 0:39243a42bc87 | 730 | if(i8Tmp<0) |
stefangun | 0:39243a42bc87 | 731 | return i8Tmp; |
stefangun | 0:39243a42bc87 | 732 | } while(i8Tmp == 0); |
stefangun | 0:39243a42bc87 | 733 | } |
stefangun | 0:39243a42bc87 | 734 | |
stefangun | 0:39243a42bc87 | 735 | i8DS2482_OWReset(dev); |
stefangun | 0:39243a42bc87 | 736 | |
stefangun | 0:39243a42bc87 | 737 | i8Tmp = i8DS2482_OWSelectDevice(dev, u8SN); |
stefangun | 0:39243a42bc87 | 738 | if(i8Tmp) return i8Tmp; |
stefangun | 0:39243a42bc87 | 739 | |
stefangun | 0:39243a42bc87 | 740 | i8Tmp = i8DS2482_OWWriteByte(dev, 0xBE); |
stefangun | 0:39243a42bc87 | 741 | if(i8Tmp) return i8Tmp; |
stefangun | 0:39243a42bc87 | 742 | |
stefangun | 0:39243a42bc87 | 743 | for(int x=0; x<9; x++) |
stefangun | 0:39243a42bc87 | 744 | { |
stefangun | 0:39243a42bc87 | 745 | |
stefangun | 0:39243a42bc87 | 746 | i16Tmp = i16DS2482_OWReadByte(dev); |
stefangun | 0:39243a42bc87 | 747 | |
stefangun | 0:39243a42bc87 | 748 | if(i16Tmp<0) |
stefangun | 0:39243a42bc87 | 749 | return i16Tmp; |
stefangun | 0:39243a42bc87 | 750 | else |
stefangun | 0:39243a42bc87 | 751 | u8Data[x] = i16Tmp; |
stefangun | 0:39243a42bc87 | 752 | } |
stefangun | 0:39243a42bc87 | 753 | // check CRC |
stefangun | 0:39243a42bc87 | 754 | u8CRC8 = calc_crc8(u8Data, 8); |
stefangun | 0:39243a42bc87 | 755 | if(u8CRC8 != u8Data[8]) |
stefangun | 0:39243a42bc87 | 756 | return -DS2482_ERR_CHECKSUM; |
stefangun | 0:39243a42bc87 | 757 | |
stefangun | 0:39243a42bc87 | 758 | // calculate temperature |
stefangun | 0:39243a42bc87 | 759 | // check sign |
stefangun | 0:39243a42bc87 | 760 | if(u8Data[1]) |
stefangun | 0:39243a42bc87 | 761 | u8Data[0] = ~u8Data[0]; |
stefangun | 0:39243a42bc87 | 762 | |
stefangun | 0:39243a42bc87 | 763 | i16Tmp = u8Data[0]; |
stefangun | 0:39243a42bc87 | 764 | |
stefangun | 0:39243a42bc87 | 765 | if(!u8Data[1]) |
stefangun | 0:39243a42bc87 | 766 | i16Tmp+=109; |
stefangun | 0:39243a42bc87 | 767 | else |
stefangun | 0:39243a42bc87 | 768 | i16Tmp=110-i16Tmp; |
stefangun | 0:39243a42bc87 | 769 | |
stefangun | 0:39243a42bc87 | 770 | return i16Tmp; |
stefangun | 0:39243a42bc87 | 771 | } |
stefangun | 0:39243a42bc87 | 772 | |
stefangun | 0:39243a42bc87 | 773 | |
stefangun | 0:39243a42bc87 | 774 | int8_t i8DS2482_OWReadDS1820Precise(struct sDS2482_t *dev, uint8_t *u8SN, uint8_t u8ManualStart, int16_t *i16Temperature) |
stefangun | 0:39243a42bc87 | 775 | { |
stefangun | 0:39243a42bc87 | 776 | int8_t i8Tmp; |
stefangun | 0:39243a42bc87 | 777 | int16_t i16Tmp; |
stefangun | 0:39243a42bc87 | 778 | uint8_t u8Data[9]; |
stefangun | 0:39243a42bc87 | 779 | uint8_t u8CRC8 = 0; |
stefangun | 0:39243a42bc87 | 780 | |
stefangun | 0:39243a42bc87 | 781 | if(u8ManualStart) |
stefangun | 0:39243a42bc87 | 782 | { |
stefangun | 0:39243a42bc87 | 783 | i8DS2482_OWReset(dev); |
stefangun | 0:39243a42bc87 | 784 | |
stefangun | 0:39243a42bc87 | 785 | i8Tmp = i8DS2482_OWSelectDevice(dev, u8SN); |
stefangun | 0:39243a42bc87 | 786 | if(i8Tmp) return i8Tmp; |
stefangun | 0:39243a42bc87 | 787 | |
stefangun | 0:39243a42bc87 | 788 | i8Tmp = i8DS2482_OWWriteByte(dev, 0x44); |
stefangun | 0:39243a42bc87 | 789 | if(i8Tmp) return i8Tmp; |
stefangun | 0:39243a42bc87 | 790 | |
stefangun | 0:39243a42bc87 | 791 | do |
stefangun | 0:39243a42bc87 | 792 | { |
stefangun | 0:39243a42bc87 | 793 | i8Tmp = i8DS2482_OWReadBit(dev); |
stefangun | 0:39243a42bc87 | 794 | if(i8Tmp<0) |
stefangun | 0:39243a42bc87 | 795 | return i8Tmp; |
stefangun | 0:39243a42bc87 | 796 | } while(i8Tmp == 0); |
stefangun | 0:39243a42bc87 | 797 | } |
stefangun | 0:39243a42bc87 | 798 | |
stefangun | 0:39243a42bc87 | 799 | i8DS2482_OWReset(dev); |
stefangun | 0:39243a42bc87 | 800 | |
stefangun | 0:39243a42bc87 | 801 | i8Tmp = i8DS2482_OWSelectDevice(dev, u8SN); |
stefangun | 0:39243a42bc87 | 802 | if(i8Tmp) return i8Tmp; |
stefangun | 0:39243a42bc87 | 803 | |
stefangun | 0:39243a42bc87 | 804 | i8Tmp = i8DS2482_OWWriteByte(dev, 0xBE); |
stefangun | 0:39243a42bc87 | 805 | if(i8Tmp) return i8Tmp; |
stefangun | 0:39243a42bc87 | 806 | |
stefangun | 0:39243a42bc87 | 807 | for(int x=0; x<9; x++) |
stefangun | 0:39243a42bc87 | 808 | { |
stefangun | 0:39243a42bc87 | 809 | |
stefangun | 0:39243a42bc87 | 810 | i16Tmp = i16DS2482_OWReadByte(dev); |
stefangun | 0:39243a42bc87 | 811 | |
stefangun | 0:39243a42bc87 | 812 | if(i16Tmp<0) |
stefangun | 0:39243a42bc87 | 813 | return i16Tmp; |
stefangun | 0:39243a42bc87 | 814 | else |
stefangun | 0:39243a42bc87 | 815 | u8Data[x] = i16Tmp; |
stefangun | 0:39243a42bc87 | 816 | } |
stefangun | 0:39243a42bc87 | 817 | // check CRC |
stefangun | 0:39243a42bc87 | 818 | u8CRC8 = calc_crc8(u8Data, 8); |
stefangun | 0:39243a42bc87 | 819 | if(u8CRC8 != u8Data[8]) |
stefangun | 0:39243a42bc87 | 820 | return -DS2482_ERR_CHECKSUM; |
stefangun | 0:39243a42bc87 | 821 | |
stefangun | 0:39243a42bc87 | 822 | // calculate temperature |
stefangun | 0:39243a42bc87 | 823 | *i16Temperature = u8Data[0]&0xFE; |
stefangun | 0:39243a42bc87 | 824 | if(u8Data[1]) |
stefangun | 0:39243a42bc87 | 825 | { |
stefangun | 0:39243a42bc87 | 826 | *i16Temperature = ~*i16Temperature; |
stefangun | 0:39243a42bc87 | 827 | *i16Temperature -= 1; |
stefangun | 0:39243a42bc87 | 828 | } |
stefangun | 0:39243a42bc87 | 829 | |
stefangun | 0:39243a42bc87 | 830 | *i16Temperature*=100; |
stefangun | 0:39243a42bc87 | 831 | *i16Temperature -= 250; |
stefangun | 0:39243a42bc87 | 832 | int16_t countPerC, countRemain; |
stefangun | 0:39243a42bc87 | 833 | countPerC = u8Data[7]; |
stefangun | 0:39243a42bc87 | 834 | countRemain = u8Data[6]; |
stefangun | 0:39243a42bc87 | 835 | |
stefangun | 0:39243a42bc87 | 836 | *i16Temperature += ((100*(countPerC-countRemain)))/countPerC; |
stefangun | 0:39243a42bc87 | 837 | |
stefangun | 0:39243a42bc87 | 838 | return 0; |
stefangun | 0:39243a42bc87 | 839 | } |