Initial import
[avr_bc100.git] / BaseTinyFirmware / IAR / Debug / List / battery.s90
1 ///////////////////////////////////////////////////////////////////////////////\r
2 //                                                                            /\r
3 // IAR Atmel AVR C/C++ Compiler V4.30F/W32              12/Mar/2008  23:01:38 /\r
4 // Copyright 1996-2007 IAR Systems. All rights reserved.                      /\r
5 //                                                                            /\r
6 //    Source file  =  C:\home\kevin\pub\src\bc100_cal\IAR\battery.c           /\r
7 //    Command line =  C:\home\kevin\pub\src\bc100_cal\IAR\battery.c           /\r
8 //                    --cpu=tiny861 -ms -o C:\home\kevin\pub\src\bc100_cal\IA /\r
9 //                    R\Debug\Obj\ -lC C:\home\kevin\pub\src\bc100_cal\IAR\De /\r
10 //                    bug\List\ -lB C:\home\kevin\pub\src\bc100_cal\IAR\Debug /\r
11 //                    \List\ --initializers_in_flash -z2 --no_cse             /\r
12 //                    --no_inline --no_code_motion --no_cross_call            /\r
13 //                    --no_clustering --no_tbaa --debug                       /\r
14 //                    -DENABLE_BIT_DEFINITIONS -e --require_prototypes -I     /\r
15 //                    "C:\Program Files\IAR Systems\Embedded Workbench        /\r
16 //                    4.0\avr\INC\" -I "C:\Program Files\IAR                  /\r
17 //                    Systems\Embedded Workbench 4.0\avr\INC\CLIB\"           /\r
18 //                    --eeprom_size 512                                       /\r
19 //    List file    =  C:\home\kevin\pub\src\bc100_cal\IAR\Debug\List\battery. /\r
20 //                    s90                                                     /\r
21 //                                                                            /\r
22 //                                                                            /\r
23 ///////////////////////////////////////////////////////////////////////////////\r
24 \r
25         NAME battery\r
26 \r
27         RSEG CSTACK:DATA:NOROOT(0)\r
28         RSEG RSTACK:DATA:NOROOT(0)\r
29 \r
30         EXTERN ?EPILOGUE_B4_L09\r
31         EXTERN ?EPILOGUE_B8_L09\r
32         EXTERN ?PROLOGUE4_L09\r
33         EXTERN ?PROLOGUE8_L09\r
34         EXTERN ?Register_R4_is_cg_reg\r
35         EXTERN ?Register_R5_is_cg_reg\r
36         EXTERN ?Register_R6_is_cg_reg\r
37         EXTERN ?Register_R7_is_cg_reg\r
38         EXTERN ?S_MUL_L02\r
39         EXTERN ?S_SHL_L02\r
40         EXTERN ?US_DIVMOD_L02\r
41         EXTERN ?need_segment_init\r
42         EXTERN __eeput8_16\r
43 \r
44         PUBWEAK `?<Segment init: NEAR_I>`\r
45         PUBWEAK `?<Segment init: NEAR_Z>`\r
46         PUBLIC BattActive\r
47         PUBLIC BattControl\r
48         PUBLIC BattData\r
49         PUBLIC BattEEPROM\r
50         PUBLIC BatteryCheck\r
51         PUBLIC BatteryDataRefresh\r
52         PUBLIC BatteryStatusRefresh\r
53         PUBLIC DisableBatteries\r
54         PUBLIC EnableBattery\r
55         PUBLIC NTC\r
56         PUBLIC NTCLookUp\r
57         PUBLIC RID\r
58         PUBLIC RIDLookUp\r
59         PUBWEAK _A_OCR1B\r
60         PUBWEAK _A_PORTB\r
61         PUBWEAK __?EEARH\r
62         PUBWEAK __?EEARL\r
63         PUBWEAK __?EECR\r
64         PUBWEAK __?EEDR\r
65 \r
66         EXTERN OWI_DetectPresence\r
67         EXTERN OWI_SendByte\r
68         EXTERN OWI_ReceiveByte\r
69         EXTERN OWI_ComputeCRC8\r
70         EXTERN Time_Set\r
71         EXTERN Time_Left\r
72         EXTERN ADCS\r
73 \r
74 // C:\home\kevin\pub\src\bc100_cal\IAR\battery.c\r
75 //    1 /* This file has been prepared for Doxygen automatic documentation generation.*/\r
76 //    2 /*! \file *********************************************************************\r
77 //    3  *\r
78 //    4  * \brief\r
79 //    5  *      Functions related to battery control and data acquisition.\r
80 //    6  *\r
81 //    7  *      Contains functions for enabling/disabling batteries, and looking up\r
82 //    8  *      their status and specifications using the ADC.\r
83 //    9  *\r
84 //   10  * \par Application note:\r
85 //   11  *      AVR458: Charging Li-Ion Batteries with BC100 \n\r
86 //   12  *      AVR463: Charging NiMH Batteries with BC100\r
87 //   13 \r
88 //   14  *\r
89 //   15  * \par Documentation\r
90 //   16  *      For comprehensive code documentation, supported compilers, compiler \r
91 //   17  *      settings and supported devices see readme.html\r
92 //   18  *\r
93 //   19  * \author\r
94 //   20  *      Atmel Corporation: http://www.atmel.com \n\r
95 //   21  *      Support email: avr@atmel.com\r
96 //   22  *\r
97 //   23  * \r
98 //   24  * $Name$\r
99 //   25  * $Revision: 2299 $\r
100 //   26  * $RCSfile$\r
101 //   27  * $URL: http://svn.norway.atmel.com/AppsAVR8/avr458_Charging_Li-Ion_Batteries_with_BC100/tag/20070904_release_1.0/code/IAR/battery.c $\r
102 //   28  * $Date: 2007-08-23 12:55:51 +0200 (to, 23 aug 2007) $\n\r
103 //   29  ******************************************************************************/\r
104 //   30 \r
105 //   31 #include <ioavr.h>\r
106 \r
107         ASEGN ABSOLUTE:DATA:NOROOT,04cH\r
108 // <unnamed> volatile __io _A_OCR1B\r
109 _A_OCR1B:\r
110         DS 1\r
111 \r
112         ASEGN ABSOLUTE:DATA:NOROOT,038H\r
113 // <unnamed> volatile __io _A_PORTB\r
114 _A_PORTB:\r
115         DS 1\r
116 //   32 #include <inavr.h>\r
117 //   33 \r
118 //   34 #include "structs.h"\r
119 //   35 #include "enums.h"\r
120 //   36 \r
121 //   37 #include "ADC.h"\r
122 //   38 #include "battery.h"\r
123 //   39 #include "main.h"\r
124 //   40 #include "OWI.h"\r
125 //   41 #include "time.h"\r
126 //   42 \r
127 //   43 #ifdef NIMH\r
128 //   44 #include "NIMHspecs.h"\r
129 //   45 #endif // NIMH\r
130 //   46 \r
131 //   47 #ifdef LIION\r
132 //   48 #include "LIIONspecs.h"\r
133 //   49 #endif // LIION\r
134 //   50 \r
135 //   51 \r
136 //   52 \r
137 //   53 //******************************************************************************\r
138 //   54 // Variables\r
139 //   55 //******************************************************************************\r
140 //   56 /* Control-struct for batteries */\r
141 //   57 /*! \brief Holds control data for both batteries\r
142 //   58  * \note Stored in EEPROM.\r
143 //   59  */\r
144 \r
145         RSEG EEPROM_I:XDATA:NOROOT(0)\r
146 //   60 __eeprom Battery_t BattControl[2] = {{TRUE, TRUE, FALSE},\r
147 BattControl:\r
148         DB 3, 3\r
149 //   61                                      {TRUE, TRUE, FALSE}};\r
150 //   62 \r
151 //   63 /* Data-struct for battery */\r
152 \r
153         RSEG NEAR_Z:DATA:NOROOT(0)\r
154         REQUIRE `?<Segment init: NEAR_Z>`\r
155 //   64 Batteries_t BattData; //!< Holds data for the current battery\r
156 BattData:\r
157         DS 12\r
158 //   65 \r
159 //   66 \r
160 //   67 /* Storage for battery EPROM */\r
161 //   68 /*! \brief Storage space for data from the batteries' own EPROMs.\r
162 //   69  * \note Stored in EEPROM.\r
163 //   70  */\r
164 \r
165         RSEG EEPROM_I:XDATA:NOROOT(0)\r
166 //   71 __eeprom unsigned char BattEEPROM[4][32];\r
167 BattEEPROM:\r
168         DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
169         DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
170         DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
171         DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
172         DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
173         DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
174         DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
175         DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0\r
176 //   72 \r
177 //   73 \r
178 //   74 //! Global that indicates current battery (0 = battery A, 1 = B)\r
179 \r
180         RSEG NEAR_Z:DATA:NOROOT(0)\r
181         REQUIRE `?<Segment init: NEAR_Z>`\r
182 //   75 unsigned char BattActive;\r
183 BattActive:\r
184         DS 1\r
185 //   76 \r
186 //   77 \r
187 //   78 /*! \brief RID lookup-table\r
188 //   79  *\r
189 //   80  * Contains Resistor ID data specified by manufacturer.\r
190 //   81  *\r
191 //   82  * \note Values have been calculated assuming a +/- 15% tolerance.\r
192 //   83  */\r
193 \r
194         RSEG NEAR_I:DATA:NOROOT(0)\r
195         REQUIRE `?<Segment init: NEAR_I>`\r
196 //   84 const RID_Lookup_t RID[RID_TABLE_SIZE] = {\r
197 RID:\r
198         DS 56\r
199         REQUIRE `?<Initializer for RID>`\r
200 //   85   {558, 659, 3900, 550, 260, 300, 10},\r
201 //   86   {744, 843, 6800, 750, 360, 300, 14},\r
202 //   87   {869, 958, 10000, 1000, 475, 300, 19},\r
203 //   88   {1097, 1153, 24000, 2000, 475, 420, 38}\r
204 //   89 };\r
205 //   90 \r
206 //   91 \r
207 //   92 /*! \brief NTC lookup-table\r
208 //   93  *\r
209 //   94  * The first entry is 0 degrees. For every entry after, temperature increases\r
210 //   95  * with 4 degrees. With 20 entries, the last one equals (20-1)*4 = 76 degrees.\n\r
211 //   96  * It must be sorted in descending ADC order.\r
212 //   97  *\r
213 //   98  * \note This was calculated for a Mitsubishi RH16-3H103FB NTC.\r
214 //   99  *\r
215 //  100  * \note NTCLookUp() must be modified if this table is changed so that:\r
216 //  101  * - first entry is no longer 0 degrees.\r
217 //  102  * - temperature difference between entries is no longer 4 degrees.\r
218 //  103  * - ADCsteps no longer specifies ADC steps per half degree.\r
219 //  104  */\r
220 //  105 // FOR VARTA POLYFLEX NTC\r
221 \r
222         RSEG NEAR_I:DATA:NOROOT(0)\r
223         REQUIRE `?<Segment init: NEAR_I>`\r
224 //  106 const NTC_Lookup_t NTC[NTC_TABLE_SIZE] = {\r
225 NTC:\r
226         DS 60\r
227         REQUIRE `?<Initializer for NTC>`\r
228 //  107         {1002, 23}, {953, 25}, {902, 26}, {849, 27}, {796, 27},\r
229 //  108         {742, 27}, {689, 26}, {637, 26}, {587, 25}, {539, 24},\r
230 //  109         {494, 22}, {451, 21}, {412, 19}, {375, 18}, {341, 17},\r
231 //  110         {310, 15}, {282, 14}, {256, 13}, {233, 11}, {212, 10}\r
232 //  111 };\r
233 //  112 \r
234 //  113 \r
235 //  114 // FOR MITSUBISHI NTC\r
236 //  115 /*\r
237 //  116 const NTC_Lookup_t NTC[NTC_TABLE_SIZE] = {\r
238 //  117   {1004, 24}, {954, 25}, {903, 26}, {850, 27}, {796, 27},\r
239 //  118   {742, 27}, {689, 27}, {637, 26}, {587, 25}, {539, 24},\r
240 //  119   {493, 22}, {451, 21}, {411, 20}, {374, 18}, {340, 17},\r
241 //  120   {309, 15}, {281, 14}, {255, 13}, {232, 11}, {211, 10}\r
242 //  121 };\r
243 //  122 */\r
244 //  123 \r
245 //  124 \r
246 //  125 //******************************************************************************\r
247 //  126 // Functions\r
248 //  127 //******************************************************************************\r
249 //  128 /*! \brief Checks if battery has changed\r
250 //  129  *\r
251 //  130  * Stores current capacity, then attempts to refresh battery status.\n\r
252 //  131  * If the refresh is successful, old capacity is compared with the new one.\r
253 //  132  * \r
254 //  133  * \retval FALSE Battery is disconnected, or capacity has changed.\r
255 //  134  * \retval TRUE All OK.\r
256 //  135  */\r
257 \r
258         RSEG CODE:CODE:NOROOT(1)\r
259 //  136 unsigned char BatteryCheck(void)\r
260 BatteryCheck:\r
261 //  137 {\r
262         RCALL   ?PROLOGUE4_L09\r
263 //  138         unsigned char success = TRUE;\r
264         LDI     R24, 1\r
265 //  139         unsigned int  oldCapacity;\r
266 //  140         \r
267 //  141         // Save to see if battery data has changed.\r
268 //  142         oldCapacity = BattData.Capacity;  \r
269         LDI     R30, LOW(BattData)\r
270         LDI     R31, (BattData) >> 8\r
271         LDD     R16, Z+4\r
272         LDD     R17, Z+5\r
273         MOVW    R27:R26, R17:R16\r
274 //  143         \r
275 //  144         if (!BatteryStatusRefresh()) {\r
276         RCALL   BatteryStatusRefresh\r
277         TST     R16\r
278         BRNE    ??BatteryCheck_0\r
279 //  145                 success = FALSE;              // Battery not present or RID was invalid.\r
280         LDI     R24, 0\r
281 //  146         }\r
282 //  147         \r
283 //  148         if (oldCapacity != BattData.Capacity) {\r
284 ??BatteryCheck_0:\r
285         LDI     R30, LOW(BattData)\r
286         LDI     R31, (BattData) >> 8\r
287         LDD     R16, Z+4\r
288         LDD     R17, Z+5\r
289         CP      R26, R16\r
290         CPC     R27, R17\r
291         BREQ    ??BatteryCheck_1\r
292 //  149                 success = FALSE;              // Battery configuration has changed.\r
293         LDI     R24, 0\r
294 //  150         }\r
295 //  151 \r
296 //  152         return(success);\r
297 ??BatteryCheck_1:\r
298         MOV     R16, R24\r
299         LDI     R30, 4\r
300         RJMP    ?EPILOGUE_B4_L09\r
301 //  153 }\r
302 //  154 \r
303 //  155 \r
304 //  156 /*! \brief Refreshes battery status information\r
305 //  157  *\r
306 //  158  * Refreshes battery status information, if it is present, based on\r
307 //  159  * RID and NTC (read by ADC).\n\r
308 //  160  * The battery must have been enabled and a complete set of ADC data must have\r
309 //  161  * been collected before calling.\n\r
310 //  162  *\r
311 //  163  * \retval FALSE No battery present.\r
312 //  164  * \retval TRUE Battery present, status refreshed.\r
313 //  165  *\r
314 //  166  * \note If ALLOW_NO_RID is defined, charging will NOT stop if no fitting entry\r
315 //  167  * is found in the lookup table. Instead, default battery data will be used.\r
316 //  168  */\r
317 \r
318         RSEG CODE:CODE:NOROOT(1)\r
319 //  169 unsigned char BatteryStatusRefresh(void)\r
320 BatteryStatusRefresh:\r
321 //  170 {\r
322         RCALL   ?PROLOGUE4_L09\r
323 //  171         // Assume the worst..\r
324 //  172         unsigned char success = FALSE;\r
325         LDI     R24, 0\r
326 //  173         \r
327 //  174         BattData.Present = FALSE;\r
328         LDI     R30, LOW(BattData)\r
329         LDI     R31, (BattData) >> 8\r
330         LD      R16, Z\r
331         ANDI    R16, 0xFE\r
332         ST      Z, R16\r
333 //  175         BattData.Charged = FALSE;\r
334         LDI     R30, LOW(BattData)\r
335         LDI     R31, (BattData) >> 8\r
336         LD      R16, Z\r
337         ANDI    R16, 0xFD\r
338         ST      Z, R16\r
339 //  176         BattData.Low = TRUE;\r
340         LDI     R30, LOW(BattData)\r
341         LDI     R31, (BattData) >> 8\r
342         LD      R16, Z\r
343         ORI     R16, 0x04\r
344         ST      Z, R16\r
345 //  177         BattData.Circuit = OW_NONE;\r
346         LDI     R16, 0\r
347         STS     (BattData + 1), R16\r
348 //  178         BattData.Temperature = 0;\r
349         LDI     R16, 0\r
350         STS     (BattData + 2), R16\r
351 //  179         BattData.Capacity = 0;\r
352         LDI     R16, 0\r
353         LDI     R17, 0\r
354         LDI     R30, LOW(BattData)\r
355         LDI     R31, (BattData) >> 8\r
356         STD     Z+4, R16\r
357         STD     Z+5, R17\r
358 //  180         BattData.MaxCurrent = 0;\r
359         LDI     R16, 0\r
360         LDI     R17, 0\r
361         LDI     R30, LOW(BattData)\r
362         LDI     R31, (BattData) >> 8\r
363         STD     Z+6, R16\r
364         STD     Z+7, R17\r
365 //  181         BattData.MaxTime = 0;\r
366         LDI     R16, 0\r
367         LDI     R17, 0\r
368         LDI     R30, LOW(BattData)\r
369         LDI     R31, (BattData) >> 8\r
370         STD     Z+8, R16\r
371         STD     Z+9, R17\r
372 //  182         BattData.MinCurrent = 0;\r
373         LDI     R16, 0\r
374         LDI     R17, 0\r
375         LDI     R30, LOW(BattData)\r
376         LDI     R31, (BattData) >> 8\r
377         STD     Z+10, R16\r
378         STD     Z+11, R17\r
379 //  183 \r
380 //  184         NTCLookUp();\r
381         RCALL   NTCLookUp\r
382 //  185         BattData.HasRID = RIDLookUp();\r
383         RCALL   RIDLookUp\r
384         MOV     R17, R16\r
385         ANDI    R17, 0x01\r
386         LDI     R30, LOW(BattData)\r
387         LDI     R31, (BattData) >> 8\r
388         BST     R17, 0\r
389         LD      R16, Z\r
390         BLD     R16, 4\r
391         ST      Z, R16\r
392         LDI     R16, 0\r
393         BLD     R16, 0\r
394 //  186 \r
395 //  187         // Is the battery voltage above minimum safe cell voltage?\r
396 //  188         if (ADCS.VBAT >= BAT_VOLTAGE_MIN) {\r
397         LDI     R30, LOW(ADCS)\r
398         LDI     R31, (ADCS) >> 8\r
399         LDD     R16, Z+10\r
400         LDD     R17, Z+11\r
401         CPI     R16, 96\r
402         LDI     R18, 9\r
403         CPC     R17, R18\r
404         BRCS    ??BatteryStatusRefresh_0\r
405 //  189                 BattData.Low = FALSE;\r
406         LDI     R30, LOW(BattData)\r
407         LDI     R31, (BattData) >> 8\r
408         LD      R16, Z\r
409         ANDI    R16, 0xFB\r
410         ST      Z, R16\r
411 //  190         }\r
412 //  191 \r
413 //  192         // Is the battery charged?\r
414 //  193         if (ADCS.VBAT >= BAT_VOLTAGE_LOW) {\r
415 ??BatteryStatusRefresh_0:\r
416         LDI     R30, LOW(ADCS)\r
417         LDI     R31, (ADCS) >> 8\r
418         LDD     R16, Z+10\r
419         LDD     R17, Z+11\r
420         CPI     R16, 210\r
421         LDI     R18, 15\r
422         CPC     R17, R18\r
423         BRCS    ??BatteryStatusRefresh_1\r
424 //  194                 BattData.Charged = TRUE;\r
425         LDI     R30, LOW(BattData)\r
426         LDI     R31, (BattData) >> 8\r
427         LD      R16, Z\r
428         ORI     R16, 0x02\r
429         ST      Z, R16\r
430 //  195         }\r
431 //  196 \r
432 //  197         // If we are not charging, yet VBAT is above safe limit, battery is present.\r
433 //  198         // If we are charging and there's a current flowing, the battery is present.\r
434 //  199         \r
435 //  200         /*! \todo If ABORT_IF_PWM_MAX is defined this last check battery presence\r
436 //  201         * check is redundant since charging will be aborted due to low current at\r
437 //  202         * max duty cycle. That is preferrable since the charge current reading is\r
438 //  203         * not 100% proof.\r
439 //  204         */\r
440 //  205         if (((OCR1B == 0) && (!BattData.Low)) ||\r
441 //  206             ((OCR1B != 0) && (ADCS.avgIBAT > 0))) {\r
442 ??BatteryStatusRefresh_1:\r
443         IN      R16, 0x2C\r
444         TST     R16\r
445         BRNE    ??BatteryStatusRefresh_2\r
446         LDI     R30, LOW(BattData)\r
447         LDI     R31, (BattData) >> 8\r
448         LD      R16, Z\r
449         SBRS    R16, 2\r
450         RJMP    ??BatteryStatusRefresh_3\r
451 ??BatteryStatusRefresh_2:\r
452         IN      R16, 0x2C\r
453         TST     R16\r
454         BREQ    ??BatteryStatusRefresh_4\r
455         LDI     R26, LOW((ADCS + 22))\r
456         LDI     R27, HIGH((ADCS + 22))\r
457         LD      R30, X+\r
458         LD      R31, X\r
459         SBIW    R27:R26, 1\r
460         SBIW    R31:R30, 1\r
461         BRLT    ??BatteryStatusRefresh_4\r
462 //  207                 BattData.Present = TRUE;\r
463 ??BatteryStatusRefresh_3:\r
464         LDI     R30, LOW(BattData)\r
465         LDI     R31, (BattData) >> 8\r
466         LD      R16, Z\r
467         ORI     R16, 0x01\r
468         ST      Z, R16\r
469 //  208                 success = TRUE;\r
470         LDI     R24, 1\r
471         RJMP    ??BatteryStatusRefresh_5\r
472 //  209         } else {\r
473 //  210                 BattData.Low = FALSE;  // (This is just a technicality..)\r
474 ??BatteryStatusRefresh_4:\r
475         LDI     R30, LOW(BattData)\r
476         LDI     R31, (BattData) >> 8\r
477         LD      R16, Z\r
478         ANDI    R16, 0xFB\r
479         ST      Z, R16\r
480 //  211                 success = FALSE;\r
481         LDI     R24, 0\r
482 //  212         }\r
483 //  213 \r
484 //  214 #ifndef ALLOW_NO_RID\r
485 //  215         // Return FALSE if no valid RID entry was found, to stop charging.\r
486 //  216         if(!BattData.HasRID) {\r
487 ??BatteryStatusRefresh_5:\r
488         LDI     R30, LOW(BattData)\r
489         LDI     R31, (BattData) >> 8\r
490         LD      R16, Z\r
491         SBRS    R16, 4\r
492 //  217                 success = FALSE;\r
493         LDI     R24, 0\r
494 //  218         }\r
495 //  219 #endif\r
496 //  220 \r
497 //  221         return(success);\r
498 ??BatteryStatusRefresh_6:\r
499         MOV     R16, R24\r
500         LDI     R30, 4\r
501         RJMP    ?EPILOGUE_B4_L09\r
502         REQUIRE _A_OCR1B\r
503 //  222 }\r
504 //  223 \r
505 //  224 \r
506 //  225 /*! \brief Refreshes battery data in the EEPROM\r
507 //  226  *\r
508 //  227  * Attempts to read 4 pages of 32 bytes each from the battery's EPROM and store\r
509 //  228  * these data in on-chip EEPROM.\n\r
510 //  229  * If unsuccessful (CRC doesn't check out), the on-chip EEPROM is cleared.\r
511 //  230  *\r
512 //  231  * \todo Updating BattData with these data. Specs needed.\r
513 //  232  *\r
514 //  233  * \retval FALSE Refresh failed.\r
515 //  234  * \retval TRUE Refresh successful.\r
516 //  235  */\r
517 \r
518         RSEG CODE:CODE:NOROOT(1)\r
519 //  236 unsigned char BatteryDataRefresh(void)\r
520 BatteryDataRefresh:\r
521 //  237 {\r
522         RCALL   ?PROLOGUE8_L09\r
523         REQUIRE ?Register_R4_is_cg_reg\r
524         REQUIRE ?Register_R5_is_cg_reg\r
525         REQUIRE ?Register_R6_is_cg_reg\r
526         REQUIRE ?Register_R7_is_cg_reg\r
527 //  238         unsigned char offset;\r
528 //  239         unsigned char i, crc, family, temp, page;\r
529 //  240         unsigned char success;\r
530 //  241         \r
531 //  242         // Look for EPROM and read 4 pages of 32 bytes each worth of data, if found.\r
532 //  243         for (page = 0; page < 4; page++)        {\r
533         LDI     R25, 0\r
534 ??BatteryDataRefresh_0:\r
535         CPI     R25, 4\r
536         BRCS    $+2+2\r
537         RJMP    ??BatteryDataRefresh_1\r
538 //  244                 success = FALSE;\r
539         LDI     R27, 0\r
540 //  245         \r
541 //  246                 if (OWI_DetectPresence(OWIBUS) == OWIBUS) {\r
542         LDI     R16, 1\r
543         RCALL   OWI_DetectPresence\r
544         CPI     R16, 1\r
545         BREQ    $+2+2\r
546         RJMP    ??BatteryDataRefresh_2\r
547 //  247                         \r
548 //  248                         // Presence detected, check type and CRC.\r
549 //  249                         OWI_SendByte(OWI_ROM_READ, OWIBUS);\r
550         LDI     R17, 1\r
551         LDI     R16, 51\r
552         RCALL   OWI_SendByte\r
553 //  250                         family = OWI_ReceiveByte(OWIBUS);\r
554         LDI     R16, 1\r
555         RCALL   OWI_ReceiveByte\r
556         MOV     R6, R16\r
557 //  251                         crc = OWI_ComputeCRC8(family,0);\r
558         LDI     R17, 0\r
559         MOV     R16, R6\r
560         RCALL   OWI_ComputeCRC8\r
561         MOV     R5, R16\r
562 //  252 \r
563 //  253                         for (i = 0; i < 6; i++) {\r
564         LDI     R24, 0\r
565 ??BatteryDataRefresh_3:\r
566         CPI     R24, 6\r
567         BRCC    ??BatteryDataRefresh_4\r
568 //  254                                 crc = OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc);\r
569         LDI     R16, 1\r
570         RCALL   OWI_ReceiveByte\r
571         MOV     R17, R5\r
572         RCALL   OWI_ComputeCRC8\r
573         MOV     R5, R16\r
574 //  255                         }\r
575         INC     R24\r
576         RJMP    ??BatteryDataRefresh_3\r
577 //  256 \r
578 //  257                         // CRC ok, device found.\r
579 //  258                         if (OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc) == 0) {\r
580 ??BatteryDataRefresh_4:\r
581         LDI     R16, 1\r
582         RCALL   OWI_ReceiveByte\r
583         MOV     R17, R5\r
584         RCALL   OWI_ComputeCRC8\r
585         TST     R16\r
586         BREQ    $+2+2\r
587         RJMP    ??BatteryDataRefresh_2\r
588 //  259                                 BattData.Circuit = family;\r
589         STS     (BattData + 1), R6\r
590 //  260 \r
591 //  261                                 // For now, we only read data from DS2505 EPROMs.\r
592 //  262                                 if (BattData.Circuit == OW_DS2505) {\r
593         LDS     R16, (BattData + 1)\r
594         CPI     R16, 9\r
595         BREQ    $+2+2\r
596         RJMP    ??BatteryDataRefresh_2\r
597 //  263                                         offset = page*32;\r
598         MOV     R16, R25\r
599         SWAP    R16\r
600         ANDI    R16, 0xF0\r
601         LSL     R16\r
602         MOV     R4, R16\r
603 //  264                                         OWI_SendByte(DS2505_DATA_READ, OWIBUS);  // Command: read data.\r
604         LDI     R17, 1\r
605         LDI     R16, 195\r
606         RCALL   OWI_SendByte\r
607 //  265                                         OWI_SendByte(offset, OWIBUS);            // Data: low address.\r
608         LDI     R17, 1\r
609         MOV     R16, R4\r
610         RCALL   OWI_SendByte\r
611 //  266                                         OWI_SendByte(0, OWIBUS);                 // Data: high address.\r
612         LDI     R17, 1\r
613         LDI     R16, 0\r
614         RCALL   OWI_SendByte\r
615 //  267 \r
616 //  268                                         // Calculate checksums.\r
617 //  269                                         crc = OWI_ComputeCRC8(DS2505_DATA_READ,0);\r
618         LDI     R17, 0\r
619         LDI     R16, 195\r
620         RCALL   OWI_ComputeCRC8\r
621         MOV     R5, R16\r
622 //  270                                         crc = OWI_ComputeCRC8(offset,crc);\r
623         MOV     R17, R5\r
624         MOV     R16, R4\r
625         RCALL   OWI_ComputeCRC8\r
626         MOV     R5, R16\r
627 //  271                                         crc = OWI_ComputeCRC8(0,crc);\r
628         MOV     R17, R5\r
629         LDI     R16, 0\r
630         RCALL   OWI_ComputeCRC8\r
631         MOV     R5, R16\r
632 //  272 \r
633 //  273                                         // Command received succesfully, now start reading data\r
634 //  274                                         // and writing it to EEPROM.\r
635 //  275                                         if (OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc) == 0) {\r
636         LDI     R16, 1\r
637         RCALL   OWI_ReceiveByte\r
638         MOV     R17, R5\r
639         RCALL   OWI_ComputeCRC8\r
640         TST     R16\r
641         BRNE    ??BatteryDataRefresh_2\r
642 //  276                                                 crc = 0;\r
643         CLR     R5\r
644 //  277                                                 \r
645 //  278                                                 // Fill page with data.\r
646 //  279                                                 for (i=0; i<32; i++) {\r
647         LDI     R24, 0\r
648 ??BatteryDataRefresh_5:\r
649         CPI     R24, 32\r
650         BRCC    ??BatteryDataRefresh_6\r
651 //  280                                                         temp = OWI_ReceiveByte(OWIBUS);\r
652         LDI     R16, 1\r
653         RCALL   OWI_ReceiveByte\r
654         MOV     R7, R16\r
655 //  281                                                         crc = OWI_ComputeCRC8(temp, crc);\r
656         MOV     R17, R5\r
657         MOV     R16, R7\r
658         RCALL   OWI_ComputeCRC8\r
659         MOV     R5, R16\r
660 //  282                                                         BattEEPROM[page][i] = temp;\r
661         MOV     R20, R25\r
662         LDI     R21, 0\r
663         LDI     R16, 32\r
664         LDI     R17, 0\r
665         RCALL   ?S_MUL_L02\r
666         LDI     R20, LOW(BattEEPROM)\r
667         LDI     R21, (BattEEPROM) >> 8\r
668         ADD     R20, R16\r
669         ADC     R21, R17\r
670         MOV     R16, R24\r
671         LDI     R17, 0\r
672         ADD     R20, R16\r
673         ADC     R21, R17\r
674         MOV     R16, R7\r
675         RCALL   __eeput8_16\r
676 //  283                                                 }\r
677         INC     R24\r
678         RJMP    ??BatteryDataRefresh_5\r
679 //  284                                                 \r
680 //  285                                                 if (OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc) == 0) {\r
681 ??BatteryDataRefresh_6:\r
682         LDI     R16, 1\r
683         RCALL   OWI_ReceiveByte\r
684         MOV     R17, R5\r
685         RCALL   OWI_ComputeCRC8\r
686         TST     R16\r
687         BRNE    ??BatteryDataRefresh_2\r
688 //  286                                                                 success = TRUE;  // Data read OK\r
689         LDI     R27, 1\r
690 //  287                                                 }\r
691 //  288                                         } else { // Not able to start reading data.\r
692 //  289                                         }\r
693 //  290                                 } else { // Wrong device type.\r
694 //  291                                 }\r
695 //  292                         } else { // No device found.             \r
696 //  293                         }\r
697 //  294                 } else { // No presence detected on one-wire bus.\r
698 //  295                 }\r
699 //  296 \r
700 //  297           // Erase local EEPROM page if there were any errors during transfer.\r
701 //  298                 if (!success) {\r
702 ??BatteryDataRefresh_2:\r
703         TST     R27\r
704         BRNE    ??BatteryDataRefresh_7\r
705 //  299                         for (i=0; i<32; i++) {\r
706         LDI     R24, 0\r
707 ??BatteryDataRefresh_8:\r
708         CPI     R24, 32\r
709         BRCC    ??BatteryDataRefresh_7\r
710 //  300                                 BattEEPROM[page][i] = 0;\r
711         LDI     R26, 0\r
712         MOV     R20, R25\r
713         LDI     R21, 0\r
714         LDI     R16, 32\r
715         LDI     R17, 0\r
716         RCALL   ?S_MUL_L02\r
717         LDI     R20, LOW(BattEEPROM)\r
718         LDI     R21, (BattEEPROM) >> 8\r
719         ADD     R20, R16\r
720         ADC     R21, R17\r
721         MOV     R16, R24\r
722         LDI     R17, 0\r
723         ADD     R20, R16\r
724         ADC     R21, R17\r
725         MOV     R16, R26\r
726         RCALL   __eeput8_16\r
727 //  301                         }\r
728         INC     R24\r
729         RJMP    ??BatteryDataRefresh_8\r
730 //  302                 }\r
731 //  303         }\r
732 ??BatteryDataRefresh_7:\r
733         INC     R25\r
734         RJMP    ??BatteryDataRefresh_0\r
735 //  304 \r
736 //  305         return(success);\r
737 ??BatteryDataRefresh_1:\r
738         MOV     R16, R27\r
739         LDI     R30, 8\r
740         RJMP    ?EPILOGUE_B8_L09\r
741 //  306 }\r
742 //  307 \r
743 //  308 \r
744 //  309 /*! \brief Enables specified battery\r
745 //  310  *\r
746 //  311  * Updates \ref BattActive to specified battery, then sets PB4/PB5 and clears\r
747 //  312  * PB5/PB4 in PORTB, depending on which battery is specified.\n\r
748 //  313  * The function takes 100 ms to allow the port switch to settle.\r
749 //  314  *\r
750 //  315  * \param bat Specifies which battery to enable (0 = battery A, 1 = B)\r
751 //  316  */\r
752 \r
753         RSEG CODE:CODE:NOROOT(1)\r
754 //  317 void EnableBattery(unsigned char bat)\r
755 EnableBattery:\r
756 //  318 {\r
757         ST      -Y, R24\r
758         MOV     R24, R16\r
759 //  319         // Use general timer, set timeout to 100ms.\r
760 //  320         Time_Set(TIMER_GEN,0,0,100);\r
761         LDI     R20, 100\r
762         LDI     R17, 0\r
763         LDI     R18, 0\r
764         LDI     R19, 0\r
765         LDI     R16, 2\r
766         RCALL   Time_Set\r
767 //  321 \r
768 //  322         // Set specified battery as the active one.\r
769 //  323         BattActive = bat;\r
770         STS     BattActive, R24\r
771 //  324 \r
772 //  325         // Enable current battery in hardware, light LED & connect battery.\r
773 //  326         PORTB |= (1 << (PB4+bat));\r
774         LDI     R16, 1\r
775         LDI     R17, 0\r
776         MOV     R20, R24\r
777         SUBI    R20, 252\r
778         RCALL   ?S_SHL_L02\r
779         IN      R17, 0x18\r
780         OR      R17, R16\r
781         OUT     0x18, R17\r
782 //  327 \r
783 //  328         // Disconnect other battery.\r
784 //  329         PORTB &= ~(1<<(PB5-bat));     \r
785         LDI     R16, 1\r
786         LDI     R17, 0\r
787         LDI     R20, 5\r
788         SUB     R20, R24\r
789         RCALL   ?S_SHL_L02\r
790         COM     R16\r
791         IN      R17, 0x18\r
792         AND     R17, R16\r
793         OUT     0x18, R17\r
794 //  330 \r
795 //  331         do { // Let port switch settle.\r
796 //  332         } while (Time_Left(TIMER_GEN));  \r
797 ??EnableBattery_0:\r
798         LDI     R16, 2\r
799         RCALL   Time_Left\r
800         TST     R16\r
801         BRNE    ??EnableBattery_0\r
802 //  333 }\r
803         LD      R24, Y+\r
804         RET\r
805         REQUIRE _A_PORTB\r
806 //  334 \r
807 //  335 \r
808 //  336 /*! \brief Disables both batteries\r
809 //  337  *\r
810 //  338  * Clears PB4 and PB5 in PORTB, disabling both batteries.\r
811 //  339  */\r
812 \r
813         RSEG CODE:CODE:NOROOT(1)\r
814 //  340 void DisableBatteries(void)\r
815 DisableBatteries:\r
816 //  341 {\r
817 //  342         // Turn off LEDs and disconnect batteries.\r
818 //  343         PORTB &= ~((1<<PB4)|(1<<PB5));  \r
819         IN      R16, 0x18\r
820         ANDI    R16, 0xCF\r
821         OUT     0x18, R16\r
822 //  344 }\r
823         RET\r
824         REQUIRE _A_PORTB\r
825 //  345 \r
826 //  346 \r
827 //  347 /*! \brief Looks up battery data from RID table\r
828 //  348  *\r
829 //  349  * Attempts to find data for the battery from the RID lookup-table.\n\r
830 //  350  * If no valid entry is found, default data (defined in battery.h)\r
831 //  351  * are used.\r
832 //  352  *\r
833 //  353  * \retval TRUE Entry found, battery data updated.\r
834 //  354  * \retval FALSE No entry found, using defaults for battery data.\r
835 //  355  */\r
836 \r
837         RSEG CODE:CODE:NOROOT(1)\r
838 //  356 unsigned char RIDLookUp (void)\r
839 RIDLookUp:\r
840 //  357 {\r
841         RCALL   ?PROLOGUE4_L09\r
842 //  358         unsigned char i, found = FALSE;\r
843         LDI     R25, 0\r
844 //  359                 \r
845 //  360         // Lookup in the RID-table. If measured RID is within the limits\r
846 //  361         // of an entry, those data are used, and TRUE is returned.\r
847 //  362         for (i = 0 ; i < RID_TABLE_SIZE; i++) {\r
848         LDI     R24, 0\r
849 ??RIDLookUp_0:\r
850         CPI     R24, 4\r
851         BRCS    $+2+2\r
852         RJMP    ??RIDLookUp_1\r
853 //  363                 if (ADCS.rawRID >= RID[i].Low) {\r
854         LDI     R30, LOW(ADCS)\r
855         LDI     R31, (ADCS) >> 8\r
856         LDD     R26, Z+2\r
857         LDD     R27, Z+3\r
858         MOV     R20, R24\r
859         LDI     R21, 0\r
860         LDI     R16, 14\r
861         LDI     R17, 0\r
862         RCALL   ?S_MUL_L02\r
863         MOVW    R31:R30, R17:R16\r
864         SUBI    R30, LOW((-(RID) & 0xFFFF))\r
865         SBCI    R31, (-(RID) & 0xFFFF) >> 8\r
866         LD      R16, Z\r
867         LDD     R17, Z+1\r
868         CP      R26, R16\r
869         CPC     R27, R17\r
870         BRCC    $+2+2\r
871         RJMP    ??RIDLookUp_2\r
872 //  364                         if (ADCS.rawRID <= RID[i].High) {\r
873         MOV     R20, R24\r
874         LDI     R21, 0\r
875         LDI     R16, 14\r
876         LDI     R17, 0\r
877         RCALL   ?S_MUL_L02\r
878         MOVW    R31:R30, R17:R16\r
879         SUBI    R30, LOW((-(RID) & 0xFFFF))\r
880         SBCI    R31, (-(RID) & 0xFFFF) >> 8\r
881         LDD     R16, Z+2\r
882         LDD     R17, Z+3\r
883         LDI     R30, LOW(ADCS)\r
884         LDI     R31, (ADCS) >> 8\r
885         LDD     R18, Z+2\r
886         LDD     R19, Z+3\r
887         CP      R16, R18\r
888         CPC     R17, R19\r
889         BRCS    ??RIDLookUp_2\r
890 //  365                                 BattData.Capacity = RID[i].Capacity;\r
891         MOV     R20, R24\r
892         LDI     R21, 0\r
893         LDI     R16, 14\r
894         LDI     R17, 0\r
895         RCALL   ?S_MUL_L02\r
896         MOVW    R31:R30, R17:R16\r
897         SUBI    R30, LOW((-(RID) & 0xFFFF))\r
898         SBCI    R31, (-(RID) & 0xFFFF) >> 8\r
899         LDD     R16, Z+6\r
900         LDD     R17, Z+7\r
901         LDI     R30, LOW(BattData)\r
902         LDI     R31, (BattData) >> 8\r
903         STD     Z+4, R16\r
904         STD     Z+5, R17\r
905 //  366                                 BattData.MaxCurrent = RID[i].Icharge;\r
906         MOV     R20, R24\r
907         LDI     R21, 0\r
908         LDI     R16, 14\r
909         LDI     R17, 0\r
910         RCALL   ?S_MUL_L02\r
911         MOVW    R31:R30, R17:R16\r
912         SUBI    R30, LOW((-(RID) & 0xFFFF))\r
913         SBCI    R31, (-(RID) & 0xFFFF) >> 8\r
914         LDD     R16, Z+8\r
915         LDD     R17, Z+9\r
916         LDI     R30, LOW(BattData)\r
917         LDI     R31, (BattData) >> 8\r
918         STD     Z+6, R16\r
919         STD     Z+7, R17\r
920 //  367                                 BattData.MaxTime = RID[i].tCutOff;\r
921         MOV     R20, R24\r
922         LDI     R21, 0\r
923         LDI     R16, 14\r
924         LDI     R17, 0\r
925         RCALL   ?S_MUL_L02\r
926         MOVW    R31:R30, R17:R16\r
927         SUBI    R30, LOW((-(RID) & 0xFFFF))\r
928         SBCI    R31, (-(RID) & 0xFFFF) >> 8\r
929         LDD     R16, Z+10\r
930         LDD     R17, Z+11\r
931         LDI     R30, LOW(BattData)\r
932         LDI     R31, (BattData) >> 8\r
933         STD     Z+8, R16\r
934         STD     Z+9, R17\r
935 //  368                                 BattData.MinCurrent = RID[i].ICutOff;\r
936         MOV     R20, R24\r
937         LDI     R21, 0\r
938         LDI     R16, 14\r
939         LDI     R17, 0\r
940         RCALL   ?S_MUL_L02\r
941         MOVW    R31:R30, R17:R16\r
942         SUBI    R30, LOW((-(RID) & 0xFFFF))\r
943         SBCI    R31, (-(RID) & 0xFFFF) >> 8\r
944         LDD     R16, Z+12\r
945         LDD     R17, Z+13\r
946         LDI     R30, LOW(BattData)\r
947         LDI     R31, (BattData) >> 8\r
948         STD     Z+10, R16\r
949         STD     Z+11, R17\r
950 //  369                                 \r
951 //  370                                 found = TRUE;\r
952         LDI     R25, 1\r
953 //  371                         }\r
954 //  372                 }\r
955 //  373         }\r
956 ??RIDLookUp_2:\r
957         INC     R24\r
958         RJMP    ??RIDLookUp_0\r
959 //  374         \r
960 //  375         // If no valid entry is found, use defaults and return FALSE.\r
961 //  376         if (!found) {\r
962 ??RIDLookUp_1:\r
963         TST     R25\r
964         BRNE    ??RIDLookUp_3\r
965 //  377                 BattData.Capacity = DEF_BAT_CAPACITY;\r
966         LDI     R16, 0\r
967         LDI     R17, 0\r
968         LDI     R30, LOW(BattData)\r
969         LDI     R31, (BattData) >> 8\r
970         STD     Z+4, R16\r
971         STD     Z+5, R17\r
972 //  378                 BattData.MaxCurrent = DEF_BAT_CURRENT_MAX;\r
973         LDI     R16, 0\r
974         LDI     R17, 0\r
975         LDI     R30, LOW(BattData)\r
976         LDI     R31, (BattData) >> 8\r
977         STD     Z+6, R16\r
978         STD     Z+7, R17\r
979 //  379                 BattData.MaxTime = DEF_BAT_TIME_MAX;\r
980         LDI     R16, 0\r
981         LDI     R17, 0\r
982         LDI     R30, LOW(BattData)\r
983         LDI     R31, (BattData) >> 8\r
984         STD     Z+8, R16\r
985         STD     Z+9, R17\r
986 //  380                 BattData.MinCurrent = DEF_BAT_CURRENT_MIN;\r
987         LDI     R16, 0\r
988         LDI     R17, 0\r
989         LDI     R30, LOW(BattData)\r
990         LDI     R31, (BattData) >> 8\r
991         STD     Z+10, R16\r
992         STD     Z+11, R17\r
993 //  381         }\r
994 //  382         \r
995 //  383         return(found);\r
996 ??RIDLookUp_3:\r
997         MOV     R16, R25\r
998         LDI     R30, 4\r
999         RJMP    ?EPILOGUE_B4_L09\r
1000 //  384 }\r
1001 //  385 \r
1002 //  386 \r
1003 //  387 /*! \brief Calculates temperature from a lookup table\r
1004 //  388  *\r
1005 //  389  * Looks up the highest NTC value below or equal to the measured one.\n\r
1006 //  390  * With the current lookup table, temperature is calculated with the formula:\n\r
1007 //  391  * 4*(index of entry) - 2*(measured NTC - NTC from entry) / (ADCsteps of entry)\r
1008 //  392  *\r
1009 //  393  * \note If the NTC-measurement is saturated, with the current lookup table,\r
1010 //  394  * the temperature will be reported as -1 C.\r
1011 //  395  *\r
1012 //  396  * \note If no valid entry is found, battery temperature is set to 80.\r
1013 //  397  */\r
1014 \r
1015         RSEG CODE:CODE:NOROOT(1)\r
1016 //  398 void NTCLookUp (void)\r
1017 NTCLookUp:\r
1018 //  399 {\r
1019         RCALL   ?PROLOGUE4_L09\r
1020 //  400         unsigned char i;\r
1021 //  401         unsigned char found = FALSE;\r
1022         LDI     R25, 0\r
1023 //  402         \r
1024 //  403         // Lookup in the NTC-table. Use the first entry which is equal or below\r
1025 //  404         // sampled NTC. Calculate temperature by using the index number, and the\r
1026 //  405         // difference between the measured NTC value and the one in the entry.\r
1027 //  406         for (i=0 ; (i < NTC_TABLE_SIZE) && (!found); i++)       {\r
1028         LDI     R24, 0\r
1029 ??NTCLookUp_0:\r
1030         CPI     R24, 20\r
1031         BRCS    $+2+2\r
1032         RJMP    ??NTCLookUp_1\r
1033         TST     R25\r
1034         BREQ    $+2+2\r
1035         RJMP    ??NTCLookUp_1\r
1036 //  407                 if (ADCS.rawNTC >= NTC[i].ADC) {\r
1037         LDI     R30, LOW(ADCS)\r
1038         LDI     R31, (ADCS) >> 8\r
1039         LDD     R26, Z+4\r
1040         LDD     R27, Z+5\r
1041         MOV     R20, R24\r
1042         LDI     R21, 0\r
1043         LDI     R16, 3\r
1044         LDI     R17, 0\r
1045         RCALL   ?S_MUL_L02\r
1046         MOVW    R31:R30, R17:R16\r
1047         SUBI    R30, LOW((-(NTC) & 0xFFFF))\r
1048         SBCI    R31, (-(NTC) & 0xFFFF) >> 8\r
1049         LD      R16, Z\r
1050         LDD     R17, Z+1\r
1051         CP      R26, R16\r
1052         CPC     R27, R17\r
1053         BRCS    ??NTCLookUp_2\r
1054 //  408                         BattData.Temperature = (i<<2) ;\r
1055         MOV     R16, R24\r
1056         LSL     R16\r
1057         LSL     R16\r
1058         STS     (BattData + 2), R16\r
1059 //  409                         BattData.ADCSteps = NTC[i].ADCsteps;  \r
1060         MOV     R20, R24\r
1061         LDI     R21, 0\r
1062         LDI     R16, 3\r
1063         LDI     R17, 0\r
1064         RCALL   ?S_MUL_L02\r
1065         MOVW    R31:R30, R17:R16\r
1066         SUBI    R30, LOW((-(NTC) & 0xFFFF))\r
1067         SBCI    R31, (-(NTC) & 0xFFFF) >> 8\r
1068         LDD     R16, Z+2\r
1069         STS     (BattData + 3), R16\r
1070 //  410                         BattData.Temperature -= ((ADCS.rawNTC - NTC[i].ADC)<<1) / BattData.ADCSteps;\r
1071         LDI     R30, LOW(ADCS)\r
1072         LDI     R31, (ADCS) >> 8\r
1073         LDD     R26, Z+4\r
1074         LDD     R27, Z+5\r
1075         MOV     R20, R24\r
1076         LDI     R21, 0\r
1077         LDI     R16, 3\r
1078         LDI     R17, 0\r
1079         RCALL   ?S_MUL_L02\r
1080         MOVW    R31:R30, R17:R16\r
1081         SUBI    R30, LOW((-(NTC) & 0xFFFF))\r
1082         SBCI    R31, (-(NTC) & 0xFFFF) >> 8\r
1083         LD      R16, Z\r
1084         LDD     R17, Z+1\r
1085         SUB     R26, R16\r
1086         SBC     R27, R17\r
1087         LSL     R26\r
1088         ROL     R27\r
1089         MOVW    R17:R16, R27:R26\r
1090         LDS     R20, (BattData + 3)\r
1091         LDI     R21, 0\r
1092         RCALL   ?US_DIVMOD_L02\r
1093         LDI     R30, LOW(BattData)\r
1094         LDI     R31, (BattData) >> 8\r
1095         LDD     R17, Z+2\r
1096         SUB     R17, R16\r
1097         STD     Z+2, R17\r
1098 //  411                         \r
1099 //  412                         found = TRUE;  // Could be done with a break, but that violates MISRA.\r
1100         LDI     R25, 1\r
1101 //  413                 }\r
1102 //  414         }\r
1103 ??NTCLookUp_2:\r
1104         INC     R24\r
1105         RJMP    ??NTCLookUp_0\r
1106 //  415         \r
1107 //  416         // For safety, is temperature is greater than the NTC \r
1108 //  417         if (!found) {\r
1109 ??NTCLookUp_1:\r
1110         TST     R25\r
1111         BRNE    ??NTCLookUp_3\r
1112 //  418                 BattData.Temperature = 80;\r
1113         LDI     R16, 80\r
1114         STS     (BattData + 2), R16\r
1115 //  419         }\r
1116 //  420 }\r
1117 ??NTCLookUp_3:\r
1118         LDI     R30, 4\r
1119         RJMP    ?EPILOGUE_B4_L09\r
1120 \r
1121         ASEGN ABSOLUTE:DATA:NOROOT,01cH\r
1122 __?EECR:\r
1123 \r
1124         ASEGN ABSOLUTE:DATA:NOROOT,01dH\r
1125 __?EEDR:\r
1126 \r
1127         ASEGN ABSOLUTE:DATA:NOROOT,01eH\r
1128 __?EEARL:\r
1129 \r
1130         ASEGN ABSOLUTE:DATA:NOROOT,01fH\r
1131 __?EEARH:\r
1132 \r
1133         RSEG INITTAB:CODE:NOROOT(0)\r
1134 `?<Segment init: NEAR_Z>`:\r
1135         DW      SFE(NEAR_Z) - SFB(NEAR_Z)\r
1136         DW      SFB(NEAR_Z)\r
1137         DW      0\r
1138         REQUIRE ?need_segment_init\r
1139 \r
1140         RSEG NEAR_ID:CODE:NOROOT(0)\r
1141 `?<Initializer for RID>`:\r
1142         DW 558, 659, 3900, 550, 260, 300, 10, 744, 843, 6800, 750, 360, 300, 14\r
1143         DW 869, 958, 10000, 1000, 475, 300, 19, 1097, 1153, 24000, 2000, 475\r
1144         DW 420, 38\r
1145 \r
1146         RSEG INITTAB:CODE:NOROOT(0)\r
1147 `?<Segment init: NEAR_I>`:\r
1148         DW      SFE(NEAR_I) - SFB(NEAR_I)\r
1149         DW      SFB(NEAR_I)\r
1150         DW      SFB(NEAR_ID)\r
1151         REQUIRE ?need_segment_init\r
1152 \r
1153         RSEG NEAR_ID:CODE:NOROOT(0)\r
1154 `?<Initializer for NTC>`:\r
1155         DW 1002\r
1156         DB 23\r
1157         DW 953\r
1158         DB 25\r
1159         DW 902\r
1160         DB 26\r
1161         DW 849\r
1162         DB 27\r
1163         DW 796\r
1164         DB 27\r
1165         DW 742\r
1166         DB 27\r
1167         DW 689\r
1168         DB 26\r
1169         DW 637\r
1170         DB 26\r
1171         DW 587\r
1172         DB 25\r
1173         DW 539\r
1174         DB 24\r
1175         DW 494\r
1176         DB 22\r
1177         DW 451\r
1178         DB 21\r
1179         DW 412\r
1180         DB 19\r
1181         DW 375\r
1182         DB 18\r
1183         DW 341\r
1184         DB 17\r
1185         DW 310\r
1186         DB 15\r
1187         DW 282\r
1188         DB 14\r
1189         DW 256\r
1190         DB 13\r
1191         DW 233\r
1192         DB 11\r
1193         DW 212\r
1194         DB 10\r
1195 \r
1196         END\r
1197 // \r
1198 //     2 bytes in segment ABSOLUTE\r
1199 // 1 064 bytes in segment CODE\r
1200 //   130 bytes in segment EEPROM_I\r
1201 //    12 bytes in segment INITTAB\r
1202 //   116 bytes in segment NEAR_I\r
1203 //   116 bytes in segment NEAR_ID\r
1204 //    13 bytes in segment NEAR_Z\r
1205 // \r
1206 // 1 180 bytes of CODE  memory (+ 12 bytes shared)\r
1207 //   129 bytes of DATA  memory (+  2 bytes shared)\r
1208 //   130 bytes of XDATA memory\r
1209 //\r
1210 //Errors: none\r
1211 //Warnings: none\r