Initial import
[avr_bc100.git] / BaseTinyFirmware / IAR / Debug / List / USI.lst
1 ###############################################################################\r
2 #                                                                             #\r
3 # IAR Atmel AVR C/C++ Compiler V4.30F/W32               12/Mar/2008  23:01:39 #\r
4 # Copyright 1996-2007 IAR Systems. All rights reserved.                       #\r
5 #                                                                             #\r
6 #    Source file  =  C:\home\kevin\pub\src\bc100_cal\IAR\USI.c                #\r
7 #    Command line =  C:\home\kevin\pub\src\bc100_cal\IAR\USI.c --cpu=tiny861  #\r
8 #                    -ms -o C:\home\kevin\pub\src\bc100_cal\IAR\Debug\Obj\    #\r
9 #                    -lC C:\home\kevin\pub\src\bc100_cal\IAR\Debug\List\ -lB  #\r
10 #                    C:\home\kevin\pub\src\bc100_cal\IAR\Debug\List\          #\r
11 #                    --initializers_in_flash -z2 --no_cse --no_inline         #\r
12 #                    --no_code_motion --no_cross_call --no_clustering         #\r
13 #                    --no_tbaa --debug -DENABLE_BIT_DEFINITIONS -e            #\r
14 #                    --require_prototypes -I "C:\Program Files\IAR            #\r
15 #                    Systems\Embedded Workbench 4.0\avr\INC\" -I "C:\Program  #\r
16 #                    Files\IAR Systems\Embedded Workbench 4.0\avr\INC\CLIB\"  #\r
17 #                    --eeprom_size 512                                        #\r
18 #    List file    =  C:\home\kevin\pub\src\bc100_cal\IAR\Debug\List\USI.lst   #\r
19 #    Object file  =  C:\home\kevin\pub\src\bc100_cal\IAR\Debug\Obj\USI.r90    #\r
20 #                                                                             #\r
21 #                                                                             #\r
22 ###############################################################################\r
23 \r
24 C:\home\kevin\pub\src\bc100_cal\IAR\USI.c\r
25       1          /* This file has been prepared for Doxygen automatic documentation generation.*/\r
26       2          /*! \file *********************************************************************\r
27       3           *\r
28       4           * \brief\r
29       5           *      Functions for use of the Universal Serial Interface\r
30       6           *\r
31       7           *      Contains high level functions for initializing the USI as an SPI slave,\r
32       8           *      interrupt handling, sending and receiving single bytes.\r
33       9           *\r
34      10           * \par Application note:\r
35      11           *      AVR458: Charging Li-Ion Batteries with BC100 \n\r
36      12           *      AVR463: Charging NiMH Batteries with BC100\r
37      13           *\r
38      14           * \par Documentation:\r
39      15           *      For comprehensive code documentation, supported compilers, compiler\r
40      16           *      settings and supported devices see readme.html\r
41      17           *\r
42      18           * \author\r
43      19           *      Atmel Corporation: http://www.atmel.com \n\r
44      20           *      Support email: avr@atmel.com \n\r
45      21           *      Original author: \n\r
46      22           *\r
47      23           * $Name$\r
48      24           * $Revision: 2299 $\r
49      25           * $RCSfile$\r
50      26           * $URL: http://svn.norway.atmel.com/AppsAVR8/avr458_Charging_Li-Ion_Batteries_with_BC100/tag/20070904_release_1.0/code/IAR/USI.c $\r
51      27           * $Date: 2007-08-23 12:55:51 +0200 (to, 23 aug 2007) $\n\r
52      28           ******************************************************************************/\r
53      29          \r
54      30          #include <ioavr.h>\r
55 \r
56    \                                 In  segment ABSOLUTE, at 0x38\r
57    \   <unnamed> volatile __io _A_PORTB\r
58    \                     _A_PORTB:\r
59    \   00000000                      DS 1\r
60 \r
61    \                                 In  segment ABSOLUTE, at 0x37\r
62    \   <unnamed> volatile __io _A_DDRB\r
63    \                     _A_DDRB:\r
64    \   00000000                      DS 1\r
65 \r
66    \                                 In  segment ABSOLUTE, at 0x2f\r
67    \   <unnamed> volatile __io _A_USIDR\r
68    \                     _A_USIDR:\r
69    \   00000000                      DS 1\r
70 \r
71    \                                 In  segment ABSOLUTE, at 0x2e\r
72    \   <unnamed> volatile __io _A_USISR\r
73    \                     _A_USISR:\r
74    \   00000000                      DS 1\r
75 \r
76    \                                 In  segment ABSOLUTE, at 0x2d\r
77    \   <unnamed> volatile __io _A_USICR\r
78    \                     _A_USICR:\r
79    \   00000000                      DS 1\r
80      31          #include <inavr.h>\r
81      32          \r
82      33          #include "enums.h"\r
83      34          #include "structs.h"\r
84      35          \r
85      36          #include "main.h"\r
86      37          #include "ADC.h"\r
87      38          #include "battery.h"\r
88      39          #include "time.h"\r
89      40          #include "USI.h"\r
90      41          \r
91      42          \r
92      43          //******************************************************************************\r
93      44          // Variables\r
94      45          //******************************************************************************\r
95      46          //! SPI status struct\r
96 \r
97    \                                 In  segment NEAR_Z, align 1, keep-with-next\r
98    \   00000000                      REQUIRE `?<Segment init: NEAR_Z>`\r
99      47          SPI_Status_t SPI;\r
100    \                     SPI:\r
101    \   00000000                      DS 4\r
102      48          \r
103      49          \r
104      50          //******************************************************************************\r
105      51          //Functions\r
106      52          //*****************************************************************************\r
107      53          /*! \brief USI Counter Overflow Interrupt Service Routine\r
108      54           *\r
109      55           * When the USI counter overflows, a byte has been transferred.\n\r
110      56           * The USIDR contents are stored and flags are updated.\r
111      57           *\r
112      58           * The protocol is quite simple and has three sequential states: command,\r
113      59           * address and data.\r
114      60           * (Keep in mind that the Master is in charge of data clocking, which means\r
115      61           * there is a one byte "delay" from when the Slave puts something to SPI till\r
116      62           * the Master can read it.)\r
117      63           *\r
118      64           * 1. If a non-zero byte is received in the command state, the ISR will\r
119      65           * store the commands to the SPI struct (read/write, EEPROM/SRAM, number of\r
120      66           * bytes). To signal that the command was received, 0xCC is put to the SPI bus.\r
121      67           * If a zero byte (0x00) is received in the command state, it is simply ignored\r
122      68           * because it is an invalid command.\r
123      69           *\r
124      70           * 2. When a byte is received in the address state, it is stored to the SPI\r
125      71           * struct. To signal that the address was received, 0xBB is put to SPI bus.\r
126      72           * \r
127      73           * 3. In the data state, variables are read/written "from back to front" until\r
128      74           * the byte counter reaches zero. Since the Master is in charge of the data\r
129      75           * clocking, the Slave will go to command state before the last byte is\r
130      76           * transferred during reading. This means that the Master should send an \r
131      77           * invalid command when getting each byte, ie 0x00.\r
132      78           *\r
133      79           * If the time between two transfers is 1 second or more, the Slave\r
134      80           * automatically reverts to command state.\r
135      81           *\r
136      82           * \note Battery charging is not automatically halted during SPI communication.\r
137      83           * This means that the current charge state (current and voltage) will\r
138      84           * remain constant during heavy and prolonged serial traffic.\r
139      85           *\r
140      86           * \todo Variable writing not implemented yet.\r
141      87           * \todo EEPROM/SRAM flag doesn't really do anything with this implementation.\r
142      88           */\r
143      89          #pragma vector=USI_OVF_vect\r
144 \r
145    \                                 In  segment CODE, align 2, keep-with-next\r
146      90          __interrupt void USI_OVF_ISR(void)\r
147    \                     USI_OVF_ISR:\r
148      91          {\r
149    \   00000000   93AA               ST      -Y, R26\r
150    \   00000002   939A               ST      -Y, R25\r
151    \   00000004   938A               ST      -Y, R24\r
152    \   00000006   93FA               ST      -Y, R31\r
153    \   00000008   93EA               ST      -Y, R30\r
154    \   0000000A   923A               ST      -Y, R3\r
155    \   0000000C   922A               ST      -Y, R2\r
156    \   0000000E   921A               ST      -Y, R1\r
157    \   00000010   920A               ST      -Y, R0\r
158    \   00000012   937A               ST      -Y, R23\r
159    \   00000014   936A               ST      -Y, R22\r
160    \   00000016   935A               ST      -Y, R21\r
161    \   00000018   934A               ST      -Y, R20\r
162    \   0000001A   933A               ST      -Y, R19\r
163    \   0000001C   932A               ST      -Y, R18\r
164    \   0000001E   931A               ST      -Y, R17\r
165    \   00000020   930A               ST      -Y, R16\r
166    \   00000022   B7AF               IN      R26, 0x3F\r
167      92                 // If the communication timed out, set ST_CMD as current state.\r
168      93                 if (!Time_Left(TIMER_USI)) {\r
169    \   00000024   E000               LDI     R16, 0\r
170    \   00000026   ....               RCALL   Time_Left\r
171    \   00000028   2300               TST     R16\r
172    \   0000002A   F431               BRNE    ??USI_OVF_ISR_0\r
173      94                         SPI.State = ST_CMD;\r
174    \   0000002C   9100....           LDS     R16, (SPI + 2)\r
175    \   00000030   730F               ANDI    R16, 0x3F\r
176    \   00000032   6400               ORI     R16, 0x40\r
177    \   00000034   9300....           STS     (SPI + 2), R16\r
178      95                 }\r
179      96          \r
180      97                 // Start communication timer. If further communication doesn't happen\r
181      98                 // within 1 second, the SPI communication state is reset to CMD.\r
182      99                 Time_Set(TIMER_USI, 0, 1, 0);\r
183    \                     ??USI_OVF_ISR_0:\r
184    \   00000038   E040               LDI     R20, 0\r
185    \   0000003A   E011               LDI     R17, 1\r
186    \   0000003C   E020               LDI     R18, 0\r
187    \   0000003E   E030               LDI     R19, 0\r
188    \   00000040   E000               LDI     R16, 0\r
189    \   00000042   ....               RCALL   Time_Set\r
190     100                 \r
191     101                 // Clear USI counter and flag completed transfer.\r
192     102                 USISR = (1<<USIOIF);\r
193    \   00000044   E400               LDI     R16, 64\r
194    \   00000046   B90E               OUT     0x0E, R16\r
195     103                 SPI.XferComplete = TRUE;\r
196    \   00000048   ....               LDI     R30, LOW(SPI)\r
197    \   0000004A   ....               LDI     R31, (SPI) >> 8\r
198    \   0000004C   8103               LDD     R16, Z+3\r
199    \   0000004E   6004               ORI     R16, 0x04\r
200    \   00000050   8303               STD     Z+3, R16\r
201     104                 \r
202     105                 // Process incoming data.\r
203     106                 switch(SPI.State)       {\r
204    \   00000052   9100....           LDS     R16, (SPI + 2)\r
205    \   00000056   0F00               LSL     R16\r
206    \   00000058   1F00               ROL     R16\r
207    \   0000005A   1F00               ROL     R16\r
208    \   0000005C   7003               ANDI    R16, 0x03\r
209    \   0000005E   5001               SUBI    R16, 1\r
210    \   00000060   F039               BREQ    ??USI_OVF_ISR_1\r
211    \   00000062   950A               DEC     R16\r
212    \   00000064   F409               BRNE    $+2+2\r
213    \   00000066   C040               RJMP    ??USI_OVF_ISR_2\r
214    \   00000068   950A               DEC     R16\r
215    \   0000006A   F409               BRNE    $+2+2\r
216    \   0000006C   C050               RJMP    ??USI_OVF_ISR_3\r
217    \   0000006E   C0C0               RJMP    ??USI_OVF_ISR_4\r
218     107                 // A valid SPI transfer starts with a Command Byte sent by the Master.\r
219     108                 case ST_CMD:   \r
220     109                         SPI.Data = USIDR;  // Store the transferred byte.\r
221    \                     ??USI_OVF_ISR_1:\r
222    \   00000070   B10F               IN      R16, 0x0F\r
223    \   00000072   9110....           LDS     R17, SPI\r
224    \   00000076   9300....           STS     SPI, R16\r
225     110                         \r
226     111                         // If the master sent 0, it is trying to get data. Ignore in this state.\r
227     112                         if (SPI.Data != 0) {\r
228    \   0000007A   9100....           LDS     R16, SPI\r
229    \   0000007E   2300               TST     R16\r
230    \   00000080   F409               BRNE    $+2+2\r
231    \   00000082   C0B6               RJMP    ??USI_OVF_ISR_4\r
232     113                                 // Does the master want to read or write?\r
233     114                                 if (SPI.Data & 0x40) {\r
234    \   00000084   ....               LDI     R30, LOW(SPI)\r
235    \   00000086   ....               LDI     R31, (SPI) >> 8\r
236    \   00000088   8100               LD      R16, Z\r
237    \   0000008A   FF06               SBRS    R16, 6\r
238    \   0000008C   C006               RJMP    ??USI_OVF_ISR_5\r
239     115                                         SPI.Read = FALSE;\r
240    \   0000008E   ....               LDI     R30, LOW(SPI)\r
241    \   00000090   ....               LDI     R31, (SPI) >> 8\r
242    \   00000092   8103               LDD     R16, Z+3\r
243    \   00000094   7F0E               ANDI    R16, 0xFE\r
244    \   00000096   8303               STD     Z+3, R16\r
245    \   00000098   C005               RJMP    ??USI_OVF_ISR_6\r
246     116                                 } else {\r
247     117                                         SPI.Read = TRUE;\r
248    \                     ??USI_OVF_ISR_5:\r
249    \   0000009A   ....               LDI     R30, LOW(SPI)\r
250    \   0000009C   ....               LDI     R31, (SPI) >> 8\r
251    \   0000009E   8103               LDD     R16, Z+3\r
252    \   000000A0   6001               ORI     R16, 0x01\r
253    \   000000A2   8303               STD     Z+3, R16\r
254     118                                 }\r
255     119          \r
256     120                                         // From/to EEPROM or SRAM?\r
257     121                                 if (SPI.Data &0x80) {\r
258    \                     ??USI_OVF_ISR_6:\r
259    \   000000A4   ....               LDI     R30, LOW(SPI)\r
260    \   000000A6   ....               LDI     R31, (SPI) >> 8\r
261    \   000000A8   8100               LD      R16, Z\r
262    \   000000AA   FF07               SBRS    R16, 7\r
263    \   000000AC   C006               RJMP    ??USI_OVF_ISR_7\r
264     122                                         SPI.EEPROM = TRUE;\r
265    \   000000AE   ....               LDI     R30, LOW(SPI)\r
266    \   000000B0   ....               LDI     R31, (SPI) >> 8\r
267    \   000000B2   8103               LDD     R16, Z+3\r
268    \   000000B4   6002               ORI     R16, 0x02\r
269    \   000000B6   8303               STD     Z+3, R16\r
270    \   000000B8   C005               RJMP    ??USI_OVF_ISR_8\r
271     123                                 } else {\r
272     124                                         SPI.EEPROM = FALSE;\r
273    \                     ??USI_OVF_ISR_7:\r
274    \   000000BA   ....               LDI     R30, LOW(SPI)\r
275    \   000000BC   ....               LDI     R31, (SPI) >> 8\r
276    \   000000BE   8103               LDD     R16, Z+3\r
277    \   000000C0   7F0D               ANDI    R16, 0xFD\r
278    \   000000C2   8303               STD     Z+3, R16\r
279     125                                 }\r
280     126          \r
281     127                                 SPI.Count = (SPI.Data & 0x3F);  // Get number of bytes to receive/send.\r
282    \                     ??USI_OVF_ISR_8:\r
283    \   000000C4   9110....           LDS     R17, (SPI + 2)\r
284    \   000000C8   7C10               ANDI    R17, 0xC0\r
285    \   000000CA   9100....           LDS     R16, SPI\r
286    \   000000CE   730F               ANDI    R16, 0x3F\r
287    \   000000D0   2B01               OR      R16, R17\r
288    \   000000D2   9300....           STS     (SPI + 2), R16\r
289     128                                 SPI.State = ST_ADDR;  // The Master will send the address byte next.\r
290    \   000000D6   9100....           LDS     R16, (SPI + 2)\r
291    \   000000DA   730F               ANDI    R16, 0x3F\r
292    \   000000DC   6800               ORI     R16, 0x80\r
293    \   000000DE   9300....           STS     (SPI + 2), R16\r
294     129          \r
295     130                                 SPI_Put(0xCC);  // Signal that command was received.\r
296    \   000000E2   EC0C               LDI     R16, 204\r
297    \   000000E4   ....               RCALL   SPI_Put\r
298    \   000000E6   C084               RJMP    ??USI_OVF_ISR_4\r
299     131                         }\r
300     132                 break;\r
301     133          \r
302     134                                 \r
303     135                 case ST_ADDR:  \r
304     136                         SPI.Data = USIDR;  // Store the address.\r
305    \                     ??USI_OVF_ISR_2:\r
306    \   000000E8   B10F               IN      R16, 0x0F\r
307    \   000000EA   9180....           LDS     R24, SPI\r
308    \   000000EE   9300....           STS     SPI, R16\r
309     137                         SPI.Address = SPI.Data;\r
310    \   000000F2   9190....           LDS     R25, (SPI + 1)\r
311    \   000000F6   9100....           LDS     R16, SPI\r
312    \   000000FA   9300....           STS     (SPI + 1), R16\r
313     138                         SPI.State = ST_DATA;  // The master will send/wait for data next.\r
314    \   000000FE   ....               LDI     R30, LOW(SPI)\r
315    \   00000100   ....               LDI     R31, (SPI) >> 8\r
316    \   00000102   8102               LDD     R16, Z+2\r
317    \   00000104   6C00               ORI     R16, 0xC0\r
318    \   00000106   8302               STD     Z+2, R16\r
319     139          \r
320     140                         SPI_Put(0xBB);  // Signal that address was received.\r
321    \   00000108   EB0B               LDI     R16, 187\r
322    \   0000010A   ....               RCALL   SPI_Put\r
323    \   0000010C   C071               RJMP    ??USI_OVF_ISR_4\r
324     141                 break;\r
325     142          \r
326     143          \r
327     144                 // Note well: this will process at least one byte, regardless of Count.\r
328     145                 case ST_DATA:\r
329     146                         if (SPI.Count-- > 0) {\r
330    \                     ??USI_OVF_ISR_3:\r
331    \   0000010E   9100....           LDS     R16, (SPI + 2)\r
332    \   00000112   2F20               MOV     R18, R16\r
333    \   00000114   7C20               ANDI    R18, 0xC0\r
334    \   00000116   2F10               MOV     R17, R16\r
335    \   00000118   951A               DEC     R17\r
336    \   0000011A   731F               ANDI    R17, 0x3F\r
337    \   0000011C   2B12               OR      R17, R18\r
338    \   0000011E   9310....           STS     (SPI + 2), R17\r
339    \   00000122   730F               ANDI    R16, 0x3F\r
340    \   00000124   3001               CPI     R16, 1\r
341    \   00000126   F408               BRCC    $+2+2\r
342    \   00000128   C05D               RJMP    ??USI_OVF_ISR_9\r
343     147                                 // Write specified variable to SPI, "back to front".\r
344     148                                 if (SPI.Read) {\r
345    \   0000012A   ....               LDI     R30, LOW(SPI)\r
346    \   0000012C   ....               LDI     R31, (SPI) >> 8\r
347    \   0000012E   8103               LDD     R16, Z+3\r
348    \   00000130   FF00               SBRS    R16, 0\r
349    \   00000132   C043               RJMP    ??USI_OVF_ISR_10\r
350     149                                         switch (SPI.Address) {\r
351    \   00000134   9100....           LDS     R16, (SPI + 1)\r
352    \   00000138   5001               SUBI    R16, 1\r
353    \   0000013A   F049               BREQ    ??USI_OVF_ISR_11\r
354    \   0000013C   950A               DEC     R16\r
355    \   0000013E   F089               BREQ    ??USI_OVF_ISR_12\r
356    \   00000140   950A               DEC     R16\r
357    \   00000142   F0C9               BREQ    ??USI_OVF_ISR_13\r
358    \   00000144   950A               DEC     R16\r
359    \   00000146   F109               BREQ    ??USI_OVF_ISR_14\r
360    \   00000148   950A               DEC     R16\r
361    \   0000014A   F151               BREQ    ??USI_OVF_ISR_15\r
362    \   0000014C   C033               RJMP    ??USI_OVF_ISR_16\r
363     150                                         case ADR_ADCS:\r
364     151                                                 SPI_Put(*(((unsigned char*)&ADCS) + (SPI.Count)));\r
365    \                     ??USI_OVF_ISR_11:\r
366    \   0000014E   9100....           LDS     R16, (SPI + 2)\r
367    \   00000152   730F               ANDI    R16, 0x3F\r
368    \   00000154   E010               LDI     R17, 0\r
369    \   00000156   01F8               MOVW    R31:R30, R17:R16\r
370    \   00000158   ....               SUBI    R30, LOW((-(ADCS) & 0xFFFF))\r
371    \   0000015A   ....               SBCI    R31, (-(ADCS) & 0xFFFF) >> 8\r
372    \   0000015C   8100               LD      R16, Z\r
373    \   0000015E   ....               RCALL   SPI_Put\r
374    \   00000160   C047               RJMP    ??USI_OVF_ISR_4\r
375     152                                         break;\r
376     153                                         \r
377     154                                         \r
378     155                                         case ADR_BATTACTIVE:\r
379     156                                                 SPI_Put(*((unsigned char*)&BattActive + (SPI.Count)));\r
380    \                     ??USI_OVF_ISR_12:\r
381    \   00000162   9100....           LDS     R16, (SPI + 2)\r
382    \   00000166   730F               ANDI    R16, 0x3F\r
383    \   00000168   E010               LDI     R17, 0\r
384    \   0000016A   01F8               MOVW    R31:R30, R17:R16\r
385    \   0000016C   ....               SUBI    R30, LOW((-(BattActive) & 0xFFFF))\r
386    \   0000016E   ....               SBCI    R31, (-(BattActive) & 0xFFFF) >> 8\r
387    \   00000170   8100               LD      R16, Z\r
388    \   00000172   ....               RCALL   SPI_Put\r
389    \   00000174   C03D               RJMP    ??USI_OVF_ISR_4\r
390     157                                         break;\r
391     158                                         \r
392     159                                         \r
393     160                                         case ADR_BATTDATA:\r
394     161                                                 SPI_Put(*((unsigned char*)&BattData + (SPI.Count)));\r
395    \                     ??USI_OVF_ISR_13:\r
396    \   00000176   9100....           LDS     R16, (SPI + 2)\r
397    \   0000017A   730F               ANDI    R16, 0x3F\r
398    \   0000017C   E010               LDI     R17, 0\r
399    \   0000017E   01F8               MOVW    R31:R30, R17:R16\r
400    \   00000180   ....               SUBI    R30, LOW((-(BattData) & 0xFFFF))\r
401    \   00000182   ....               SBCI    R31, (-(BattData) & 0xFFFF) >> 8\r
402    \   00000184   8100               LD      R16, Z\r
403    \   00000186   ....               RCALL   SPI_Put\r
404    \   00000188   C033               RJMP    ??USI_OVF_ISR_4\r
405     162                                         break;\r
406     163                                         \r
407     164                                         \r
408     165                                         case ADR_BATTCTRL:\r
409     166                                                 SPI_Put(*((__eeprom unsigned char*)&BattControl + (SPI.Count)));\r
410    \                     ??USI_OVF_ISR_14:\r
411    \   0000018A   9100....           LDS     R16, (SPI + 2)\r
412    \   0000018E   730F               ANDI    R16, 0x3F\r
413    \   00000190   E010               LDI     R17, 0\r
414    \   00000192   ....               LDI     R20, LOW(BattControl)\r
415    \   00000194   ....               LDI     R21, (BattControl) >> 8\r
416    \   00000196   0F40               ADD     R20, R16\r
417    \   00000198   1F51               ADC     R21, R17\r
418    \   0000019A   ....               RCALL   __eeget8_16\r
419    \   0000019C   ....               RCALL   SPI_Put\r
420    \   0000019E   C028               RJMP    ??USI_OVF_ISR_4\r
421     167                                         break;\r
422     168                                         \r
423     169                                         case ADR_TIMERS:\r
424     170                                                 SPI_Put(*((unsigned char*)&timeval + (SPI.Count)));\r
425    \                     ??USI_OVF_ISR_15:\r
426    \   000001A0   9100....           LDS     R16, (SPI + 2)\r
427    \   000001A4   730F               ANDI    R16, 0x3F\r
428    \   000001A6   E010               LDI     R17, 0\r
429    \   000001A8   01F8               MOVW    R31:R30, R17:R16\r
430    \   000001AA   ....               SUBI    R30, LOW((-(timeval) & 0xFFFF))\r
431    \   000001AC   ....               SBCI    R31, (-(timeval) & 0xFFFF) >> 8\r
432    \   000001AE   8100               LD      R16, Z\r
433    \   000001B0   ....               RCALL   SPI_Put\r
434    \   000001B2   C01E               RJMP    ??USI_OVF_ISR_4\r
435     171                                         break;\r
436     172          \r
437     173                                         \r
438     174                                         default:\r
439     175                                                 SPI_Put(0);\r
440    \                     ??USI_OVF_ISR_16:\r
441    \   000001B4   E000               LDI     R16, 0\r
442    \   000001B6   ....               RCALL   SPI_Put\r
443    \   000001B8   C01B               RJMP    ??USI_OVF_ISR_4\r
444     176                                         break;\r
445     177                                         }\r
446     178                                 } else {\r
447     179                                         // Read byte from SPI\r
448     180                                         SPI.Data = USIDR;\r
449    \                     ??USI_OVF_ISR_10:\r
450    \   000001BA   B10F               IN      R16, 0x0F\r
451    \   000001BC   9110....           LDS     R17, SPI\r
452    \   000001C0   9300....           STS     SPI, R16\r
453     181          \r
454     182                                         // ********************************************\r
455     183                                         // THIS FUNCTION HAS NOT BEEN FULLY IMPLEMENTED\r
456     184                                         // ********************************************\r
457     185                                                                         \r
458     186                                         // Save byte to specified variable.\r
459     187                                         switch (SPI.Address) {\r
460    \   000001C4   9100....           LDS     R16, (SPI + 1)\r
461    \   000001C8   5004               SUBI    R16, 4\r
462    \   000001CA   F491               BRNE    ??USI_OVF_ISR_4\r
463     188                                         case ADR_BATTCTRL:\r
464     189                                                 *((__eeprom unsigned char*)&BattControl + SPI.Count) = SPI.Data;\r
465    \   000001CC   9100....           LDS     R16, SPI\r
466    \   000001D0   9120....           LDS     R18, (SPI + 2)\r
467    \   000001D4   732F               ANDI    R18, 0x3F\r
468    \   000001D6   E030               LDI     R19, 0\r
469    \   000001D8   ....               LDI     R20, LOW(BattControl)\r
470    \   000001DA   ....               LDI     R21, (BattControl) >> 8\r
471    \   000001DC   0F42               ADD     R20, R18\r
472    \   000001DE   1F53               ADC     R21, R19\r
473    \   000001E0   ....               RCALL   __eeput8_16\r
474    \   000001E2   C006               RJMP    ??USI_OVF_ISR_4\r
475     190                                         break;\r
476     191          \r
477     192                                         \r
478     193                                         default:\r
479     194                                         break;\r
480     195                                         }\r
481     196                                 }\r
482     197                                 \r
483     198          \r
484     199                         } else {\r
485     200                                 SPI.State = ST_CMD;\r
486    \                     ??USI_OVF_ISR_9:\r
487    \   000001E4   9100....           LDS     R16, (SPI + 2)\r
488    \   000001E8   730F               ANDI    R16, 0x3F\r
489    \   000001EA   6400               ORI     R16, 0x40\r
490    \   000001EC   9300....           STS     (SPI + 2), R16\r
491     201                         }\r
492     202                 break;\r
493     203          \r
494     204                 default:  // Shouldn't end up here. (Unknown SPI-state)\r
495     205                 break;\r
496     206                 }\r
497     207          }\r
498    \                     ??USI_OVF_ISR_4:\r
499    \   000001F0   BFAF               OUT     0x3F, R26\r
500    \   000001F2   9109               LD      R16, Y+\r
501    \   000001F4   9119               LD      R17, Y+\r
502    \   000001F6   9129               LD      R18, Y+\r
503    \   000001F8   9139               LD      R19, Y+\r
504    \   000001FA   9149               LD      R20, Y+\r
505    \   000001FC   9159               LD      R21, Y+\r
506    \   000001FE   9169               LD      R22, Y+\r
507    \   00000200   9179               LD      R23, Y+\r
508    \   00000202   9009               LD      R0, Y+\r
509    \   00000204   9019               LD      R1, Y+\r
510    \   00000206   9029               LD      R2, Y+\r
511    \   00000208   9039               LD      R3, Y+\r
512    \   0000020A   91E9               LD      R30, Y+\r
513    \   0000020C   91F9               LD      R31, Y+\r
514    \   0000020E   9189               LD      R24, Y+\r
515    \   00000210   9199               LD      R25, Y+\r
516    \   00000212   91A9               LD      R26, Y+\r
517    \   00000214   9518               RETI\r
518    \   00000216                      REQUIRE _A_USIDR\r
519    \   00000216                      REQUIRE _A_USISR\r
520     208          \r
521     209          \r
522     210          /*! \brief Initializes USI as an SPI slave\r
523     211           *\r
524     212           * Initializes USI as a 3-wire SPI slave using the pins specified in USI.h for\r
525     213           * I/O and clock, and USI counter overflow interrupts enabled.\n\r
526     214           * Also initializes the SPI status struct.\r
527     215           * \r
528     216           * \param spi_mode Specifies if USI should trigger on positive (0) or negative\r
529     217           * (1) edge of clock signal\r
530     218           *\r
531     219           * \note Clears the stored data\r
532     220           *\r
533     221           * \todo Timer should reset SPI protocol on timeout\r
534     222           */\r
535 \r
536    \                                 In  segment CODE, align 2, keep-with-next\r
537     223          void SPI_Init(unsigned char spi_mode)\r
538    \                     SPI_Init:\r
539     224          {\r
540     225                 __disable_interrupt();\r
541    \   00000000   94F8               CLI\r
542     226                 \r
543     227                 // Configure outputs and inputs, enable pull-ups for DATAIN and CLOCK pins.\r
544     228                 USI_DIR_REG |= (1<<USI_DATAOUT_PIN);\r
545    \   00000002   9AB9               SBI     0x17, 0x01\r
546     229                 USI_DIR_REG &= ~((1<<USI_DATAIN_PIN) | (1<<USI_CLOCK_PIN));\r
547    \   00000004   B317               IN      R17, 0x17\r
548    \   00000006   7F1A               ANDI    R17, 0xFA\r
549    \   00000008   BB17               OUT     0x17, R17\r
550     230                 USI_OUT_REG |= (1<<USI_DATAIN_PIN) | (1<<USI_CLOCK_PIN);\r
551    \   0000000A   B318               IN      R17, 0x18\r
552    \   0000000C   6015               ORI     R17, 0x05\r
553    \   0000000E   BB18               OUT     0x18, R17\r
554     231                 \r
555     232                 // Configure USI to 3-wire slave mode with overflow interrupt\r
556     233                 USICR = ( (1<<USIOIE) | (1<<USIWM0) | (1<<USICS1) | (spi_mode<<USICS0) );\r
557    \   00000010   2F10               MOV     R17, R16\r
558    \   00000012   0F11               LSL     R17\r
559    \   00000014   0F11               LSL     R17\r
560    \   00000016   6518               ORI     R17, 0x58\r
561    \   00000018   B91D               OUT     0x0D, R17\r
562     234          \r
563     235                 // Initialize the SPI struct\r
564     236                 SPI.Data = 0;                 // Clear data.\r
565    \   0000001A   E010               LDI     R17, 0\r
566    \   0000001C   9310....           STS     SPI, R17\r
567     237                 SPI.State = ST_CMD;           // Initial SPI state: wait for command.\r
568    \   00000020   9110....           LDS     R17, (SPI + 2)\r
569    \   00000024   731F               ANDI    R17, 0x3F\r
570    \   00000026   6410               ORI     R17, 0x40\r
571    \   00000028   9310....           STS     (SPI + 2), R17\r
572     238                 SPI.Read = FALSE;             // Doesn't matter right now.\r
573    \   0000002C   ....               LDI     R30, LOW(SPI)\r
574    \   0000002E   ....               LDI     R31, (SPI) >> 8\r
575    \   00000030   8113               LDD     R17, Z+3\r
576    \   00000032   7F1E               ANDI    R17, 0xFE\r
577    \   00000034   8313               STD     Z+3, R17\r
578     239                 SPI.EEPROM = FALSE;           // Doesn't matter right now.\r
579    \   00000036   ....               LDI     R30, LOW(SPI)\r
580    \   00000038   ....               LDI     R31, (SPI) >> 8\r
581    \   0000003A   8113               LDD     R17, Z+3\r
582    \   0000003C   7F1D               ANDI    R17, 0xFD\r
583    \   0000003E   8313               STD     Z+3, R17\r
584     240                 SPI.Count = 0;                // Doesn't matter right now.\r
585    \   00000040   ....               LDI     R30, LOW(SPI)\r
586    \   00000042   ....               LDI     R31, (SPI) >> 8\r
587    \   00000044   8112               LDD     R17, Z+2\r
588    \   00000046   7C10               ANDI    R17, 0xC0\r
589    \   00000048   8312               STD     Z+2, R17\r
590     241                 SPI.Address = 0;              // Doesn't matter right now.\r
591    \   0000004A   E010               LDI     R17, 0\r
592    \   0000004C   9310....           STS     (SPI + 1), R17\r
593     242                 SPI.XferComplete = FALSE;     // We haven't even started a transfer yet.\r
594    \   00000050   ....               LDI     R30, LOW(SPI)\r
595    \   00000052   ....               LDI     R31, (SPI) >> 8\r
596    \   00000054   8113               LDD     R17, Z+3\r
597    \   00000056   7F1B               ANDI    R17, 0xFB\r
598    \   00000058   8313               STD     Z+3, R17\r
599     243                 SPI.WriteCollision = FALSE;   // ..And therefore a collision hasn't happened.\r
600    \   0000005A   ....               LDI     R30, LOW(SPI)\r
601    \   0000005C   ....               LDI     R31, (SPI) >> 8\r
602    \   0000005E   8113               LDD     R17, Z+3\r
603    \   00000060   7F17               ANDI    R17, 0xF7\r
604    \   00000062   8313               STD     Z+3, R17\r
605     244          \r
606     245                 __enable_interrupt();\r
607    \   00000064   9478               SEI\r
608     246          }\r
609    \   00000066   9508               RET\r
610    \   00000068                      REQUIRE _A_PORTB\r
611    \   00000068                      REQUIRE _A_DDRB\r
612    \   00000068                      REQUIRE _A_USICR\r
613     247          \r
614     248          \r
615     249          // Put one byte on bus. Use this function like you would write to the SPDR\r
616     250          // register in the native SPI module. Calling this function will prepare a\r
617     251          // byte for the next transfer initiated by the master device. If a transfer\r
618     252          // is in progress, this function will set the write collision flag and return\r
619     253          // without altering the data registers.\r
620     254          //\r
621     255          // Returns 0 if a write collision occurred, 1 otherwise.\r
622     256          /*! \brief Write a byte to SPI bus\r
623     257           *\r
624     258           * This function first checks if a transmission is in progress, and if so, flags\r
625     259           * a write collision, and returns FALSE.\n\r
626     260           * If a transmission is not in progress, the flags for write collision and\r
627     261           * transfer complete are cleared, and the input byte is written to SPDR.\n\r
628     262           *\r
629     263           * \param val The byte to send.\r
630     264           *\r
631     265           * \retval FALSE A write collision happened.\r
632     266           * \retval TRUE Byte written to SPDR.\r
633     267           */\r
634 \r
635    \                                 In  segment CODE, align 2, keep-with-next\r
636     268          unsigned char SPI_Put(unsigned char val)\r
637    \                     SPI_Put:\r
638     269          {\r
639    \   00000000   2F10               MOV     R17, R16\r
640     270                 // Check if transmission in progress, i.e. if USI counter doesn't equal zero.\r
641     271                 // If this fails, flag a write collision and return.\r
642     272                 if((USISR & 0x0F) != 0) {\r
643    \   00000002   B10E               IN      R16, 0x0E\r
644    \   00000004   700F               ANDI    R16, 0x0F\r
645    \   00000006   2300               TST     R16\r
646    \   00000008   F039               BREQ    ??SPI_Put_0\r
647     273                         SPI.WriteCollision = TRUE;\r
648    \   0000000A   ....               LDI     R30, LOW(SPI)\r
649    \   0000000C   ....               LDI     R31, (SPI) >> 8\r
650    \   0000000E   8103               LDD     R16, Z+3\r
651    \   00000010   6008               ORI     R16, 0x08\r
652    \   00000012   8303               STD     Z+3, R16\r
653     274                         return(FALSE);\r
654    \   00000014   E000               LDI     R16, 0\r
655    \   00000016   9508               RET\r
656     275                 }\r
657     276          \r
658     277                 // Reinitialize flags.\r
659     278                 SPI.XferComplete = FALSE;\r
660    \                     ??SPI_Put_0:\r
661    \   00000018   ....               LDI     R30, LOW(SPI)\r
662    \   0000001A   ....               LDI     R31, (SPI) >> 8\r
663    \   0000001C   8103               LDD     R16, Z+3\r
664    \   0000001E   7F0B               ANDI    R16, 0xFB\r
665    \   00000020   8303               STD     Z+3, R16\r
666     279                 SPI.WriteCollision = FALSE;\r
667    \   00000022   ....               LDI     R30, LOW(SPI)\r
668    \   00000024   ....               LDI     R31, (SPI) >> 8\r
669    \   00000026   8103               LDD     R16, Z+3\r
670    \   00000028   7F07               ANDI    R16, 0xF7\r
671    \   0000002A   8303               STD     Z+3, R16\r
672     280          \r
673     281                 USIDR = val;  // Put data in USI data register.\r
674    \   0000002C   B91F               OUT     0x0F, R17\r
675     282          \r
676     283                 return (TRUE);\r
677    \   0000002E   E001               LDI     R16, 1\r
678    \   00000030   9508               RET\r
679    \   00000032                      REQUIRE _A_USIDR\r
680    \   00000032                      REQUIRE _A_USISR\r
681     284          }\r
682     285          \r
683     286          \r
684     287          // Get one byte from bus. This function only returns the previous stored\r
685     288          // USIDR value. The transfer complete flag is not checked. Use this function\r
686     289          // like you would read from the SPDR register in the native SPI module.\r
687     290          /*! \brief Get the last byte received from SPI bus\r
688     291           *\r
689     292           * This function simply returns the last byte stored to the SPI status struct,\r
690     293           * without checking if a completed transfer is flagged.\r
691     294           *\r
692     295           * \retval SPI.Data The last byte read from SPI.\r
693     296           */\r
694 \r
695    \                                 In  segment CODE, align 2, keep-with-next\r
696     297          unsigned char SPI_Get(void)\r
697    \                     SPI_Get:\r
698     298          {\r
699     299                 return SPI.Data;\r
700    \   00000000   9100....           LDS     R16, SPI\r
701    \   00000004   9508               RET\r
702     300          }\r
703     301          \r
704     302          \r
705     303          /*! \brief Wait for SPI transfer to complete\r
706     304           *\r
707     305           * This function waits for a transfer complete to be flagged.\r
708     306           */\r
709 \r
710    \                                 In  segment CODE, align 2, keep-with-next\r
711     307          void SPI_Wait(void)\r
712    \                     SPI_Wait:\r
713    \                     ??SPI_Wait_0:\r
714     308          {\r
715     309                 do {  // Wait for transfer complete.\r
716     310                 } while (SPI.XferComplete == FALSE);\r
717    \   00000000   ....               LDI     R30, LOW(SPI)\r
718    \   00000002   ....               LDI     R31, (SPI) >> 8\r
719    \   00000004   8103               LDD     R16, Z+3\r
720    \   00000006   FF02               SBRS    R16, 2\r
721    \   00000008   CFFB               RJMP    ??SPI_Wait_0\r
722     311          }\r
723    \   0000000A   9508               RET\r
724 \r
725    \                                 In  segment INTVEC, offset 0x10, root\r
726    \                     `??USI_OVF_ISR??INTVEC 16`:\r
727    \   00000010   ....               RJMP    USI_OVF_ISR\r
728 \r
729    Maximum stack usage in bytes:\r
730 \r
731      Function       CSTACK RSTACK\r
732      --------       ------ ------\r
733      SPI_Get            0      2\r
734      SPI_Init           0      2\r
735      SPI_Put            0      2\r
736      SPI_Wait           0      2\r
737      USI_OVF_ISR       17      4\r
738        -> Time_Left    17      2\r
739        -> Time_Set     17      2\r
740        -> SPI_Put      17      2\r
741        -> SPI_Put      17      2\r
742        -> SPI_Put      17      2\r
743        -> SPI_Put      17      2\r
744        -> SPI_Put      17      2\r
745        -> SPI_Put      17      2\r
746        -> SPI_Put      17      2\r
747        -> SPI_Put      17      2\r
748 \r
749 \r
750    Segment part sizes:\r
751 \r
752      Function/Label           Bytes\r
753      --------------           -----\r
754      _A_PORTB                    1\r
755      _A_DDRB                     1\r
756      _A_USIDR                    1\r
757      _A_USISR                    1\r
758      _A_USICR                    1\r
759      SPI                         4\r
760      USI_OVF_ISR               534\r
761      SPI_Init                  104\r
762      SPI_Put                    50\r
763      SPI_Get                     6\r
764      ??SPI_Wait_0               12\r
765      ??USI_OVF_ISR??INTVEC 16    2\r
766       Others                     6\r
767 \r
768  \r
769    5 bytes in segment ABSOLUTE\r
770  706 bytes in segment CODE\r
771    6 bytes in segment INITTAB\r
772    2 bytes in segment INTVEC\r
773    4 bytes in segment NEAR_Z\r
774  \r
775  706 bytes of CODE memory (+ 8 bytes shared)\r
776    4 bytes of DATA memory (+ 5 bytes shared)\r
777 \r
778 Errors: none\r
779 Warnings: none\r