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