1 ###############################################################################
\r
3 # IAR Atmel AVR C/C++ Compiler V4.30F/W32 13/Mar/2008 04:49:36 #
\r
4 # Copyright 1996-2007 IAR Systems. All rights reserved. #
\r
6 # Source file = C:\home\kevin\pub\src\bc100\IAR\OWI.c #
\r
7 # Command line = C:\home\kevin\pub\src\bc100\IAR\OWI.c #
\r
8 # --cpu=tiny861 -ms -o C:\home\kevin\pub\src\bc10 #
\r
9 # 0\IAR\Release\Obj\ -D NDEBUG -lCN #
\r
10 # C:\home\kevin\pub\src\bc100\IAR\Release\List\ #
\r
11 # -lB C:\home\kevin\pub\src\bc100\IAR\Release\Lis #
\r
12 # t\ --initializers_in_flash -s9 --no_cross_call #
\r
13 # --no_tbaa -DENABLE_BIT_DEFINITIONS -e -I #
\r
14 # "C:\Program Files\IAR Systems\Embedded #
\r
15 # Workbench 4.0\avr\INC\" -I "C:\Program #
\r
16 # Files\IAR Systems\Embedded Workbench #
\r
17 # 4.0\avr\INC\CLIB\" --eeprom_size 512 #
\r
18 # --misrac=5-9,11-12,14,16-17,19-21,24-26,29-32, #
\r
19 # 34-35,38-39,42-43,46,50,52-54,56-59,61-62, #
\r
20 # 64-65,68-80,83-84,87-91,94-95,98-100,103-110, #
\r
22 # Enabled MISRA C rules = 5-9,11-12,14,16-17,19-21,24-26,29-32,34-35, #
\r
23 # 38-39,42-43,46,50,52-54,56-59,61-62,64-65, #
\r
24 # 68-80,83-84,87-91,94-95,98-100,103-110,112-126 #
\r
25 # Checked = 5,7-9,11-12,14,17,19-21,24,29-32,34-35,38-39, #
\r
26 # 42,46,50,52-54,56-59,61-62,64,68-69,71-80, #
\r
27 # 83-84,87-89,91,94-95,98,100,104-105,108-109, #
\r
29 # Not checked = 6,16,25-26,43,65,70,90,99,103,106-107,110, #
\r
31 # List file = C:\home\kevin\pub\src\bc100\IAR\Release\List\OW #
\r
33 # Object file = C:\home\kevin\pub\src\bc100\IAR\Release\Obj\OWI #
\r
37 ###############################################################################
\r
39 C:\home\kevin\pub\src\bc100\IAR\OWI.c
\r
40 1 /* This file has been prepared for Doxygen automatic documentation generation.*/
\r
41 2 /*! \file ********************************************************************
\r
44 5 * Functions for 1-Wire(R) bus communication
\r
46 7 * High level functions for transmission of full bytes on the 1-Wire(R)
\r
47 8 * bus and implementations of ROM commands.\n
\r
48 9 * Polled software only implementation of the basic bit-level signalling
\r
49 10 * in the 1-Wire(R) protocol.\n
\r
50 11 * Includes functions for computing and checking CRC8 & 16 values of data
\r
51 12 * sets, and of 64 bit ROM identifiers.
\r
52 13 * Supported devices: All AVRs.
\r
54 15 * \par Application Note:
\r
55 16 * AVR458: Charging Li-Ion Batteries with BC100\n
\r
56 17 * AVR463: Charging NiMH Batteries with BC100\n
\r
57 18 * One-wire protocol based on AVR318 - Dallas 1-Wire(R) master.
\r
59 20 * \par Documentation:
\r
60 21 * For comprehensive code documentation, supported compilers, compiler
\r
61 22 * settings and supported devices see readme.html
\r
64 25 * Atmel Corporation: http://www.atmel.com \n
\r
65 26 * Support email: avr@atmel.com \n
\r
66 27 * Original author: \n
\r
69 30 * $Revision: 2299 $
\r
71 32 * $URL: http://svn.norway.atmel.com/AppsAVR8/avr458_Charging_Li-Ion_Batteries_with_BC100/tag/20070904_release_1.0/code/IAR/OWI.c $
\r
72 33 * $Date: 2007-08-23 12:55:51 +0200 (to, 23 aug 2007) $\n
\r
73 34 ****************************************************************************/
\r
75 36 #include <ioavr.h>
\r
77 \ In segment ABSOLUTE, at 0x3b
\r
78 \ <unnamed> volatile __io _A_PORTA
\r
82 \ In segment ABSOLUTE, at 0x3a
\r
83 \ <unnamed> volatile __io _A_DDRA
\r
87 \ In segment ABSOLUTE, at 0x39
\r
88 \ <unnamed> volatile __io _A_PINA
\r
91 37 #include <inavr.h>
\r
96 42 //******************************************************************************
\r
98 44 //******************************************************************************
\r
99 45 /*! \brief Initialization of the one wire bus(es). (Software only driver)
\r
101 47 * This function initializes the 1-Wire bus(es) by releasing it and
\r
102 48 * waiting until any presence signals are finished.
\r
104 50 * \param pins A bitmask of the buses to initialize.
\r
107 \ In segment CODE, align 2, keep-with-next
\r
108 52 void OWI_Init(unsigned char pins){
\r
110 53 OWI_RELEASE_BUS(pins);
\r
111 \ 00000000 9500 COM R16
\r
112 \ 00000002 B31A IN R17, 0x1A
\r
113 \ 00000004 2310 AND R17, R16
\r
114 \ 00000006 BB1A OUT 0x1A, R17
\r
115 \ 00000008 B31B IN R17, 0x1B
\r
116 \ 0000000A 2310 AND R17, R16
\r
117 \ 0000000C BB1B OUT 0x1B, R17
\r
118 54 // The first rising edge can be interpreted by a slave as the end of a
\r
119 55 // Reset-pulse. Delay for the required reset recovery time (H) to be
\r
120 56 // sure that the real reset is interpreted correctly.
\r
121 57 __delay_cycles(OWI_DELAY_H_STD_MODE);
\r
122 \ 0000000E EB0C LDI R16, 188
\r
123 \ 00000010 E013 LDI R17, 3
\r
124 \ 00000012 5001 SUBI R16, 1
\r
125 \ 00000014 4010 SBCI R17, 0
\r
126 \ 00000016 F7E9 BRNE $-4
\r
127 \ 00000018 C000 RJMP $+2
\r
129 \ 0000001A 9508 RET
\r
130 \ 0000001C REQUIRE _A_PORTA
\r
131 \ 0000001C REQUIRE _A_DDRA
\r
134 61 /*! \brief Write a '1' bit to the bus(es). (Software only driver)
\r
136 63 * Generates the waveform for transmission of a '1' bit on the 1-Wire
\r
139 66 * \param pins A bitmask of the buses to write to.
\r
142 \ In segment CODE, align 2, keep-with-next
\r
143 68 void OWI_WriteBit1(unsigned char pins){
\r
145 69 unsigned char intState;
\r
147 71 // Disable interrupts.
\r
148 72 intState = __save_interrupt();
\r
149 \ 00000000 B71F IN R17, 0x3F
\r
150 73 __disable_interrupt();
\r
151 \ 00000002 94F8 CLI
\r
153 75 // Drive bus low and delay.
\r
154 76 OWI_PULL_BUS_LOW(pins);
\r
155 \ 00000004 B32A IN R18, 0x1A
\r
156 \ 00000006 2B20 OR R18, R16
\r
157 \ 00000008 BB2A OUT 0x1A, R18
\r
158 \ 0000000A 9500 COM R16
\r
159 \ 0000000C B32B IN R18, 0x1B
\r
160 \ 0000000E 2320 AND R18, R16
\r
161 \ 00000010 BB2B OUT 0x1B, R18
\r
162 77 __delay_cycles(OWI_DELAY_A_STD_MODE);
\r
163 \ 00000012 E02B LDI R18, 11
\r
164 \ 00000014 952A DEC R18
\r
165 \ 00000016 F7F1 BRNE $-2
\r
166 \ 00000018 C000 RJMP $+2
\r
168 79 // Release bus and delay.
\r
169 80 OWI_RELEASE_BUS(pins);
\r
170 \ 0000001A B32A IN R18, 0x1A
\r
171 \ 0000001C 2320 AND R18, R16
\r
172 \ 0000001E BB2A OUT 0x1A, R18
\r
173 \ 00000020 B32B IN R18, 0x1B
\r
174 \ 00000022 2320 AND R18, R16
\r
175 \ 00000024 BB2B OUT 0x1B, R18
\r
176 81 __delay_cycles(OWI_DELAY_B_STD_MODE);
\r
177 \ 00000026 EA06 LDI R16, 166
\r
178 \ 00000028 950A DEC R16
\r
179 \ 0000002A F7F1 BRNE $-2
\r
180 \ 0000002C 0000 NOP
\r
182 83 // Restore interrupts.
\r
183 84 __restore_interrupt(intState);
\r
184 \ 0000002E BF1F OUT 0x3F, R17
\r
186 \ 00000030 9508 RET
\r
187 \ 00000032 REQUIRE _A_PORTA
\r
188 \ 00000032 REQUIRE _A_DDRA
\r
190 87 /*! \brief Write a '0' to the bus(es). (Software only driver)
\r
192 89 * Generates the waveform for transmission of a '0' bit on the 1-Wire(R)
\r
195 92 * \param pins A bitmask of the buses to write to.
\r
198 \ In segment CODE, align 2, keep-with-next
\r
199 94 void OWI_WriteBit0(unsigned char pins)
\r
202 96 unsigned char intState;
\r
204 98 // Disable interrupts.
\r
205 99 intState = __save_interrupt();
\r
206 \ 00000000 B71F IN R17, 0x3F
\r
207 100 __disable_interrupt();
\r
208 \ 00000002 94F8 CLI
\r
210 102 // Drive bus low and delay.
\r
211 103 OWI_PULL_BUS_LOW(pins);
\r
212 \ 00000004 B32A IN R18, 0x1A
\r
213 \ 00000006 2B20 OR R18, R16
\r
214 \ 00000008 BB2A OUT 0x1A, R18
\r
215 \ 0000000A 9500 COM R16
\r
216 \ 0000000C B32B IN R18, 0x1B
\r
217 \ 0000000E 2320 AND R18, R16
\r
218 \ 00000010 BB2B OUT 0x1B, R18
\r
219 104 __delay_cycles(OWI_DELAY_C_STD_MODE);
\r
220 \ 00000012 E92B LDI R18, 155
\r
221 \ 00000014 952A DEC R18
\r
222 \ 00000016 F7F1 BRNE $-2
\r
223 \ 00000018 C000 RJMP $+2
\r
225 106 // Release bus and delay.
\r
226 107 OWI_RELEASE_BUS(pins);
\r
227 \ 0000001A B32A IN R18, 0x1A
\r
228 \ 0000001C 2320 AND R18, R16
\r
229 \ 0000001E BB2A OUT 0x1A, R18
\r
230 \ 00000020 B32B IN R18, 0x1B
\r
231 \ 00000022 2320 AND R18, R16
\r
232 \ 00000024 BB2B OUT 0x1B, R18
\r
233 108 __delay_cycles(OWI_DELAY_D_STD_MODE);
\r
234 \ 00000026 E106 LDI R16, 22
\r
235 \ 00000028 950A DEC R16
\r
236 \ 0000002A F7F1 BRNE $-2
\r
237 \ 0000002C 0000 NOP
\r
239 110 // Restore interrupts.
\r
240 111 __restore_interrupt(intState);
\r
241 \ 0000002E BF1F OUT 0x3F, R17
\r
243 \ 00000030 9508 RET
\r
244 \ 00000032 REQUIRE _A_PORTA
\r
245 \ 00000032 REQUIRE _A_DDRA
\r
247 114 /*! \brief Read a bit from the bus(es). (Software only driver)
\r
249 116 * Generates the waveform for reception of a bit on the 1-Wire(R) bus(es).
\r
251 118 * \param pins A bitmask of the bus(es) to read from.
\r
253 120 * \return A bitmask of the buses where a '1' was read.
\r
256 \ In segment CODE, align 2, keep-with-next
\r
257 122 unsigned char OWI_ReadBit(unsigned char pins)
\r
260 124 unsigned char intState;
\r
261 125 unsigned char bitsRead;
\r
263 127 // Disable interrupts.
\r
264 128 intState = __save_interrupt();
\r
265 \ 00000000 B72F IN R18, 0x3F
\r
266 129 __disable_interrupt();
\r
267 \ 00000002 94F8 CLI
\r
269 131 // Drive bus low and delay.
\r
270 132 OWI_PULL_BUS_LOW(pins);
\r
271 \ 00000004 B31A IN R17, 0x1A
\r
272 \ 00000006 2B10 OR R17, R16
\r
273 \ 00000008 BB1A OUT 0x1A, R17
\r
274 \ 0000000A 2F10 MOV R17, R16
\r
275 \ 0000000C 9510 COM R17
\r
276 \ 0000000E B33B IN R19, 0x1B
\r
277 \ 00000010 2331 AND R19, R17
\r
278 \ 00000012 BB3B OUT 0x1B, R19
\r
279 133 __delay_cycles(OWI_DELAY_A_STD_MODE);
\r
280 \ 00000014 E03B LDI R19, 11
\r
281 \ 00000016 953A DEC R19
\r
282 \ 00000018 F7F1 BRNE $-2
\r
283 \ 0000001A C000 RJMP $+2
\r
285 135 // Release bus and delay.
\r
286 136 OWI_RELEASE_BUS(pins);
\r
287 \ 0000001C B33A IN R19, 0x1A
\r
288 \ 0000001E 2331 AND R19, R17
\r
289 \ 00000020 BB3A OUT 0x1A, R19
\r
290 \ 00000022 B33B IN R19, 0x1B
\r
291 \ 00000024 2331 AND R19, R17
\r
292 \ 00000026 BB3B OUT 0x1B, R19
\r
293 137 __delay_cycles(OWI_DELAY_E_STD_MODE);
\r
294 \ 00000028 E113 LDI R17, 19
\r
295 \ 0000002A 951A DEC R17
\r
296 \ 0000002C F7F1 BRNE $-2
\r
297 \ 0000002E C000 RJMP $+2
\r
299 139 // Sample bus and delay.
\r
300 140 bitsRead = OWI_PIN & pins;
\r
301 \ 00000030 B319 IN R17, 0x19
\r
302 \ 00000032 2310 AND R17, R16
\r
303 141 __delay_cycles(OWI_DELAY_F_STD_MODE);
\r
304 \ 00000034 E80E LDI R16, 142
\r
305 \ 00000036 950A DEC R16
\r
306 \ 00000038 F7F1 BRNE $-2
\r
307 \ 0000003A 0000 NOP
\r
309 143 // Restore interrupts.
\r
310 144 __restore_interrupt(intState);
\r
311 \ 0000003C BF2F OUT 0x3F, R18
\r
313 146 return bitsRead;
\r
314 \ 0000003E 2F01 MOV R16, R17
\r
315 \ 00000040 9508 RET
\r
316 \ 00000042 REQUIRE _A_PORTA
\r
317 \ 00000042 REQUIRE _A_DDRA
\r
318 \ 00000042 REQUIRE _A_PINA
\r
322 150 /*! \brief Send a Reset signal and listen for Presence signal. (software
\r
325 153 * Generates the waveform for transmission of a Reset pulse on the
\r
326 154 * 1-Wire(R) bus and listens for presence signals.
\r
328 156 * \param pins A bitmask of the buses to send the Reset signal on.
\r
330 158 * \return A bitmask of the buses where a presence signal was detected.
\r
333 \ In segment CODE, align 2, keep-with-next
\r
334 160 unsigned char OWI_DetectPresence(unsigned char pins)
\r
335 \ OWI_DetectPresence:
\r
337 162 unsigned char intState;
\r
338 163 unsigned char presenceDetected;
\r
340 165 // Disable interrupts.
\r
341 166 intState = __save_interrupt();
\r
342 \ 00000000 B72F IN R18, 0x3F
\r
343 167 __disable_interrupt();
\r
344 \ 00000002 94F8 CLI
\r
346 169 // Drive bus low and delay.
\r
347 170 OWI_PULL_BUS_LOW(pins);
\r
348 \ 00000004 B31A IN R17, 0x1A
\r
349 \ 00000006 2B10 OR R17, R16
\r
350 \ 00000008 BB1A OUT 0x1A, R17
\r
351 \ 0000000A 2F10 MOV R17, R16
\r
352 \ 0000000C 9510 COM R17
\r
353 \ 0000000E B33B IN R19, 0x1B
\r
354 \ 00000010 2331 AND R19, R17
\r
355 \ 00000012 BB3B OUT 0x1B, R19
\r
356 171 __delay_cycles(OWI_DELAY_H_STD_MODE);
\r
357 \ 00000014 EB4C LDI R20, 188
\r
358 \ 00000016 E053 LDI R21, 3
\r
359 \ 00000018 5041 SUBI R20, 1
\r
360 \ 0000001A 4050 SBCI R21, 0
\r
361 \ 0000001C F7E9 BRNE $-4
\r
362 \ 0000001E C000 RJMP $+2
\r
364 173 // Release bus and delay.
\r
365 174 OWI_RELEASE_BUS(pins);
\r
366 \ 00000020 B33A IN R19, 0x1A
\r
367 \ 00000022 2331 AND R19, R17
\r
368 \ 00000024 BB3A OUT 0x1A, R19
\r
369 \ 00000026 B33B IN R19, 0x1B
\r
370 \ 00000028 2331 AND R19, R17
\r
371 \ 0000002A BB3B OUT 0x1B, R19
\r
372 175 __delay_cycles(OWI_DELAY_I_STD_MODE);
\r
373 \ 0000002C EB16 LDI R17, 182
\r
374 \ 0000002E 951A DEC R17
\r
375 \ 00000030 F7F1 BRNE $-2
\r
376 \ 00000032 0000 NOP
\r
378 177 // Sample bus to detect presence signal and delay.
\r
379 178 presenceDetected = ((~OWI_PIN) & pins);
\r
380 \ 00000034 B319 IN R17, 0x19
\r
381 \ 00000036 9510 COM R17
\r
382 \ 00000038 2301 AND R16, R17
\r
383 179 __delay_cycles(OWI_DELAY_J_STD_MODE);
\r
384 \ 0000003A E340 LDI R20, 48
\r
385 \ 0000003C E053 LDI R21, 3
\r
386 \ 0000003E 5041 SUBI R20, 1
\r
387 \ 00000040 4050 SBCI R21, 0
\r
388 \ 00000042 F7E9 BRNE $-4
\r
389 \ 00000044 C000 RJMP $+2
\r
391 181 // Restore interrupts.
\r
392 182 __restore_interrupt(intState);
\r
393 \ 00000046 BF2F OUT 0x3F, R18
\r
395 184 return presenceDetected;
\r
396 \ 00000048 9508 RET
\r
397 \ 0000004A REQUIRE _A_PORTA
\r
398 \ 0000004A REQUIRE _A_DDRA
\r
399 \ 0000004A REQUIRE _A_PINA
\r
403 188 /*! \brief Sends one byte of data on the 1-Wire(R) bus(es).
\r
405 190 * This function automates the task of sending a complete byte
\r
406 191 * of data on the 1-Wire bus(es).
\r
408 193 * \param data The data to send on the bus(es).
\r
410 195 * \param pins A bitmask of the buses to send the data to.
\r
413 \ In segment CODE, align 2, keep-with-next
\r
414 197 void OWI_SendByte(unsigned char data, unsigned char pins)
\r
417 \ 00000000 93AA ST -Y, R26
\r
418 \ 00000002 939A ST -Y, R25
\r
419 \ 00000004 938A ST -Y, R24
\r
420 \ 00000006 2FA0 MOV R26, R16
\r
421 \ 00000008 2F91 MOV R25, R17
\r
422 199 unsigned char temp;
\r
423 200 unsigned char i;
\r
425 202 // Do once for each bit
\r
426 203 for (i = 0; i < 8; i++) {
\r
427 \ 0000000A E088 LDI R24, 8
\r
428 204 // Determine if LSB is '0' or '1' and transmit corresponding
\r
429 205 // waveform on the bus.
\r
430 206 temp = data & 0x01;
\r
433 \ ??OWI_SendByte_0:
\r
434 \ 0000000C FBA0 BST R26, 0
\r
435 \ 0000000E 2F09 MOV R16, R25
\r
436 \ 00000010 F416 BRTC ??OWI_SendByte_1
\r
437 209 OWI_WriteBit1(pins);
\r
438 \ 00000012 .... RCALL OWI_WriteBit1
\r
439 \ 00000014 C001 RJMP ??OWI_SendByte_2
\r
441 211 OWI_WriteBit0(pins);
\r
442 \ ??OWI_SendByte_1:
\r
443 \ 00000016 .... RCALL OWI_WriteBit0
\r
446 214 data >>= 1; // Right shift the data to get next bit.
\r
447 \ ??OWI_SendByte_2:
\r
448 \ 00000018 95A6 LSR R26
\r
450 \ 0000001A 958A DEC R24
\r
451 \ 0000001C F7B9 BRNE ??OWI_SendByte_0
\r
453 \ 0000001E 9189 LD R24, Y+
\r
454 \ 00000020 9199 LD R25, Y+
\r
455 \ 00000022 91A9 LD R26, Y+
\r
456 \ 00000024 9508 RET
\r
459 219 /*! \brief Receives one byte of data from the 1-Wire(R) bus.
\r
461 221 * This function automates the task of receiving a complete byte
\r
462 222 * of data from the 1-Wire bus.
\r
464 224 * \param pin A bitmask of the bus to read from.
\r
466 226 * \return The byte read from the bus.
\r
469 \ In segment CODE, align 2, keep-with-next
\r
470 228 unsigned char OWI_ReceiveByte(unsigned char pin)
\r
473 \ 00000000 93AA ST -Y, R26
\r
474 \ 00000002 939A ST -Y, R25
\r
475 \ 00000004 938A ST -Y, R24
\r
476 \ 00000006 2FA0 MOV R26, R16
\r
477 230 unsigned char data;
\r
478 231 unsigned char i;
\r
480 233 // Clear the temporary input variable.
\r
482 \ 00000008 E090 LDI R25, 0
\r
484 236 // Do once for each bit
\r
485 237 for (i = 0; i < 8; i++) {
\r
486 \ 0000000A E088 LDI R24, 8
\r
487 238 // Shift temporary input variable right.
\r
489 \ ??OWI_ReceiveByte_0:
\r
490 \ 0000000C 9596 LSR R25
\r
492 241 // Set the MSB if a '1' value is read from the bus.
\r
493 242 // Leave as it is ('0') else.
\r
494 243 if (OWI_ReadBit(pin)) {
\r
495 \ 0000000E 2F0A MOV R16, R26
\r
496 \ 00000010 .... RCALL OWI_ReadBit
\r
497 \ 00000012 2300 TST R16
\r
498 \ 00000014 F009 BREQ ??OWI_ReceiveByte_1
\r
500 \ 00000016 6890 ORI R25, 0x80
\r
503 \ ??OWI_ReceiveByte_1:
\r
504 \ 00000018 958A DEC R24
\r
505 \ 0000001A F7C1 BRNE ??OWI_ReceiveByte_0
\r
508 \ 0000001C 2F09 MOV R16, R25
\r
509 \ 0000001E 9189 LD R24, Y+
\r
510 \ 00000020 9199 LD R25, Y+
\r
511 \ 00000022 91A9 LD R26, Y+
\r
512 \ 00000024 9508 RET
\r
516 252 /*! \brief Sends the SKIP ROM command to the 1-Wire bus(es).
\r
518 254 * \param pins A bitmask of the buses to send the SKIP ROM command to.
\r
521 \ In segment CODE, align 2, keep-with-next
\r
522 256 void OWI_SkipRom(unsigned char pins)
\r
525 258 // Send the SKIP ROM command on the bus.
\r
526 259 OWI_SendByte(OWI_ROM_SKIP, pins);
\r
527 \ 00000000 2F10 MOV R17, R16
\r
528 \ 00000002 EC0C LDI R16, 204
\r
529 \ 00000004 .... RJMP OWI_SendByte
\r
533 263 /*! \brief Sends the READ ROM command and reads back the ROM id.
\r
535 265 * \param romValue A pointer where the id will be placed.
\r
537 267 * \param pin A bitmask of the bus to read from.
\r
540 \ In segment CODE, align 2, keep-with-next
\r
541 269 void OWI_ReadRom(unsigned char * romValue, unsigned char pin)
\r
544 \ 00000000 93BA ST -Y, R27
\r
545 \ 00000002 93AA ST -Y, R26
\r
546 \ 00000004 939A ST -Y, R25
\r
547 \ 00000006 938A ST -Y, R24
\r
548 \ 00000008 01D8 MOVW R27:R26, R17:R16
\r
549 \ 0000000A 2F92 MOV R25, R18
\r
550 271 unsigned char bytesLeft = 8;
\r
552 273 // Send the READ ROM command on the bus.
\r
553 274 OWI_SendByte(OWI_ROM_READ, pin);
\r
554 \ 0000000C 2F12 MOV R17, R18
\r
555 \ 0000000E E303 LDI R16, 51
\r
556 \ 00000010 .... RCALL OWI_SendByte
\r
557 \ 00000012 E088 LDI R24, 8
\r
560 277 while (bytesLeft > 0) {
\r
561 278 // Place the received data in memory.
\r
562 279 *romValue++ = OWI_ReceiveByte(pin);
\r
564 \ 00000014 2F09 MOV R16, R25
\r
565 \ 00000016 .... RCALL OWI_ReceiveByte
\r
566 \ 00000018 930D ST X+, R16
\r
568 \ 0000001A 958A DEC R24
\r
570 \ 0000001C F7D9 BRNE ??OWI_ReadRom_0
\r
572 \ 0000001E REQUIRE ?Subroutine0
\r
573 \ 0000001E ; // Fall through to label ?Subroutine0
\r
575 \ In segment CODE, align 2, keep-with-next
\r
577 \ 00000000 9189 LD R24, Y+
\r
578 \ 00000002 9199 LD R25, Y+
\r
579 \ 00000004 91A9 LD R26, Y+
\r
580 \ 00000006 91B9 LD R27, Y+
\r
581 \ 00000008 9508 RET
\r
584 285 /*! \brief Sends the MATCH ROM command and the ROM id to match against.
\r
586 287 * \param romValue A pointer to the ID to match against.
\r
588 289 * \param pins A bitmask of the buses to perform the MATCH ROM command on.
\r
591 \ In segment CODE, align 2, keep-with-next
\r
592 291 void OWI_MatchRom(unsigned char * romValue, unsigned char pins)
\r
595 \ 00000000 93BA ST -Y, R27
\r
596 \ 00000002 93AA ST -Y, R26
\r
597 \ 00000004 939A ST -Y, R25
\r
598 \ 00000006 938A ST -Y, R24
\r
599 \ 00000008 01D8 MOVW R27:R26, R17:R16
\r
600 \ 0000000A 2F92 MOV R25, R18
\r
601 293 unsigned char bytesLeft = 8;
\r
603 295 // Send the MATCH ROM command.
\r
604 296 OWI_SendByte(OWI_ROM_MATCH, pins);
\r
605 \ 0000000C 2F12 MOV R17, R18
\r
606 \ 0000000E E505 LDI R16, 85
\r
607 \ 00000010 .... RCALL OWI_SendByte
\r
608 \ 00000012 E088 LDI R24, 8
\r
610 298 // Do once for each byte.
\r
611 299 while (bytesLeft > 0) {
\r
612 300 // Transmit 1 byte of the ID to match.
\r
613 301 OWI_SendByte(*romValue++, pins);
\r
614 \ ??OWI_MatchRom_0:
\r
615 \ 00000014 2F19 MOV R17, R25
\r
616 \ 00000016 910D LD R16, X+
\r
617 \ 00000018 .... RCALL OWI_SendByte
\r
619 \ 0000001A 958A DEC R24
\r
621 \ 0000001C F7D9 BRNE ??OWI_MatchRom_0
\r
623 \ 0000001E .... RJMP ?Subroutine0
\r
626 307 /*! \brief Sends the SEARCH ROM command and returns 1 id found on the
\r
627 308 * 1-Wire(R) bus.
\r
629 310 * \param bitPattern A pointer to an 8 byte char array where the
\r
630 311 * discovered identifier will be placed. When
\r
631 312 * searching for several slaves, a copy of the
\r
632 313 * last found identifier should be supplied in
\r
633 314 * the array, or the search will fail.
\r
635 316 * \param lastDeviation The bit position where the algorithm made a
\r
636 317 * choice the last time it was run. This argument
\r
637 318 * should be 0 when a search is initiated. Supplying
\r
638 319 * the return argument of this function when calling
\r
639 320 * repeatedly will go through the complete slave
\r
642 323 * \param pin A bit-mask of the bus to perform a ROM search on.
\r
644 325 * \return The last bit position where there was a discrepancy between slave
\r
645 326 * addresses the last time this function was run. Returns OWI_ROM_SEARCH_FAILED
\r
646 327 * if an error was detected (e.g. a device was connected to the bus during the
\r
647 328 * search), or OWI_ROM_SEARCH_FINISHED when there are no more devices to be
\r
650 331 * \note See main.c for an example of how to utilize this function.
\r
653 \ In segment CODE, align 2, keep-with-next
\r
654 333 unsigned char OWI_SearchRom(unsigned char * bitPattern,
\r
656 334 unsigned char lastDeviation, unsigned char pin)
\r
658 \ 00000000 927A ST -Y, R7
\r
659 \ 00000002 926A ST -Y, R6
\r
660 \ 00000004 925A ST -Y, R5
\r
661 \ 00000006 924A ST -Y, R4
\r
662 \ 00000008 93BA ST -Y, R27
\r
663 \ 0000000A 93AA ST -Y, R26
\r
664 \ 0000000C 939A ST -Y, R25
\r
665 \ 0000000E 938A ST -Y, R24
\r
666 \ 00000010 REQUIRE ?Register_R4_is_cg_reg
\r
667 \ 00000010 REQUIRE ?Register_R5_is_cg_reg
\r
668 \ 00000010 REQUIRE ?Register_R6_is_cg_reg
\r
669 \ 00000010 REQUIRE ?Register_R7_is_cg_reg
\r
670 \ 00000010 01D8 MOVW R27:R26, R17:R16
\r
671 \ 00000012 2E62 MOV R6, R18
\r
672 \ 00000014 2E43 MOV R4, R19
\r
673 336 unsigned char currentBit = 1;
\r
674 \ 00000016 E081 LDI R24, 1
\r
675 337 unsigned char newDeviation = 0;
\r
676 \ 00000018 2455 CLR R5
\r
677 338 unsigned char bitMask = 0x01;
\r
678 \ 0000001A E091 LDI R25, 1
\r
679 339 unsigned char bitA;
\r
680 340 unsigned char bitB;
\r
682 342 // Send SEARCH ROM command on the bus.
\r
683 343 OWI_SendByte(OWI_ROM_SEARCH, pin);
\r
684 \ 0000001C 2F13 MOV R17, R19
\r
685 \ 0000001E EF00 LDI R16, 240
\r
686 \ 00000020 .... RCALL OWI_SendByte
\r
688 345 // Walk through all 64 bits.
\r
689 346 while (currentBit <= 64) {
\r
690 347 // Read bit from bus twice.
\r
691 348 bitA = OWI_ReadBit(pin);
\r
692 \ ??OWI_SearchRom_0:
\r
693 \ 00000022 2D04 MOV R16, R4
\r
694 \ 00000024 .... RCALL OWI_ReadBit
\r
695 \ 00000026 2E70 MOV R7, R16
\r
696 349 bitB = OWI_ReadBit(pin);
\r
697 \ 00000028 2D04 MOV R16, R4
\r
698 \ 0000002A .... RCALL OWI_ReadBit
\r
700 351 if (bitA && bitB) {
\r
701 \ 0000002C 2077 TST R7
\r
702 \ 0000002E F021 BREQ ??OWI_SearchRom_1
\r
703 \ 00000030 2300 TST R16
\r
704 \ 00000032 F011 BREQ ??OWI_SearchRom_1
\r
705 352 // Both bits 1 (Error).
\r
706 353 newDeviation = OWI_ROM_SEARCH_FAILED;
\r
707 354 return newDeviation;
\r
708 \ 00000034 EF0F LDI R16, 255
\r
709 \ 00000036 C02C RJMP ??OWI_SearchRom_2
\r
710 355 } else if (bitA ^ bitB) {
\r
711 \ ??OWI_SearchRom_1:
\r
712 \ 00000038 2507 EOR R16, R7
\r
713 \ 0000003A F069 BREQ ??OWI_SearchRom_3
\r
714 356 // Bits A and B are different. All devices have the same bit here.
\r
715 357 // Set the bit in bitPattern to this value.
\r
717 \ 0000003C 2077 TST R7
\r
718 \ 0000003E F029 BREQ ??OWI_SearchRom_4
\r
719 359 (*bitPattern) |= bitMask;
\r
720 \ ??OWI_SearchRom_5:
\r
721 \ 00000040 01FD MOVW R31:R30, R27:R26
\r
722 \ 00000042 8100 LD R16, Z
\r
723 \ 00000044 2B09 OR R16, R25
\r
724 \ 00000046 8300 ST Z, R16
\r
725 \ 00000048 C014 RJMP ??OWI_SearchRom_6
\r
727 361 (*bitPattern) &= ~bitMask;
\r
728 \ ??OWI_SearchRom_4:
\r
729 \ 0000004A 2F09 MOV R16, R25
\r
730 \ 0000004C 9500 COM R16
\r
731 \ 0000004E 911C LD R17, X
\r
732 \ 00000050 2310 AND R17, R16
\r
733 \ 00000052 931C ST X, R17
\r
734 \ 00000054 C00E RJMP ??OWI_SearchRom_6
\r
737 364 // If this is where a choice was made the last time,
\r
738 365 // a '1' bit is selected this time.
\r
739 366 if (currentBit == lastDeviation) {
\r
740 \ ??OWI_SearchRom_3:
\r
741 \ 00000056 1586 CP R24, R6
\r
742 \ 00000058 F399 BREQ ??OWI_SearchRom_5
\r
743 367 (*bitPattern) |= bitMask;
\r
746 370 // For the rest of the id, '0' bits are selected when
\r
747 371 // discrepancies occur.
\r
748 372 else if (currentBit > lastDeviation) {
\r
749 \ 0000005A 1668 CP R6, R24
\r
750 \ 0000005C F430 BRCC ??OWI_SearchRom_7
\r
751 373 (*bitPattern) &= ~bitMask;
\r
752 \ 0000005E 2F09 MOV R16, R25
\r
753 \ 00000060 9500 COM R16
\r
754 \ 00000062 911C LD R17, X
\r
755 \ 00000064 2310 AND R17, R16
\r
756 \ 00000066 931C ST X, R17
\r
757 374 newDeviation = currentBit;
\r
758 \ 00000068 C003 RJMP ??OWI_SearchRom_8
\r
761 377 // If current bit in bit pattern = 0, then this is
\r
762 378 // out new deviation.
\r
763 379 else if ( !(*bitPattern & bitMask)) {
\r
764 \ ??OWI_SearchRom_7:
\r
765 \ 0000006A 910C LD R16, X
\r
766 \ 0000006C 2309 AND R16, R25
\r
767 \ 0000006E F409 BRNE ??OWI_SearchRom_6
\r
768 380 newDeviation = currentBit;
\r
769 \ ??OWI_SearchRom_8:
\r
770 \ 00000070 2E58 MOV R5, R24
\r
773 383 // IF the bit is already 1, do nothing.
\r
778 388 // Send the selected bit to the bus.
\r
779 389 if ((*bitPattern) & bitMask) {
\r
780 \ ??OWI_SearchRom_6:
\r
781 \ 00000072 910C LD R16, X
\r
782 \ 00000074 2309 AND R16, R25
\r
783 \ 00000076 2D04 MOV R16, R4
\r
784 \ 00000078 F011 BREQ ??OWI_SearchRom_9
\r
785 390 OWI_WriteBit1(pin);
\r
786 \ 0000007A .... RCALL OWI_WriteBit1
\r
787 \ 0000007C C001 RJMP ??OWI_SearchRom_10
\r
789 392 OWI_WriteBit0(pin);
\r
790 \ ??OWI_SearchRom_9:
\r
791 \ 0000007E .... RCALL OWI_WriteBit0
\r
794 395 // Increment current bit.
\r
796 \ ??OWI_SearchRom_10:
\r
797 \ 00000080 9583 INC R24
\r
799 398 // Adjust bitMask and bitPattern pointer.
\r
801 \ 00000082 0F99 LSL R25
\r
802 400 if (!bitMask) {
\r
803 \ 00000084 F411 BRNE ??OWI_SearchRom_11
\r
804 401 bitMask = 0x01;
\r
805 \ 00000086 E091 LDI R25, 1
\r
807 \ 00000088 9611 ADIW R27:R26, 1
\r
810 \ ??OWI_SearchRom_11:
\r
811 \ 0000008A 3481 CPI R24, 65
\r
812 \ 0000008C F250 BRCS ??OWI_SearchRom_0
\r
814 406 return newDeviation;
\r
815 \ 0000008E 2D05 MOV R16, R5
\r
816 \ ??OWI_SearchRom_2:
\r
817 \ 00000090 9189 LD R24, Y+
\r
818 \ 00000092 9199 LD R25, Y+
\r
819 \ 00000094 91A9 LD R26, Y+
\r
820 \ 00000096 91B9 LD R27, Y+
\r
821 \ 00000098 9049 LD R4, Y+
\r
822 \ 0000009A 9059 LD R5, Y+
\r
823 \ 0000009C 9069 LD R6, Y+
\r
824 \ 0000009E 9079 LD R7, Y+
\r
825 \ 000000A0 9508 RET
\r
829 410 /* Functions for handling CRC */
\r
830 411 /*! \brief Compute the CRC8 value of a data set.
\r
832 413 * This function will compute the CRC8 or DOW-CRC of inData using seed
\r
833 414 * as inital value for the CRC.
\r
835 416 * \param inData One byte of data to compute CRC from.
\r
837 418 * \param seed The starting value of the CRC.
\r
839 420 * \return The CRC8 of inData with seed as initial value.
\r
841 422 * \note Setting seed to 0 computes the crc8 of the inData.
\r
843 424 * \note Constantly passing the return value of this function
\r
844 425 * As the seed argument computes the CRC8 value of a
\r
845 426 * longer string of data.
\r
848 \ In segment CODE, align 2, keep-with-next
\r
849 428 unsigned char OWI_ComputeCRC8(unsigned char inData, unsigned char seed)
\r
852 430 unsigned char bitsLeft;
\r
853 431 unsigned char temp;
\r
855 433 for (bitsLeft = 8; bitsLeft > 0; bitsLeft--) {
\r
856 \ 00000000 E038 LDI R19, 8
\r
857 434 temp = ((seed ^ inData) & 0x01);
\r
859 436 if (temp == 0) {
\r
860 \ ??OWI_ComputeCRC8_0:
\r
861 \ 00000002 2F21 MOV R18, R17
\r
862 \ 00000004 7021 ANDI R18, 0x01
\r
863 \ 00000006 2F40 MOV R20, R16
\r
864 \ 00000008 7041 ANDI R20, 0x01
\r
865 \ 0000000A 2742 EOR R20, R18
\r
866 \ 0000000C F411 BRNE ??OWI_ComputeCRC8_1
\r
868 \ 0000000E 9516 LSR R17
\r
869 \ 00000010 C004 RJMP ??OWI_ComputeCRC8_2
\r
874 \ ??OWI_ComputeCRC8_1:
\r
875 \ 00000012 E128 LDI R18, 24
\r
876 \ 00000014 2712 EOR R17, R18
\r
877 \ 00000016 9516 LSR R17
\r
878 \ 00000018 6810 ORI R17, 0x80
\r
882 \ ??OWI_ComputeCRC8_2:
\r
883 \ 0000001A 9506 LSR R16
\r
885 \ 0000001C 953A DEC R19
\r
886 \ 0000001E F789 BRNE ??OWI_ComputeCRC8_0
\r
888 \ 00000020 2F01 MOV R16, R17
\r
889 \ 00000022 9508 RET
\r
893 450 /*! \brief Compute the CRC16 value of a data set.
\r
895 452 * This function will compute the CRC16 of inData using seed
\r
896 453 * as inital value for the CRC.
\r
898 455 * \param inData One byte of data to compute CRC from.
\r
900 457 * \param seed The starting value of the CRC.
\r
902 459 * \return The CRC16 of inData with seed as initial value.
\r
904 461 * \note Setting seed to 0 computes the crc16 of the inData.
\r
906 463 * \note Constantly passing the return value of this function
\r
907 464 * As the seed argument computes the CRC16 value of a
\r
908 465 * longer string of data.
\r
911 \ In segment CODE, align 2, keep-with-next
\r
912 467 unsigned int OWI_ComputeCRC16(unsigned char inData, unsigned int seed)
\r
913 \ OWI_ComputeCRC16:
\r
915 469 unsigned char bitsLeft;
\r
916 470 unsigned char temp;
\r
918 472 for (bitsLeft = 8; bitsLeft > 0; bitsLeft--) {
\r
919 \ 00000000 E018 LDI R17, 8
\r
920 473 temp = ((seed ^ inData) & 0x01);
\r
922 475 if (temp == 0) {
\r
923 \ ??OWI_ComputeCRC16_0:
\r
924 \ 00000002 2F42 MOV R20, R18
\r
925 \ 00000004 7041 ANDI R20, 0x01
\r
926 \ 00000006 2F50 MOV R21, R16
\r
927 \ 00000008 7051 ANDI R21, 0x01
\r
928 \ 0000000A 2754 EOR R21, R20
\r
929 \ 0000000C F419 BRNE ??OWI_ComputeCRC16_1
\r
931 \ 0000000E 9536 LSR R19
\r
932 \ 00000010 9527 ROR R18
\r
933 \ 00000012 C008 RJMP ??OWI_ComputeCRC16_2
\r
935 478 seed ^= 0x4002;
\r
937 480 seed |= 0x8000;
\r
938 \ ??OWI_ComputeCRC16_1:
\r
939 \ 00000014 E042 LDI R20, 2
\r
940 \ 00000016 E450 LDI R21, 64
\r
941 \ 00000018 2742 EOR R20, R18
\r
942 \ 0000001A 2753 EOR R21, R19
\r
943 \ 0000001C 019A MOVW R19:R18, R21:R20
\r
944 \ 0000001E 9536 LSR R19
\r
945 \ 00000020 9527 ROR R18
\r
946 \ 00000022 6830 ORI R19, 0x80
\r
950 \ ??OWI_ComputeCRC16_2:
\r
951 \ 00000024 9506 LSR R16
\r
953 \ 00000026 951A DEC R17
\r
954 \ 00000028 F761 BRNE ??OWI_ComputeCRC16_0
\r
957 \ 0000002A 0189 MOVW R17:R16, R19:R18
\r
958 \ 0000002C 9508 RET
\r
962 490 /*! \brief Calculate and check the CRC of a 64 bit ROM identifier.
\r
964 492 * This function computes the CRC8 value of the first 56 bits of a
\r
965 493 * 64 bit identifier. It then checks the calculated value against the
\r
966 494 * CRC value stored in ROM.
\r
968 496 * \param *romValue A pointer to an array holding a 64 bit identifier.
\r
970 498 * \retval OWI_CRC_OK The CRC's matched.
\r
971 499 * \retval OWI_CRC_ERROR Calculated and stored CRC did not match.
\r
974 \ In segment CODE, align 2, keep-with-next
\r
975 501 unsigned char OWI_CheckRomCRC(unsigned char *romValue)
\r
978 \ 00000000 93BA ST -Y, R27
\r
979 \ 00000002 93AA ST -Y, R26
\r
980 \ 00000004 938A ST -Y, R24
\r
981 \ 00000006 01D8 MOVW R27:R26, R17:R16
\r
982 503 unsigned char i;
\r
983 504 unsigned char crc8 = 0;
\r
984 \ 00000008 E010 LDI R17, 0
\r
986 506 for (i = 0; i < 7; i++) {
\r
987 \ 0000000A E087 LDI R24, 7
\r
988 507 crc8 = OWI_ComputeCRC8(*romValue, crc8);
\r
989 \ ??OWI_CheckRomCRC_0:
\r
990 \ 0000000C 910D LD R16, X+
\r
991 \ 0000000E .... RCALL OWI_ComputeCRC8
\r
992 \ 00000010 2F10 MOV R17, R16
\r
995 \ 00000012 958A DEC R24
\r
996 \ 00000014 F7D9 BRNE ??OWI_CheckRomCRC_0
\r
998 511 if (crc8 == (*romValue)) {
\r
999 \ 00000016 910C LD R16, X
\r
1000 \ 00000018 1710 CP R17, R16
\r
1001 \ 0000001A F411 BRNE ??OWI_CheckRomCRC_1
\r
1002 512 return OWI_CRC_OK;
\r
1003 \ 0000001C E000 LDI R16, 0
\r
1004 \ 0000001E C001 RJMP ??OWI_CheckRomCRC_2
\r
1007 515 return OWI_CRC_ERROR;
\r
1008 \ ??OWI_CheckRomCRC_1:
\r
1009 \ 00000020 E001 LDI R16, 1
\r
1010 \ ??OWI_CheckRomCRC_2:
\r
1011 \ 00000022 9189 LD R24, Y+
\r
1012 \ 00000024 91A9 LD R26, Y+
\r
1013 \ 00000026 91B9 LD R27, Y+
\r
1014 \ 00000028 9508 RET
\r
1017 Maximum stack usage in bytes:
\r
1019 Function CSTACK RSTACK
\r
1020 -------- ------ ------
\r
1021 OWI_CheckRomCRC 3 2
\r
1022 -> OWI_ComputeCRC8 3 2
\r
1023 OWI_ComputeCRC16 0 2
\r
1024 OWI_ComputeCRC8 0 2
\r
1025 OWI_DetectPresence 0 2
\r
1028 -> OWI_SendByte 4 2
\r
1029 -> OWI_SendByte 4 2
\r
1032 -> OWI_SendByte 4 2
\r
1033 -> OWI_ReceiveByte 4 2
\r
1034 OWI_ReceiveByte 3 2
\r
1035 -> OWI_ReadBit 3 2
\r
1037 -> OWI_SendByte 8 2
\r
1038 -> OWI_ReadBit 8 2
\r
1039 -> OWI_ReadBit 8 2
\r
1040 -> OWI_WriteBit1 8 2
\r
1041 -> OWI_WriteBit0 8 2
\r
1043 -> OWI_WriteBit1 3 2
\r
1044 -> OWI_WriteBit0 3 2
\r
1046 -> OWI_SendByte 0 2
\r
1051 Segment part sizes:
\r
1053 Function/Label Bytes
\r
1054 -------------- -----
\r
1062 OWI_DetectPresence 74
\r
1064 OWI_ReceiveByte 38
\r
1070 OWI_ComputeCRC8 36
\r
1071 OWI_ComputeCRC16 46
\r
1072 OWI_CheckRomCRC 42
\r
1075 3 bytes in segment ABSOLUTE
\r
1076 708 bytes in segment CODE
\r
1078 708 bytes of CODE memory
\r
1079 0 bytes of DATA memory (+ 3 bytes shared)
\r