Mercurial > ~darius > hgwebdir.cgi > avr
annotate 1wire.c @ 41:5898fba6593c
Add temperature control.
- Split out console stuff to cons.[ch]. Set up stdio so we can use printf etc.
- Use \r\n as the line terminator consistently.
- Add OWGetTemp to get temperatures from a device.
- Load/save settings in EEPROM, defaults loaded from flash.
Nearly feature complete except you can't edit ROM IDs without a programming tool :)
(To be fixed)
Needs more testing.
author | darius@inchoate.localdomain |
---|---|
date | Sun, 06 Jul 2008 22:19:53 +0930 |
parents | 0aa6bf4b98ae |
children | efd44dc40934 |
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 | |
32
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
33 /* |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
34 * No user servicable parts inside |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
35 * |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
36 * Modify 1wire-config.h |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
37 */ |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
38 |
0 | 39 #include <stdio.h> |
40 #include <avr/io.h> | |
41 #include <avr/pgmspace.h> | |
21 | 42 #include <util/delay.h> |
0 | 43 #include "1wire.h" |
32
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
44 #include "1wire-config.h" |
41 | 45 #include "cons.h" |
0 | 46 |
47 static uint8_t OW_LastDevice = 0; | |
48 static uint8_t OW_LastDiscrepancy = 0; | |
49 static uint8_t OW_LastFamilyDiscrepancy = 0; | |
50 | |
32
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
51 /*----------------------------------------------------------------------------- |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
52 * Configure the IO port as we need |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
53 */ |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
54 void |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
55 OWInit(void) { |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
56 OWBUSINIT(); |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
57 OWSETBUSHIGH(); |
0 | 58 } |
59 | |
60 /*----------------------------------------------------------------------------- | |
22
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
61 * 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
|
62 * 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
|
63 * |
0 | 64 * (NOTE: Does not handle alarm presence from DS2404/DS1994) |
65 */ | |
12 | 66 uint8_t |
0 | 67 OWTouchReset(void) { |
32
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
68 OWDELAY_G; |
22
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
69 |
32
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
70 /* Check the bus isn't being held low (ie it's broken) Do it after |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
71 * the delay so we guarantee we don't see a slave from a previous |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
72 * comms attempt |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
73 */ |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
74 if(OWREADBUS() == 0) |
22
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
75 return 2; |
0 | 76 |
32
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
77 OWSETBUSLOW(); |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
78 OWDELAY_H; |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
79 OWSETBUSHIGH(); |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
80 OWDELAY_I; |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
81 |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
82 return(OWREADBUS()); |
0 | 83 } |
84 | |
85 /*----------------------------------------------------------------------------- | |
86 * Send a 1-wire write bit. | |
87 */ | |
88 void | |
12 | 89 OWWriteBit(uint8_t bit) { |
32
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
90 OWDELAY_I; |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
91 |
0 | 92 if (bit) { |
32
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
93 OWSETBUSLOW(); |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
94 OWDELAY_A; |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
95 OWSETBUSHIGH(); |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
96 OWDELAY_B; |
0 | 97 } else { |
32
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
98 OWSETBUSLOW(); |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
99 OWDELAY_C; |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
100 OWSETBUSHIGH(); |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
101 OWDELAY_D; |
0 | 102 } |
103 } | |
104 | |
105 /*----------------------------------------------------------------------------- | |
106 * Read a bit from the 1-wire bus and return it. | |
107 */ | |
12 | 108 uint8_t |
0 | 109 OWReadBit(void) { |
32
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
110 OWDELAY_I; |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
111 |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
112 OWSETBUSLOW(); |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
113 OWDELAY_A; |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
114 OWSETBUSHIGH(); |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
115 OWDELAY_E; |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
116 return(OWREADBUS()); |
0 | 117 } |
118 | |
119 /*----------------------------------------------------------------------------- | |
120 * Write a byte to the 1-wire bus | |
121 */ | |
122 void | |
123 OWWriteByte(uint8_t data) { | |
12 | 124 uint8_t i; |
0 | 125 |
126 /* Send LSB first */ | |
127 for (i = 0; i < 8; i++) { | |
128 OWWriteBit(data & 0x01); | |
129 data >>= 1; | |
130 } | |
131 } | |
132 | |
133 /*----------------------------------------------------------------------------- | |
134 * Read a byte from the 1-wire bus | |
135 */ | |
12 | 136 uint8_t |
0 | 137 OWReadByte(void) { |
138 int i, result = 0; | |
139 | |
140 for (i = 0; i < 8; i++) { | |
141 result >>= 1; | |
142 if (OWReadBit()) | |
143 result |= 0x80; | |
144 } | |
145 return(result); | |
146 } | |
147 | |
148 /*----------------------------------------------------------------------------- | |
149 * Write a 1-wire data byte and return the sampled result. | |
150 */ | |
12 | 151 uint8_t |
0 | 152 OWTouchByte(uint8_t data) { |
12 | 153 uint8_t i, result = 0; |
0 | 154 |
155 for (i = 0; i < 8; i++) { | |
156 result >>= 1; | |
157 | |
158 /* If sending a 1 then read a bit, otherwise write a 0 */ | |
159 if (data & 0x01) { | |
160 if (OWReadBit()) | |
161 result |= 0x80; | |
162 } else | |
163 OWWriteBit(0); | |
164 | |
165 data >>= 1; | |
166 } | |
167 | |
168 return(result); | |
169 } | |
170 | |
171 /*----------------------------------------------------------------------------- | |
172 * Write a block of bytes to the 1-wire bus and return the sampled result in | |
173 * the same buffer | |
174 */ | |
175 void | |
176 OWBlock(uint8_t *data, int len) { | |
177 int i; | |
178 | |
179 for (i = 0; i < len; i++) | |
180 data[i] = OWTouchByte(data[i]); | |
181 } | |
182 | |
183 | |
184 /*----------------------------------------------------------------------------- | |
185 * Send a 1 wire command to a device, or all if no ROM ID provided | |
186 */ | |
187 void | |
188 OWSendCmd(uint8_t *ROM, uint8_t cmd) { | |
12 | 189 uint8_t i; |
0 | 190 |
191 OWTouchReset(); | |
192 | |
193 if (ROM == NULL) | |
194 OWWriteByte(OW_SKIP_ROM_CMD); | |
195 else { | |
196 OWWriteByte(OW_MATCH_ROM_CMD); | |
197 for (i = 0; i < 8; i++) | |
198 OWWriteByte(ROM[i]); | |
199 } | |
200 OWWriteByte(cmd); | |
201 } | |
202 | |
203 /*----------------------------------------------------------------------------- | |
204 * Search algorithm from App note 187 (and 162) | |
205 * | |
10 | 206 * OWFirst/OWNext return.. |
207 * 1 when something is found, | |
208 * 0 no more modules | |
16 | 209 * -1 if no presence pulse, |
10 | 210 * -2 if bad CRC, |
211 * -3 if bad wiring. | |
0 | 212 */ |
12 | 213 uint8_t |
0 | 214 OWFirst(uint8_t *ROM, uint8_t do_reset, uint8_t alarm_only) { |
215 /* Reset state */ | |
216 OW_LastDiscrepancy = 0; | |
217 OW_LastDevice = 0; | |
218 OW_LastFamilyDiscrepancy = 0; | |
219 | |
220 /* Go looking */ | |
221 return (OWNext(ROM, do_reset, alarm_only)); | |
222 } | |
223 | |
224 /* Returns 1 when something is found, 0 if nothing left */ | |
12 | 225 uint8_t |
0 | 226 OWNext(uint8_t *ROM, uint8_t do_reset, uint8_t alarm_only) { |
227 uint8_t bit_test, search_direction, bit_number; | |
10 | 228 uint8_t last_zero, rom_byte_number, rom_byte_mask; |
0 | 229 uint8_t lastcrc8, crcaccum; |
12 | 230 int8_t next_result; |
0 | 231 |
232 /* Init for search */ | |
21 | 233 bit_number = 1; |
234 last_zero = 0; | |
235 rom_byte_number = 0; | |
236 rom_byte_mask = 1; | |
237 next_result = OW_NOMODULES; | |
238 lastcrc8 = 0; | |
239 crcaccum = 0; | |
0 | 240 |
21 | 241 /* if the last call was not the last one */ |
242 if (!OW_LastDevice) { | |
243 /* check if reset first is requested */ | |
244 if (do_reset) { | |
245 /* reset the 1-wire | |
246 * if there are no parts on 1-wire, return 0 */ | |
41 | 247 OWPUTSP(PSTR("Resetting\r\n")); |
22
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
248 switch (OWTouchReset()) { |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
249 case 0: |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
250 break; |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
251 |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
252 case 1: |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
253 /* reset the search */ |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
254 OW_LastDiscrepancy = 0; |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
255 OW_LastFamilyDiscrepancy = 0; |
41 | 256 OWPUTSP(PSTR("No devices on bus\r\n")); |
22
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
257 return OW_NOPRESENCE; |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
258 break; |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
259 |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
260 case 2: |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
261 /* reset the search */ |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
262 OW_LastDiscrepancy = 0; |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
263 OW_LastFamilyDiscrepancy = 0; |
41 | 264 OWPUTSP(PSTR("Bus appears to be being held low\r\n")); |
22
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
265 return OW_BADWIRE; |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
266 break; |
bd792ebf813d
Report the bus being held low back to the caller from OWFirst/Next.
darius
parents:
21
diff
changeset
|
267 |
21 | 268 } |
269 } | |
0 | 270 |
21 | 271 /* If finding alarming devices issue a different command */ |
272 if (alarm_only) | |
273 OWWriteByte(OW_SEARCH_ALRM_CMD); /* issue the alarming search command */ | |
274 else | |
275 OWWriteByte(OW_SEARCH_ROM_CMD); /* issue the search command */ | |
0 | 276 |
21 | 277 /* pause before beginning the search */ |
32
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
278 OWDELAY_I; |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
279 OWDELAY_I; |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
280 OWDELAY_I; |
b0cb873c0206
Isolate the bus frobbing parts and the delays into a separate header.
darius
parents:
29
diff
changeset
|
281 |
21 | 282 /* loop to do the search */ |
283 do { | |
284 /* read a bit and its compliment */ | |
285 bit_test = OWReadBit() << 1; | |
286 bit_test |= OWReadBit(); | |
0 | 287 |
41 | 288 OWPRINTFP(PSTR("bit_test = %d\r\n"), bit_test); |
0 | 289 |
21 | 290 /* check for no devices on 1-wire */ |
291 if (bit_test == 3) { | |
41 | 292 OWPRINTFP(PSTR("bit_test = %d\r\n"), bit_test); |
21 | 293 return(OW_BADWIRE); |
294 } | |
295 else { | |
296 /* all devices coupled have 0 or 1 */ | |
297 if (bit_test > 0) | |
298 search_direction = !(bit_test & 0x01); /* bit write value for search */ | |
299 else { | |
300 /* if this discrepancy is before the Last Discrepancy | |
301 * on a previous OWNext then pick the same as last time */ | |
302 if (bit_number < OW_LastDiscrepancy) | |
303 search_direction = ((ROM[rom_byte_number] & rom_byte_mask) > 0); | |
304 else | |
305 /* if equal to last pick 1, if not then pick 0 */ | |
306 search_direction = (bit_number == OW_LastDiscrepancy); | |
0 | 307 |
21 | 308 /* if 0 was picked then record its position in LastZero */ |
309 if (search_direction == 0) { | |
310 last_zero = bit_number; | |
0 | 311 |
21 | 312 /* check for Last discrepancy in family */ |
313 if (last_zero < 9) | |
314 OW_LastFamilyDiscrepancy = last_zero; | |
315 } | |
316 } | |
0 | 317 |
21 | 318 /* set or clear the bit in the ROM byte rom_byte_number |
319 * with mask rom_byte_mask */ | |
320 if (search_direction == 1) | |
321 ROM[rom_byte_number] |= rom_byte_mask; | |
322 else | |
323 ROM[rom_byte_number] &= ~rom_byte_mask; | |
0 | 324 |
21 | 325 /* serial number search direction write bit */ |
326 OWWriteBit(search_direction); | |
0 | 327 |
21 | 328 /* increment the byte counter bit_number |
329 * and shift the mask rom_byte_mask */ | |
330 bit_number++; | |
331 rom_byte_mask <<= 1; | |
0 | 332 |
21 | 333 /* if the mask is 0 then go to new ROM byte rom_byte_number |
334 * and reset mask */ | |
335 if (rom_byte_mask == 0) { | |
336 OWCRC(ROM[rom_byte_number], &crcaccum); /* accumulate the CRC */ | |
337 lastcrc8 = crcaccum; | |
0 | 338 |
21 | 339 rom_byte_number++; |
340 rom_byte_mask = 1; | |
341 } | |
342 } | |
343 } while (rom_byte_number < 8); /* loop until through all ROM bytes 0-7 */ | |
0 | 344 |
21 | 345 /* if the search was successful then */ |
346 if (!(bit_number < 65) || lastcrc8) { | |
347 if (lastcrc8) { | |
41 | 348 OWPRINTFP(PSTR("Bad CRC (%d)\r\n"), lastcrc8); |
21 | 349 next_result = OW_BADCRC; |
350 } else { | |
351 /* search successful so set LastDiscrepancy,LastDevice,next_result */ | |
352 OW_LastDiscrepancy = last_zero; | |
353 OW_LastDevice = (OW_LastDiscrepancy == 0); | |
41 | 354 OWPRINTFP(PSTR("Last device = %d\r\n"), OW_LastDevice); |
21 | 355 next_result = OW_FOUND; |
356 } | |
357 } | |
358 } | |
0 | 359 |
21 | 360 /* if no device found then reset counters so next 'next' will be |
361 * like a first */ | |
362 if (next_result != OW_FOUND || ROM[0] == 0) { | |
363 OW_LastDiscrepancy = 0; | |
364 OW_LastDevice = 0; | |
365 OW_LastFamilyDiscrepancy = 0; | |
366 } | |
0 | 367 |
21 | 368 if (next_result == OW_FOUND && ROM[0] == 0x00) |
369 next_result = OW_BADWIRE; | |
10 | 370 |
21 | 371 return next_result; |
0 | 372 |
373 } | |
374 | |
375 uint8_t PROGMEM dscrc_table[] = { | |
376 0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65, | |
377 157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220, | |
378 35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98, | |
379 190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255, | |
380 70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7, | |
381 219, 133,103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154, | |
382 101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36, | |
383 248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185, | |
384 140,210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113,147, 205, | |
385 17, 79, 173, 243, 112, 46, 204, 146, 211,141, 111, 49, 178, 236, 14, 80, | |
386 175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82,176, 238, | |
387 50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115, | |
388 202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139, | |
389 87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22, | |
390 233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168, | |
391 116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53 | |
392 }; | |
393 | |
33
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
394 /*----------------------------------------------------------------------------- |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
395 * Update *crc based on the value of x |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
396 */ |
0 | 397 void |
398 OWCRC(uint8_t x, uint8_t *crc) { | |
399 *crc = pgm_read_byte(&dscrc_table[(*crc) ^ x]); | |
400 } | |
33
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
401 |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
402 /*----------------------------------------------------------------------------- |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
403 * Program a DS2502's memory |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
404 * |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
405 * Arguments |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
406 * ROM - ROM ID (or NULL to send SKIP_ROM) |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
407 * start - Start address (bytes) |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
408 * len - Length of data to write |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
409 * data - Data to write |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
410 * exact - If true, only accept exact matches for programming, |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
411 * otherwise only ensure the bits we requested were |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
412 * programmed [to 0] |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
413 * status - If true program status rather than memory |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
414 * |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
415 * Returns.. |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
416 * 0 if all is OK |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
417 * 1 if the programming was unsuccessful |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
418 * 2 if the parameters were invalid |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
419 * 3 if the DS2502 didn't respond appropriately (also happens if the |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
420 * module doesn't exist) |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
421 */ |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
422 uint8_t |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
423 OWProgROM(uint8_t *ROM, uint8_t start, uint8_t len, uint8_t *data, uint8_t exact, uint8_t status) { |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
424 #if defined(OWSETVPPON) && defined(OWSETVPPOFF) |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
425 uint8_t crc, i, tmp; |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
426 |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
427 /* Stupid programmer detection */ |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
428 if (status) { |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
429 if (start + len > 3) |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
430 return(2); |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
431 } else { |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
432 if (start + len > 127) |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
433 return(2); |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
434 } |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
435 |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
436 if (len < 1) |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
437 return(2); |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
438 |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
439 OWDELAY_I; |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
440 if (OWTouchReset() != 0) { |
41 | 441 cons_putsP(PSTR("No presence pulse\r\n")); |
33
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
442 return(3); |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
443 } |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
444 |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
445 crc = 0; |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
446 |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
447 /* Send the command */ |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
448 if (status) { |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
449 OWSendCmd(ROM, OW_WRITE_STATUS); |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
450 OWCRC(OW_WRITE_STATUS, &crc); |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
451 } else { |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
452 OWSendCmd(ROM, OW_WRITE_MEMORY); |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
453 OWCRC(OW_WRITE_MEMORY, &crc); |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
454 } |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
455 |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
456 /* And the start address |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
457 * (2 bytes even though one would do) |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
458 */ |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
459 OWWriteByte(start); |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
460 OWCRC(start, &crc); |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
461 |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
462 OWWriteByte(0x00); |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
463 OWCRC(0x00, &crc); |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
464 |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
465 for (i = 0; i < len; i++) { |
41 | 466 cons_putsP(PSTR("Programming ")); |
467 cons_puts_hex(data[i]); | |
468 cons_putsP(PSTR(" to ")); | |
469 cons_puts_hex(start + i); | |
470 cons_putsP(PSTR("\r\n")); | |
33
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
471 |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
472 OWWriteByte(data[i]); |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
473 OWCRC(data[i], &crc); |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
474 |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
475 tmp = OWReadByte(); |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
476 |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
477 if (crc != tmp) { |
41 | 478 cons_putsP(PSTR("CRC mismatch ")); |
479 cons_puts_hex(crc); | |
480 cons_putsP(PSTR(" vs ")); | |
481 cons_puts_hex(tmp); | |
482 cons_putsP(PSTR("\r\n")); | |
33
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
483 |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
484 OWTouchReset(); |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
485 return(3); |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
486 } |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
487 |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
488 OWSETVPPON(); |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
489 OWDELAY_H; |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
490 OWSETVPPOFF(); |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
491 |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
492 tmp = OWReadByte(); |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
493 |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
494 /* Check the bits we turned off are off */ |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
495 /* |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
496 for (i = 0; i < 8; i++) |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
497 if (!(data[i] & 1 << i) && (tmp & 1 << i)) |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
498 return(-3); |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
499 */ |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
500 if ((!data[i] & tmp) != 0) { |
41 | 501 cons_putsP(PSTR("Readback mismatch ")); |
502 cons_puts_hex(data[i]); | |
503 cons_putsP(PSTR(" vs ")); | |
504 cons_puts_hex(data[i]); | |
505 cons_putsP(PSTR("\r\n")); | |
33
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
506 |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
507 OWTouchReset(); |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
508 return(3); |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
509 } |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
510 |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
511 /* The DS2502 loads it's CRC register with the address of the |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
512 * next byte */ |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
513 crc = 0; |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
514 OWCRC(start + i + 1, &crc); |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
515 } |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
516 |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
517 return(0); |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
518 #else |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
519 return(1); |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
520 #endif |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
521 } |
0aa6bf4b98ae
- Don't wrap individual debug statements in ifdef, use a conditionally
darius
parents:
32
diff
changeset
|
522 |
41 | 523 /* |
524 * OWGetTemp | |
525 * | |
526 * Get the temperature from a 1wire bus module | |
527 * | |
528 * Returns temperature in hundredths of a degree or OW_TEMP_xxx on | |
529 * error. | |
530 */ | |
531 int16_t | |
532 OWGetTemp(uint8_t *ROM) { | |
533 int8_t i; | |
534 uint8_t crc, buf[9]; | |
535 int16_t temp; | |
536 int16_t tfrac; | |
537 | |
538 if (ROM[0] != OW_FAMILY_TEMP) | |
539 return OW_TEMP_WRONG_FAM; | |
540 | |
541 OWSendCmd(ROM, OW_CONVERTT_CMD); | |
542 | |
543 i = 0; | |
544 | |
545 /* Wait for the conversion */ | |
546 while (OWReadBit() == 0) | |
547 i = 1; | |
548 | |
549 /* Check that we talked to a module and it did something */ | |
550 if (i == 0) { | |
551 return OW_TEMP_NO_ROM; | |
552 } | |
553 | |
554 OWSendCmd(ROM, OW_RD_SCR_CMD); | |
555 crc = 0; | |
556 for (i = 0; i < 8; i++) { | |
557 buf[i] = OWReadByte(); | |
558 OWCRC(buf[i], &crc); | |
559 } | |
560 buf[i] = OWReadByte(); | |
561 if (crc != buf[8]) | |
562 return OW_TEMP_CRC_ERR; | |
563 temp = buf[0]; | |
564 if (buf[1] & 0x80) | |
565 temp -= 256; | |
566 | |
567 /* Chop off 0.5 degree bit */ | |
568 temp >>= 1; | |
569 | |
570 /* Calulate the fractional remainder */ | |
571 tfrac = buf[7] - buf[6]; | |
572 | |
573 /* Work in 100'th of degreess to save on floats */ | |
574 tfrac *= (int16_t)100; | |
575 | |
576 /* Divide by count */ | |
577 tfrac /= buf[7]; | |
578 | |
579 /* Subtract 0.25 deg from temp */ | |
580 tfrac += 75; | |
581 if (tfrac < 100) | |
582 temp--; | |
583 else | |
584 tfrac -= 100; | |
585 | |
586 i = temp; | |
587 temp *= 100; | |
588 temp += tfrac; | |
589 | |
590 return(temp); | |
591 } |