Mercurial > ~darius > hgwebdir.cgi > avr
comparison 1wire.c @ 10:eb1faf51968e
- Add some useful return values to search functions.
- Remove some unecessary trailing \'s in macros
- Replace some inline assembly I missed last time with C/macros.
author | darius |
---|---|
date | Mon, 12 Jul 2004 23:59:00 +0930 |
parents | f9a085a0ba93 |
children | 4b141cc7cbd4 |
comparison
equal
deleted
inserted
replaced
9:7ed10c59ba06 | 10:eb1faf51968e |
---|---|
45 static uint8_t OW_LastDiscrepancy = 0; | 45 static uint8_t OW_LastDiscrepancy = 0; |
46 static uint8_t OW_LastFamilyDiscrepancy = 0; | 46 static uint8_t OW_LastFamilyDiscrepancy = 0; |
47 | 47 |
48 static void | 48 static void |
49 OWdelay(void) { | 49 OWdelay(void) { |
50 asm volatile ( | 50 DELAY_I; |
51 "ldi r21, 50\n\t" | |
52 "_OWdelay:\n\t" | |
53 "nop\n\t" | |
54 "nop\n\t" | |
55 "nop\n\t" | |
56 "nop\n\t" | |
57 "nop\n\t" | |
58 "nop\n\t" | |
59 "nop\n\t" | |
60 "nop\n\t" | |
61 "nop\n\t" | |
62 "nop\n\t" | |
63 "nop\n\t" | |
64 "nop\n\t" | |
65 "nop\n\t" | |
66 "dec r21\n\t" | |
67 "brne _OWdelay\n\t" | |
68 ::: "r21"); | |
69 } | 51 } |
70 | 52 |
71 /*----------------------------------------------------------------------------- | 53 /*----------------------------------------------------------------------------- |
72 * Generate a 1-Wire reset, return 1 if no presence detect was found, | 54 * Generate a 1-Wire reset, return 1 if no presence detect was found, |
73 * return 0 otherwise. | 55 * return 0 otherwise. |
74 * (NOTE: Does not handle alarm presence from DS2404/DS1994) | 56 * (NOTE: Does not handle alarm presence from DS2404/DS1994) |
75 */ | 57 */ |
76 int | 58 int |
77 OWTouchReset(void) { | 59 OWTouchReset(void) { |
78 uint8_t result; | 60 DELAY_G; |
79 | 61 OWIREOUTPORT &= ~(_BV(OWIREOUTPIN)); |
80 asm volatile ( | 62 OWIREDDR |= _BV(OWIREOUTPIN); |
81 /* Delay G (0 usec) */ | 63 DELAY_H; |
82 "\n\t" | 64 OWIREDDR &= ~(_BV(OWIREOUTPIN)); |
83 /* Drive bus low */ | 65 DELAY_I; |
84 "cbi %[out], %[opin]\n\t" | 66 |
85 "sbi %[ddr], %[opin]\n\t" | 67 return(OWIREINPORT & _BV(OWIREINPIN) ? 1 : 0); |
86 /* Delay H (480 usec) */ | |
87 "ldi r21, 120\n\t" | |
88 "loopH:\n\t" | |
89 "nop\n\t" | |
90 "nop\n\t" | |
91 "nop\n\t" | |
92 "nop\n\t" | |
93 "nop\n\t" | |
94 "nop\n\t" | |
95 "nop\n\t" | |
96 "nop\n\t" | |
97 "nop\n\t" | |
98 "nop\n\t" | |
99 "nop\n\t" | |
100 "nop\n\t" | |
101 "nop\n\t" | |
102 "dec r21\n\t" | |
103 "brne loopH\n\t" | |
104 /* Release bus */ | |
105 "cbi %[ddr], %[opin]\n\t" | |
106 /* Delay I (70 usec) */ | |
107 "ldi r21, 35\n\t" | |
108 "loopI:\n\t" | |
109 "nop\n\t" | |
110 "nop\n\t" | |
111 "nop\n\t" | |
112 "nop\n\t" | |
113 "nop\n\t" | |
114 "dec r21\n\t" | |
115 "brne loopI\n\t" | |
116 /* Sample for presense */ | |
117 "ldi %[result], 0\n\t" | |
118 "sbi %[ddr], 1\n\t" | |
119 "sbi %[out], 1\n\t" | |
120 /* 1 == no presence */ | |
121 "sbic %[in], %[ipin]\n\t" | |
122 "ldi %[result], 1\n\t" | |
123 "cbi %[out], 1\n\t" | |
124 | |
125 : [result] "=r" (result) /* Outputs */ | |
126 : [out] "I" (_SFR_IO_ADDR(OWIREOUTPORT)), /* Inputs */ | |
127 [ddr] "I" (_SFR_IO_ADDR(OWIREDDR)), | |
128 [opin] "I" (OWIREOUTPIN), | |
129 [in] "I" (_SFR_IO_ADDR(OWIREINPORT)), | |
130 [ipin] "I" (OWIREINPIN) | |
131 : "r21"); /* Clobbers */ | |
132 | |
133 return(result); | |
134 } | 68 } |
135 | 69 |
136 /*----------------------------------------------------------------------------- | 70 /*----------------------------------------------------------------------------- |
137 * Send a 1-wire write bit. | 71 * Send a 1-wire write bit. |
138 */ | 72 */ |
255 } | 189 } |
256 | 190 |
257 /*----------------------------------------------------------------------------- | 191 /*----------------------------------------------------------------------------- |
258 * Search algorithm from App note 187 (and 162) | 192 * Search algorithm from App note 187 (and 162) |
259 * | 193 * |
260 * Returns 1 when something is found, 0 if nothing present | 194 * OWFirst/OWNext return.. |
195 * 1 when something is found, | |
196 * 0 no more modules | |
197 * -1 if no presense pulse, | |
198 * -2 if bad CRC, | |
199 * -3 if bad wiring. | |
261 */ | 200 */ |
262 int | 201 int |
263 OWFirst(uint8_t *ROM, uint8_t do_reset, uint8_t alarm_only) { | 202 OWFirst(uint8_t *ROM, uint8_t do_reset, uint8_t alarm_only) { |
264 /* Reset state */ | 203 /* Reset state */ |
265 OW_LastDiscrepancy = 0; | 204 OW_LastDiscrepancy = 0; |
272 | 211 |
273 /* Returns 1 when something is found, 0 if nothing left */ | 212 /* Returns 1 when something is found, 0 if nothing left */ |
274 int | 213 int |
275 OWNext(uint8_t *ROM, uint8_t do_reset, uint8_t alarm_only) { | 214 OWNext(uint8_t *ROM, uint8_t do_reset, uint8_t alarm_only) { |
276 uint8_t bit_test, search_direction, bit_number; | 215 uint8_t bit_test, search_direction, bit_number; |
277 uint8_t last_zero, rom_byte_number, next_result; | 216 uint8_t last_zero, rom_byte_number, rom_byte_mask; |
278 uint8_t rom_byte_mask; | |
279 uint8_t lastcrc8, crcaccum; | 217 uint8_t lastcrc8, crcaccum; |
218 int next_result; | |
280 char errstr[30]; | 219 char errstr[30]; |
281 | 220 |
282 /* Init for search */ | 221 /* Init for search */ |
283 bit_number = 1; | 222 bit_number = 1; |
284 last_zero = 0; | 223 last_zero = 0; |
285 rom_byte_number = 0; | 224 rom_byte_number = 0; |
286 rom_byte_mask = 1; | 225 rom_byte_mask = 1; |
287 next_result = 0; | 226 next_result = OW_NOMODULES; |
288 lastcrc8 = 0; | 227 lastcrc8 = 0; |
289 crcaccum = 0; | 228 crcaccum = 0; |
290 | 229 |
291 /* if the last call was not the last one */ | 230 /* if the last call was not the last one */ |
292 if (!OW_LastDevice) { | 231 if (!OW_LastDevice) { |
302 OW_LastDiscrepancy = 0; | 241 OW_LastDiscrepancy = 0; |
303 OW_LastFamilyDiscrepancy = 0; | 242 OW_LastFamilyDiscrepancy = 0; |
304 #if OW_DEBUG | 243 #if OW_DEBUG |
305 uart_putsP(PSTR("No devices on bus\n\r")); | 244 uart_putsP(PSTR("No devices on bus\n\r")); |
306 #endif | 245 #endif |
307 return 0; | 246 return OW_NOPRESENCE; |
308 } | 247 } |
309 } | 248 } |
310 | 249 |
311 /* If finding alarming devices issue a different command */ | 250 /* If finding alarming devices issue a different command */ |
312 if (alarm_only) | 251 if (alarm_only) |
330 uart_puts(errstr); | 269 uart_puts(errstr); |
331 #endif | 270 #endif |
332 | 271 |
333 /* check for no devices on 1-wire */ | 272 /* check for no devices on 1-wire */ |
334 if (bit_test == 3) { | 273 if (bit_test == 3) { |
274 #if OW_DEBUG | |
335 sprintf_P(errstr, PSTR("bit_test = %d\n\r"), bit_test); | 275 sprintf_P(errstr, PSTR("bit_test = %d\n\r"), bit_test); |
336 uart_puts(errstr); | 276 uart_puts(errstr); |
337 break; | 277 #endif |
278 return(OW_BADWIRE); | |
338 } | 279 } |
339 else { | 280 else { |
340 /* all devices coupled have 0 or 1 */ | 281 /* all devices coupled have 0 or 1 */ |
341 if (bit_test > 0) | 282 if (bit_test > 0) |
342 search_direction = !(bit_test & 0x01); /* bit write value for search */ | 283 search_direction = !(bit_test & 0x01); /* bit write value for search */ |
389 /* if the search was successful then */ | 330 /* if the search was successful then */ |
390 if (!(bit_number < 65) || lastcrc8) { | 331 if (!(bit_number < 65) || lastcrc8) { |
391 if (lastcrc8) { | 332 if (lastcrc8) { |
392 sprintf_P(errstr, PSTR("Bad CRC (%d)\n\r"), lastcrc8); | 333 sprintf_P(errstr, PSTR("Bad CRC (%d)\n\r"), lastcrc8); |
393 uart_puts(errstr); | 334 uart_puts(errstr); |
394 next_result = 0; | 335 next_result = OW_BADCRC; |
395 } else { | 336 } else { |
396 /* search successful so set LastDiscrepancy,LastDevice,next_result */ | 337 /* search successful so set LastDiscrepancy,LastDevice,next_result */ |
397 OW_LastDiscrepancy = last_zero; | 338 OW_LastDiscrepancy = last_zero; |
398 OW_LastDevice = (OW_LastDiscrepancy == 0); | 339 OW_LastDevice = (OW_LastDiscrepancy == 0); |
399 #if OW_DEBUG | 340 #if OW_DEBUG |
400 sprintf_P(errstr, PSTR("Last device = %d\n\r"), OW_LastDevice); | 341 sprintf_P(errstr, PSTR("Last device = %d\n\r"), OW_LastDevice); |
401 uart_puts(errstr); | 342 uart_puts(errstr); |
402 #endif | 343 #endif |
403 next_result = 1; | 344 next_result = OW_FOUND; |
404 } | 345 } |
405 } | 346 } |
406 } | 347 } |
407 | 348 |
408 /* if no device found then reset counters so next 'next' will be | 349 /* if no device found then reset counters so next 'next' will be |
409 * like a first */ | 350 * like a first */ |
410 if (!next_result || !ROM[0]) { | 351 if (next_result != OW_FOUND || ROM[0] == 0) { |
411 OW_LastDiscrepancy = 0; | 352 OW_LastDiscrepancy = 0; |
412 OW_LastDevice = 0; | 353 OW_LastDevice = 0; |
413 OW_LastFamilyDiscrepancy = 0; | 354 OW_LastFamilyDiscrepancy = 0; |
414 next_result = 0; | |
415 } | 355 } |
416 | 356 |
357 if (next_result == OW_FOUND && ROM[0] == 0x00) | |
358 next_result = OW_BADWIRE; | |
359 | |
417 return next_result; | 360 return next_result; |
418 | 361 |
419 } | 362 } |
420 | 363 |
421 uint8_t PROGMEM dscrc_table[] = { | 364 uint8_t PROGMEM dscrc_table[] = { |