Mercurial > ~darius > hgwebdir.cgi > avr
annotate 1wire.c @ 23:845934a4e7fe
Add code to talk to a Phillips PDIUSBB12.
author | darius |
---|---|
date | Mon, 12 Dec 2005 23:32:59 +1030 |
parents | bd792ebf813d |
children | 02b67e09ca12 |
rev | line source |
---|---|
0 | 1 /* |
2 * Various 1 wire routines | |
12 | 3 * Search routine is copied from the Dallas owpd library with mods |
4 * available from here http://www.ibutton.com/software/1wire/wirekit.html | |
0 | 5 * |
8
f9a085a0ba93
Change the 1 wire routines to mostly C with assembly delay routines
darius
parents:
0
diff
changeset
|
6 * $Id$ |
f9a085a0ba93
Change the 1 wire routines to mostly C with assembly delay routines
darius
parents:
0
diff
changeset
|
7 * |
0 | 8 * Copyright (c) 2004 |
9 * Daniel O'Connor <darius@dons.net.au>. All rights reserved. | |
10 * | |
11 * Redistribution and use in source and binary forms, with or without | |
12 * modification, are permitted provided that the following conditions | |
13 * are met: | |
14 * 1. Redistributions of source code must retain the above copyright | |
15 * notice, this list of conditions and the following disclaimer. | |
16 * 2. Redistributions in binary form must reproduce the above copyright | |
17 * notice, this list of conditions and the following disclaimer in the | |
18 * documentation and/or other materials provided with the distribution. | |
19 * | |
20 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
23 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE | |
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
30 * SUCH DAMAGE. | |
31 */ | |
32 | |
33 #include <stdio.h> | |
34 #include <avr/io.h> | |
35 #include <avr/pgmspace.h> | |
21 | 36 #include <util/delay.h> |
0 | 37 #include "1wire.h" |
8
f9a085a0ba93
Change the 1 wire routines to mostly C with assembly delay routines
darius
parents:
0
diff
changeset
|
38 #include "1wire-delay.h" |
0 | 39 |
12 | 40 #if OW_DEBUG |
0 | 41 void uart_putsP(const char *addr); |
42 void uart_puts(const char *addr); | |
43 void uart_getc(); | |
21 | 44 char uart_putc(char c); |
12 | 45 #endif |
0 | 46 |
47 static uint8_t OW_LastDevice = 0; | |
48 static uint8_t OW_LastDiscrepancy = 0; | |
49 static uint8_t OW_LastFamilyDiscrepancy = 0; | |
50 | |
51 static void | |
52 OWdelay(void) { | |
10 | 53 DELAY_I; |
0 | 54 } |
55 | |
56 /*----------------------------------------------------------------------------- | |
22
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
57 * Generate a 1-Wire reset, return 0 if presence pulse was found, 1 if it |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
58 * wasn't, or 2 if the line appears to be being held low. |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
59 * |
21 | 60 * |
0 | 61 * (NOTE: Does not handle alarm presence from DS2404/DS1994) |
62 */ | |
12 | 63 uint8_t |
0 | 64 OWTouchReset(void) { |
10 | 65 DELAY_G; |
22
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
66 |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
67 if (!(OWIREINPORT & _BV(OWIREINPIN))) |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
68 return 2; |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
69 |
10 | 70 OWIREOUTPORT &= ~(_BV(OWIREOUTPIN)); |
71 OWIREDDR |= _BV(OWIREOUTPIN); | |
72 DELAY_H; | |
73 OWIREDDR &= ~(_BV(OWIREOUTPIN)); | |
74 DELAY_I; | |
0 | 75 |
10 | 76 return(OWIREINPORT & _BV(OWIREINPIN) ? 1 : 0); |
0 | 77 } |
78 | |
79 /*----------------------------------------------------------------------------- | |
80 * Send a 1-wire write bit. | |
81 */ | |
82 void | |
12 | 83 OWWriteBit(uint8_t bit) { |
0 | 84 OWdelay(); |
85 if (bit) { | |
8
f9a085a0ba93
Change the 1 wire routines to mostly C with assembly delay routines
darius
parents:
0
diff
changeset
|
86 OWIREOUTPORT &= ~(_BV(OWIREOUTPIN)); |
f9a085a0ba93
Change the 1 wire routines to mostly C with assembly delay routines
darius
parents:
0
diff
changeset
|
87 OWIREDDR |= _BV(OWIREOUTPIN); |
f9a085a0ba93
Change the 1 wire routines to mostly C with assembly delay routines
darius
parents:
0
diff
changeset
|
88 DELAY_A; |
f9a085a0ba93
Change the 1 wire routines to mostly C with assembly delay routines
darius
parents:
0
diff
changeset
|
89 OWIREDDR &= ~(_BV(OWIREOUTPIN)); |
f9a085a0ba93
Change the 1 wire routines to mostly C with assembly delay routines
darius
parents:
0
diff
changeset
|
90 DELAY_B; |
0 | 91 } else { |
8
f9a085a0ba93
Change the 1 wire routines to mostly C with assembly delay routines
darius
parents:
0
diff
changeset
|
92 OWIREOUTPORT &= ~(_BV(OWIREOUTPIN)); |
f9a085a0ba93
Change the 1 wire routines to mostly C with assembly delay routines
darius
parents:
0
diff
changeset
|
93 OWIREDDR |= _BV(OWIREOUTPIN); |
f9a085a0ba93
Change the 1 wire routines to mostly C with assembly delay routines
darius
parents:
0
diff
changeset
|
94 DELAY_C; |
f9a085a0ba93
Change the 1 wire routines to mostly C with assembly delay routines
darius
parents:
0
diff
changeset
|
95 OWIREDDR &= ~(_BV(OWIREOUTPIN)); |
f9a085a0ba93
Change the 1 wire routines to mostly C with assembly delay routines
darius
parents:
0
diff
changeset
|
96 DELAY_D; |
0 | 97 } |
98 } | |
99 | |
100 /*----------------------------------------------------------------------------- | |
101 * Read a bit from the 1-wire bus and return it. | |
102 */ | |
12 | 103 uint8_t |
0 | 104 OWReadBit(void) { |
105 OWdelay(); | |
106 | |
8
f9a085a0ba93
Change the 1 wire routines to mostly C with assembly delay routines
darius
parents:
0
diff
changeset
|
107 OWIREOUTPORT &= ~(_BV(OWIREOUTPIN)); |
f9a085a0ba93
Change the 1 wire routines to mostly C with assembly delay routines
darius
parents:
0
diff
changeset
|
108 OWIREDDR |= _BV(OWIREOUTPIN); |
f9a085a0ba93
Change the 1 wire routines to mostly C with assembly delay routines
darius
parents:
0
diff
changeset
|
109 DELAY_A; |
f9a085a0ba93
Change the 1 wire routines to mostly C with assembly delay routines
darius
parents:
0
diff
changeset
|
110 OWIREDDR &= ~(_BV(OWIREOUTPIN)); |
f9a085a0ba93
Change the 1 wire routines to mostly C with assembly delay routines
darius
parents:
0
diff
changeset
|
111 DELAY_E; |
f9a085a0ba93
Change the 1 wire routines to mostly C with assembly delay routines
darius
parents:
0
diff
changeset
|
112 return(OWIREINPORT & _BV(OWIREINPIN) ? 1 : 0); |
0 | 113 } |
114 | |
115 /*----------------------------------------------------------------------------- | |
116 * Write a byte to the 1-wire bus | |
117 */ | |
118 void | |
119 OWWriteByte(uint8_t data) { | |
12 | 120 uint8_t i; |
0 | 121 |
122 /* Send LSB first */ | |
123 for (i = 0; i < 8; i++) { | |
124 OWWriteBit(data & 0x01); | |
125 data >>= 1; | |
126 } | |
127 } | |
128 | |
129 /*----------------------------------------------------------------------------- | |
130 * Read a byte from the 1-wire bus | |
131 */ | |
12 | 132 uint8_t |
0 | 133 OWReadByte(void) { |
134 int i, result = 0; | |
135 | |
136 for (i = 0; i < 8; i++) { | |
137 result >>= 1; | |
138 if (OWReadBit()) | |
139 result |= 0x80; | |
140 } | |
141 return(result); | |
142 } | |
143 | |
144 /*----------------------------------------------------------------------------- | |
145 * Write a 1-wire data byte and return the sampled result. | |
146 */ | |
12 | 147 uint8_t |
0 | 148 OWTouchByte(uint8_t data) { |
12 | 149 uint8_t i, result = 0; |
0 | 150 |
151 for (i = 0; i < 8; i++) { | |
152 result >>= 1; | |
153 | |
154 /* If sending a 1 then read a bit, otherwise write a 0 */ | |
155 if (data & 0x01) { | |
156 if (OWReadBit()) | |
157 result |= 0x80; | |
158 } else | |
159 OWWriteBit(0); | |
160 | |
161 data >>= 1; | |
162 } | |
163 | |
164 return(result); | |
165 } | |
166 | |
167 /*----------------------------------------------------------------------------- | |
168 * Write a block of bytes to the 1-wire bus and return the sampled result in | |
169 * the same buffer | |
170 */ | |
171 void | |
172 OWBlock(uint8_t *data, int len) { | |
173 int i; | |
174 | |
175 for (i = 0; i < len; i++) | |
176 data[i] = OWTouchByte(data[i]); | |
177 } | |
178 | |
179 | |
180 /*----------------------------------------------------------------------------- | |
181 * Send a 1 wire command to a device, or all if no ROM ID provided | |
182 */ | |
183 void | |
184 OWSendCmd(uint8_t *ROM, uint8_t cmd) { | |
12 | 185 uint8_t i; |
0 | 186 |
187 OWTouchReset(); | |
188 | |
189 if (ROM == NULL) | |
190 OWWriteByte(OW_SKIP_ROM_CMD); | |
191 else { | |
192 OWWriteByte(OW_MATCH_ROM_CMD); | |
193 for (i = 0; i < 8; i++) | |
194 OWWriteByte(ROM[i]); | |
195 } | |
196 | |
197 OWWriteByte(cmd); | |
198 } | |
199 | |
200 /*----------------------------------------------------------------------------- | |
201 * Search algorithm from App note 187 (and 162) | |
202 * | |
10 | 203 * OWFirst/OWNext return.. |
204 * 1 when something is found, | |
205 * 0 no more modules | |
16 | 206 * -1 if no presence pulse, |
10 | 207 * -2 if bad CRC, |
208 * -3 if bad wiring. | |
0 | 209 */ |
12 | 210 uint8_t |
0 | 211 OWFirst(uint8_t *ROM, uint8_t do_reset, uint8_t alarm_only) { |
212 /* Reset state */ | |
213 OW_LastDiscrepancy = 0; | |
214 OW_LastDevice = 0; | |
215 OW_LastFamilyDiscrepancy = 0; | |
216 | |
217 /* Go looking */ | |
218 return (OWNext(ROM, do_reset, alarm_only)); | |
219 } | |
220 | |
221 /* Returns 1 when something is found, 0 if nothing left */ | |
12 | 222 uint8_t |
0 | 223 OWNext(uint8_t *ROM, uint8_t do_reset, uint8_t alarm_only) { |
224 uint8_t bit_test, search_direction, bit_number; | |
10 | 225 uint8_t last_zero, rom_byte_number, rom_byte_mask; |
0 | 226 uint8_t lastcrc8, crcaccum; |
12 | 227 int8_t next_result; |
0 | 228 |
229 /* Init for search */ | |
21 | 230 bit_number = 1; |
231 last_zero = 0; | |
232 rom_byte_number = 0; | |
233 rom_byte_mask = 1; | |
234 next_result = OW_NOMODULES; | |
235 lastcrc8 = 0; | |
236 crcaccum = 0; | |
0 | 237 |
21 | 238 /* if the last call was not the last one */ |
239 if (!OW_LastDevice) { | |
240 /* check if reset first is requested */ | |
241 if (do_reset) { | |
242 /* reset the 1-wire | |
243 * if there are no parts on 1-wire, return 0 */ | |
0 | 244 #if OW_DEBUG |
21 | 245 uart_putsP(PSTR("Resetting\n\r")); |
0 | 246 #endif |
22
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
247 switch (OWTouchReset()) { |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
248 case 0: |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
249 break; |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
250 |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
251 case 1: |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
252 /* reset the search */ |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
253 OW_LastDiscrepancy = 0; |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
254 OW_LastFamilyDiscrepancy = 0; |
0 | 255 #if OW_DEBUG |
22
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
256 uart_putsP(PSTR("No devices on bus\n\r")); |
0 | 257 #endif |
22
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
258 return OW_NOPRESENCE; |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
259 break; |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
260 |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
261 case 2: |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
262 /* reset the search */ |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
263 OW_LastDiscrepancy = 0; |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
264 OW_LastFamilyDiscrepancy = 0; |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
265 #if OW_DEBUG |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
266 uart_putsP(PSTR("Bus appears to be being held low\n\r")); |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
267 #endif |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
268 return OW_BADWIRE; |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
269 break; |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
270 |
21 | 271 } |
272 } | |
0 | 273 |
21 | 274 /* If finding alarming devices issue a different command */ |
275 if (alarm_only) | |
276 OWWriteByte(OW_SEARCH_ALRM_CMD); /* issue the alarming search command */ | |
277 else | |
278 OWWriteByte(OW_SEARCH_ROM_CMD); /* issue the search command */ | |
0 | 279 |
21 | 280 /* pause before beginning the search */ |
281 OWdelay(); | |
282 OWdelay(); | |
283 OWdelay(); | |
0 | 284 |
21 | 285 /* loop to do the search */ |
286 do { | |
287 /* read a bit and its compliment */ | |
288 bit_test = OWReadBit() << 1; | |
289 bit_test |= OWReadBit(); | |
0 | 290 |
291 #if OW_DEBUG | |
21 | 292 sprintf_P(errstr, PSTR("bit_test = %d\n\r"), bit_test); |
293 uart_puts(errstr); | |
0 | 294 #endif |
295 | |
21 | 296 /* check for no devices on 1-wire */ |
297 if (bit_test == 3) { | |
10 | 298 #if OW_DEBUG |
21 | 299 sprintf_P(errstr, PSTR("bit_test = %d\n\r"), bit_test); |
300 uart_puts(errstr); | |
10 | 301 #endif |
21 | 302 return(OW_BADWIRE); |
303 } | |
304 else { | |
305 /* all devices coupled have 0 or 1 */ | |
306 if (bit_test > 0) | |
307 search_direction = !(bit_test & 0x01); /* bit write value for search */ | |
308 else { | |
309 /* if this discrepancy is before the Last Discrepancy | |
310 * on a previous OWNext then pick the same as last time */ | |
311 if (bit_number < OW_LastDiscrepancy) | |
312 search_direction = ((ROM[rom_byte_number] & rom_byte_mask) > 0); | |
313 else | |
314 /* if equal to last pick 1, if not then pick 0 */ | |
315 search_direction = (bit_number == OW_LastDiscrepancy); | |
0 | 316 |
21 | 317 /* if 0 was picked then record its position in LastZero */ |
318 if (search_direction == 0) { | |
319 last_zero = bit_number; | |
0 | 320 |
21 | 321 /* check for Last discrepancy in family */ |
322 if (last_zero < 9) | |
323 OW_LastFamilyDiscrepancy = last_zero; | |
324 } | |
325 } | |
0 | 326 |
21 | 327 /* set or clear the bit in the ROM byte rom_byte_number |
328 * with mask rom_byte_mask */ | |
329 if (search_direction == 1) | |
330 ROM[rom_byte_number] |= rom_byte_mask; | |
331 else | |
332 ROM[rom_byte_number] &= ~rom_byte_mask; | |
0 | 333 |
21 | 334 /* serial number search direction write bit */ |
335 OWWriteBit(search_direction); | |
0 | 336 |
21 | 337 /* increment the byte counter bit_number |
338 * and shift the mask rom_byte_mask */ | |
339 bit_number++; | |
340 rom_byte_mask <<= 1; | |
0 | 341 |
21 | 342 /* if the mask is 0 then go to new ROM byte rom_byte_number |
343 * and reset mask */ | |
344 if (rom_byte_mask == 0) { | |
345 OWCRC(ROM[rom_byte_number], &crcaccum); /* accumulate the CRC */ | |
346 lastcrc8 = crcaccum; | |
0 | 347 |
21 | 348 rom_byte_number++; |
349 rom_byte_mask = 1; | |
350 } | |
351 } | |
352 } while (rom_byte_number < 8); /* loop until through all ROM bytes 0-7 */ | |
0 | 353 |
21 | 354 /* if the search was successful then */ |
355 if (!(bit_number < 65) || lastcrc8) { | |
356 if (lastcrc8) { | |
12 | 357 #if OW_DEBUG |
21 | 358 sprintf_P(errstr, PSTR("Bad CRC (%d)\n\r"), lastcrc8); |
359 uart_puts(errstr); | |
12 | 360 #endif |
21 | 361 next_result = OW_BADCRC; |
362 } else { | |
363 /* search successful so set LastDiscrepancy,LastDevice,next_result */ | |
364 OW_LastDiscrepancy = last_zero; | |
365 OW_LastDevice = (OW_LastDiscrepancy == 0); | |
0 | 366 #if OW_DEBUG |
21 | 367 sprintf_P(errstr, PSTR("Last device = %d\n\r"), OW_LastDevice); |
368 uart_puts(errstr); | |
0 | 369 #endif |
21 | 370 next_result = OW_FOUND; |
371 } | |
372 } | |
373 } | |
0 | 374 |
21 | 375 /* if no device found then reset counters so next 'next' will be |
376 * like a first */ | |
377 if (next_result != OW_FOUND || ROM[0] == 0) { | |
378 OW_LastDiscrepancy = 0; | |
379 OW_LastDevice = 0; | |
380 OW_LastFamilyDiscrepancy = 0; | |
381 } | |
0 | 382 |
21 | 383 if (next_result == OW_FOUND && ROM[0] == 0x00) |
384 next_result = OW_BADWIRE; | |
10 | 385 |
21 | 386 return next_result; |
0 | 387 |
388 } | |
389 | |
390 uint8_t PROGMEM dscrc_table[] = { | |
391 0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65, | |
392 157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220, | |
393 35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98, | |
394 190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255, | |
395 70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7, | |
396 219, 133,103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154, | |
397 101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36, | |
398 248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185, | |
399 140,210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113,147, 205, | |
400 17, 79, 173, 243, 112, 46, 204, 146, 211,141, 111, 49, 178, 236, 14, 80, | |
401 175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82,176, 238, | |
402 50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115, | |
403 202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139, | |
404 87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22, | |
405 233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168, | |
406 116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53 | |
407 }; | |
408 | |
409 void | |
410 OWCRC(uint8_t x, uint8_t *crc) { | |
411 *crc = pgm_read_byte(&dscrc_table[(*crc) ^ x]); | |
412 } |