Initial import
[avr_bc100.git] / BaseTinyFirmware / IAR / Debug / List / OWI.s90
1 ///////////////////////////////////////////////////////////////////////////////\r
2 //                                                                            /\r
3 // IAR Atmel AVR C/C++ Compiler V4.30F/W32              12/Mar/2008  23:01:38 /\r
4 // Copyright 1996-2007 IAR Systems. All rights reserved.                      /\r
5 //                                                                            /\r
6 //    Source file  =  C:\home\kevin\pub\src\bc100_cal\IAR\OWI.c               /\r
7 //    Command line =  C:\home\kevin\pub\src\bc100_cal\IAR\OWI.c               /\r
8 //                    --cpu=tiny861 -ms -o C:\home\kevin\pub\src\bc100_cal\IA /\r
9 //                    R\Debug\Obj\ -lC C:\home\kevin\pub\src\bc100_cal\IAR\De /\r
10 //                    bug\List\ -lB C:\home\kevin\pub\src\bc100_cal\IAR\Debug /\r
11 //                    \List\ --initializers_in_flash -z2 --no_cse             /\r
12 //                    --no_inline --no_code_motion --no_cross_call            /\r
13 //                    --no_clustering --no_tbaa --debug                       /\r
14 //                    -DENABLE_BIT_DEFINITIONS -e --require_prototypes -I     /\r
15 //                    "C:\Program Files\IAR Systems\Embedded Workbench        /\r
16 //                    4.0\avr\INC\" -I "C:\Program Files\IAR                  /\r
17 //                    Systems\Embedded Workbench 4.0\avr\INC\CLIB\"           /\r
18 //                    --eeprom_size 512                                       /\r
19 //    List file    =  C:\home\kevin\pub\src\bc100_cal\IAR\Debug\List\OWI.s90  /\r
20 //                                                                            /\r
21 //                                                                            /\r
22 ///////////////////////////////////////////////////////////////////////////////\r
23 \r
24         NAME OWI\r
25 \r
26         RSEG CSTACK:DATA:NOROOT(0)\r
27         RSEG RSTACK:DATA:NOROOT(0)\r
28 \r
29         EXTERN ?EPILOGUE_B3_L09\r
30         EXTERN ?EPILOGUE_B4_L09\r
31         EXTERN ?EPILOGUE_B9_L09\r
32         EXTERN ?PROLOGUE3_L09\r
33         EXTERN ?PROLOGUE4_L09\r
34         EXTERN ?PROLOGUE9_L09\r
35         EXTERN ?Register_R4_is_cg_reg\r
36         EXTERN ?Register_R5_is_cg_reg\r
37         EXTERN ?Register_R6_is_cg_reg\r
38         EXTERN ?Register_R7_is_cg_reg\r
39         EXTERN ?Register_R8_is_cg_reg\r
40 \r
41         PUBLIC OWI_CheckRomCRC\r
42         PUBLIC OWI_ComputeCRC16\r
43         PUBLIC OWI_ComputeCRC8\r
44         PUBLIC OWI_DetectPresence\r
45         PUBLIC OWI_Init\r
46         PUBLIC OWI_MatchRom\r
47         PUBLIC OWI_ReadBit\r
48         PUBLIC OWI_ReadRom\r
49         PUBLIC OWI_ReceiveByte\r
50         PUBLIC OWI_SearchRom\r
51         PUBLIC OWI_SendByte\r
52         PUBLIC OWI_SkipRom\r
53         PUBLIC OWI_WriteBit0\r
54         PUBLIC OWI_WriteBit1\r
55         PUBWEAK _A_DDRA\r
56         PUBWEAK _A_PINA\r
57         PUBWEAK _A_PORTA\r
58         PUBWEAK __?EEARH\r
59         PUBWEAK __?EEARL\r
60         PUBWEAK __?EECR\r
61         PUBWEAK __?EEDR\r
62 \r
63 // C:\home\kevin\pub\src\bc100_cal\IAR\OWI.c\r
64 //    1 /* This file has been prepared for Doxygen automatic documentation generation.*/\r
65 //    2 /*! \file ********************************************************************\r
66 //    3  *\r
67 //    4  * \brief\r
68 //    5  *      Functions for 1-Wire(R) bus communication\r
69 //    6  *\r
70 //    7  *      High level functions for transmission of full bytes on the 1-Wire(R)\r
71 //    8  *      bus and implementations of ROM commands.\n\r
72 //    9  *      Polled software only implementation of the basic bit-level signalling\r
73 //   10  *      in the 1-Wire(R) protocol.\n\r
74 //   11  *      Includes functions for computing and checking CRC8 & 16 values of data\r
75 //   12  *      sets, and of 64 bit ROM identifiers.\r
76 //   13  *      Supported devices:  All AVRs.\r
77 //   14  *\r
78 //   15  * \par Application Note:\r
79 //   16  *      AVR458: Charging Li-Ion Batteries with BC100\n\r
80 //   17  *      AVR463: Charging NiMH Batteries with BC100\n\r
81 //   18  *      One-wire protocol based on AVR318 - Dallas 1-Wire(R) master.\r
82 //   19  *\r
83 //   20  * \par Documentation:\r
84 //   21  *      For comprehensive code documentation, supported compilers, compiler\r
85 //   22  *      settings and supported devices see readme.html\r
86 //   23  *\r
87 //   24  * \author\r
88 //   25  *      Atmel Corporation: http://www.atmel.com \n\r
89 //   26  *      Support email: avr@atmel.com \n\r
90 //   27  *      Original author: \n\r
91 //   28  *\r
92 //   29  * $Name$\r
93 //   30  * $Revision: 2299 $\r
94 //   31  * $RCSfile$\r
95 //   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
96 //   33  * $Date: 2007-08-23 12:55:51 +0200 (to, 23 aug 2007) $\n\r
97 //   34 ****************************************************************************/\r
98 //   35 \r
99 //   36 #include <ioavr.h>\r
100 \r
101         ASEGN ABSOLUTE:DATA:NOROOT,03bH\r
102 // <unnamed> volatile __io _A_PORTA\r
103 _A_PORTA:\r
104         DS 1\r
105 \r
106         ASEGN ABSOLUTE:DATA:NOROOT,03aH\r
107 // <unnamed> volatile __io _A_DDRA\r
108 _A_DDRA:\r
109         DS 1\r
110 \r
111         ASEGN ABSOLUTE:DATA:NOROOT,039H\r
112 // <unnamed> volatile __io _A_PINA\r
113 _A_PINA:\r
114         DS 1\r
115 //   37 #include <inavr.h>\r
116 //   38 \r
117 //   39 #include "OWI.h"\r
118 //   40 \r
119 //   41 \r
120 //   42 //******************************************************************************\r
121 //   43 // Functions\r
122 //   44 //******************************************************************************\r
123 //   45 /*! \brief Initialization of the one wire bus(es). (Software only driver)\r
124 //   46  *  \r
125 //   47  *  This function initializes the 1-Wire bus(es) by releasing it and\r
126 //   48  *  waiting until any presence signals are finished.\r
127 //   49  *\r
128 //   50  *  \param  pins    A bitmask of the buses to initialize.\r
129 //   51  */\r
130 \r
131         RSEG CODE:CODE:NOROOT(1)\r
132 //   52 void OWI_Init(unsigned char pins){\r
133 OWI_Init:\r
134 //   53         OWI_RELEASE_BUS(pins);\r
135         MOV     R17, R16\r
136         COM     R17\r
137         IN      R18, 0x1A\r
138         AND     R18, R17\r
139         OUT     0x1A, R18\r
140         MOV     R17, R16\r
141         COM     R17\r
142         IN      R18, 0x1B\r
143         AND     R18, R17\r
144         OUT     0x1B, R18\r
145 //   54         // The first rising edge can be interpreted by a slave as the end of a\r
146 //   55         // Reset-pulse. Delay for the required reset recovery time (H) to be \r
147 //   56         // sure that the real reset is interpreted correctly.\r
148 //   57         __delay_cycles(OWI_DELAY_H_STD_MODE);\r
149         LDI     R18, 188\r
150         LDI     R19, 3\r
151         SUBI    R18, 1\r
152         SBCI    R19, 0\r
153         BRNE    $-4\r
154         RJMP    $+2\r
155 //   58 }\r
156         RET\r
157         REQUIRE _A_PORTA\r
158         REQUIRE _A_DDRA\r
159 //   59 \r
160 //   60 \r
161 //   61 /*! \brief  Write a '1' bit to the bus(es). (Software only driver)\r
162 //   62  *\r
163 //   63  *  Generates the waveform for transmission of a '1' bit on the 1-Wire\r
164 //   64  *  bus.\r
165 //   65  *\r
166 //   66  *  \param  pins    A bitmask of the buses to write to.\r
167 //   67  */\r
168 \r
169         RSEG CODE:CODE:NOROOT(1)\r
170 //   68 void OWI_WriteBit1(unsigned char pins){\r
171 OWI_WriteBit1:\r
172 //   69         unsigned char intState;\r
173 //   70         \r
174 //   71         // Disable interrupts.\r
175 //   72         intState = __save_interrupt();\r
176         IN      R18, 0x3F\r
177         MOV     R17, R18\r
178 //   73         __disable_interrupt();\r
179         CLI\r
180 //   74         \r
181 //   75         // Drive bus low and delay.\r
182 //   76         OWI_PULL_BUS_LOW(pins);\r
183         IN      R18, 0x1A\r
184         OR      R18, R16\r
185         OUT     0x1A, R18\r
186         MOV     R18, R16\r
187         COM     R18\r
188         IN      R19, 0x1B\r
189         AND     R19, R18\r
190         OUT     0x1B, R19\r
191 //   77         __delay_cycles(OWI_DELAY_A_STD_MODE);\r
192         LDI     R18, 11\r
193         DEC     R18\r
194         BRNE    $-2\r
195         RJMP    $+2\r
196 //   78         \r
197 //   79         // Release bus and delay.\r
198 //   80         OWI_RELEASE_BUS(pins);\r
199         MOV     R18, R16\r
200         COM     R18\r
201         IN      R19, 0x1A\r
202         AND     R19, R18\r
203         OUT     0x1A, R19\r
204         MOV     R18, R16\r
205         COM     R18\r
206         IN      R19, 0x1B\r
207         AND     R19, R18\r
208         OUT     0x1B, R19\r
209 //   81         __delay_cycles(OWI_DELAY_B_STD_MODE);\r
210         LDI     R18, 166\r
211         DEC     R18\r
212         BRNE    $-2\r
213         NOP\r
214 //   82         \r
215 //   83         // Restore interrupts.\r
216 //   84         __restore_interrupt(intState);\r
217         OUT     0x3F, R17\r
218 //   85 }\r
219         RET\r
220         REQUIRE _A_PORTA\r
221         REQUIRE _A_DDRA\r
222 //   86 \r
223 //   87 /*! \brief  Write a '0' to the bus(es). (Software only driver)\r
224 //   88  *\r
225 //   89  *  Generates the waveform for transmission of a '0' bit on the 1-Wire(R)\r
226 //   90  *  bus.\r
227 //   91  *\r
228 //   92  *  \param  pins    A bitmask of the buses to write to.\r
229 //   93  */\r
230 \r
231         RSEG CODE:CODE:NOROOT(1)\r
232 //   94 void OWI_WriteBit0(unsigned char pins)\r
233 OWI_WriteBit0:\r
234 //   95 {\r
235 //   96         unsigned char intState;\r
236 //   97         \r
237 //   98         // Disable interrupts.\r
238 //   99         intState = __save_interrupt();\r
239         IN      R18, 0x3F\r
240         MOV     R17, R18\r
241 //  100         __disable_interrupt();\r
242         CLI\r
243 //  101         \r
244 //  102         // Drive bus low and delay.\r
245 //  103         OWI_PULL_BUS_LOW(pins);\r
246         IN      R18, 0x1A\r
247         OR      R18, R16\r
248         OUT     0x1A, R18\r
249         MOV     R18, R16\r
250         COM     R18\r
251         IN      R19, 0x1B\r
252         AND     R19, R18\r
253         OUT     0x1B, R19\r
254 //  104         __delay_cycles(OWI_DELAY_C_STD_MODE);\r
255         LDI     R18, 155\r
256         DEC     R18\r
257         BRNE    $-2\r
258         RJMP    $+2\r
259 //  105         \r
260 //  106         // Release bus and delay.\r
261 //  107         OWI_RELEASE_BUS(pins);\r
262         MOV     R18, R16\r
263         COM     R18\r
264         IN      R19, 0x1A\r
265         AND     R19, R18\r
266         OUT     0x1A, R19\r
267         MOV     R18, R16\r
268         COM     R18\r
269         IN      R19, 0x1B\r
270         AND     R19, R18\r
271         OUT     0x1B, R19\r
272 //  108         __delay_cycles(OWI_DELAY_D_STD_MODE);\r
273         LDI     R18, 22\r
274         DEC     R18\r
275         BRNE    $-2\r
276         NOP\r
277 //  109         \r
278 //  110         // Restore interrupts.\r
279 //  111         __restore_interrupt(intState);\r
280         OUT     0x3F, R17\r
281 //  112 }\r
282         RET\r
283         REQUIRE _A_PORTA\r
284         REQUIRE _A_DDRA\r
285 //  113 \r
286 //  114 /*! \brief  Read a bit from the bus(es). (Software only driver)\r
287 //  115  *\r
288 //  116  *  Generates the waveform for reception of a bit on the 1-Wire(R) bus(es).\r
289 //  117  *\r
290 //  118  *  \param  pins    A bitmask of the bus(es) to read from.\r
291 //  119  *\r
292 //  120  *  \return A bitmask of the buses where a '1' was read.\r
293 //  121  */\r
294 \r
295         RSEG CODE:CODE:NOROOT(1)\r
296 //  122 unsigned char OWI_ReadBit(unsigned char pins)\r
297 OWI_ReadBit:\r
298 //  123 {\r
299         MOV     R17, R16\r
300 //  124         unsigned char intState;\r
301 //  125         unsigned char bitsRead;\r
302 //  126         \r
303 //  127         // Disable interrupts.\r
304 //  128         intState = __save_interrupt();\r
305         IN      R19, 0x3F\r
306         MOV     R18, R19\r
307 //  129         __disable_interrupt();\r
308         CLI\r
309 //  130         \r
310 //  131         // Drive bus low and delay.\r
311 //  132         OWI_PULL_BUS_LOW(pins);\r
312         IN      R19, 0x1A\r
313         OR      R19, R17\r
314         OUT     0x1A, R19\r
315         MOV     R19, R17\r
316         COM     R19\r
317         IN      R20, 0x1B\r
318         AND     R20, R19\r
319         OUT     0x1B, R20\r
320 //  133         __delay_cycles(OWI_DELAY_A_STD_MODE);\r
321         LDI     R19, 11\r
322         DEC     R19\r
323         BRNE    $-2\r
324         RJMP    $+2\r
325 //  134         \r
326 //  135         // Release bus and delay.\r
327 //  136         OWI_RELEASE_BUS(pins);\r
328         MOV     R19, R17\r
329         COM     R19\r
330         IN      R20, 0x1A\r
331         AND     R20, R19\r
332         OUT     0x1A, R20\r
333         MOV     R19, R17\r
334         COM     R19\r
335         IN      R20, 0x1B\r
336         AND     R20, R19\r
337         OUT     0x1B, R20\r
338 //  137         __delay_cycles(OWI_DELAY_E_STD_MODE);\r
339         LDI     R19, 19\r
340         DEC     R19\r
341         BRNE    $-2\r
342         RJMP    $+2\r
343 //  138         \r
344 //  139         // Sample bus and delay.\r
345 //  140         bitsRead = OWI_PIN & pins;\r
346         IN      R19, 0x19\r
347         AND     R19, R17\r
348         MOV     R16, R19\r
349 //  141         __delay_cycles(OWI_DELAY_F_STD_MODE);\r
350         LDI     R19, 142\r
351         DEC     R19\r
352         BRNE    $-2\r
353         NOP\r
354 //  142         \r
355 //  143         // Restore interrupts.\r
356 //  144         __restore_interrupt(intState);\r
357         OUT     0x3F, R18\r
358 //  145         \r
359 //  146         return bitsRead;\r
360         RET\r
361         REQUIRE _A_PORTA\r
362         REQUIRE _A_DDRA\r
363         REQUIRE _A_PINA\r
364 //  147 }\r
365 //  148 \r
366 //  149 \r
367 //  150 /*! \brief  Send a Reset signal and listen for Presence signal. (software\r
368 //  151  *  only driver)\r
369 //  152  *\r
370 //  153  *  Generates the waveform for transmission of a Reset pulse on the \r
371 //  154  *  1-Wire(R) bus and listens for presence signals.\r
372 //  155  *\r
373 //  156  *  \param  pins    A bitmask of the buses to send the Reset signal on.\r
374 //  157  *\r
375 //  158  *  \return A bitmask of the buses where a presence signal was detected.\r
376 //  159  */\r
377 \r
378         RSEG CODE:CODE:NOROOT(1)\r
379 //  160 unsigned char OWI_DetectPresence(unsigned char pins)\r
380 OWI_DetectPresence:\r
381 //  161 {\r
382         MOV     R17, R16\r
383 //  162         unsigned char intState;\r
384 //  163         unsigned char presenceDetected;\r
385 //  164         \r
386 //  165         // Disable interrupts.\r
387 //  166         intState = __save_interrupt();\r
388         IN      R19, 0x3F\r
389         MOV     R18, R19\r
390 //  167         __disable_interrupt();\r
391         CLI\r
392 //  168         \r
393 //  169         // Drive bus low and delay.\r
394 //  170         OWI_PULL_BUS_LOW(pins);\r
395         IN      R19, 0x1A\r
396         OR      R19, R17\r
397         OUT     0x1A, R19\r
398         MOV     R19, R17\r
399         COM     R19\r
400         IN      R20, 0x1B\r
401         AND     R20, R19\r
402         OUT     0x1B, R20\r
403 //  171         __delay_cycles(OWI_DELAY_H_STD_MODE);\r
404         LDI     R20, 188\r
405         LDI     R21, 3\r
406         SUBI    R20, 1\r
407         SBCI    R21, 0\r
408         BRNE    $-4\r
409         RJMP    $+2\r
410 //  172         \r
411 //  173         // Release bus and delay.\r
412 //  174         OWI_RELEASE_BUS(pins);\r
413         MOV     R19, R17\r
414         COM     R19\r
415         IN      R20, 0x1A\r
416         AND     R20, R19\r
417         OUT     0x1A, R20\r
418         MOV     R19, R17\r
419         COM     R19\r
420         IN      R20, 0x1B\r
421         AND     R20, R19\r
422         OUT     0x1B, R20\r
423 //  175         __delay_cycles(OWI_DELAY_I_STD_MODE);\r
424         LDI     R19, 182\r
425         DEC     R19\r
426         BRNE    $-2\r
427         NOP\r
428 //  176         \r
429 //  177         // Sample bus to detect presence signal and delay.\r
430 //  178         presenceDetected = ((~OWI_PIN) & pins);\r
431         IN      R19, 0x19\r
432         COM     R19\r
433         AND     R19, R17\r
434         MOV     R16, R19\r
435 //  179         __delay_cycles(OWI_DELAY_J_STD_MODE);\r
436         LDI     R20, 48\r
437         LDI     R21, 3\r
438         SUBI    R20, 1\r
439         SBCI    R21, 0\r
440         BRNE    $-4\r
441         RJMP    $+2\r
442 //  180         \r
443 //  181         // Restore interrupts.\r
444 //  182         __restore_interrupt(intState);\r
445         OUT     0x3F, R18\r
446 //  183         \r
447 //  184         return presenceDetected;\r
448         RET\r
449         REQUIRE _A_PORTA\r
450         REQUIRE _A_DDRA\r
451         REQUIRE _A_PINA\r
452 //  185 }\r
453 //  186 \r
454 //  187 \r
455 //  188 /*! \brief  Sends one byte of data on the 1-Wire(R) bus(es).\r
456 //  189  *  \r
457 //  190  *  This function automates the task of sending a complete byte\r
458 //  191  *  of data on the 1-Wire bus(es).\r
459 //  192  *\r
460 //  193  *  \param  data    The data to send on the bus(es).\r
461 //  194  *  \r
462 //  195  *  \param  pins    A bitmask of the buses to send the data to.\r
463 //  196  */\r
464 \r
465         RSEG CODE:CODE:NOROOT(1)\r
466 //  197 void OWI_SendByte(unsigned char data, unsigned char pins)\r
467 OWI_SendByte:\r
468 //  198 {\r
469         RCALL   ?PROLOGUE4_L09\r
470         MOV     R26, R16\r
471         MOV     R25, R17\r
472 //  199         unsigned char temp;\r
473 //  200         unsigned char i;\r
474 //  201         \r
475 //  202         // Do once for each bit\r
476 //  203         for (i = 0; i < 8; i++) {\r
477         LDI     R24, 0\r
478 ??OWI_SendByte_0:\r
479         CPI     R24, 8\r
480         BRCC    ??OWI_SendByte_1\r
481 //  204                 // Determine if LSB is '0' or '1' and transmit corresponding\r
482 //  205                 // waveform on the bus.\r
483 //  206                 temp = data & 0x01;\r
484         MOV     R16, R26\r
485         ANDI    R16, 0x01\r
486         MOV     R27, R16\r
487 //  207                 \r
488 //  208                 if (temp) {\r
489         TST     R27\r
490         BREQ    ??OWI_SendByte_2\r
491 //  209                         OWI_WriteBit1(pins);\r
492         MOV     R16, R25\r
493         RCALL   OWI_WriteBit1\r
494         RJMP    ??OWI_SendByte_3\r
495 //  210                 } else {\r
496 //  211                         OWI_WriteBit0(pins);\r
497 ??OWI_SendByte_2:\r
498         MOV     R16, R25\r
499         RCALL   OWI_WriteBit0\r
500 //  212                 }\r
501 //  213         \r
502 //  214                 data >>= 1;  // Right shift the data to get next bit.\r
503 ??OWI_SendByte_3:\r
504         LSR     R26\r
505 //  215         }\r
506         INC     R24\r
507         RJMP    ??OWI_SendByte_0\r
508 //  216 }\r
509 ??OWI_SendByte_1:\r
510         LDI     R30, 4\r
511         RJMP    ?EPILOGUE_B4_L09\r
512 //  217 \r
513 //  218 \r
514 //  219 /*! \brief  Receives one byte of data from the 1-Wire(R) bus.\r
515 //  220  *\r
516 //  221  *  This function automates the task of receiving a complete byte \r
517 //  222  *  of data from the 1-Wire bus.\r
518 //  223  *\r
519 //  224  *  \param  pin     A bitmask of the bus to read from.\r
520 //  225  *  \r
521 //  226  *  \return     The byte read from the bus.\r
522 //  227  */\r
523 \r
524         RSEG CODE:CODE:NOROOT(1)\r
525 //  228 unsigned char OWI_ReceiveByte(unsigned char pin)\r
526 OWI_ReceiveByte:\r
527 //  229 {\r
528         RCALL   ?PROLOGUE3_L09\r
529         MOV     R26, R16\r
530 //  230         unsigned char data;\r
531 //  231         unsigned char i;\r
532 //  232         \r
533 //  233         // Clear the temporary input variable.\r
534 //  234         data = 0x00;\r
535         LDI     R25, 0\r
536 //  235         \r
537 //  236         // Do once for each bit\r
538 //  237         for (i = 0; i < 8; i++) {\r
539         LDI     R24, 0\r
540 ??OWI_ReceiveByte_0:\r
541         CPI     R24, 8\r
542         BRCC    ??OWI_ReceiveByte_1\r
543 //  238                 // Shift temporary input variable right.\r
544 //  239                 data >>= 1;\r
545         LSR     R25\r
546 //  240                 \r
547 //  241                 // Set the MSB if a '1' value is read from the bus.\r
548 //  242                 // Leave as it is ('0') else.\r
549 //  243                 if (OWI_ReadBit(pin)) {\r
550         MOV     R16, R26\r
551         RCALL   OWI_ReadBit\r
552         TST     R16\r
553         BREQ    ??OWI_ReceiveByte_2\r
554 //  244                         data |= 0x80;\r
555         ORI     R25, 0x80\r
556         LDI     R16, 1\r
557 //  245                 }\r
558 //  246         }\r
559 ??OWI_ReceiveByte_2:\r
560         INC     R24\r
561         RJMP    ??OWI_ReceiveByte_0\r
562 //  247         \r
563 //  248         return data;\r
564 ??OWI_ReceiveByte_1:\r
565         MOV     R16, R25\r
566         LDI     R30, 3\r
567         RJMP    ?EPILOGUE_B3_L09\r
568 //  249 }\r
569 //  250 \r
570 //  251 \r
571 //  252 /*! \brief  Sends the SKIP ROM command to the 1-Wire bus(es).\r
572 //  253  *\r
573 //  254  *  \param  pins    A bitmask of the buses to send the SKIP ROM command to.\r
574 //  255  */\r
575 \r
576         RSEG CODE:CODE:NOROOT(1)\r
577 //  256 void OWI_SkipRom(unsigned char pins)\r
578 OWI_SkipRom:\r
579 //  257 {\r
580         ST      -Y, R24\r
581         MOV     R24, R16\r
582 //  258         // Send the SKIP ROM command on the bus.\r
583 //  259         OWI_SendByte(OWI_ROM_SKIP, pins);\r
584         MOV     R17, R24\r
585         LDI     R16, 204\r
586         RCALL   OWI_SendByte\r
587 //  260 }\r
588         LD      R24, Y+\r
589         RET\r
590 //  261 \r
591 //  262 \r
592 //  263 /*! \brief  Sends the READ ROM command and reads back the ROM id.\r
593 //  264  *\r
594 //  265  *  \param  romValue    A pointer where the id will be placed.\r
595 //  266  *\r
596 //  267  *  \param  pin     A bitmask of the bus to read from.\r
597 //  268  */\r
598 \r
599         RSEG CODE:CODE:NOROOT(1)\r
600 //  269 void OWI_ReadRom(unsigned char * romValue, unsigned char pin)\r
601 OWI_ReadRom:\r
602 //  270 {\r
603         RCALL   ?PROLOGUE4_L09\r
604         MOVW    R27:R26, R17:R16\r
605         MOV     R25, R18\r
606 //  271         unsigned char bytesLeft = 8;\r
607         LDI     R24, 8\r
608 //  272         \r
609 //  273         // Send the READ ROM command on the bus.\r
610 //  274         OWI_SendByte(OWI_ROM_READ, pin);\r
611         MOV     R17, R25\r
612         LDI     R16, 51\r
613         RCALL   OWI_SendByte\r
614 //  275         \r
615 //  276         // Do 8 times.\r
616 //  277         while (bytesLeft > 0) {\r
617 ??OWI_ReadRom_0:\r
618         CPI     R24, 1\r
619         BRCS    ??OWI_ReadRom_1\r
620 //  278                 // Place the received data in memory.\r
621 //  279                 *romValue++ = OWI_ReceiveByte(pin);\r
622         MOV     R16, R25\r
623         RCALL   OWI_ReceiveByte\r
624         ST      X, R16\r
625         ADIW    R27:R26, 1\r
626 //  280                 bytesLeft--;\r
627         DEC     R24\r
628         RJMP    ??OWI_ReadRom_0\r
629 //  281         }\r
630 //  282 }\r
631 ??OWI_ReadRom_1:\r
632         LDI     R30, 4\r
633         RJMP    ?EPILOGUE_B4_L09\r
634 //  283 \r
635 //  284 \r
636 //  285 /*! \brief  Sends the MATCH ROM command and the ROM id to match against.\r
637 //  286  *\r
638 //  287  *  \param  romValue    A pointer to the ID to match against.\r
639 //  288  *\r
640 //  289  *  \param  pins    A bitmask of the buses to perform the MATCH ROM command on.\r
641 //  290  */\r
642 \r
643         RSEG CODE:CODE:NOROOT(1)\r
644 //  291 void OWI_MatchRom(unsigned char * romValue, unsigned char pins)\r
645 OWI_MatchRom:\r
646 //  292 {\r
647         RCALL   ?PROLOGUE4_L09\r
648         MOVW    R27:R26, R17:R16\r
649         MOV     R25, R18\r
650 //  293         unsigned char bytesLeft = 8;   \r
651         LDI     R24, 8\r
652 //  294         \r
653 //  295         // Send the MATCH ROM command.\r
654 //  296         OWI_SendByte(OWI_ROM_MATCH, pins);\r
655         MOV     R17, R25\r
656         LDI     R16, 85\r
657         RCALL   OWI_SendByte\r
658 //  297         \r
659 //  298         // Do once for each byte.\r
660 //  299         while (bytesLeft > 0) {\r
661 ??OWI_MatchRom_0:\r
662         CPI     R24, 1\r
663         BRCS    ??OWI_MatchRom_1\r
664 //  300                 // Transmit 1 byte of the ID to match.\r
665 //  301                 OWI_SendByte(*romValue++, pins);\r
666         MOV     R17, R25\r
667         LD      R16, X\r
668         RCALL   OWI_SendByte\r
669         ADIW    R27:R26, 1\r
670 //  302                 bytesLeft--;\r
671         DEC     R24\r
672         RJMP    ??OWI_MatchRom_0\r
673 //  303         }\r
674 //  304 }\r
675 ??OWI_MatchRom_1:\r
676         LDI     R30, 4\r
677         RJMP    ?EPILOGUE_B4_L09\r
678 //  305 \r
679 //  306 \r
680 //  307 /*! \brief  Sends the SEARCH ROM command and returns 1 id found on the \r
681 //  308  *          1-Wire(R) bus.\r
682 //  309  *\r
683 //  310  *  \param  bitPattern      A pointer to an 8 byte char array where the \r
684 //  311  *                          discovered identifier will be placed. When \r
685 //  312  *                          searching for several slaves, a copy of the \r
686 //  313  *                          last found identifier should be supplied in \r
687 //  314  *                          the array, or the search will fail.\r
688 //  315  *\r
689 //  316  *  \param  lastDeviation   The bit position where the algorithm made a \r
690 //  317  *                          choice the last time it was run. This argument \r
691 //  318  *                          should be 0 when a search is initiated. Supplying \r
692 //  319  *                          the return argument of this function when calling \r
693 //  320  *                          repeatedly will go through the complete slave \r
694 //  321  *                          search.\r
695 //  322  *\r
696 //  323  *  \param  pin             A bit-mask of the bus to perform a ROM search on.\r
697 //  324  *\r
698 //  325  *  \return The last bit position where there was a discrepancy between slave\r
699 //  326  *  addresses the last time this function was run. Returns OWI_ROM_SEARCH_FAILED\r
700 //  327  *  if an error was detected (e.g. a device was connected to the bus during the\r
701 //  328  *  search), or OWI_ROM_SEARCH_FINISHED when there are no more devices to be\r
702 //  329  *  discovered.\r
703 //  330  *\r
704 //  331  *  \note   See main.c for an example of how to utilize this function.\r
705 //  332  */\r
706 \r
707         RSEG CODE:CODE:NOROOT(1)\r
708 //  333 unsigned char OWI_SearchRom(unsigned char * bitPattern,\r
709 OWI_SearchRom:\r
710 //  334                                                 unsigned char lastDeviation, unsigned char pin)\r
711 //  335 {\r
712         RCALL   ?PROLOGUE9_L09\r
713         REQUIRE ?Register_R4_is_cg_reg\r
714         REQUIRE ?Register_R5_is_cg_reg\r
715         REQUIRE ?Register_R6_is_cg_reg\r
716         REQUIRE ?Register_R7_is_cg_reg\r
717         REQUIRE ?Register_R8_is_cg_reg\r
718         MOVW    R5:R4, R17:R16\r
719         MOV     R8, R18\r
720         MOV     R27, R19\r
721 //  336         unsigned char currentBit = 1;\r
722         LDI     R24, 1\r
723 //  337         unsigned char newDeviation = 0;\r
724         LDI     R26, 0\r
725 //  338         unsigned char bitMask = 0x01;\r
726         LDI     R25, 1\r
727 //  339         unsigned char bitA;\r
728 //  340         unsigned char bitB;\r
729 //  341         \r
730 //  342         // Send SEARCH ROM command on the bus.\r
731 //  343         OWI_SendByte(OWI_ROM_SEARCH, pin);\r
732         MOV     R17, R27\r
733         LDI     R16, 240\r
734         RCALL   OWI_SendByte\r
735 //  344         \r
736 //  345         // Walk through all 64 bits.\r
737 //  346         while (currentBit <= 64) {\r
738 ??OWI_SearchRom_0:\r
739         CPI     R24, 65\r
740         BRCS    $+2+2\r
741         RJMP    ??OWI_SearchRom_1\r
742 //  347                 // Read bit from bus twice.\r
743 //  348                 bitA = OWI_ReadBit(pin);\r
744         MOV     R16, R27\r
745         RCALL   OWI_ReadBit\r
746         MOV     R6, R16\r
747 //  349                 bitB = OWI_ReadBit(pin);\r
748         MOV     R16, R27\r
749         RCALL   OWI_ReadBit\r
750         MOV     R7, R16\r
751 //  350                 \r
752 //  351                 if (bitA && bitB) {\r
753         TST     R6\r
754         BREQ    ??OWI_SearchRom_2\r
755         TST     R7\r
756         BREQ    ??OWI_SearchRom_2\r
757 //  352                         // Both bits 1 (Error).\r
758 //  353                         newDeviation = OWI_ROM_SEARCH_FAILED;\r
759         LDI     R26, 255\r
760 //  354                         return newDeviation;\r
761         MOV     R16, R26\r
762         RJMP    ??OWI_SearchRom_3\r
763 //  355                 } else if (bitA ^ bitB) {\r
764 ??OWI_SearchRom_2:\r
765         MOV     R16, R7\r
766         EOR     R16, R6\r
767         TST     R16\r
768         BREQ    ??OWI_SearchRom_4\r
769 //  356                         // Bits A and B are different. All devices have the same bit here.\r
770 //  357                         // Set the bit in bitPattern to this value.\r
771 //  358                         if (bitA) {\r
772         TST     R6\r
773         BREQ    ??OWI_SearchRom_5\r
774 //  359                                 (*bitPattern) |= bitMask;\r
775         MOVW    R31:R30, R5:R4\r
776         LD      R16, Z\r
777         OR      R16, R25\r
778         ST      Z, R16\r
779         RJMP    ??OWI_SearchRom_6\r
780 //  360                         } else {\r
781 //  361                                 (*bitPattern) &= ~bitMask;\r
782 ??OWI_SearchRom_5:\r
783         MOV     R16, R25\r
784         COM     R16\r
785         MOVW    R31:R30, R5:R4\r
786         LD      R17, Z\r
787         AND     R17, R16\r
788         ST      Z, R17\r
789         RJMP    ??OWI_SearchRom_6\r
790 //  362                         }\r
791 //  363                 } else {\r
792 //  364                         // If this is where a choice was made the last time,\r
793 //  365                         // a '1' bit is selected this time.\r
794 //  366                         if (currentBit == lastDeviation) {\r
795 ??OWI_SearchRom_4:\r
796         CP      R24, R8\r
797         BRNE    ??OWI_SearchRom_7\r
798 //  367                                 (*bitPattern) |= bitMask;\r
799         MOVW    R31:R30, R5:R4\r
800         LD      R16, Z\r
801         OR      R16, R25\r
802         ST      Z, R16\r
803         RJMP    ??OWI_SearchRom_6\r
804 //  368                         }\r
805 //  369                         \r
806 //  370                         // For the rest of the id, '0' bits are selected when\r
807 //  371                         // discrepancies occur.\r
808 //  372                         else if (currentBit > lastDeviation) {\r
809 ??OWI_SearchRom_7:\r
810         CP      R8, R24\r
811         BRCC    ??OWI_SearchRom_8\r
812 //  373                                 (*bitPattern) &= ~bitMask;\r
813         MOV     R16, R25\r
814         COM     R16\r
815         MOVW    R31:R30, R5:R4\r
816         LD      R17, Z\r
817         AND     R17, R16\r
818         ST      Z, R17\r
819 //  374                                 newDeviation = currentBit;\r
820         MOV     R26, R24\r
821         RJMP    ??OWI_SearchRom_6\r
822 //  375                         }\r
823 //  376                         \r
824 //  377                         // If current bit in bit pattern = 0, then this is\r
825 //  378                         // out new deviation.\r
826 //  379                         else if ( !(*bitPattern & bitMask)) {\r
827 ??OWI_SearchRom_8:\r
828         MOVW    R31:R30, R5:R4\r
829         LD      R16, Z\r
830         AND     R16, R25\r
831         TST     R16\r
832         BRNE    ??OWI_SearchRom_6\r
833 //  380                                 newDeviation = currentBit;\r
834         MOV     R26, R24\r
835 //  381                         }\r
836 //  382                         \r
837 //  383                 // IF the bit is already 1, do nothing.\r
838 //  384                         else {\r
839 //  385                         }\r
840 //  386                 }\r
841 //  387                 \r
842 //  388                 // Send the selected bit to the bus.\r
843 //  389                 if ((*bitPattern) & bitMask) {\r
844 ??OWI_SearchRom_6:\r
845         MOVW    R31:R30, R5:R4\r
846         LD      R16, Z\r
847         AND     R16, R25\r
848         TST     R16\r
849         BREQ    ??OWI_SearchRom_9\r
850 //  390                         OWI_WriteBit1(pin);\r
851         MOV     R16, R27\r
852         RCALL   OWI_WriteBit1\r
853         RJMP    ??OWI_SearchRom_10\r
854 //  391                 } else {\r
855 //  392                         OWI_WriteBit0(pin);\r
856 ??OWI_SearchRom_9:\r
857         MOV     R16, R27\r
858         RCALL   OWI_WriteBit0\r
859 //  393                 }\r
860 //  394                 \r
861 //  395                 // Increment current bit.    \r
862 //  396                 currentBit++;\r
863 ??OWI_SearchRom_10:\r
864         INC     R24\r
865 //  397                 \r
866 //  398                 // Adjust bitMask and bitPattern pointer.    \r
867 //  399                 bitMask <<= 1;\r
868         LSL     R25\r
869 //  400                 if (!bitMask) {\r
870         TST     R25\r
871         BREQ    $+2+2\r
872         RJMP    ??OWI_SearchRom_0\r
873 //  401                         bitMask = 0x01;\r
874         LDI     R25, 1\r
875 //  402                         bitPattern++;\r
876         LDI     R16, 1\r
877         ADD     R4, R16\r
878         LDI     R16, 0\r
879         ADC     R5, R16\r
880         RJMP    ??OWI_SearchRom_0\r
881 //  403                 }\r
882 //  404         }\r
883 //  405         \r
884 //  406         return newDeviation;\r
885 ??OWI_SearchRom_1:\r
886         MOV     R16, R26\r
887 ??OWI_SearchRom_3:\r
888         LDI     R30, 9\r
889         RJMP    ?EPILOGUE_B9_L09\r
890 //  407 }\r
891 //  408 \r
892 //  409 \r
893 //  410 /* Functions for handling CRC */\r
894 //  411 /*! \brief  Compute the CRC8 value of a data set.\r
895 //  412  *\r
896 //  413  *  This function will compute the CRC8 or DOW-CRC of inData using seed\r
897 //  414  *  as inital value for the CRC.\r
898 //  415  *\r
899 //  416  *  \param  inData  One byte of data to compute CRC from.\r
900 //  417  *\r
901 //  418  *  \param  seed    The starting value of the CRC.\r
902 //  419  *\r
903 //  420  *  \return The CRC8 of inData with seed as initial value.\r
904 //  421  *\r
905 //  422  *  \note   Setting seed to 0 computes the crc8 of the inData.\r
906 //  423  *\r
907 //  424  *  \note   Constantly passing the return value of this function \r
908 //  425  *          As the seed argument computes the CRC8 value of a\r
909 //  426  *          longer string of data.\r
910 //  427  */\r
911 \r
912         RSEG CODE:CODE:NOROOT(1)\r
913 //  428 unsigned char OWI_ComputeCRC8(unsigned char inData, unsigned char seed)\r
914 OWI_ComputeCRC8:\r
915 //  429 {\r
916         MOV     R19, R16\r
917         MOV     R16, R17\r
918 //  430         unsigned char bitsLeft;\r
919 //  431         unsigned char temp;\r
920 //  432         \r
921 //  433         for (bitsLeft = 8; bitsLeft > 0; bitsLeft--) {\r
922         LDI     R17, 8\r
923 ??OWI_ComputeCRC8_0:\r
924         CPI     R17, 1\r
925         BRCS    ??OWI_ComputeCRC8_1\r
926 //  434                 temp = ((seed ^ inData) & 0x01);\r
927         MOV     R21, R16\r
928         ANDI    R21, 0x01\r
929         MOV     R18, R19\r
930         ANDI    R18, 0x01\r
931         EOR     R18, R21\r
932         ANDI    R18, 0x01\r
933         MOV     R20, R18\r
934 //  435                 \r
935 //  436                 if (temp == 0) {\r
936         TST     R20\r
937         BRNE    ??OWI_ComputeCRC8_2\r
938 //  437                 seed >>= 1;\r
939         LSR     R16\r
940         RJMP    ??OWI_ComputeCRC8_3\r
941 //  438                 } else {\r
942 //  439                         seed ^= 0x18;\r
943 ??OWI_ComputeCRC8_2:\r
944         LDI     R18, 24\r
945         EOR     R16, R18\r
946 //  440                         seed >>= 1;\r
947         LSR     R16\r
948 //  441                         seed |= 0x80;\r
949         ORI     R16, 0x80\r
950         LDI     R18, 1\r
951 //  442                 }\r
952 //  443                 \r
953 //  444                 inData >>= 1;\r
954 ??OWI_ComputeCRC8_3:\r
955         LSR     R19\r
956 //  445         }\r
957         DEC     R17\r
958         RJMP    ??OWI_ComputeCRC8_0\r
959 //  446         return seed;    \r
960 ??OWI_ComputeCRC8_1:\r
961         RET\r
962 //  447 }\r
963 //  448 \r
964 //  449 \r
965 //  450 /*! \brief  Compute the CRC16 value of a data set.\r
966 //  451  *\r
967 //  452  *  This function will compute the CRC16 of inData using seed\r
968 //  453  *  as inital value for the CRC.\r
969 //  454  *\r
970 //  455  *  \param  inData  One byte of data to compute CRC from.\r
971 //  456  *\r
972 //  457  *  \param  seed    The starting value of the CRC.\r
973 //  458  *\r
974 //  459  *  \return The CRC16 of inData with seed as initial value.\r
975 //  460  *\r
976 //  461  *  \note   Setting seed to 0 computes the crc16 of the inData.\r
977 //  462  *\r
978 //  463  *  \note   Constantly passing the return value of this function \r
979 //  464  *          As the seed argument computes the CRC16 value of a\r
980 //  465  *          longer string of data.\r
981 //  466  */\r
982 \r
983         RSEG CODE:CODE:NOROOT(1)\r
984 //  467 unsigned int OWI_ComputeCRC16(unsigned char inData, unsigned int seed)\r
985 OWI_ComputeCRC16:\r
986 //  468 {\r
987         MOV     R21, R16\r
988 //  469         unsigned char bitsLeft;\r
989 //  470         unsigned char temp;\r
990 //  471         \r
991 //  472         for (bitsLeft = 8; bitsLeft > 0; bitsLeft--) {\r
992         LDI     R20, 8\r
993 ??OWI_ComputeCRC16_0:\r
994         CPI     R20, 1\r
995         BRCS    ??OWI_ComputeCRC16_1\r
996 //  473                 temp = ((seed ^ inData) & 0x01);\r
997         MOV     R17, R18\r
998         ANDI    R17, 0x01\r
999         MOV     R16, R21\r
1000         ANDI    R16, 0x01\r
1001         EOR     R16, R17\r
1002         ANDI    R16, 0x01\r
1003         MOV     R22, R16\r
1004 //  474                 \r
1005 //  475                 if (temp == 0) {\r
1006         TST     R22\r
1007         BRNE    ??OWI_ComputeCRC16_2\r
1008 //  476                         seed >>= 1;\r
1009         LSR     R19\r
1010         ROR     R18\r
1011         RJMP    ??OWI_ComputeCRC16_3\r
1012 //  477           } else {\r
1013 //  478                         seed ^= 0x4002;\r
1014 ??OWI_ComputeCRC16_2:\r
1015         LDI     R16, 2\r
1016         LDI     R17, 64\r
1017         EOR     R18, R16\r
1018         EOR     R19, R17\r
1019 //  479                         seed >>= 1;\r
1020         LSR     R19\r
1021         ROR     R18\r
1022 //  480                         seed |= 0x8000;\r
1023         ORI     R19, 0x80\r
1024         LDI     R16, 1\r
1025         LDI     R17, 0\r
1026 //  481                 }\r
1027 //  482 \r
1028 //  483                 inData >>= 1;\r
1029 ??OWI_ComputeCRC16_3:\r
1030         LSR     R21\r
1031 //  484         }\r
1032         DEC     R20\r
1033         RJMP    ??OWI_ComputeCRC16_0\r
1034 //  485         \r
1035 //  486         return seed;    \r
1036 ??OWI_ComputeCRC16_1:\r
1037         MOVW    R17:R16, R19:R18\r
1038         RET\r
1039 //  487 }\r
1040 //  488 \r
1041 //  489 \r
1042 //  490 /*! \brief  Calculate and check the CRC of a 64 bit ROM identifier.\r
1043 //  491  *  \r
1044 //  492  *  This function computes the CRC8 value of the first 56 bits of a\r
1045 //  493  *  64 bit identifier. It then checks the calculated value against the\r
1046 //  494  *  CRC value stored in ROM.\r
1047 //  495  *\r
1048 //  496  *  \param  *romValue    A pointer to an array holding a 64 bit identifier.\r
1049 //  497  *\r
1050 //  498  *  \retval OWI_CRC_OK      The CRC's matched.\r
1051 //  499  *  \retval OWI_CRC_ERROR   Calculated and stored CRC did not match.\r
1052 //  500  */\r
1053 \r
1054         RSEG CODE:CODE:NOROOT(1)\r
1055 //  501 unsigned char OWI_CheckRomCRC(unsigned char *romValue)\r
1056 OWI_CheckRomCRC:\r
1057 //  502 {\r
1058         RCALL   ?PROLOGUE4_L09\r
1059         MOVW    R27:R26, R17:R16\r
1060 //  503         unsigned char i;\r
1061 //  504         unsigned char crc8 = 0;\r
1062         LDI     R25, 0\r
1063 //  505         \r
1064 //  506         for (i = 0; i < 7; i++) {\r
1065         LDI     R24, 0\r
1066 ??OWI_CheckRomCRC_0:\r
1067         CPI     R24, 7\r
1068         BRCC    ??OWI_CheckRomCRC_1\r
1069 //  507                 crc8 = OWI_ComputeCRC8(*romValue, crc8);\r
1070         MOV     R17, R25\r
1071         MOVW    R31:R30, R27:R26\r
1072         LD      R16, Z\r
1073         RCALL   OWI_ComputeCRC8\r
1074         MOV     R25, R16\r
1075 //  508                 romValue++;\r
1076         ADIW    R27:R26, 1\r
1077 //  509         }\r
1078         INC     R24\r
1079         RJMP    ??OWI_CheckRomCRC_0\r
1080 //  510         \r
1081 //  511         if (crc8 == (*romValue)) {\r
1082 ??OWI_CheckRomCRC_1:\r
1083         LD      R16, X\r
1084         CP      R25, R16\r
1085         BRNE    ??OWI_CheckRomCRC_2\r
1086 //  512                 return OWI_CRC_OK;\r
1087         LDI     R16, 0\r
1088         RJMP    ??OWI_CheckRomCRC_3\r
1089 //  513         }\r
1090 //  514         \r
1091 //  515         return OWI_CRC_ERROR;\r
1092 ??OWI_CheckRomCRC_2:\r
1093         LDI     R16, 1\r
1094 ??OWI_CheckRomCRC_3:\r
1095         LDI     R30, 4\r
1096         RJMP    ?EPILOGUE_B4_L09\r
1097 //  516 }\r
1098 \r
1099         ASEGN ABSOLUTE:DATA:NOROOT,01cH\r
1100 __?EECR:\r
1101 \r
1102         ASEGN ABSOLUTE:DATA:NOROOT,01dH\r
1103 __?EEDR:\r
1104 \r
1105         ASEGN ABSOLUTE:DATA:NOROOT,01eH\r
1106 __?EEARL:\r
1107 \r
1108         ASEGN ABSOLUTE:DATA:NOROOT,01fH\r
1109 __?EEARH:\r
1110 \r
1111         END\r
1112 // \r
1113 //   3 bytes in segment ABSOLUTE\r
1114 // 820 bytes in segment CODE\r
1115 // \r
1116 // 820 bytes of CODE memory\r
1117 //   0 bytes of DATA memory (+ 3 bytes shared)\r
1118 //\r
1119 //Errors: none\r
1120 //Warnings: none\r