?lang_form? ?lang_select? ?lang_submit? ?lang_endform?
{HEADER END}
{BLAME START}

library

?curdirlinks? -

Blame information for rev 6

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 "dallas.h" // include dallas support
18  
19 //----- Global Variables -------------------------------------------------------
20 static u08 last_discrep = 0; // last discrepancy for FindDevices
21 static u08 done_flag = 0; // done flag for FindDevices
22  
23 u08 dallas_crc; // current crc global variable
24 u08 dallas_crc_table[] = // dallas crc lookup table
25 {
26 0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
27 157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
28 35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
29 190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
30 70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
31 219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
32 101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
33 248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
34 140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
35 17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
36 175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
37 50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
38 202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
39 87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
40 233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
41 116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53
42 };
43  
44 //----- Functions --------------------------------------------------------------
45  
46 /*--------------------------------------------------------------------------
47 * dallasFindNextDevice: find the next device on the bus
48 * input................ rom_id - pointer to store the rom id found
49 * returns.............. true or false if a device was found
50 *-------------------------------------------------------------------------*/
51 u08 dallasFindNextDevice(dallas_rom_id_T* rom_id);
52  
53 void dallasDelayUs(u16 us)
54 {
55 while(us--) // 6 cycles
56 {
57 asm volatile ("nop");
58 asm volatile ("nop");
59 asm volatile ("nop");
60 asm volatile ("nop");
61 asm volatile ("nop");
62 asm volatile ("nop");
63 asm volatile ("nop");
64 } // loop jump 2 cycles
65 }
66  
67 void dallasInit(void)
68 {
69 }
70  
71 u08 dallasReset(void)
72 {
73 u08 presence = DALLAS_PRESENCE;
74  
75 cli();
76  
77 // pull line low
78 sbi(DALLAS_DDR, DALLAS_PIN);
79 cbi(DALLAS_PORT, DALLAS_PIN);
80  
81 // wait for presence
82 dallasDelayUs(480);
83  
84 // allow line to return high
85 cbi(DALLAS_DDR, DALLAS_PIN);
86 sbi(DALLAS_PORT, DALLAS_PIN);
87  
88 // wait for presence
89 dallasDelayUs(70);
90  
91 // if device is not present, pin will be 1
92 if (inb(DALLAS_PORTIN) & 0x01<<DALLAS_PIN)
93 presence = DALLAS_NO_PRESENCE;
94  
95 // wait for end of timeslot
96 dallasDelayUs(410);
97  
98 sei();
99  
100 // now that we have reset, let's check bus health
101 // it should be noted that a delay may be needed here for devices that
102 // send out an alarming presence pulse signal after a reset
103 cbi(DALLAS_DDR, DALLAS_PIN);
104 sbi(DALLAS_PORT, DALLAS_PIN);
105 //dallasDelayUs(200);
106 if (!(inb(DALLAS_PORTIN) & (0x01<<DALLAS_PIN))) // it should be pulled up to high
107 return DALLAS_BUS_ERROR;
108  
109 return presence;
110 }
111  
112 u08 dallasReadBit(void)
113 {
114 u08 bit = 0;
115  
116 // pull line low to start timeslot
117 sbi(DALLAS_DDR, DALLAS_PIN);
118 cbi(DALLAS_PORT, DALLAS_PIN);
119  
120 // delay appropriate time
121 dallasDelayUs(6);
122  
123 // release the bus
124 cbi(DALLAS_DDR, DALLAS_PIN);
125 sbi(DALLAS_PORT, DALLAS_PIN);
126  
127 // delay appropriate time
128 dallasDelayUs(9);
129  
130 // read the pin and set the variable to 1 if the pin is high
131 if (inb(DALLAS_PORTIN) & 0x01<<DALLAS_PIN)
132 bit = 1;
133  
134 // finish read timeslot
135 dallasDelayUs(55);
136  
137 return bit;
138 }
139  
140 void dallasWriteBit(u08 bit)
141 {
142 // drive bus low
143 sbi(DALLAS_DDR, DALLAS_PIN);
144 cbi(DALLAS_PORT, DALLAS_PIN);
145  
146 // delay the proper time if we want to write a 0 or 1
147 if (bit)
148 dallasDelayUs(6);
149 else
150 dallasDelayUs(60);
151  
152 // release bus
153 cbi(DALLAS_DDR, DALLAS_PIN);
154 sbi(DALLAS_PORT, DALLAS_PIN);
155  
156 // delay the proper time if we want to write a 0 or 1
157 if (bit)
158 dallasDelayUs(64);
159 else
160 dallasDelayUs(10);
161 }
162  
163 u08 dallasReadByte(void)
164 {
165 u08 i;
166 u08 byte = 0;
167  
168 cli();
169  
170 // read all 8 bits
171 for(i=0;i<8;i++)
172 {
173 if (dallasReadBit())
174 byte |= 0x01<<i;
175  
176 // allow a us delay between each read
177 dallasDelayUs(1);
178 }
179  
180 sei();
181  
182 return byte;
183 }
184  
185 void dallasWriteByte(u08 byte)
186 {
187 u08 i;
188  
189 cli();
190  
191 // write all 8 bits
192 for(i=0;i<8;i++)
193 {
194 dallasWriteBit((byte>>i) & 0x01);
195  
196 // allow a us delay between each write
197 dallasDelayUs(1);
198 }
199  
200 sei();
201 }
202  
203 u08 dallasReadRAM(dallas_rom_id_T* rom_id, u16 addr, u08 len, u08 *data)
204 {
205 u08 i;
206 u08 error;
207  
208 union int16_var_U
209 {
210 u16 i16;
211 u08 i08[2];
212 } int16_var;
213  
214 // first make sure we actually have something to do
215 if (data == NULL)
216 return DALLAS_NULL_POINTER;
217 if (len == 0)
218 return DALLAS_ZERO_LEN;
219  
220 // reset the bus and request the device
221 error = dallasMatchROM(rom_id);
222 if (error != DALLAS_NO_ERROR)
223 return error;
224  
225 // enter read mode
226 dallasWriteByte(DALLAS_READ_MEMORY);
227  
228 // write address one byte at a time
229 int16_var.i16 = addr;
230 dallasWriteByte(int16_var.i08[0]);
231 dallasWriteByte(int16_var.i08[1]);
232  
233 // read data from device 1 byte at a time
234 for(i=0;i<len;i++)
235 data[i] = dallasReadByte();
236  
237 return DALLAS_NO_ERROR;
238 }
239  
240 u08 dallasWriteRAM(dallas_rom_id_T* rom_id, u16 addr, u08 len, u08* data)
241 {
242 u08 i;
243 u08 error;
244  
245 union int16_var_U
246 {
247 u16 i16;
248 u08 i08[2];
249 } int16_var;
250  
251 // first make sure we actually have something to do
252 if (data == NULL)
253 return DALLAS_NULL_POINTER;
254 if (len == 0)
255 return DALLAS_ZERO_LEN;
256  
257 // reset the bus and request the device
258 error = dallasMatchROM(rom_id);
259 if (error != DALLAS_NO_ERROR)
260 return error;
261  
262 // enter write mode
263 dallasWriteByte(DALLAS_WRITE_MEMORY);
264  
265 // write address one byte at a time
266 int16_var.i16 = addr;
267 dallasWriteByte(int16_var.i08[0]);
268 dallasWriteByte(int16_var.i08[1]);
269  
270 // write data one byte at a time
271 for(i=0;i<len;i++)
272 {
273 dallasWriteByte(data[i]);
274  
275 // future: Check CRC16, for now just read it so we can go on
276 dallasReadByte();
277 dallasReadByte();
278  
279 // verify the data
280 if (dallasReadByte() != data[i])
281 return DALLAS_VERIFY_ERROR;
282 }
283  
284 return DALLAS_NO_ERROR;
285 }
286  
287 void dallasWaitUntilDone(void)
288 {
289 //timerPause(6);
290  
291 // wait until we recieve a one
292 cli();
293 while(!dallasReadBit());
294 sei();
295 }
296  
297 u08 dallasReadROM(dallas_rom_id_T* rom_id)
298 {
299 u08 i;
300  
301 // reset the 1-wire bus and look for presence
302 i = dallasReset();
303 if (i != DALLAS_PRESENCE)
304 return i;
305  
306 // send READ ROM command
307 dallasWriteByte(DALLAS_READ_ROM);
308  
309 // get the device's ID 1 byte at a time
310 for(i=0;i<8;i++)
311 rom_id->byte[i] = dallasReadByte();
312  
313 return DALLAS_NO_ERROR;
314 }
315  
316 u08 dallasMatchROM(dallas_rom_id_T* rom_id)
317 {
318 u08 i;
319  
320 // reset the 1-wire and look for presence
321 i = dallasReset();
322 if (i != DALLAS_PRESENCE)
323 return i;
324  
325 // send MATCH ROM command
326 dallasWriteByte(DALLAS_MATCH_ROM);
327  
328 // write id one byte at a time
329 for(i=0;i<8;i++)
330 dallasWriteByte(rom_id->byte[i]);
331  
332 return DALLAS_NO_ERROR;
333 }
334  
335 void dallasPrintROM(dallas_rom_id_T* rom_id)
336 {
337 s08 i;
338  
339 // print out the rom in the format: xx xx xx xx xx xx xx xx
340 for(i=7;i>=0;i--)
341 {
342 rprintfu08(rom_id->byte[i]);
343 rprintfChar(' ');
344 }
345  
346 // print out the rom in the format: 0xXXXXXXXXXXXXXXXX
347 rprintfProgStrM(" (0x");
348 for(i=7;i>=0;i--)
349 {
350 rprintfu08(rom_id->byte[i]);
351 }
352 rprintfProgStrM("ULL)");
353  
354 }
355  
356 u08 dallasAddressCheck(dallas_rom_id_T* rom_id, u08 family)
357 {
358 // u08 i;
359  
360 // dallas_crc = 0;
361  
362 // for(i=1;i<7;i++)
363 // {
364 // dallasCRC(rom_id->byte[i]);
365 // rprintfu08(rom_id->byte[i]);
366 // rprintfChar(' ');
367 // }
368 // rprintfCRLF();
369  
370 // rprintfu08(dallas_crc);
371 // rprintfCRLF();
372  
373 //run CRC on address
374  
375 //make sure we have the correct family
376 if (rom_id->byte[DALLAS_FAMILY_IDX] == family)
377 return DALLAS_NO_ERROR;
378  
379 return DALLAS_ADDRESS_ERROR;
380 }
381  
382 u08 dallasCRC(u08 i)
383 {
384 // update the crc global variable and return it
385 dallas_crc = dallas_crc_table[dallas_crc^i];
386 return dallas_crc;
387 }
388  
389 u08 dallasFindDevices(dallas_rom_id_T rom_id[])
390 {
391 u08 num_found = 0;
392 dallas_rom_id_T id;
393  
394 // reset the rom search last discrepancy global
395 last_discrep = 0;
396 done_flag = FALSE;
397  
398 // check to make sure presence is detected before we start
399 if (dallasReset() == DALLAS_PRESENCE)
400 {
401 // --> stang
402 //while (dallasFindNextDevice(&rom_id[num_found]) && (num_found<DALLAS_MAX_DEVICES))
403 // num_found++;
404  
405 // continues until no additional devices are found
406 while (dallasFindNextDevice(&id) && (num_found<DALLAS_MAX_DEVICES))
407 memcpy(&rom_id[num_found++], &id, 8);
408 }
409  
410 return num_found;
411 }
412  
413 u08 dallasFindNextDevice(dallas_rom_id_T* rom_id)
414 {
415 u08 bit;
416 u08 i = 0;
417 u08 bit_index = 1;
418 u08 byte_index = 0;
419 u08 bit_mask = 1;
420 u08 discrep_marker = 0;
421  
422 // reset the CRC
423 dallas_crc = 0;
424  
425 if (done_flag || dallasReset() != DALLAS_PRESENCE)
426 {
427 // no more devices parts detected
428 return FALSE;
429 }
430  
431 // send search ROM command
432 dallasWriteByte(DALLAS_SEARCH_ROM);
433  
434 // loop until through all 8 ROM bytes
435 while(byte_index<8)
436 {
437 // read line 2 times to determine status of devices
438 // 00 - devices connected to bus with conflicting bits
439 // 01 - all devices have a 0 in this position
440 // 10 - all devices ahve a 1 in this position
441 // 11 - there are no devices connected to bus
442 i = 0;
443 cli();
444 if (dallasReadBit())
445 i = 2; // store the msb if 1
446 dallasDelayUs(120);
447 if (dallasReadBit())
448 i |= 1; // store the lsb if 1
449 sei();
450  
451 if (i==3)
452 {
453 // there are no devices on the 1-wire
454 break;
455 }
456 else
457 {
458 if (i>0)
459 {
460 // all devices coupled have 0 or 1
461 // shift 1 to determine if the msb is 0 or 1
462 bit = i>>1;
463 }
464 else
465 {
466 // if this discrepancy is before the last discrepancy on a
467 // previous FindNextDevice then pick the same as last time
468 if (bit_index<last_discrep)
469 bit = ((rom_id->byte[byte_index] & bit_mask) > 0);
470 else
471 bit = (bit_index==last_discrep);
472  
473 // if 0 was picked then record position with bit mask
474 if (!bit)
475 discrep_marker = bit_index;
476 }
477  
478 // isolate bit in rom_id->byte[byte_index] with bit mask
479 if (bit)
480 rom_id->byte[byte_index] |= bit_mask;
481 else
482 rom_id->byte[byte_index] &= ~bit_mask;
483  
484 // ROM search write
485 cli();
486 dallasWriteBit(bit);
487 sei();
488  
489 // ncrement bit index counter and shift the bit mask
490 bit_index++;
491 bit_mask <<= 1;
492  
493 if (!bit_mask)
494 {
495 // if the mask is 0 then go to new ROM
496 // accumulate the CRC and incriment the byte index and bit mask
497 dallasCRC(rom_id->byte[byte_index]);
498 byte_index++;
499 bit_mask++;
500 }
501 }
502 }
503  
504 if ((bit_index < 65) || dallas_crc)
505 {
506 // search was unsuccessful - reset the last discrepancy to 0 and return false
507 last_discrep = 0;
508 return FALSE;
509 }
510  
511 // search was successful, so set last_discrep and done_flag
512 last_discrep = discrep_marker;
513 done_flag = (last_discrep==0);
514  
515 return TRUE;
516 }
517  
518 void dallasPrintError(u08 error)
519 {
520 // if there was not an error, return
521 if (error == DALLAS_NO_ERROR)
522 return;
523  
524 // print header message
525 rprintfProgStrM("ERROR ");
526 rprintfChar(error);
527 rprintfProgStrM(": ");
528  
529 // print custom error message
530 switch (error)
531 {
532 case DALLAS_NO_PRESENCE:
533 rprintfProgStrM("no presence detected");
534 break;
535 case DALLAS_INVALID_CHANNEL:
536 rprintfProgStrM("Invalid Chan");
537 break;
538 case DALLAS_VERIFY_ERROR:
539 rprintfProgStrM("Verify");
540 break;
541 case DALLAS_ADDRESS_ERROR:
542 rprintfProgStrM("Bad Addr");
543 break;
544 case DALLAS_CRC_ERROR:
545 rprintfProgStrM("Data CRC");
546 break;
547 case DALLAS_DEVICE_ERROR:
548 rprintfProgStrM("No response");
549 break;
550 case DALLAS_FORMAT_ERROR:
551 rprintfProgStrM("Bad return format");
552 break;
553 case DALLAS_NULL_POINTER:
554 rprintfProgStrM("Null Pointer");
555 break;
556 case DALLAS_ZERO_LEN:
557 rprintfProgStrM("RAM rd/wr 0 bytes");
558 break;
559 case DALLAS_BUS_ERROR:
560 rprintfProgStrM("Bus error, check pullup");
561 break;
562 case DALLAS_RESOLUTION_ERROR:
563 rprintfProgStrM("resolution out of range");
564 break;
565 default:
566 rprintfProgStrM("Unknown");
567 }
568 rprintfCRLF();
569 }
{BLAME END}
{FOOTER START}

Powered by WebSVN v2.8.3