Initial import
[avr_bc100.git] / BaseTinyFirmware / IAR / Debug / List / ADC.lst
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\ADC.c                #\r
7 #    Command line =  C:\home\kevin\pub\src\bc100_cal\IAR\ADC.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\ADC.lst   #\r
19 #    Object file  =  C:\home\kevin\pub\src\bc100_cal\IAR\Debug\Obj\ADC.r90    #\r
20 #                                                                             #\r
21 #                                                                             #\r
22 ###############################################################################\r
23 \r
24 C:\home\kevin\pub\src\bc100_cal\IAR\ADC.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 ADC\r
30       6           *\r
31       7           *      Contains high level functions for initializing the ADC, interrupt\r
32       8           *      handling, and treatment of samples.\n\r
33       9           *      The ADC is set to free running mode and uses an external reference\r
34      10           *      voltage.\n\r
35      11           *      To make all sampling take at least 25 clock cycles the ADC is stopped\r
36      12           *      and restarted by the ISR.\r
37      13           *\r
38      14           * \par Application note:\r
39      15           *      AVR458: Charging Li-Ion Batteries with BC100 \n\r
40      16           *      AVR463: Charging NiMH Batteries with BC100\r
41      17           *\r
42      18           * \par Documentation:\r
43      19           *      For comprehensive code documentation, supported compilers, compiler\r
44      20           *      settings and supported devices see readme.html\r
45      21           *\r
46      22           * \author\r
47      23           *      Atmel Corporation: http://www.atmel.com \n\r
48      24           *      Support email: avr@atmel.com \n\r
49      25           *      Original author: \n\r
50      26           *\r
51      27           * $Name$\r
52      28           * $Revision: 2299 $\r
53      29           * $RCSfile$\r
54      30           * $URL: http://svn.norway.atmel.com/AppsAVR8/avr458_Charging_Li-Ion_Batteries_with_BC100/tag/20070904_release_1.0/code/IAR/ADC.c $\r
55      31           * $Date: 2007-08-23 12:55:51 +0200 (to, 23 aug 2007) $\n\r
56      32           ******************************************************************************/\r
57      33          \r
58      34          #include <ioavr.h>\r
59 \r
60    \                                 In  segment ABSOLUTE, at 0x3b\r
61    \   <unnamed> volatile __io _A_PORTA\r
62    \                     _A_PORTA:\r
63    \   00000000                      DS 1\r
64 \r
65    \                                 In  segment ABSOLUTE, at 0x3a\r
66    \   <unnamed> volatile __io _A_DDRA\r
67    \                     _A_DDRA:\r
68    \   00000000                      DS 1\r
69 \r
70    \                                 In  segment ABSOLUTE, at 0x27\r
71    \   <unnamed> volatile __io _A_ADMUX\r
72    \                     _A_ADMUX:\r
73    \   00000000                      DS 1\r
74 \r
75    \                                 In  segment ABSOLUTE, at 0x26\r
76    \   <unnamed> volatile __io _A_ADCSRA\r
77    \                     _A_ADCSRA:\r
78    \   00000000                      DS 1\r
79 \r
80    \                                 In  segment ABSOLUTE, at 0x24\r
81    \   <unnamed> volatile __io _A_ADC\r
82    \                     _A_ADC:\r
83    \   00000000                      DS 2\r
84 \r
85    \                                 In  segment ABSOLUTE, at 0x23\r
86    \   <unnamed> volatile __io _A_ADCSRB\r
87    \                     _A_ADCSRB:\r
88    \   00000000                      DS 1\r
89      35          #include <inavr.h>\r
90      36          \r
91      37          #include "structs.h"\r
92      38          \r
93      39          #include "main.h"\r
94      40          #include "ADC.h"\r
95      41          \r
96      42          \r
97      43          //******************************************************************************\r
98      44          // Variables\r
99      45          //******************************************************************************\r
100      46          // ADC status struct.\r
101      47          //! \brief Holds sampled data and ADC-status\r
102 \r
103    \                                 In  segment NEAR_Z, align 1, keep-with-next\r
104    \   00000000                      REQUIRE `?<Segment init: NEAR_Z>`\r
105      48          ADC_Status_t ADCS;\r
106    \                     ADCS:\r
107    \   00000000                      DS 24\r
108      49          \r
109      50          \r
110      51          /*! \brief Indicates maximum battery voltage.\r
111      52           *\r
112      53           * This variable is stored in EEPROM and indicates how much the battery voltage\r
113      54           * is downscaled by HW before it is sampled. The amount of downscaling depends\r
114      55           * on the maximum battery voltage, and is necessary to avoid saturation of the\r
115      56           * ADC (reference voltage is 2.5 V).\r
116      57           *\r
117      58           * \note Used by the ADC ISR when calling ScaleU() and ScaleI().\r
118      59           *\r
119      60           * \note Defaults to 1, which means 10 V max battery voltage.\r
120      61           *\r
121      62           * \note Table of settings:\r
122      63           * <pre>\r
123      64           * VBAT_RANGE | Max battery voltage | Jumper setting\r
124      65           *         0  |             5V      |        1/2\r
125      66           *         1  |            10V      |        1/4\r
126      67           *         2  |            20V      |        1/8\r
127      68           *         3  |            30V      |       1/12\r
128      69           *         4  |            40V      |       1/16\r
129      70           * </pre>\r
130      71           */\r
131      72          // Maximum battery voltage (affects scaling of samples).\r
132 \r
133    \                                 In  segment EEPROM_I, align 1, keep-with-next\r
134      73          __eeprom unsigned char VBAT_RANGE = 1;\r
135    \                     VBAT_RANGE:\r
136    \   00000000   01                 DB 1\r
137      74          \r
138      75          \r
139      76          //******************************************************************************\r
140      77          // Functions\r
141      78          //******************************************************************************\r
142      79          /*! \brief Interrupt Service routine for ADC.\r
143      80           *\r
144      81           * This ISR stores the sampled values in the ADC status-struct, then\r
145      82           * updates the ADC MUX to the next channel in the scanning-sequence.\n\r
146      83           * Once the sequence is completed, ADCS.Flag is set and unless\r
147      84           * ADCS.Halt has been set, the sequence starts over. Otherwise, the ADC \r
148      85           * is disabled.\n\r
149      86           * If the mains voltage is below minimum, ADCS.Mains gets set to FALSE.\r
150      87           *\r
151      88           * \note Table of scanning sequence:\r
152      89           * <pre>\r
153      90           * Seq |    MUX |  pos I/P |  neg I/P | gain | measure | signed\r
154      91           * ----+--------+----------+----------+------+---------+-------\r
155      92           *  01 | 000001 | ADC1/PA1 |      n/a |   1x |     NTC |     no\r
156      93           *  02 | 000010 | ADC2/PA2 |      n/a |   1x |     RID |     no\r
157      94           *  03 | 000011 | ADC3/PA4 |      n/a |   1x |    VIN- |     no\r
158      95           *  04 | 000100 | ADC4/PA5 |      n/a |   1x |    VIN+ |     no\r
159      96           *  05 | 000101 | ADC5/PA6 |      n/a |   1x |   VBAT- |     no\r
160      97           *  06 | 000110 | ADC6/PA7 |      n/a |   1x |   VBAT+ |     no\r
161      98           *  07 | 010010 | ADC4/PA5 | ADC3/PA4 |  20x |     IIN |     no\r
162      99           *  08 | 010111 | ADC6/PA7 | ADC5/PA6 |  20x |    IBAT |    yes\r
163     100           * </pre>\r
164     101           *\r
165     102           * \todo IIN (#7 in sequence) is never used.\r
166     103           *\r
167     104           * \todo Signed is never set. Signed measurements of IBAT will halve the\r
168     105           * measuring sensitivity, and is therefore not favourable. At the moment,\r
169     106           * great currents (f.ex. if something happens with the battery) will be\r
170     107           * interpreted as negative, which might cause unfavourable behaviour during\r
171     108           * charging (depending on what PWM behaviour is defined), f.ex.\r
172     109           * ConstantCurrent() will keep increasing the PWM output. This results in an\r
173     110           * PWM controller error being flagged and the program going into\r
174     111           * error-state and eventually reinitializing.\r
175     112           */\r
176     113          #pragma vector=ADC_vect\r
177 \r
178    \                                 In  segment CODE, align 2, keep-with-next\r
179     114          __interrupt void ADC_ISR(void)\r
180    \                     ADC_ISR:\r
181     115          {\r
182    \   00000000   925A               ST      -Y, R5\r
183    \   00000002   924A               ST      -Y, R4\r
184    \   00000004   93BA               ST      -Y, R27\r
185    \   00000006   93AA               ST      -Y, R26\r
186    \   00000008   939A               ST      -Y, R25\r
187    \   0000000A   938A               ST      -Y, R24\r
188    \   0000000C   93FA               ST      -Y, R31\r
189    \   0000000E   93EA               ST      -Y, R30\r
190    \   00000010   923A               ST      -Y, R3\r
191    \   00000012   922A               ST      -Y, R2\r
192    \   00000014   921A               ST      -Y, R1\r
193    \   00000016   920A               ST      -Y, R0\r
194    \   00000018   937A               ST      -Y, R23\r
195    \   0000001A   936A               ST      -Y, R22\r
196    \   0000001C   935A               ST      -Y, R21\r
197    \   0000001E   934A               ST      -Y, R20\r
198    \   00000020   933A               ST      -Y, R19\r
199    \   00000022   932A               ST      -Y, R18\r
200    \   00000024   931A               ST      -Y, R17\r
201    \   00000026   930A               ST      -Y, R16\r
202    \   00000028   B65F               IN      R5, 0x3F\r
203    \   0000002A                      REQUIRE ?Register_R4_is_cg_reg\r
204    \   0000002A                      REQUIRE ?Register_R5_is_cg_reg\r
205     116                 static unsigned char avgIndex = 0;\r
206     117                 unsigned char i, Next, Signed;\r
207     118                 signed int  temp = 0;\r
208    \   0000002A   E0A0               LDI     R26, 0\r
209    \   0000002C   E0B0               LDI     R27, 0\r
210     119                 \r
211     120                 Signed = FALSE;  // Presume next conversion is unipolar.\r
212    \   0000002E   2444               CLR     R4\r
213     121                 ADCSRA &= ~(1<<ADEN);  // Stop conversion before handling. This makes all\r
214    \   00000030   9837               CBI     0x06, 0x07\r
215     122                   // conversions take at least 25 ADCCLK. (It is restarted later)\r
216     123                 \r
217     124                 // Handle the conversion, depending on what channel it is from, then\r
218     125                 // switch to the next channel in the sequence.\r
219     126                 switch (ADCS.MUX){\r
220    \   00000032   9100....           LDS     R16, ADCS\r
221    \   00000036   710F               ANDI    R16, 0x1F\r
222    \   00000038   5001               SUBI    R16, 1\r
223    \   0000003A   F051               BREQ    ??ADC_ISR_0\r
224    \   0000003C   950A               DEC     R16\r
225    \   0000003E   F081               BREQ    ??ADC_ISR_1\r
226    \   00000040   950A               DEC     R16\r
227    \   00000042   F0B1               BREQ    ??ADC_ISR_2\r
228    \   00000044   5002               SUBI    R16, 2\r
229    \   00000046   F189               BREQ    ??ADC_ISR_3\r
230    \   00000048   5102               SUBI    R16, 18\r
231    \   0000004A   F409               BRNE    $+2+2\r
232    \   0000004C   C040               RJMP    ??ADC_ISR_4\r
233    \   0000004E   C0AF               RJMP    ??ADC_ISR_5\r
234     127                         // MUX = 0b000001 => ADC1 (PA1) = NTC\r
235     128                         case 0x01:\r
236     129                                 ADCS.rawNTC = ADC;\r
237    \                     ??ADC_ISR_0:\r
238    \   00000050   B104               IN      R16, 0x04\r
239    \   00000052   B115               IN      R17, 0x05\r
240    \   00000054   ....               LDI     R30, LOW(ADCS)\r
241    \   00000056   ....               LDI     R31, (ADCS) >> 8\r
242    \   00000058   8304               STD     Z+4, R16\r
243    \   0000005A   8315               STD     Z+5, R17\r
244     130                                 Next=0x02;\r
245    \   0000005C   E092               LDI     R25, 2\r
246    \   0000005E   C0A8               RJMP    ??ADC_ISR_6\r
247     131                         break;\r
248     132          \r
249     133                         \r
250     134                         // MUX = 0b000010 => ADC2 (PA2) = RID\r
251     135                         case 0x02:\r
252     136                                 ADCS.rawRID = ADC;\r
253    \                     ??ADC_ISR_1:\r
254    \   00000060   B104               IN      R16, 0x04\r
255    \   00000062   B115               IN      R17, 0x05\r
256    \   00000064   ....               LDI     R30, LOW(ADCS)\r
257    \   00000066   ....               LDI     R31, (ADCS) >> 8\r
258    \   00000068   8302               STD     Z+2, R16\r
259    \   0000006A   8313               STD     Z+3, R17\r
260     137                                 Next=0x03;\r
261    \   0000006C   E093               LDI     R25, 3\r
262    \   0000006E   C0A0               RJMP    ??ADC_ISR_6\r
263     138                         break;\r
264     139          \r
265     140                         \r
266     141                         // MUX = 0b000011 => ADC3 (PA4) = VIN-\r
267     142                         case 0x03:\r
268     143                                 // Supply voltage is always divided by 16.\r
269     144                                 ADCS.VIN = ScaleU(4, (unsigned int)ADC);  // Cast because ADC is short.\r
270    \                     ??ADC_ISR_2:\r
271    \   00000070   B124               IN      R18, 0x04\r
272    \   00000072   B135               IN      R19, 0x05\r
273    \   00000074   E004               LDI     R16, 4\r
274    \   00000076   ....               RCALL   ScaleU\r
275    \   00000078   ....               LDI     R30, LOW(ADCS)\r
276    \   0000007A   ....               LDI     R31, (ADCS) >> 8\r
277    \   0000007C   8700               STD     Z+8, R16\r
278    \   0000007E   8711               STD     Z+9, R17\r
279     145                                 \r
280     146                                 // Is mains failing?\r
281     147                                 if (ADCS.VIN < VIN_MIN) {\r
282    \   00000080   ....               LDI     R30, LOW(ADCS)\r
283    \   00000082   ....               LDI     R31, (ADCS) >> 8\r
284    \   00000084   8500               LDD     R16, Z+8\r
285    \   00000086   8511               LDD     R17, Z+9\r
286    \   00000088   3300               CPI     R16, 48\r
287    \   0000008A   E121               LDI     R18, 17\r
288    \   0000008C   0712               CPC     R17, R18\r
289    \   0000008E   F430               BRCC    ??ADC_ISR_7\r
290     148                                         ADCS.Mains = FALSE;\r
291    \   00000090   ....               LDI     R30, LOW(ADCS)\r
292    \   00000092   ....               LDI     R31, (ADCS) >> 8\r
293    \   00000094   8100               LD      R16, Z\r
294    \   00000096   7B0F               ANDI    R16, 0xBF\r
295    \   00000098   8300               ST      Z, R16\r
296    \   0000009A   C005               RJMP    ??ADC_ISR_8\r
297     149                                 } else {\r
298     150                                         ADCS.Mains = TRUE;\r
299    \                     ??ADC_ISR_7:\r
300    \   0000009C   ....               LDI     R30, LOW(ADCS)\r
301    \   0000009E   ....               LDI     R31, (ADCS) >> 8\r
302    \   000000A0   8100               LD      R16, Z\r
303    \   000000A2   6400               ORI     R16, 0x40\r
304    \   000000A4   8300               ST      Z, R16\r
305     151                                 }\r
306     152                                 \r
307     153                                 Next=0x05;\r
308    \                     ??ADC_ISR_8:\r
309    \   000000A6   E095               LDI     R25, 5\r
310    \   000000A8   C083               RJMP    ??ADC_ISR_6\r
311     154                         break;\r
312     155          \r
313     156                         \r
314     157                         // MUX = 0b000101 => ADC5 (PA6) = VBAT-\r
315     158                         case 0x05:\r
316     159                                 ADCS.rawVBAT = ADC;\r
317    \                     ??ADC_ISR_3:\r
318    \   000000AA   B104               IN      R16, 0x04\r
319    \   000000AC   B115               IN      R17, 0x05\r
320    \   000000AE   ....               LDI     R30, LOW(ADCS)\r
321    \   000000B0   ....               LDI     R31, (ADCS) >> 8\r
322    \   000000B2   8306               STD     Z+6, R16\r
323    \   000000B4   8317               STD     Z+7, R17\r
324     160                                 \r
325     161                                 // Scale voltage according to jumper setting.\r
326     162                                 ADCS.VBAT = ScaleU(VBAT_RANGE, (unsigned int)ADC); // ADC is a short.\r
327    \   000000B6   B124               IN      R18, 0x04\r
328    \   000000B8   B135               IN      R19, 0x05\r
329    \   000000BA   ....               LDI     R20, LOW(VBAT_RANGE)\r
330    \   000000BC   ....               LDI     R21, (VBAT_RANGE) >> 8\r
331    \   000000BE   ....               RCALL   __eeget8_16\r
332    \   000000C0   ....               RCALL   ScaleU\r
333    \   000000C2   ....               LDI     R30, LOW(ADCS)\r
334    \   000000C4   ....               LDI     R31, (ADCS) >> 8\r
335    \   000000C6   8702               STD     Z+10, R16\r
336    \   000000C8   8713               STD     Z+11, R17\r
337     163                                 Next=0x17;\r
338    \   000000CA   E197               LDI     R25, 23\r
339    \   000000CC   C071               RJMP    ??ADC_ISR_6\r
340     164          //                     Signed = TRUE;  // Next conversion is bipolar. Halves sensitivity!\r
341     165                         break;\r
342     166          \r
343     167          \r
344     168                         case 0x17:  // MUX = 0b010111 => 20 x [ADC6(PA7) - ADC5(PA6)] = IBAT\r
345     169                                 // If bipolar, from -512 to 0, to 511:\r
346     170                                 // 0x200 ... 0x3ff, 0x000, 0x001 ... 0x1FF\r
347     171                         \r
348     172                                 // Scale sample according to jumper setting, handle negative numbers.\r
349     173                                 if (ADC > 511) {\r
350    \                     ??ADC_ISR_4:\r
351    \   000000CE   B104               IN      R16, 0x04\r
352    \   000000D0   B115               IN      R17, 0x05\r
353    \   000000D2   3000               CPI     R16, 0\r
354    \   000000D4   E022               LDI     R18, 2\r
355    \   000000D6   0712               CPC     R17, R18\r
356    \   000000D8   F0C8               BRCS    ??ADC_ISR_9\r
357     174                                         ADCS.IBAT = -(signed int)ScaleI(VBAT_RANGE,\r
358     175                                                      (1024 - (ADC-ADCS.ADC5_G20_OS)));\r
359    \   000000DA   E000               LDI     R16, 0\r
360    \   000000DC   E014               LDI     R17, 4\r
361    \   000000DE   B124               IN      R18, 0x04\r
362    \   000000E0   B135               IN      R19, 0x05\r
363    \   000000E2   1B02               SUB     R16, R18\r
364    \   000000E4   0B13               SBC     R17, R19\r
365    \   000000E6   9120....           LDS     R18, (ADCS + 1)\r
366    \   000000EA   9522               SWAP    R18\r
367    \   000000EC   702F               ANDI    R18, 0x0F\r
368    \   000000EE   E030               LDI     R19, 0\r
369    \   000000F0   0F20               ADD     R18, R16\r
370    \   000000F2   1F31               ADC     R19, R17\r
371    \   000000F4   ....               LDI     R20, LOW(VBAT_RANGE)\r
372    \   000000F6   ....               LDI     R21, (VBAT_RANGE) >> 8\r
373    \   000000F8   ....               RCALL   __eeget8_16\r
374    \   000000FA   ....               RCALL   ScaleI\r
375    \   000000FC   9511               NEG     R17\r
376    \   000000FE   9501               NEG     R16\r
377    \   00000100   4010               SBCI    R17, 0\r
378    \   00000102   ....               LDI     R30, LOW(ADCS)\r
379    \   00000104   ....               LDI     R31, (ADCS) >> 8\r
380    \   00000106   8704               STD     Z+12, R16\r
381    \   00000108   8715               STD     Z+13, R17\r
382    \   0000010A   C01C               RJMP    ??ADC_ISR_10\r
383     176                                 } else if (ADC > 0) {\r
384    \                     ??ADC_ISR_9:\r
385    \   0000010C   B104               IN      R16, 0x04\r
386    \   0000010E   B115               IN      R17, 0x05\r
387    \   00000110   2B01               OR      R16, R17\r
388    \   00000112   F091               BREQ    ??ADC_ISR_11\r
389     177                                         ADCS.IBAT = ScaleI(VBAT_RANGE, (ADC-ADCS.ADC5_G20_OS));\r
390    \   00000114   B124               IN      R18, 0x04\r
391    \   00000116   B135               IN      R19, 0x05\r
392    \   00000118   9100....           LDS     R16, (ADCS + 1)\r
393    \   0000011C   9502               SWAP    R16\r
394    \   0000011E   700F               ANDI    R16, 0x0F\r
395    \   00000120   E010               LDI     R17, 0\r
396    \   00000122   1B20               SUB     R18, R16\r
397    \   00000124   0B31               SBC     R19, R17\r
398    \   00000126   ....               LDI     R20, LOW(VBAT_RANGE)\r
399    \   00000128   ....               LDI     R21, (VBAT_RANGE) >> 8\r
400    \   0000012A   ....               RCALL   __eeget8_16\r
401    \   0000012C   ....               RCALL   ScaleI\r
402    \   0000012E   ....               LDI     R30, LOW(ADCS)\r
403    \   00000130   ....               LDI     R31, (ADCS) >> 8\r
404    \   00000132   8704               STD     Z+12, R16\r
405    \   00000134   8715               STD     Z+13, R17\r
406    \   00000136   C006               RJMP    ??ADC_ISR_10\r
407     178                                 } else {\r
408     179                                         ADCS.IBAT = 0;\r
409    \                     ??ADC_ISR_11:\r
410    \   00000138   E000               LDI     R16, 0\r
411    \   0000013A   E010               LDI     R17, 0\r
412    \   0000013C   ....               LDI     R30, LOW(ADCS)\r
413    \   0000013E   ....               LDI     R31, (ADCS) >> 8\r
414    \   00000140   8704               STD     Z+12, R16\r
415    \   00000142   8715               STD     Z+13, R17\r
416     180                                 }\r
417     181          \r
418     182                                 // Insert sample of battery current into the averaging-array\r
419     183                                 // (overwriting the oldest sample), then recalculate and store the\r
420     184                                 // average. This is the last conversion in the sequence, so\r
421     185                                 // flag a complete ADC-cycle and restart sequence.\r
422     186                                 ADCS.discIBAT[(avgIndex++ & 0x03)] = ADCS.IBAT;\r
423    \                     ??ADC_ISR_10:\r
424    \   00000144   ....               LDI     R30, LOW(ADCS)\r
425    \   00000146   ....               LDI     R31, (ADCS) >> 8\r
426    \   00000148   8524               LDD     R18, Z+12\r
427    \   0000014A   8535               LDD     R19, Z+13\r
428    \   0000014C   9100....           LDS     R16, ??avgIndex\r
429    \   00000150   E010               LDI     R17, 0\r
430    \   00000152   7003               ANDI    R16, 0x03\r
431    \   00000154   7010               ANDI    R17, 0x00\r
432    \   00000156   0F00               LSL     R16\r
433    \   00000158   1F11               ROL     R17\r
434    \   0000015A   01F8               MOVW    R31:R30, R17:R16\r
435    \   0000015C   ....               SUBI    R30, LOW((-(ADCS) & 0xFFFF))\r
436    \   0000015E   ....               SBCI    R31, (-(ADCS) & 0xFFFF) >> 8\r
437    \   00000160   8726               STD     Z+14, R18\r
438    \   00000162   8737               STD     Z+15, R19\r
439    \   00000164   ....               LDI     R30, LOW(??avgIndex)\r
440    \   00000166   ....               LDI     R31, (??avgIndex) >> 8\r
441    \   00000168   8100               LD      R16, Z\r
442    \   0000016A   9503               INC     R16\r
443    \   0000016C   8300               ST      Z, R16\r
444     187                                 for (i = 0; i < 4 ; i++) {\r
445    \   0000016E   E080               LDI     R24, 0\r
446    \                     ??ADC_ISR_12:\r
447    \   00000170   3084               CPI     R24, 4\r
448    \   00000172   F468               BRCC    ??ADC_ISR_13\r
449     188                                         temp += ADCS.discIBAT[i];\r
450    \   00000174   2F08               MOV     R16, R24\r
451    \   00000176   E010               LDI     R17, 0\r
452    \   00000178   0F00               LSL     R16\r
453    \   0000017A   1F11               ROL     R17\r
454    \   0000017C   01F8               MOVW    R31:R30, R17:R16\r
455    \   0000017E   ....               SUBI    R30, LOW((-(ADCS) & 0xFFFF))\r
456    \   00000180   ....               SBCI    R31, (-(ADCS) & 0xFFFF) >> 8\r
457    \   00000182   8506               LDD     R16, Z+14\r
458    \   00000184   8517               LDD     R17, Z+15\r
459    \   00000186   0FA0               ADD     R26, R16\r
460    \   00000188   1FB1               ADC     R27, R17\r
461     189                                 }\r
462    \   0000018A   9583               INC     R24\r
463    \   0000018C   CFF1               RJMP    ??ADC_ISR_12\r
464     190                                 \r
465     191                                 ADCS.avgIBAT = (temp / 4);\r
466    \                     ??ADC_ISR_13:\r
467    \   0000018E   018D               MOVW    R17:R16, R27:R26\r
468    \   00000190   E044               LDI     R20, 4\r
469    \   00000192   E050               LDI     R21, 0\r
470    \   00000194   ....               RCALL   ?SS_DIVMOD_L02\r
471    \   00000196   ....               LDI     R30, LOW(ADCS)\r
472    \   00000198   ....               LDI     R31, (ADCS) >> 8\r
473    \   0000019A   8B06               STD     Z+22, R16\r
474    \   0000019C   8B17               STD     Z+23, R17\r
475     192                                 \r
476     193                                 ADCS.Flag = TRUE;\r
477    \   0000019E   ....               LDI     R30, LOW(ADCS)\r
478    \   000001A0   ....               LDI     R31, (ADCS) >> 8\r
479    \   000001A2   8100               LD      R16, Z\r
480    \   000001A4   6200               ORI     R16, 0x20\r
481    \   000001A6   8300               ST      Z, R16\r
482     194                                 Next=0x01;\r
483    \   000001A8   E091               LDI     R25, 1\r
484     195                                 Signed = FALSE;  // This is the only bipolar conversion.\r
485    \   000001AA   2444               CLR     R4\r
486    \   000001AC   C001               RJMP    ??ADC_ISR_6\r
487     196                         break;\r
488     197          \r
489     198                         \r
490     199                         default:  // Should not happen. (Invalid MUX-channel)\r
491     200                                 Next=0x01;  // Start at the beginning of sequence.\r
492    \                     ??ADC_ISR_5:\r
493    \   000001AE   E091               LDI     R25, 1\r
494     201                         break;\r
495     202                 }\r
496     203                 \r
497     204                 // Update MUX to next channel in sequence, set a bipolar conversion if\r
498     205                 // this has been flagged.\r
499     206                 ADCS.MUX = Next;                    \r
500    \                     ??ADC_ISR_6:\r
501    \   000001B0   9110....           LDS     R17, ADCS\r
502    \   000001B4   7E10               ANDI    R17, 0xE0\r
503    \   000001B6   2F09               MOV     R16, R25\r
504    \   000001B8   710F               ANDI    R16, 0x1F\r
505    \   000001BA   2B01               OR      R16, R17\r
506    \   000001BC   9300....           STS     ADCS, R16\r
507     207                 ADMUX = (1<<REFS0) + ADCS.MUX;      \r
508    \   000001C0   9100....           LDS     R16, ADCS\r
509    \   000001C4   710F               ANDI    R16, 0x1F\r
510    \   000001C6   5C00               SUBI    R16, 192\r
511    \   000001C8   B907               OUT     0x07, R16\r
512     208          \r
513     209                 if (Signed)     {\r
514    \   000001CA   2044               TST     R4\r
515    \   000001CC   F011               BREQ    ??ADC_ISR_14\r
516     210                   ADCSRB |= (1<<BIN);               \r
517    \   000001CE   9A1F               SBI     0x03, 0x07\r
518    \   000001D0   C001               RJMP    ??ADC_ISR_15\r
519     211                 } else {\r
520     212                   ADCSRB &= ~(1<<BIN);              \r
521    \                     ??ADC_ISR_14:\r
522    \   000001D2   981F               CBI     0x03, 0x07\r
523     213                 }\r
524     214          \r
525     215                 // Re-enable the ADC unless a halt has been flagged and a conversion\r
526     216                 // cycle has completed.\r
527     217                 if (!((ADCS.Halt) && (ADCS.Flag))) {\r
528    \                     ??ADC_ISR_15:\r
529    \   000001D4   9100....           LDS     R16, ADCS\r
530    \   000001D8   7A00               ANDI    R16, 0xA0\r
531    \   000001DA   3A00               CPI     R16, 160\r
532    \   000001DC   F019               BREQ    ??ADC_ISR_16\r
533     218                   ADCSRA |= (1<<ADEN)|(1<<ADSC);    \r
534    \   000001DE   B106               IN      R16, 0x06\r
535    \   000001E0   6C00               ORI     R16, 0xC0\r
536    \   000001E2   B906               OUT     0x06, R16\r
537     219                 }\r
538     220          }\r
539    \                     ??ADC_ISR_16:\r
540    \   000001E4   BE5F               OUT     0x3F, R5\r
541    \   000001E6   9109               LD      R16, Y+\r
542    \   000001E8   9119               LD      R17, Y+\r
543    \   000001EA   9129               LD      R18, Y+\r
544    \   000001EC   9139               LD      R19, Y+\r
545    \   000001EE   9149               LD      R20, Y+\r
546    \   000001F0   9159               LD      R21, Y+\r
547    \   000001F2   9169               LD      R22, Y+\r
548    \   000001F4   9179               LD      R23, Y+\r
549    \   000001F6   9009               LD      R0, Y+\r
550    \   000001F8   9019               LD      R1, Y+\r
551    \   000001FA   9029               LD      R2, Y+\r
552    \   000001FC   9039               LD      R3, Y+\r
553    \   000001FE   91E9               LD      R30, Y+\r
554    \   00000200   91F9               LD      R31, Y+\r
555    \   00000202   9189               LD      R24, Y+\r
556    \   00000204   9199               LD      R25, Y+\r
557    \   00000206   91A9               LD      R26, Y+\r
558    \   00000208   91B9               LD      R27, Y+\r
559    \   0000020A   9049               LD      R4, Y+\r
560    \   0000020C   9059               LD      R5, Y+\r
561    \   0000020E   9518               RETI\r
562    \   00000210                      REQUIRE _A_ADMUX\r
563    \   00000210                      REQUIRE _A_ADCSRA\r
564    \   00000210                      REQUIRE _A_ADC\r
565    \   00000210                      REQUIRE _A_ADCSRB\r
566 \r
567    \                                 In  segment NEAR_Z, align 1, keep-with-next\r
568    \   00000000                      REQUIRE `?<Segment init: NEAR_Z>`\r
569    \                     ??avgIndex:\r
570    \   00000000                      DS 1\r
571     221          \r
572     222          \r
573     223          /*! \brief Scales sample to represent "actual voltage" in mV.\r
574     224           *\r
575     225           * This function returns the actual sampled voltage, scaled according\r
576     226           * to the jumper settings.\r
577     227           *\r
578     228           * \param setting Indicates what downscaling was used.\r
579     229           * \param data The sampled value.\r
580     230           *\r
581     231           * \note Table for setting-parameter:\n\r
582     232           * <pre>\r
583     233           * Presume VREF = 2.5V and Gain = 1x.\r
584     234           * => Resolution @ 1/1 = 2.5V / 1024 = 2.4414 mV/LSB\r
585     235           * setting | source |   R1 | R2/(R1+R2) | UADC(LSB) | U(MAX)\r
586     236           * --------+--------+------+------------+-----------+-------\r
587     237           *     N/A |        |    - |       -    |   2.441mV |  2.50V\r
588     238           *       0 |   VBAT |  10k |     1/2    |   4.883mV |  5.00V\r
589     239           *       1 |   VBAT |  30k |     1/4    |   9.766mV |  9.99V\r
590     240           *       2 |   VBAT |  70k |     1/8    |   19.53mV | 19.98V\r
591     241           *       3 |   VBAT | 110k |    1/12    |   29.30mV | 29.97V\r
592     242           *       4 |   VBAT | 150k |    1/16    |   39.06mV | 39.96V\r
593     243           *       4 |    VIN | 150k |    1/16    |   39.06mV | 39.96V\r
594     244           * </pre>\r
595     245           */\r
596 \r
597    \                                 In  segment CODE, align 2, keep-with-next\r
598     246          unsigned int ScaleU(unsigned char setting, unsigned int data)\r
599    \                     ScaleU:\r
600     247          {\r
601    \   00000000   ....               RCALL   ?PROLOGUE6_L09\r
602    \   00000002                      REQUIRE ?Register_R4_is_cg_reg\r
603    \   00000002                      REQUIRE ?Register_R5_is_cg_reg\r
604    \   00000002   2FA0               MOV     R26, R16\r
605    \   00000004   01C9               MOVW    R25:R24, R19:R18\r
606     248                 // Temporary variable needed.\r
607     249                 unsigned int scaled = 0;\r
608    \   00000006   2444               CLR     R4\r
609    \   00000008   2455               CLR     R5\r
610     250          \r
611     251                 // Jumper setting 3: mV/LSB = 29.30 ~= 29 + 1/4 + 1/16\r
612     252                 if (setting == 3)       {\r
613    \   0000000A   30A3               CPI     R26, 3\r
614    \   0000000C   F491               BRNE    ??ScaleU_0\r
615     253                         scaled = 29 * data;\r
616    \   0000000E   01AC               MOVW    R21:R20, R25:R24\r
617    \   00000010   E10D               LDI     R16, 29\r
618    \   00000012   E010               LDI     R17, 0\r
619    \   00000014   ....               RCALL   ?S_MUL_L02\r
620    \   00000016   0128               MOVW    R5:R4, R17:R16\r
621     254                         scaled += (data >> 2);\r
622    \   00000018   018C               MOVW    R17:R16, R25:R24\r
623    \   0000001A   9516               LSR     R17\r
624    \   0000001C   9507               ROR     R16\r
625    \   0000001E   9516               LSR     R17\r
626    \   00000020   9507               ROR     R16\r
627    \   00000022   0E40               ADD     R4, R16\r
628    \   00000024   1E51               ADC     R5, R17\r
629     255                         scaled += (data >> 4);\r
630    \   00000026   018C               MOVW    R17:R16, R25:R24\r
631    \   00000028   E044               LDI     R20, 4\r
632    \   0000002A   ....               RCALL   ?US_SHR_L02\r
633    \   0000002C   0E40               ADD     R4, R16\r
634    \   0000002E   1E51               ADC     R5, R17\r
635    \   00000030   C011               RJMP    ??ScaleU_1\r
636     256                 } else {\r
637     257                         // Jumper setting 4: mV/LSB = 39.06 ~= 39 + 1/16\r
638     258                         scaled = 39 * data;\r
639    \                     ??ScaleU_0:\r
640    \   00000032   01AC               MOVW    R21:R20, R25:R24\r
641    \   00000034   E207               LDI     R16, 39\r
642    \   00000036   E010               LDI     R17, 0\r
643    \   00000038   ....               RCALL   ?S_MUL_L02\r
644    \   0000003A   0128               MOVW    R5:R4, R17:R16\r
645     259                         scaled += (data >> 4);\r
646    \   0000003C   018C               MOVW    R17:R16, R25:R24\r
647    \   0000003E   E044               LDI     R20, 4\r
648    \   00000040   ....               RCALL   ?US_SHR_L02\r
649    \   00000042   0E40               ADD     R4, R16\r
650    \   00000044   1E51               ADC     R5, R17\r
651     260                         \r
652     261                         if (setting <3) {\r
653    \   00000046   30A3               CPI     R26, 3\r
654    \   00000048   F428               BRCC    ??ScaleU_1\r
655     262                                 // Jumper setting 0: mV/LSB = 4.883 = 39.06 / 8\r
656     263                                 //                1: mV/LSB = 9.766 = 39.06 / 4\r
657     264                                 //                2: mV/LSB = 19.53 = 39.06 / 2\r
658     265                                 scaled = (scaled >> (3-setting));\r
659    \   0000004A   0182               MOVW    R17:R16, R5:R4\r
660    \   0000004C   E043               LDI     R20, 3\r
661    \   0000004E   1B4A               SUB     R20, R26\r
662    \   00000050   ....               RCALL   ?US_SHR_L02\r
663    \   00000052   0128               MOVW    R5:R4, R17:R16\r
664     266                         }\r
665     267                 }\r
666     268          \r
667     269                 return(scaled);\r
668    \                     ??ScaleU_1:\r
669    \   00000054   0182               MOVW    R17:R16, R5:R4\r
670    \   00000056   E0E6               LDI     R30, 6\r
671    \   00000058   ....               RJMP    ?EPILOGUE_B6_L09\r
672     270          }\r
673     271          \r
674     272          \r
675     273          /*! \brief Scales sample to represent "actual current" in mA.\r
676     274           *\r
677     275           * This function returns the actual sampled current, scaled according\r
678     276           * to the jumper settings.\r
679     277           *\r
680     278           * \param setting Indicates what downscaling was used.\r
681     279           * \param data The sampled value.\r
682     280           *\r
683     281           * \note Table for setting-parameter:\n\r
684     282           * <pre>\r
685     283           * Presume VREF = 2.5V and Gain = 1x or 20x.\r
686     284           * => Resolution(U) @ (1/1 and 20x) = 2.5V / (GAIN x 1024) = 0.1221 mV/LSB\r
687     285           * => Resolution(I) = Resolution(U) / Rshunt = Resolution(U) / 0.07\r
688     286           * Setting |   R1 | R2/(R1+R2) |   U(LSB) |   I(LSB) | I(MAX) | Gain\r
689     287           * --------+------+------------+----------+----------+--------+-----\r
690     288           *     N/A |    - |       -    | 0.1221mV |  1.744mA |  1.78A |  20x\r
691     289           *       0 |  10k |     1/2    | 0.2442mV |  3.489mA |  3.57A |  20x\r
692     290           *       1 |  30k |     1/4    | 0.4884mV |  6.978mA |  7.14A |  20x\r
693     291           *       2 |  70k |     1/8    | 0.9768mV | 13.955mA |  14.3A |  20x\r
694     292           *       3 | 110k |    1/12    | 1.4652mV | 20.931mA |  21.4A |  20x\r
695     293           *       4 | 150k |    1/16    | 1.9536mV | 27.909mA |  28.5A |  20x\r
696     294           *       5 |  10k |     1/2    | 2.4414mV | 34.877mA |  35.7A |   1x\r
697     295           * </pre>\r
698     296           */\r
699 \r
700    \                                 In  segment CODE, align 2, keep-with-next\r
701     297          unsigned int ScaleI(unsigned char setting, unsigned int data)\r
702    \                     ScaleI:\r
703     298          {\r
704    \   00000000   ....               RCALL   ?PROLOGUE6_L09\r
705    \   00000002                      REQUIRE ?Register_R4_is_cg_reg\r
706    \   00000002                      REQUIRE ?Register_R5_is_cg_reg\r
707    \   00000002   2FA0               MOV     R26, R16\r
708    \   00000004   01C9               MOVW    R25:R24, R19:R18\r
709     299                 // Temporary variable needed.\r
710     300                 unsigned int  scaled = 0;\r
711    \   00000006   2444               CLR     R4\r
712    \   00000008   2455               CLR     R5\r
713     301                 \r
714     302                 // Jumper setting 3: mA/LSB = 20.931mA ~= 21 - 1/16 + 1/128\r
715     303                 if (setting == 3) {\r
716    \   0000000A   30A3               CPI     R26, 3\r
717    \   0000000C   F499               BRNE    ??ScaleI_0\r
718     304                         scaled = 21 * data;\r
719    \   0000000E   01AC               MOVW    R21:R20, R25:R24\r
720    \   00000010   E105               LDI     R16, 21\r
721    \   00000012   E010               LDI     R17, 0\r
722    \   00000014   ....               RCALL   ?S_MUL_L02\r
723    \   00000016   0128               MOVW    R5:R4, R17:R16\r
724     305                         scaled -= (data >> 4);\r
725    \   00000018   018C               MOVW    R17:R16, R25:R24\r
726    \   0000001A   E044               LDI     R20, 4\r
727    \   0000001C   ....               RCALL   ?US_SHR_L02\r
728    \   0000001E   1A40               SUB     R4, R16\r
729    \   00000020   0A51               SBC     R5, R17\r
730     306                         scaled += (data >> 7);\r
731    \   00000022   018C               MOVW    R17:R16, R25:R24\r
732    \   00000024   0F00               LSL     R16\r
733    \   00000026   2F01               MOV     R16, R17\r
734    \   00000028   1F00               ROL     R16\r
735    \   0000002A   E010               LDI     R17, 0\r
736    \   0000002C   1F11               ROL     R17\r
737    \   0000002E   0E40               ADD     R4, R16\r
738    \   00000030   1E51               ADC     R5, R17\r
739    \   00000032   C016               RJMP    ??ScaleI_1\r
740     307                 }       else    { // Jumper setting 4: mA/LSB = 27.909mA ~= 28 - 1/8 + 1/32\r
741     308                         scaled = 28 * data;\r
742    \                     ??ScaleI_0:\r
743    \   00000034   01AC               MOVW    R21:R20, R25:R24\r
744    \   00000036   E10C               LDI     R16, 28\r
745    \   00000038   E010               LDI     R17, 0\r
746    \   0000003A   ....               RCALL   ?S_MUL_L02\r
747    \   0000003C   0128               MOVW    R5:R4, R17:R16\r
748     309                         scaled -= (data >> 3);\r
749    \   0000003E   018C               MOVW    R17:R16, R25:R24\r
750    \   00000040   E043               LDI     R20, 3\r
751    \   00000042   ....               RCALL   ?US_SHR_L02\r
752    \   00000044   1A40               SUB     R4, R16\r
753    \   00000046   0A51               SBC     R5, R17\r
754     310                         scaled += (data >> 5);\r
755    \   00000048   018C               MOVW    R17:R16, R25:R24\r
756    \   0000004A   E045               LDI     R20, 5\r
757    \   0000004C   ....               RCALL   ?US_SHR_L02\r
758    \   0000004E   0E40               ADD     R4, R16\r
759    \   00000050   1E51               ADC     R5, R17\r
760     311                         \r
761     312                         if (setting <3) {\r
762    \   00000052   30A3               CPI     R26, 3\r
763    \   00000054   F428               BRCC    ??ScaleI_1\r
764     313                                 // Jumper setting 0: mA/LSB = 3.489mA = 27.909 / 8\r
765     314                                 //                1: mA/LSB = 6.978mA = 27.909 / 4\r
766     315                                 //                2: mA/LSB = 13.955mA = 27.909 / 2\r
767     316                                 scaled = (scaled >> (3-setting));\r
768    \   00000056   0182               MOVW    R17:R16, R5:R4\r
769    \   00000058   E043               LDI     R20, 3\r
770    \   0000005A   1B4A               SUB     R20, R26\r
771    \   0000005C   ....               RCALL   ?US_SHR_L02\r
772    \   0000005E   0128               MOVW    R5:R4, R17:R16\r
773     317                         }\r
774     318                 }\r
775     319                 \r
776     320                 return(scaled);\r
777    \                     ??ScaleI_1:\r
778    \   00000060   0182               MOVW    R17:R16, R5:R4\r
779    \   00000062   E0E6               LDI     R30, 6\r
780    \   00000064   ....               RJMP    ?EPILOGUE_B6_L09\r
781     321          }\r
782     322          \r
783     323          \r
784     324          /*! \brief Waits for two full cycles of ADC-conversions to occur.\r
785     325           *\r
786     326           * This function clears the cycle complete-flag, then waits for it to be set\r
787     327           * again. This is then repeated once before the function exits.\r
788     328           * \r
789     329           */\r
790 \r
791    \                                 In  segment CODE, align 2, keep-with-next\r
792     330          void ADC_Wait(void)\r
793    \                     ADC_Wait:\r
794     331          {\r
795     332                 // Clear ADC flag and wait for cycle to complete.\r
796     333                 ADCS.Flag = FALSE;              \r
797    \   00000000   ....               LDI     R30, LOW(ADCS)\r
798    \   00000002   ....               LDI     R31, (ADCS) >> 8\r
799    \   00000004   8100               LD      R16, Z\r
800    \   00000006   7D0F               ANDI    R16, 0xDF\r
801    \   00000008   8300               ST      Z, R16\r
802     334                 do {\r
803     335                 } while (ADCS.Flag == FALSE);      \r
804    \                     ??ADC_Wait_0:\r
805    \   0000000A   ....               LDI     R30, LOW(ADCS)\r
806    \   0000000C   ....               LDI     R31, (ADCS) >> 8\r
807    \   0000000E   8100               LD      R16, Z\r
808    \   00000010   FF05               SBRS    R16, 5\r
809    \   00000012   CFFB               RJMP    ??ADC_Wait_0\r
810     336                 \r
811     337                 // Repeat, so we are sure the data beong to the same cycle.\r
812     338                 ADCS.Flag = FALSE;              \r
813    \   00000014   ....               LDI     R30, LOW(ADCS)\r
814    \   00000016   ....               LDI     R31, (ADCS) >> 8\r
815    \   00000018   8100               LD      R16, Z\r
816    \   0000001A   7D0F               ANDI    R16, 0xDF\r
817    \   0000001C   8300               ST      Z, R16\r
818     339                 do {\r
819     340                 } while (ADCS.Flag == FALSE);      \r
820    \                     ??ADC_Wait_1:\r
821    \   0000001E   ....               LDI     R30, LOW(ADCS)\r
822    \   00000020   ....               LDI     R31, (ADCS) >> 8\r
823    \   00000022   8100               LD      R16, Z\r
824    \   00000024   FF05               SBRS    R16, 5\r
825    \   00000026   CFFB               RJMP    ??ADC_Wait_1\r
826     341          }\r
827    \   00000028   9508               RET\r
828     342          \r
829     343          \r
830     344          /*! \brief Initializes ADC and input pins.\r
831     345           *\r
832     346           * This function initializes the ADC to free running mode, sampling from\r
833     347           * PA1/2/4/5/6/7, and using an external reference voltage (PA3).\n\r
834     348           * It also measures and stores calibration data for offset.\r
835     349           *\r
836     350           * \todo Odd offset measurement for ADC3_G20_OS? It is never used anyway.\r
837     351           *\r
838     352           * \note Table of MUX settings for offset measurement:\r
839     353           * <pre>\r
840     354           *    Ch | Pin |    Gain |    MUX\r
841     355           * ------+-----+---------+-------\r
842     356           *  ADC1 | PA1 |     20x | 001101\r
843     357           *  ADC3 | PA4 |     20x | 010001\r
844     358           *  ADC5 | PA6 |     20x | 010110\r
845     359           *  ADC9 | PB6 |     20x | 011011\r
846     360           *  ADC0 | PA0 | 20x/32x | 111000\r
847     361           *  ADC0 | PA0 |   1x/8x | 111001\r
848     362           *  ADC1 | PA1 | 20x/32x | 111010\r
849     363           *  ADC2 | PA2 | 20x/32x | 111011\r
850     364           *  ADC4 | PA5 | 20x/32x | 111100\r
851     365           *  ADC5 | PA6 | 20x/32x | 111101\r
852     366           *  ADC6 | PA7 | 20x/32x | 111110\r
853     367           * </pre>\r
854     368           */\r
855 \r
856    \                                 In  segment CODE, align 2, keep-with-next\r
857     369          void ADC_Init(void)\r
858    \                     ADC_Init:\r
859     370          {\r
860    \   00000000   938A               ST      -Y, R24\r
861     371                 unsigned char i;\r
862     372          \r
863     373                 __disable_interrupt();\r
864    \   00000002   94F8               CLI\r
865     374          \r
866     375                 ADCS.Halt = FALSE; // Enable consecutive runs of ADC.\r
867    \   00000004   ....               LDI     R30, LOW(ADCS)\r
868    \   00000006   ....               LDI     R31, (ADCS) >> 8\r
869    \   00000008   8100               LD      R16, Z\r
870    \   0000000A   770F               ANDI    R16, 0x7F\r
871    \   0000000C   8300               ST      Z, R16\r
872     376          \r
873     377                 // Configure ADC pins (inputs and disabled pull-ups).\r
874     378                 DDRA &= ~((1<<PA1)|(1<<PA2)|(1<<PA4)|(1<<PA5)|(1<<PA6)|(1<<PA7));\r
875    \   0000000E   B30A               IN      R16, 0x1A\r
876    \   00000010   7009               ANDI    R16, 0x09\r
877    \   00000012   BB0A               OUT     0x1A, R16\r
878     379                 PORTA &= ~((1<<PA1)|(1<<PA2)|(1<<PA4)|(1<<PA5)|(1<<PA6)|(1<<PA7));\r
879    \   00000014   B30B               IN      R16, 0x1B\r
880    \   00000016   7009               ANDI    R16, 0x09\r
881    \   00000018   BB0B               OUT     0x1B, R16\r
882     380          \r
883     381                 // Set ADC3 as reference, and MUX to measure the same pin.\r
884     382                 ADMUX = (1<<REFS0) | (1<<MUX0) | (1<<MUX1);\r
885    \   0000001A   E403               LDI     R16, 67\r
886    \   0000001C   B907               OUT     0x07, R16\r
887     383                 \r
888     384                 ADCSRB = 0;\r
889    \   0000001E   E000               LDI     R16, 0\r
890    \   00000020   B903               OUT     0x03, R16\r
891     385          \r
892     386                 // Start conversion, no interrupt (disable ADC-ISR).\r
893     387                 ADCSRA = (1<<ADEN) | (1<<ADSC) | ADC_PRESCALER; \r
894    \   00000022   EC07               LDI     R16, 199\r
895    \   00000024   B906               OUT     0x06, R16\r
896     388          \r
897     389                 do { // Wait for conversion to finish.\r
898     390                 } while (!(ADCSRA & (1<<ADIF)));\r
899    \                     ??ADC_Init_0:\r
900    \   00000026   9B34               SBIS    0x06, 0x04\r
901    \   00000028   CFFE               RJMP    ??ADC_Init_0\r
902     391          \r
903     392                 ADCSRA |= (1<<ADIF);  // Clear ADC interrupt flag manually.\r
904    \   0000002A   9A34               SBI     0x06, 0x04\r
905     393          \r
906     394                 ADCS.ADC3_G20_OS = ADC;  // Save the sampled offset.\r
907    \   0000002C   9120....           LDS     R18, (ADCS + 1)\r
908    \   00000030   7F20               ANDI    R18, 0xF0\r
909    \   00000032   B104               IN      R16, 0x04\r
910    \   00000034   B115               IN      R17, 0x05\r
911    \   00000036   700F               ANDI    R16, 0x0F\r
912    \   00000038   2B02               OR      R16, R18\r
913    \   0000003A   9300....           STS     (ADCS + 1), R16\r
914     395          \r
915     396                 ADMUX = (1<<REFS0) | 0x16;  // ADC5/ADC5 (external ref.), 20x\r
916    \   0000003E   E506               LDI     R16, 86\r
917    \   00000040   B907               OUT     0x07, R16\r
918     397                 \r
919     398                 // Start conversion, no interrupt. ADC_PRESCALER is defined in ADC.h.\r
920     399                 ADCSRA = (1<<ADEN) | (1<<ADSC) | ADC_PRESCALER; \r
921    \   00000042   EC07               LDI     R16, 199\r
922    \   00000044   B906               OUT     0x06, R16\r
923     400          \r
924     401                 do { // Wait for conversion to finish.\r
925     402                 } while (!(ADCSRA & (1<<ADIF)));\r
926    \                     ??ADC_Init_1:\r
927    \   00000046   9B34               SBIS    0x06, 0x04\r
928    \   00000048   CFFE               RJMP    ??ADC_Init_1\r
929     403          \r
930     404                 ADCSRA |= (1<<ADIF);  // Clear ADC interrupt flag.\r
931    \   0000004A   9A34               SBI     0x06, 0x04\r
932     405          \r
933     406                 ADCS.ADC5_G20_OS = ADC;  // Save the sampled offset.\r
934    \   0000004C   9120....           LDS     R18, (ADCS + 1)\r
935    \   00000050   702F               ANDI    R18, 0x0F\r
936    \   00000052   B104               IN      R16, 0x04\r
937    \   00000054   B115               IN      R17, 0x05\r
938    \   00000056   9502               SWAP    R16\r
939    \   00000058   7F00               ANDI    R16, 0xF0\r
940    \   0000005A   2B02               OR      R16, R18\r
941    \   0000005C   9300....           STS     (ADCS + 1), R16\r
942     407          \r
943     408                 // Reset the ADC-cycle.\r
944     409                 ADCS.Flag = FALSE;      \r
945    \   00000060   ....               LDI     R30, LOW(ADCS)\r
946    \   00000062   ....               LDI     R31, (ADCS) >> 8\r
947    \   00000064   8100               LD      R16, Z\r
948    \   00000066   7D0F               ANDI    R16, 0xDF\r
949    \   00000068   8300               ST      Z, R16\r
950     410                 ADCS.MUX = 0x01;                    \r
951    \   0000006A   9100....           LDS     R16, ADCS\r
952    \   0000006E   7E00               ANDI    R16, 0xE0\r
953    \   00000070   6001               ORI     R16, 0x01\r
954    \   00000072   9300....           STS     ADCS, R16\r
955     411                 ADMUX = (1<<REFS0) | ADCS.MUX;      \r
956    \   00000076   9100....           LDS     R16, ADCS\r
957    \   0000007A   710F               ANDI    R16, 0x1F\r
958    \   0000007C   6400               ORI     R16, 0x40\r
959    \   0000007E   B907               OUT     0x07, R16\r
960     412          \r
961     413                 // Clear averaged battery current and the discrete readings.\r
962     414                 ADCS.avgIBAT = 0;\r
963    \   00000080   E000               LDI     R16, 0\r
964    \   00000082   E010               LDI     R17, 0\r
965    \   00000084   ....               LDI     R30, LOW(ADCS)\r
966    \   00000086   ....               LDI     R31, (ADCS) >> 8\r
967    \   00000088   8B06               STD     Z+22, R16\r
968    \   0000008A   8B17               STD     Z+23, R17\r
969     415                 \r
970     416                 for (i = 0; i < 4; i++) {\r
971    \   0000008C   E080               LDI     R24, 0\r
972    \                     ??ADC_Init_2:\r
973    \   0000008E   3084               CPI     R24, 4\r
974    \   00000090   F468               BRCC    ??ADC_Init_3\r
975     417                         ADCS.discIBAT[i] = 0;             \r
976    \   00000092   E000               LDI     R16, 0\r
977    \   00000094   E010               LDI     R17, 0\r
978    \   00000096   2F28               MOV     R18, R24\r
979    \   00000098   E030               LDI     R19, 0\r
980    \   0000009A   0F22               LSL     R18\r
981    \   0000009C   1F33               ROL     R19\r
982    \   0000009E   01F9               MOVW    R31:R30, R19:R18\r
983    \   000000A0   ....               SUBI    R30, LOW((-(ADCS) & 0xFFFF))\r
984    \   000000A2   ....               SBCI    R31, (-(ADCS) & 0xFFFF) >> 8\r
985    \   000000A4   8706               STD     Z+14, R16\r
986    \   000000A6   8717               STD     Z+15, R17\r
987     418                 }\r
988    \   000000A8   9583               INC     R24\r
989    \   000000AA   CFF1               RJMP    ??ADC_Init_2\r
990     419                 \r
991     420                 // Re-enable the ADC and ISR.\r
992     421                 ADCSRA=(1<<ADEN)|(1<<ADSC)|(1<<ADIE)|ADC_PRESCALER;\r
993    \                     ??ADC_Init_3:\r
994    \   000000AC   EC0F               LDI     R16, 207\r
995    \   000000AE   B906               OUT     0x06, R16\r
996     422                 \r
997     423                 __enable_interrupt();\r
998    \   000000B0   9478               SEI\r
999     424          \r
1000     425                 // Get a complete cycle of data before returning.\r
1001     426                 ADC_Wait();\r
1002    \   000000B2   ....               RCALL   ADC_Wait\r
1003     427          }\r
1004    \   000000B4   9189               LD      R24, Y+\r
1005    \   000000B6   9508               RET\r
1006    \   000000B8                      REQUIRE _A_PORTA\r
1007    \   000000B8                      REQUIRE _A_DDRA\r
1008    \   000000B8                      REQUIRE _A_ADMUX\r
1009    \   000000B8                      REQUIRE _A_ADCSRA\r
1010    \   000000B8                      REQUIRE _A_ADC\r
1011    \   000000B8                      REQUIRE _A_ADCSRB\r
1012 \r
1013    \                                 In  segment INTVEC, offset 0x16, root\r
1014    \                     `??ADC_ISR??INTVEC 22`:\r
1015    \   00000016   ....               RJMP    ADC_ISR\r
1016 \r
1017    Maximum stack usage in bytes:\r
1018 \r
1019      Function      CSTACK RSTACK\r
1020      --------      ------ ------\r
1021      ADC_ISR          20      4\r
1022        -> ScaleU      20      2\r
1023        -> ScaleU      20      2\r
1024        -> ScaleI      20      2\r
1025        -> ScaleI      20      2\r
1026      ADC_Init          1      2\r
1027        -> ADC_Wait     1      2\r
1028      ADC_Wait          0      2\r
1029      ScaleI            6      4\r
1030      ScaleU            6      4\r
1031 \r
1032 \r
1033    Segment part sizes:\r
1034 \r
1035      Function/Label       Bytes\r
1036      --------------       -----\r
1037      _A_PORTA                1\r
1038      _A_DDRA                 1\r
1039      _A_ADMUX                1\r
1040      _A_ADCSRA               1\r
1041      _A_ADC                  2\r
1042      _A_ADCSRB               1\r
1043      ADCS                   24\r
1044      VBAT_RANGE              1\r
1045      ADC_ISR               528\r
1046      avgIndex                1\r
1047      ScaleU                 90\r
1048      ScaleI                102\r
1049      ADC_Wait               42\r
1050      ADC_Init              184\r
1051      ??ADC_ISR??INTVEC 22    2\r
1052       Others                 6\r
1053 \r
1054  \r
1055    7 bytes in segment ABSOLUTE\r
1056  946 bytes in segment CODE\r
1057    1 byte  in segment EEPROM_I\r
1058    6 bytes in segment INITTAB\r
1059    2 bytes in segment INTVEC\r
1060   25 bytes in segment NEAR_Z\r
1061  \r
1062  946 bytes of CODE  memory (+ 8 bytes shared)\r
1063   25 bytes of DATA  memory (+ 7 bytes shared)\r
1064    1 byte  of XDATA memory\r
1065 \r
1066 Errors: none\r
1067 Warnings: none\r