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