| Line No. | Rev | Author | Line |
|---|---|---|---|
| 1 | 6 | kaklik | //***************************************************************************** |
| 2 | // File Name : dallas.c |
||
| 3 | // Title : Dallas 1-Wire Library |
||
| 4 | // Revision : 6 |
||
| 5 | // Notes : |
||
| 6 | // Target MCU : Atmel AVR series |
||
| 7 | // Editor Tabs : 4 |
||
| 8 | // |
||
| 9 | //***************************************************************************** |
||
| 10 | |||
| 11 | //----- Include Files --------------------------------------------------------- |
||
| 12 | #include <avr/io.h> // include I/O definitions (port names, pin names, etc) |
||
| 13 | #include <avr/interrupt.h> // include interrupt support |
||
| 14 | #include <string.h> // include string support |
||
| 15 | #include "rprintf.h" // include rprintf function library |
||
| 16 | #include "timer128.h" // include timer function library |
||
| 17 | #include "ds2482.h" // include dallas support |
||
| 18 | #include "dallas.h" // include dallas support |
||
| 19 | |||
| 20 | //----- Global Variables ------------------------------------------------------- |
||
| 21 | static u08 last_discrep = 0; // last discrepancy for FindDevices |
||
| 22 | static u08 done_flag = 0; // done flag for FindDevices |
||
| 23 | |||
| 24 | u08 dallas_crc; // current crc global variable |
||
| 25 | u08 dallas_crc_table[] = // dallas crc lookup table |
||
| 26 | { |
||
| 27 | 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65, |
||
| 28 | 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220, |
||
| 29 | 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98, |
||
| 30 | 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255, |
||
| 31 | 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7, |
||
| 32 | 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154, |
||
| 33 | 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36, |
||
| 34 | 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185, |
||
| 35 | 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205, |
||
| 36 | 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80, |
||
| 37 | 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238, |
||
| 38 | 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115, |
||
| 39 | 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139, |
||
| 40 | 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22, |
||
| 41 | 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168, |
||
| 42 | 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53 |
||
| 43 | }; |
||
| 44 | |||
| 45 | //----- Functions -------------------------------------------------------------- |
||
| 46 | |||
| 47 | /*-------------------------------------------------------------------------- |
||
| 48 | * dallasFindNextDevice: find the next device on the bus |
||
| 49 | * input................ rom_id - pointer to store the rom id found |
||
| 50 | * returns.............. true or false if a device was found |
||
| 51 | *-------------------------------------------------------------------------*/ |
||
| 52 | u08 dallasFindNextDevice(dallas_rom_id_T* rom_id); |
||
| 53 | |||
| 54 | void dallasInit(void) |
||
| 55 | { |
||
| 56 | //ds2482Init(); |
||
| 57 | } |
||
| 58 | |||
| 59 | u08 dallasReset(void) |
||
| 60 | { |
||
| 61 | // reset the bus |
||
| 62 | if(ds2482BusReset()) |
||
| 63 | return DALLAS_PRESENCE; |
||
| 64 | else |
||
| 65 | return DALLAS_NO_PRESENCE; |
||
| 66 | } |
||
| 67 | |||
| 68 | u08 dallasReadBit(void) |
||
| 69 | { |
||
| 70 | return ds2482BusTransferBit(1); |
||
| 71 | } |
||
| 72 | |||
| 73 | void dallasWriteBit(u08 bit) |
||
| 74 | { |
||
| 75 | ds2482BusTransferBit(bit); |
||
| 76 | } |
||
| 77 | |||
| 78 | u08 dallasReadByte(void) |
||
| 79 | { |
||
| 80 | return ds2482BusReadByte(); |
||
| 81 | } |
||
| 82 | |||
| 83 | void dallasWriteByte(u08 byte) |
||
| 84 | { |
||
| 85 | ds2482BusWriteByte(byte); |
||
| 86 | } |
||
| 87 | |||
| 88 | u08 dallasReadRAM(dallas_rom_id_T* rom_id, u16 addr, u08 len, u08 *data) |
||
| 89 | { |
||
| 90 | u08 i; |
||
| 91 | u08 error; |
||
| 92 | |||
| 93 | union int16_var_U |
||
| 94 | { |
||
| 95 | u16 i16; |
||
| 96 | u08 i08[2]; |
||
| 97 | } int16_var; |
||
| 98 | |||
| 99 | // first make sure we actually have something to do |
||
| 100 | if (data == NULL) |
||
| 101 | return DALLAS_NULL_POINTER; |
||
| 102 | if (len == 0) |
||
| 103 | return DALLAS_ZERO_LEN; |
||
| 104 | |||
| 105 | // reset the bus and request the device |
||
| 106 | error = dallasMatchROM(rom_id); |
||
| 107 | if (error != DALLAS_NO_ERROR) |
||
| 108 | return error; |
||
| 109 | |||
| 110 | // enter read mode |
||
| 111 | dallasWriteByte(DALLAS_READ_MEMORY); |
||
| 112 | |||
| 113 | // write address one byte at a time |
||
| 114 | int16_var.i16 = addr; |
||
| 115 | dallasWriteByte(int16_var.i08[0]); |
||
| 116 | dallasWriteByte(int16_var.i08[1]); |
||
| 117 | |||
| 118 | // read data from device 1 byte at a time |
||
| 119 | for(i=0;i<len;i++) |
||
| 120 | data[i] = dallasReadByte(); |
||
| 121 | |||
| 122 | return DALLAS_NO_ERROR; |
||
| 123 | } |
||
| 124 | |||
| 125 | u08 dallasWriteRAM(dallas_rom_id_T* rom_id, u16 addr, u08 len, u08* data) |
||
| 126 | { |
||
| 127 | u08 i; |
||
| 128 | u08 error; |
||
| 129 | |||
| 130 | union int16_var_U |
||
| 131 | { |
||
| 132 | u16 i16; |
||
| 133 | u08 i08[2]; |
||
| 134 | } int16_var; |
||
| 135 | |||
| 136 | // first make sure we actually have something to do |
||
| 137 | if (data == NULL) |
||
| 138 | return DALLAS_NULL_POINTER; |
||
| 139 | if (len == 0) |
||
| 140 | return DALLAS_ZERO_LEN; |
||
| 141 | |||
| 142 | // reset the bus and request the device |
||
| 143 | error = dallasMatchROM(rom_id); |
||
| 144 | if (error != DALLAS_NO_ERROR) |
||
| 145 | return error; |
||
| 146 | |||
| 147 | // enter write mode |
||
| 148 | dallasWriteByte(DALLAS_WRITE_MEMORY); |
||
| 149 | |||
| 150 | // write address one byte at a time |
||
| 151 | int16_var.i16 = addr; |
||
| 152 | dallasWriteByte(int16_var.i08[0]); |
||
| 153 | dallasWriteByte(int16_var.i08[1]); |
||
| 154 | |||
| 155 | // write data one byte at a time |
||
| 156 | for(i=0;i<len;i++) |
||
| 157 | { |
||
| 158 | dallasWriteByte(data[i]); |
||
| 159 | |||
| 160 | // future: Check CRC16, for now just read it so we can go on |
||
| 161 | dallasReadByte(); |
||
| 162 | dallasReadByte(); |
||
| 163 | |||
| 164 | // verify the data |
||
| 165 | if (dallasReadByte() != data[i]) |
||
| 166 | return DALLAS_VERIFY_ERROR; |
||
| 167 | } |
||
| 168 | |||
| 169 | return DALLAS_NO_ERROR; |
||
| 170 | } |
||
| 171 | |||
| 172 | void dallasWaitUntilDone(void) |
||
| 173 | { |
||
| 174 | //timerPause(6); |
||
| 175 | |||
| 176 | // wait until we recieve a one |
||
| 177 | // cli(); |
||
| 178 | // while(!dallasReadBit()); |
||
| 179 | // sei(); |
||
| 180 | while(!ds2482BusLevel()); |
||
| 181 | } |
||
| 182 | |||
| 183 | u08 dallasReadROM(dallas_rom_id_T* rom_id) |
||
| 184 | { |
||
| 185 | u08 i; |
||
| 186 | |||
| 187 | // reset the 1-wire bus and look for presence |
||
| 188 | i = dallasReset(); |
||
| 189 | if (i != DALLAS_PRESENCE) |
||
| 190 | return i; |
||
| 191 | |||
| 192 | // send READ ROM command |
||
| 193 | dallasWriteByte(DALLAS_READ_ROM); |
||
| 194 | |||
| 195 | // get the device's ID 1 byte at a time |
||
| 196 | for(i=0;i<8;i++) |
||
| 197 | rom_id->byte[i] = dallasReadByte(); |
||
| 198 | |||
| 199 | return DALLAS_NO_ERROR; |
||
| 200 | } |
||
| 201 | |||
| 202 | u08 dallasMatchROM(dallas_rom_id_T* rom_id) |
||
| 203 | { |
||
| 204 | u08 i; |
||
| 205 | |||
| 206 | // reset the 1-wire and look for presence |
||
| 207 | i = dallasReset(); |
||
| 208 | if (i != DALLAS_PRESENCE) |
||
| 209 | return i; |
||
| 210 | |||
| 211 | // send MATCH ROM command |
||
| 212 | dallasWriteByte(DALLAS_MATCH_ROM); |
||
| 213 | |||
| 214 | // write id one byte at a time |
||
| 215 | for(i=0;i<8;i++) |
||
| 216 | dallasWriteByte(rom_id->byte[i]); |
||
| 217 | |||
| 218 | return DALLAS_NO_ERROR; |
||
| 219 | } |
||
| 220 | |||
| 221 | void dallasPrintROM(dallas_rom_id_T* rom_id) |
||
| 222 | { |
||
| 223 | s08 i; |
||
| 224 | |||
| 225 | // print out the rom in the format: xx xx xx xx xx xx xx xx |
||
| 226 | for(i=7;i>=0;i--) |
||
| 227 | { |
||
| 228 | rprintfu08(rom_id->byte[i]); |
||
| 229 | rprintfChar(' '); |
||
| 230 | } |
||
| 231 | } |
||
| 232 | |||
| 233 | u08 dallasAddressCheck(dallas_rom_id_T* rom_id, u08 family) |
||
| 234 | { |
||
| 235 | // u08 i; |
||
| 236 | |||
| 237 | // dallas_crc = 0; |
||
| 238 | |||
| 239 | // for(i=1;i<7;i++) |
||
| 240 | // { |
||
| 241 | // dallasCRC(rom_id->byte[i]); |
||
| 242 | // rprintfu08(rom_id->byte[i]); |
||
| 243 | // rprintfChar(' '); |
||
| 244 | // } |
||
| 245 | // rprintfCRLF(); |
||
| 246 | |||
| 247 | // rprintfu08(dallas_crc); |
||
| 248 | // rprintfCRLF(); |
||
| 249 | |||
| 250 | //run CRC on address |
||
| 251 | |||
| 252 | //make sure we have the correct family |
||
| 253 | if (rom_id->byte[DALLAS_FAMILY_IDX] == family) |
||
| 254 | return DALLAS_NO_ERROR; |
||
| 255 | |||
| 256 | return DALLAS_ADDRESS_ERROR; |
||
| 257 | } |
||
| 258 | |||
| 259 | u08 dallasCRC(u08 i) |
||
| 260 | { |
||
| 261 | // update the crc global variable and return it |
||
| 262 | dallas_crc = dallas_crc_table[dallas_crc^i]; |
||
| 263 | return dallas_crc; |
||
| 264 | } |
||
| 265 | |||
| 266 | u08 dallasFindDevices(dallas_rom_id_T rom_id[]) |
||
| 267 | { |
||
| 268 | u08 num_found = 0; |
||
| 269 | dallas_rom_id_T id; |
||
| 270 | |||
| 271 | // reset the rom search last discrepancy global |
||
| 272 | last_discrep = 0; |
||
| 273 | done_flag = FALSE; |
||
| 274 | |||
| 275 | // check to make sure presence is detected before we start |
||
| 276 | if (dallasReset() == DALLAS_PRESENCE) |
||
| 277 | { |
||
| 278 | // --> stang |
||
| 279 | //while (dallasFindNextDevice(&rom_id[num_found]) && (num_found<DALLAS_MAX_DEVICES)) |
||
| 280 | // num_found++; |
||
| 281 | |||
| 282 | // continues until no additional devices are found |
||
| 283 | while (dallasFindNextDevice(&id) && (num_found<DALLAS_MAX_DEVICES)) |
||
| 284 | memcpy(&rom_id[num_found++], &id, 8); |
||
| 285 | } |
||
| 286 | |||
| 287 | return num_found; |
||
| 288 | } |
||
| 289 | |||
| 290 | u08 dallasFindNextDevice(dallas_rom_id_T* rom_id) |
||
| 291 | { |
||
| 292 | u08 bit; |
||
| 293 | u08 i = 0; |
||
| 294 | u08 bit_index = 1; |
||
| 295 | u08 byte_index = 0; |
||
| 296 | u08 bit_mask = 1; |
||
| 297 | u08 discrep_marker = 0; |
||
| 298 | |||
| 299 | // reset the CRC |
||
| 300 | dallas_crc = 0; |
||
| 301 | |||
| 302 | if (done_flag || dallasReset() != DALLAS_PRESENCE) |
||
| 303 | { |
||
| 304 | // no more devices parts detected |
||
| 305 | return FALSE; |
||
| 306 | } |
||
| 307 | |||
| 308 | // send search ROM command |
||
| 309 | dallasWriteByte(DALLAS_SEARCH_ROM); |
||
| 310 | |||
| 311 | // loop until through all 8 ROM bytes |
||
| 312 | while(byte_index<8) |
||
| 313 | { |
||
| 314 | // read line 2 times to determine status of devices |
||
| 315 | // 00 - devices connected to bus with conflicting bits |
||
| 316 | // 01 - all devices have a 0 in this position |
||
| 317 | // 10 - all devices ahve a 1 in this position |
||
| 318 | // 11 - there are no devices connected to bus |
||
| 319 | i = 0; |
||
| 320 | cli(); |
||
| 321 | if (dallasReadBit()) |
||
| 322 | i = 2; // store the msb if 1 |
||
| 323 | //delay_us(120); |
||
| 324 | delay(120); |
||
| 325 | if (dallasReadBit()) |
||
| 326 | i |= 1; // store the lsb if 1 |
||
| 327 | sei(); |
||
| 328 | |||
| 329 | if (i==3) |
||
| 330 | { |
||
| 331 | // there are no devices on the 1-wire |
||
| 332 | break; |
||
| 333 | } |
||
| 334 | else |
||
| 335 | { |
||
| 336 | if (i>0) |
||
| 337 | { |
||
| 338 | // all devices coupled have 0 or 1 |
||
| 339 | // shift 1 to determine if the msb is 0 or 1 |
||
| 340 | bit = i>>1; |
||
| 341 | } |
||
| 342 | else |
||
| 343 | { |
||
| 344 | // if this discrepancy is before the last discrepancy on a |
||
| 345 | // previous FindNextDevice then pick the same as last time |
||
| 346 | if (bit_index<last_discrep) |
||
| 347 | bit = ((rom_id->byte[byte_index] & bit_mask) > 0); |
||
| 348 | else |
||
| 349 | bit = (bit_index==last_discrep); |
||
| 350 | |||
| 351 | // if 0 was picked then record position with bit mask |
||
| 352 | if (!bit) |
||
| 353 | discrep_marker = bit_index; |
||
| 354 | } |
||
| 355 | |||
| 356 | // isolate bit in rom_id->byte[byte_index] with bit mask |
||
| 357 | if (bit) |
||
| 358 | rom_id->byte[byte_index] |= bit_mask; |
||
| 359 | else |
||
| 360 | rom_id->byte[byte_index] &= ~bit_mask; |
||
| 361 | |||
| 362 | // ROM search write |
||
| 363 | //cli(); |
||
| 364 | dallasWriteBit(bit); |
||
| 365 | //sei(); |
||
| 366 | |||
| 367 | // ncrement bit index counter and shift the bit mask |
||
| 368 | bit_index++; |
||
| 369 | bit_mask <<= 1; |
||
| 370 | |||
| 371 | if (!bit_mask) |
||
| 372 | { |
||
| 373 | // if the mask is 0 then go to new ROM |
||
| 374 | // accumulate the CRC and incriment the byte index and bit mask |
||
| 375 | dallasCRC(rom_id->byte[byte_index]); |
||
| 376 | byte_index++; |
||
| 377 | bit_mask++; |
||
| 378 | } |
||
| 379 | } |
||
| 380 | } |
||
| 381 | |||
| 382 | if ((bit_index < 65) || dallas_crc) |
||
| 383 | { |
||
| 384 | // search was unsuccessful - reset the last discrepancy to 0 and return false |
||
| 385 | last_discrep = 0; |
||
| 386 | return FALSE; |
||
| 387 | } |
||
| 388 | |||
| 389 | // search was successful, so set last_discrep and done_flag |
||
| 390 | last_discrep = discrep_marker; |
||
| 391 | done_flag = (last_discrep==0); |
||
| 392 | |||
| 393 | return TRUE; |
||
| 394 | } |
||
| 395 | |||
| 396 | void dallasPrintError(u08 error) |
||
| 397 | { |
||
| 398 | // if there was not an error, return |
||
| 399 | if (error == DALLAS_NO_ERROR) |
||
| 400 | return; |
||
| 401 | |||
| 402 | // print header message |
||
| 403 | rprintfProgStrM("ERROR "); |
||
| 404 | rprintfChar(error); |
||
| 405 | rprintfProgStrM(": "); |
||
| 406 | |||
| 407 | // print custom error message |
||
| 408 | switch (error) |
||
| 409 | { |
||
| 410 | case DALLAS_NO_PRESENCE: |
||
| 411 | rprintfProgStrM("no presence detected"); |
||
| 412 | break; |
||
| 413 | case DALLAS_INVALID_CHANNEL: |
||
| 414 | rprintfProgStrM("Invalid Chan"); |
||
| 415 | break; |
||
| 416 | case DALLAS_VERIFY_ERROR: |
||
| 417 | rprintfProgStrM("Verify"); |
||
| 418 | break; |
||
| 419 | case DALLAS_ADDRESS_ERROR: |
||
| 420 | rprintfProgStrM("Bad Addr"); |
||
| 421 | break; |
||
| 422 | case DALLAS_CRC_ERROR: |
||
| 423 | rprintfProgStrM("Data CRC"); |
||
| 424 | break; |
||
| 425 | case DALLAS_DEVICE_ERROR: |
||
| 426 | rprintfProgStrM("No response"); |
||
| 427 | break; |
||
| 428 | case DALLAS_FORMAT_ERROR: |
||
| 429 | rprintfProgStrM("Bad return format"); |
||
| 430 | break; |
||
| 431 | case DALLAS_NULL_POINTER: |
||
| 432 | rprintfProgStrM("Null Pointer"); |
||
| 433 | break; |
||
| 434 | case DALLAS_ZERO_LEN: |
||
| 435 | rprintfProgStrM("RAM rd/wr 0 bytes"); |
||
| 436 | break; |
||
| 437 | case DALLAS_BUS_ERROR: |
||
| 438 | rprintfProgStrM("Bus error, check pullup"); |
||
| 439 | break; |
||
| 440 | case DALLAS_RESOLUTION_ERROR: |
||
| 441 | rprintfProgStrM("resolution out of range"); |
||
| 442 | break; |
||
| 443 | default: |
||
| 444 | rprintfProgStrM("Unknown"); |
||
| 445 | } |
||
| 446 | rprintfCRLF(); |
||
| 447 | } |
Powered by WebSVN v2.8.3