Initial import
[avr_bc100.git] / BaseTinyFirmware / IAR / Release / List / chargefunc.s90
1 ///////////////////////////////////////////////////////////////////////////////\r
2 //                                                                            /\r
3 // IAR Atmel AVR C/C++ Compiler V4.30F/W32              13/Mar/2008  04:52:01 /\r
4 // Copyright 1996-2007 IAR Systems. All rights reserved.                      /\r
5 //                                                                            /\r
6 //    Source file           =  C:\home\kevin\pub\src\bc100\IAR\chargefunc.c   /\r
7 //    Command line          =  C:\home\kevin\pub\src\bc100\IAR\chargefunc.c   /\r
8 //                             --cpu=tiny861 -ms -o C:\home\kevin\pub\src\bc1 /\r
9 //                             00\IAR\Release\Obj\ -D NDEBUG -lCN             /\r
10 //                             C:\home\kevin\pub\src\bc100\IAR\Release\List\  /\r
11 //                             -lB C:\home\kevin\pub\src\bc100\IAR\Release\Li /\r
12 //                             st\ --initializers_in_flash -s9                /\r
13 //                             --no_cross_call --no_tbaa                      /\r
14 //                             -DENABLE_BIT_DEFINITIONS -e -I "C:\Program     /\r
15 //                             Files\IAR Systems\Embedded Workbench           /\r
16 //                             4.0\avr\INC\" -I "C:\Program Files\IAR         /\r
17 //                             Systems\Embedded Workbench 4.0\avr\INC\CLIB\"  /\r
18 //                             --eeprom_size 512 --misrac=5-9,11-12,14,16-17, /\r
19 //                             19-21,24-26,29-32,34-35,38-39,42-43,46,50,     /\r
20 //                             52-54,56-59,61-62,64-65,68-80,83-84,87-91,     /\r
21 //                             94-95,98-100,103-110,112-126                   /\r
22 //    Enabled MISRA C rules =  5-9,11-12,14,16-17,19-21,24-26,29-32,34-35,    /\r
23 //                             38-39,42-43,46,50,52-54,56-59,61-62,64-65,     /\r
24 //                             68-80,83-84,87-91,94-95,98-100,103-110,112-126 /\r
25 //      Checked             =  5,7-9,11-12,14,17,19-21,24,29-32,34-35,38-39,  /\r
26 //                             42,46,50,52-54,56-59,61-62,64,68-69,71-80,     /\r
27 //                             83-84,87-89,91,94-95,98,100,104-105,108-109,   /\r
28 //                             112-115,118-126                                /\r
29 //      Not checked         =  6,16,25-26,43,65,70,90,99,103,106-107,110,     /\r
30 //                             116-117                                        /\r
31 //    List file             =  C:\home\kevin\pub\src\bc100\IAR\Release\List\c /\r
32 //                             hargefunc.s90                                  /\r
33 //                                                                            /\r
34 //                                                                            /\r
35 ///////////////////////////////////////////////////////////////////////////////\r
36 \r
37         NAME chargefunc\r
38 \r
39         RSEG CSTACK:DATA:NOROOT(0)\r
40         RSEG RSTACK:DATA:NOROOT(0)\r
41 \r
42         EXTERN ?Register_R4_is_cg_reg\r
43         EXTERN ?Register_R5_is_cg_reg\r
44         EXTERN ?Register_R6_is_cg_reg\r
45         EXTERN ?Register_R7_is_cg_reg\r
46         EXTERN ?Register_R8_is_cg_reg\r
47         EXTERN ?Register_R9_is_cg_reg\r
48         EXTERN ?S_MUL_L02\r
49         EXTERN ?need_segment_init\r
50         EXTERN __eeget8_16\r
51         EXTERN __eeput8_16\r
52 \r
53         PUBWEAK `?<Segment init: NEAR_Z>`\r
54         PUBLIC ChargeParameters\r
55         PUBLIC ConstantCurrent\r
56         PUBLIC ConstantVoltage\r
57         PUBLIC HaltNow\r
58         PUBLIC HaltParameters\r
59         PUBWEAK _A_OCR1B\r
60         PUBWEAK __?EEARH\r
61         PUBWEAK __?EEARL\r
62         PUBWEAK __?EECR\r
63         PUBWEAK __?EEDR\r
64 \r
65         EXTERN ADC_Wait\r
66         EXTERN Time_Stop\r
67         EXTERN Time_Start\r
68         EXTERN PWM_IncrementDutyCycle\r
69         EXTERN SetErrorFlag\r
70         EXTERN PWM_DecrementDutyCycle\r
71         EXTERN Time_Set\r
72         EXTERN Time_Left\r
73         EXTERN PWM_Stop\r
74         EXTERN BatteryCheck\r
75         EXTERN ADCS\r
76         EXTERN BattActive\r
77         EXTERN BattControl\r
78         EXTERN BattData\r
79 \r
80 // C:\home\kevin\pub\src\bc100\IAR\chargefunc.c\r
81 //    1 /* This file has been prepared for Doxygen automatic documentation generation.*/\r
82 //    2 /*! \file *********************************************************************\r
83 //    3  *\r
84 //    4  * \brief\r
85 //    5  *      Charge functions\r
86 //    6  *\r
87 //    7  *      Contains the functions for charging with constant current and voltage,\r
88 //    8  *      and for deciding when to halt.\r
89 //    9  *\r
90 //   10  * \par Application note:\r
91 //   11  *      AVR458: Charging Li-Ion Batteries with BC100 \n\r
92 //   12  *      AVR463: Charging NiMH Batteries with BC100\r
93 //   13  *\r
94 //   14  * \par Documentation\r
95 //   15  *      For comprehensive code documentation, supported compilers, compiler \r
96 //   16  *      settings and supported devices see readme.html\r
97 //   17  *\r
98 //   18  * \author\r
99 //   19  *      Atmel Corporation: http://www.atmel.com \n\r
100 //   20  *      Support email: avr@atmel.com\r
101 //   21  *\r
102 //   22  * \r
103 //   23  * $Name$\r
104 //   24  * $Revision: 2299 $\r
105 //   25  * $RCSfile$\r
106 //   26  * $URL: http://svn.norway.atmel.com/AppsAVR8/avr458_Charging_Li-Ion_Batteries_with_BC100/tag/20070904_release_1.0/code/IAR/chargefunc.c $\r
107 //   27  * $Date: 2007-08-23 12:55:51 +0200 (to, 23 aug 2007) $\n\r
108 //   28  ******************************************************************************/\r
109 //   29 \r
110 //   30 #include <ioavr.h>\r
111 \r
112         ASEGN ABSOLUTE:DATA:NOROOT,04cH\r
113 // <unnamed> volatile __io _A_OCR1B\r
114 _A_OCR1B:\r
115         DS 1\r
116 //   31 \r
117 //   32 #include "enums.h"\r
118 //   33 #include "structs.h"\r
119 //   34 \r
120 //   35 #include "ADC.h"\r
121 //   36 #include "battery.h"\r
122 //   37 #include "chargefunc.h"\r
123 //   38 #include "main.h"\r
124 //   39 #include "menu.h"\r
125 //   40 #include "PWM.h"\r
126 //   41 #include "statefunc.h"\r
127 //   42 #include "time.h"\r
128 //   43 \r
129 //   44 #ifdef NIMH\r
130 //   45 #include "NIMHspecs.h"\r
131 //   46 #endif // NIMH\r
132 //   47 \r
133 //   48 #ifdef LIION\r
134 //   49 #include "LIIONspecs.h"\r
135 //   50 #endif // LIION\r
136 //   51 \r
137 //   52 \r
138 //   53 //******************************************************************************\r
139 //   54 // Variables\r
140 //   55 //******************************************************************************\r
141 //   56 //! Struct that holds parameters for ConstantCurrent() and ConstantVoltage().\r
142 \r
143         RSEG NEAR_Z:DATA:NOROOT(0)\r
144         REQUIRE `?<Segment init: NEAR_Z>`\r
145 //   57 ChargeParameters_t ChargeParameters;\r
146 //   58 \r
147 //   59 //! Struct that holds parameters for HaltNow().\r
148 //   60 HaltParameters_t HaltParameters;\r
149 HaltParameters:\r
150         DS 17\r
151 ChargeParameters:\r
152         DS 5\r
153 //   61 \r
154 //   62 \r
155 //   63 //******************************************************************************\r
156 //   64 // Functions\r
157 //   65 //******************************************************************************\r
158 //   66 /*! \brief Charges battery with a constant current.\r
159 //   67  *\r
160 //   68  * This function applies a constant current (set in ChargeParameters.Current)\r
161 //   69  * to the battery until HaltNow() returns TRUE, or a PWM error occurs and\r
162 //   70  * \ref ABORT_IF_PWM_MIN or \ref ABORT_IF_PWM_MAX is defined.\n\r
163 //   71  * The charge current can vary with +/- \ref BAT_CURRENT_HYST.\n\r
164 //   72  * If the Master inhibits charging, timers are stopped and PWM output dropped.\r
165 //   73  * Once the battery is no longer flagged for charge inhibit, timers are\r
166 //   74  * started again and charging resumed.\r
167 //   75  *\r
168 //   76  * \retval ChargeParameters.NextState Next state once this stage is done.\r
169 //   77  * If no errors occured, this will be whatever was set in Charge(). Otherwise,\r
170 //   78  * HaltNow() will have set a new next state.\r
171 //   79  */\r
172 \r
173         RSEG CODE:CODE:NOROOT(1)\r
174 //   80 unsigned char ConstantCurrent(void)\r
175 ConstantCurrent:\r
176 //   81 {\r
177         ST      -Y, R5\r
178         ST      -Y, R4\r
179         ST      -Y, R27\r
180         ST      -Y, R26\r
181         ST      -Y, R25\r
182         ST      -Y, R24\r
183         REQUIRE ?Register_R4_is_cg_reg\r
184         REQUIRE ?Register_R5_is_cg_reg\r
185 //   82         unsigned char error = FALSE,\r
186         CLR     R5\r
187 //   83                       wasStopped = FALSE;\r
188         CLR     R4\r
189 //   84         \r
190 //   85         do      {\r
191 //   86       // Wait for ADC conversions to complete.\r
192 //   87                 ADC_Wait();\r
193 ??ConstantCurrent_0:\r
194         RCALL   ADC_Wait\r
195 //   88 \r
196 //   89                 // If Master has flagged for a charge inhibit, pause charging.\r
197 //   90                 // (This is to prevent damage during prolonged serial communication.)\r
198 //   91                 if (BattControl[BattActive].ChargeInhibit) {\r
199         LDS     R16, BattActive\r
200         LDI     R17, 0\r
201         LDI     R20, LOW(BattControl)\r
202         LDI     R21, (BattControl) >> 8\r
203         ADD     R20, R16\r
204         ADC     R21, R17\r
205         RCALL   __eeget8_16\r
206         ANDI    R16, 0x04\r
207         BREQ    ??ConstantCurrent_1\r
208 //   92                         wasStopped = TRUE;\r
209         CLR     R4\r
210         INC     R4\r
211 //   93                         Time_Stop();\r
212         RCALL   Time_Stop\r
213 //   94                         OCR1B = 0;\r
214         LDI     R16, 0\r
215         OUT     0x2C, R16\r
216         RJMP    ??ConstantCurrent_2\r
217 //   95                 } else {\r
218 //   96                         // Continue charging!\r
219 //   97                         if (wasStopped) {\r
220 ??ConstantCurrent_1:\r
221         TST     R4\r
222         BREQ    ??ConstantCurrent_3\r
223 //   98                                 wasStopped = FALSE;\r
224         CLR     R4\r
225 //   99                                 \r
226 //  100                                 // Timer variables are not reset by this.\r
227 //  101                                 Time_Start();\r
228         RCALL   Time_Start\r
229 //  102                         }\r
230 //  103          \r
231 //  104                         // Adjust the charge current to within ChargeParameters.Current\r
232 //  105                         // +/- BAT_CURRENT_HYST.\r
233 //  106                         if ((ADCS.avgIBAT < 0) ||\r
234 //  107                             (ADCS.avgIBAT < (ChargeParameters.Current - BAT_CURRENT_HYST))) {\r
235 ??ConstantCurrent_3:\r
236         LDI     R30, LOW(ADCS)\r
237         LDI     R31, (ADCS) >> 8\r
238         LDD     R16, Z+22\r
239         LDD     R17, Z+23\r
240         TST     R17\r
241         BRMI    ??ConstantCurrent_4\r
242         LDI     R26, LOW((HaltParameters + 19))\r
243         LDI     R27, HIGH((HaltParameters + 19))\r
244         LD      R30, X+\r
245         LD      R31, X\r
246         MOVW    R25:R24, R31:R30\r
247         SBIW    R25:R24, 3\r
248         CP      R16, R24\r
249         CPC     R17, R25\r
250         BRCC    ??ConstantCurrent_5\r
251 //  108                                          \r
252 //  109                                 if(!PWM_IncrementDutyCycle()) {\r
253 ??ConstantCurrent_4:\r
254         RCALL   PWM_IncrementDutyCycle\r
255         TST     R16\r
256         BRNE    ??ConstantCurrent_2\r
257 //  110 #ifdef ABORT_IF_PWM_MAX\r
258 //  111                                 // If the duty cycle cannot be incremented, flag error and\r
259 //  112                                 // go to error state.\r
260 //  113                                         SetErrorFlag(ERR_PWM_CONTROL);\r
261 ??ConstantCurrent_6:\r
262         LDI     R16, 4\r
263         RCALL   SetErrorFlag\r
264 //  114                                         ChargeParameters.NextState = ST_ERROR;\r
265         LDI     R16, 90\r
266         STS     (HaltParameters + 21), R16\r
267 //  115                                         error = TRUE;\r
268         CLR     R5\r
269         INC     R5\r
270         RJMP    ??ConstantCurrent_2\r
271 //  116 #endif\r
272 //  117                                 }\r
273 //  118                         } else if ((ADCS.avgIBAT >= 0) &&\r
274 ??ConstantCurrent_5:\r
275         ADIW    R31:R30, 3\r
276         CP      R30, R16\r
277         CPC     R31, R17\r
278         BRCC    ??ConstantCurrent_2\r
279 //  119                                  (ADCS.avgIBAT > (ChargeParameters.Current + BAT_CURRENT_HYST))) {\r
280 //  120                                          \r
281 //  121                                 if(!PWM_DecrementDutyCycle()) {\r
282         RCALL   PWM_DecrementDutyCycle\r
283         TST     R16\r
284         BREQ    ??ConstantCurrent_6\r
285 //  122 #ifdef ABORT_IF_PWM_MIN\r
286 //  123                                         // If the duty cycle cannot be decremented, flag error and\r
287 //  124                                         // go to error state.\r
288 //  125                                         SetErrorFlag(ERR_PWM_CONTROL);\r
289 //  126                                         ChargeParameters.NextState = ST_ERROR;\r
290 //  127                                         error = TRUE;\r
291 //  128 #endif\r
292 //  129                                 }\r
293 //  130                         }\r
294 //  131                 }\r
295 //  132         } while ((!HaltNow()) && (!error));\r
296 ??ConstantCurrent_2:\r
297         RCALL   HaltNow\r
298         TST     R16\r
299         BRNE    ??ConstantCurrent_7\r
300         TST     R5\r
301         BREQ    ??ConstantCurrent_0\r
302 //  133 \r
303 //  134         // Return the next state to Charge(). If an error has occured, this will\r
304 //  135         // point to some other state than the next state of charging.\r
305 //  136         return(ChargeParameters.NextState);\r
306 ??ConstantCurrent_7:\r
307         LDS     R16, (HaltParameters + 21)\r
308         LD      R24, Y+\r
309         LD      R25, Y+\r
310         LD      R26, Y+\r
311         LD      R27, Y+\r
312         LD      R4, Y+\r
313         LD      R5, Y+\r
314         RET\r
315         REQUIRE _A_OCR1B\r
316 //  137 }\r
317 //  138 \r
318 //  139 \r
319 //  140 /*! \brief Charges battery with a constant voltage\r
320 //  141  *\r
321 //  142  * This function applies a constant voltage (set in ChargeParameters.Voltage)\r
322 //  143  * to the battery until HaltNow() returns TRUE, or a PWM error occurs and\r
323 //  144  * \ref ABORT_IF_PWM_MIN or \ref ABORT_IF_PWM_MAX is defined.\n\r
324 //  145  * The charge voltage can vary with +/- \ref BAT_VOLTAGE_HYST.\n\r
325 //  146  * If the Master inhibits charging, timers are stopped and PWM output dropped.\r
326 //  147  * Once the battery is no longer flagged for charge inhibit, timers are\r
327 //  148  * started again and charging resumed.\r
328 //  149  *\r
329 //  150  * \retval ChargeParameters.NextState Next state once this stage is done.\r
330 //  151  * If no errors occured, this will be whatever was set in Charge(). Otherwise,\r
331 //  152  * HaltNow() will have set a new next state.\r
332 //  153  */\r
333 \r
334         RSEG CODE:CODE:NOROOT(1)\r
335 //  154 unsigned char ConstantVoltage(void)\r
336 ConstantVoltage:\r
337 //  155 {\r
338         ST      -Y, R27\r
339         ST      -Y, R26\r
340         ST      -Y, R25\r
341         ST      -Y, R24\r
342 //  156         unsigned char error = FALSE,\r
343         LDI     R25, 0\r
344 //  157                       wasStopped = FALSE;\r
345         LDI     R24, 0\r
346 //  158         \r
347 //  159         do{\r
348 //  160                 \r
349 //  161                 // Wait for ADC conversions to complete.\r
350 //  162                 ADC_Wait();\r
351 ??ConstantVoltage_0:\r
352         RCALL   ADC_Wait\r
353 //  163                 \r
354 //  164                 // If Master has flagged for a charge inhibit, pause charging.\r
355 //  165                 // (This is to prevent damage during prolonged serial communication.)\r
356 //  166                 if (BattControl[BattActive].ChargeInhibit) {\r
357         LDS     R16, BattActive\r
358         LDI     R17, 0\r
359         LDI     R20, LOW(BattControl)\r
360         LDI     R21, (BattControl) >> 8\r
361         ADD     R20, R16\r
362         ADC     R21, R17\r
363         RCALL   __eeget8_16\r
364         ANDI    R16, 0x04\r
365         BREQ    ??ConstantVoltage_1\r
366 //  167                         wasStopped = TRUE;\r
367         LDI     R24, 1\r
368 //  168                         Time_Stop();\r
369         RCALL   Time_Stop\r
370 //  169                         OCR1B = 0;\r
371         LDI     R16, 0\r
372         OUT     0x2C, R16\r
373         RJMP    ??ConstantVoltage_2\r
374 //  170                 }\r
375 //  171                 \r
376 //  172                 else {\r
377 //  173                         // Continue charging!\r
378 //  174                         if (wasStopped) {\r
379 ??ConstantVoltage_1:\r
380         TST     R24\r
381         BREQ    ??ConstantVoltage_3\r
382 //  175                                 wasStopped = FALSE;\r
383         LDI     R24, 0\r
384 //  176                                 \r
385 //  177                                 // Timer variables aren't reset by this.\r
386 //  178                                 Time_Start();\r
387         RCALL   Time_Start\r
388 //  179                         }\r
389 //  180                         \r
390 //  181                         // Adjust the charge voltage to within ChargeParameters.Voltage\r
391 //  182                         // +/- BAT_VOLTAGE_HYST.\r
392 //  183                         if (ADCS.VBAT < (ChargeParameters.Voltage - BAT_VOLTAGE_HYST)) {\r
393 ??ConstantVoltage_3:\r
394         LDI     R26, LOW(HaltParameters)\r
395         LDI     R27, (HaltParameters) >> 8\r
396         MOVW    R31:R30, R27:R26\r
397         LDD     R16, Z+17\r
398         LDD     R17, Z+18\r
399         LDI     R30, LOW(ADCS)\r
400         LDI     R31, (ADCS) >> 8\r
401         LDD     R18, Z+10\r
402         LDD     R19, Z+11\r
403         MOVW    R31:R30, R17:R16\r
404         SBIW    R31:R30, 10\r
405         CP      R18, R30\r
406         CPC     R19, R31\r
407         BRCC    ??ConstantVoltage_4\r
408 //  184 \r
409 //  185                                 if(!PWM_IncrementDutyCycle()) {\r
410         RCALL   PWM_IncrementDutyCycle\r
411         TST     R16\r
412         BRNE    ??ConstantVoltage_2\r
413 //  186 #ifdef ABORT_IF_PWM_MAX\r
414 //  187                                 // Flag PWM control error and go to error-state if the duty\r
415 //  188                                 // cycle cannot be incremented.\r
416 //  189                                         SetErrorFlag(ERR_PWM_CONTROL);\r
417 ??ConstantVoltage_5:\r
418         LDI     R16, 4\r
419         RCALL   SetErrorFlag\r
420 //  190                                         ChargeParameters.NextState = ST_ERROR;\r
421         LDI     R16, 90\r
422         MOVW    R31:R30, R27:R26\r
423         STD     Z+21, R16\r
424 //  191                                         error = TRUE;\r
425         LDI     R25, 1\r
426         RJMP    ??ConstantVoltage_2\r
427 //  192 #endif\r
428 //  193                                 }\r
429 //  194                         } else if (ADCS.VBAT > (ChargeParameters.Voltage + BAT_VOLTAGE_HYST)) {\r
430 ??ConstantVoltage_4:\r
431         SUBI    R16, 246\r
432         SBCI    R17, 255\r
433         CP      R16, R18\r
434         CPC     R17, R19\r
435         BRCC    ??ConstantVoltage_2\r
436 //  195 \r
437 //  196                                 if(!PWM_DecrementDutyCycle()) {\r
438         RCALL   PWM_DecrementDutyCycle\r
439         TST     R16\r
440         BREQ    ??ConstantVoltage_5\r
441 //  197 #ifdef ABORT_IF_PWM_MIN\r
442 //  198                                         // Flag PWM control error and go to error-state if duty\r
443 //  199                                         // cycle cannot be decremented.\r
444 //  200                                         SetErrorFlag(ERR_PWM_CONTROL);\r
445 //  201                                         ChargeParameters.NextState = ST_ERROR;\r
446 //  202                                         error = TRUE;\r
447 //  203 #endif\r
448 //  204                                 }\r
449 //  205                         }\r
450 //  206                 }\r
451 //  207 \r
452 //  208         } while ((!HaltNow()) && (!error));\r
453 ??ConstantVoltage_2:\r
454         RCALL   HaltNow\r
455         TST     R16\r
456         BRNE    ??ConstantVoltage_6\r
457         TST     R25\r
458         BREQ    ??ConstantVoltage_0\r
459 //  209 \r
460 //  210         // Return the next state to Charge(). If an error has occured, this will\r
461 //  211         // point to some other state than the next state of charging.\r
462 //  212         return(ChargeParameters.NextState);\r
463 ??ConstantVoltage_6:\r
464         LDS     R16, (HaltParameters + 21)\r
465         LD      R24, Y+\r
466         LD      R25, Y+\r
467         LD      R26, Y+\r
468         LD      R27, Y+\r
469         RET\r
470         REQUIRE _A_OCR1B\r
471 //  213 }\r
472 //  214 \r
473 //  215 \r
474 //  216 /*! \brief Determines when to halt charging.\r
475 //  217  *\r
476 //  218  * This function evaluates parameters depending on what has been flagged in\r
477 //  219  * HaltParameters.HaltFlags, and returns TRUE or FALSE if the charging should\r
478 //  220  * halt or not.\n\r
479 //  221  * In addition, error flagging on timeout (battery exhaustion) can be set.\n\r
480 //  222  *\r
481 //  223  * The function also checks if the battery temperature is within limits,\r
482 //  224  * if mains is OK, and if BatteryCheck() returns TRUE.\r
483 //  225  * If an error is detected, the associated errorflag is set and \r
484 //  226  * ChargeParameters.NextState is changed to an appropriate state.\r
485 //  227  *\r
486 //  228  * \retval TRUE Halt now.\r
487 //  229  * \retval FALSE Don't halt now.\r
488 //  230  *\r
489 //  231  * \note See chargefunc.h for definitions of halt flags.\r
490 //  232  * \note It is generally a bad idea not to halt on a timeout.\r
491 //  233  * \note If HALT_ON_VOLTAGE_DROP is set, HaltParameters.VBATMax should be\r
492 //  234  * reset in Charge() before calling a charging-function.\r
493 //  235  *\r
494 //  236  * \todo "Priorities" of standard error checks OK?\r
495 //  237  */\r
496 \r
497         RSEG CODE:CODE:NOROOT(1)\r
498 //  238 unsigned char HaltNow(void)\r
499 HaltNow:\r
500 //  239 {\r
501         ST      -Y, R9\r
502         ST      -Y, R8\r
503         ST      -Y, R7\r
504         ST      -Y, R6\r
505         ST      -Y, R5\r
506         ST      -Y, R4\r
507         ST      -Y, R27\r
508         ST      -Y, R26\r
509         ST      -Y, R25\r
510         ST      -Y, R24\r
511         REQUIRE ?Register_R4_is_cg_reg\r
512         REQUIRE ?Register_R5_is_cg_reg\r
513         REQUIRE ?Register_R6_is_cg_reg\r
514         REQUIRE ?Register_R7_is_cg_reg\r
515         REQUIRE ?Register_R8_is_cg_reg\r
516         REQUIRE ?Register_R9_is_cg_reg\r
517 //  240         unsigned char i, halt = FALSE;\r
518         CLR     R7\r
519 //  241         \r
520 //  242         // Wait for a full ADC-cycle to finish.\r
521 //  243         ADC_Wait();\r
522         RCALL   ADC_Wait\r
523 //  244 \r
524 //  245         // Evaluate ADC readings according to HaltFlags. Flag errors if selected.\r
525 //  246         // If an error is flagged, ChargeParameters.NextState is set to ST_ERROR.\r
526 //  247         // (Gets overridden if either mains is failing, or the battery changes.)\r
527 //  248         for (i = 0x01; i != 0; i <<= 1) {\r
528         CLR     R6\r
529         INC     R6\r
530         LDI     R24, LOW(ADCS)\r
531         LDI     R25, (ADCS) >> 8\r
532         LDI     R16, LOW(BattData)\r
533         MOV     R4, R16\r
534         LDI     R16, (BattData) >> 8\r
535         MOV     R5, R16\r
536         LDI     R26, LOW(HaltParameters)\r
537         LDI     R27, (HaltParameters) >> 8\r
538 //  249                 if (HaltParameters.HaltFlags & i) {\r
539 ??HaltNow_0:\r
540         LD      R16, X\r
541         AND     R16, R6\r
542         BRNE    $+2+2\r
543         RJMP    ??HaltNow_1\r
544 //  250                         switch (i) {\r
545         MOV     R16, R6\r
546         DEC     R16\r
547         BREQ    ??HaltNow_2\r
548         DEC     R16\r
549         BREQ    ??HaltNow_3\r
550         SUBI    R16, 2\r
551         BREQ    ??HaltNow_4\r
552         SUBI    R16, 4\r
553         BREQ    ??HaltNow_5\r
554         SUBI    R16, 8\r
555         BRNE    $+2+2\r
556         RJMP    ??HaltNow_6\r
557         RJMP    ??HaltNow_1\r
558 //  251                         // Is VBAT less than the recorded maximum?\r
559 //  252                         case HALT_VOLTAGE_DROP:\r
560 //  253 \r
561 //  254                                 // Update VBATMax if VBAT is higher. Evaluate for halt otherwise.\r
562 //  255                                 if (ADCS.VBAT > HaltParameters.VBATMax) {\r
563 ??HaltNow_2:\r
564         MOVW    R31:R30, R27:R26\r
565         LDD     R16, Z+13\r
566         LDD     R17, Z+14\r
567         MOVW    R31:R30, R25:R24\r
568         LDD     R18, Z+10\r
569         LDD     R19, Z+11\r
570         CP      R16, R18\r
571         CPC     R17, R19\r
572         BRCC    ??HaltNow_7\r
573 //  256                                         HaltParameters.VBATMax = ADCS.VBAT;\r
574         MOVW    R31:R30, R27:R26\r
575         STD     Z+13, R18\r
576         STD     Z+14, R19\r
577         RJMP    ??HaltNow_1\r
578 //  257                                 } else if((HaltParameters.VBATMax - ADCS.VBAT) >= \r
579 //  258                                           HaltParameters.VoltageDrop) {\r
580 ??HaltNow_7:\r
581         SUB     R16, R18\r
582         SBC     R17, R19\r
583         MOVW    R31:R30, R27:R26\r
584         LDD     R18, Z+1\r
585         LDD     R19, Z+2\r
586         CP      R16, R18\r
587         CPC     R17, R19\r
588         BRCC    $+2+2\r
589         RJMP    ??HaltNow_1\r
590 //  259                                         halt = TRUE;\r
591 ??HaltNow_8:\r
592         CLR     R7\r
593         INC     R7\r
594         RJMP    ??HaltNow_1\r
595 //  260                                 }\r
596 //  261                         break;\r
597 //  262 \r
598 //  263                         \r
599 //  264                         // Has VBAT reached the maximum limit?\r
600 //  265                         case HALT_VOLTAGE_MAX:  \r
601 //  266                                 \r
602 //  267                                 if (ADCS.VBAT >= HaltParameters.VoltageMax) {\r
603 ??HaltNow_3:\r
604         MOVW    R31:R30, R25:R24\r
605         LDD     R16, Z+10\r
606         LDD     R17, Z+11\r
607         MOVW    R31:R30, R27:R26\r
608         LDD     R18, Z+3\r
609         LDD     R19, Z+4\r
610 ??HaltNow_9:\r
611         CP      R16, R18\r
612         CPC     R17, R19\r
613         BRCC    $+2+2\r
614         RJMP    ??HaltNow_1\r
615         RJMP    ??HaltNow_8\r
616 //  268                                         halt = TRUE;\r
617 //  269                                 }\r
618 //  270                                 break;\r
619 //  271 \r
620 //  272 \r
621 //  273                         // Has IBAT reached the minimum limit?\r
622 //  274                         case HALT_CURRENT_MIN:\r
623 //  275                                 \r
624 //  276                                 if (ADCS.avgIBAT <= HaltParameters.CurrentMin) {\r
625 ??HaltNow_4:\r
626         MOVW    R31:R30, R27:R26\r
627         LDD     R16, Z+5\r
628         LDD     R17, Z+6\r
629         MOVW    R31:R30, R25:R24\r
630         LDD     R18, Z+22\r
631         LDD     R19, Z+23\r
632         RJMP    ??HaltNow_9\r
633 //  277                                         halt = TRUE;\r
634 //  278                                 }\r
635 //  279                                 break;\r
636 //  280         \r
637 //  281                                 \r
638 //  282                         // Is the temperature rising too fast?\r
639 //  283                         case HALT_TEMPERATURE_RISE:\r
640 //  284 \r
641 //  285                                 // If rawNTC has increased, the temperature has dropped.\r
642 //  286                                 // We can store this value for now, and start the timer.\r
643 //  287                                 // Otherwise, check if NTC has changed too fast.\r
644 //  288                                 if (ADCS.rawNTC > HaltParameters.LastNTC) {\r
645 ??HaltNow_5:\r
646         MOVW    R31:R30, R25:R24\r
647         LDD     R16, Z+4\r
648         LDD     R17, Z+5\r
649         MOVW    R31:R30, R27:R26\r
650         LDD     R8, Z+15\r
651         LDD     R9, Z+16\r
652         CP      R8, R16\r
653         CPC     R9, R17\r
654         BRCC    ??HaltNow_10\r
655 //  289                                         HaltParameters.LastNTC = ADCS.rawNTC;\r
656 ??HaltNow_11:\r
657         MOVW    R31:R30, R25:R24\r
658         LDD     R16, Z+4\r
659         LDD     R17, Z+5\r
660         MOVW    R31:R30, R27:R26\r
661         STD     Z+15, R16\r
662         STD     Z+16, R17\r
663 //  290                                         Time_Set(TIMER_TEMP,0,30,0);\r
664         LDI     R20, 0\r
665         LDI     R17, 30\r
666         LDI     R18, 0\r
667         LDI     R19, 0\r
668         LDI     R16, 3\r
669         RCALL   Time_Set\r
670         RJMP    ??HaltNow_1\r
671 //  291                                         \r
672 //  292                                 // Is the increase in temperature greater than the set threshold?\r
673 //  293                                 } else  if ((HaltParameters.LastNTC - ADCS.rawNTC) >=\r
674 //  294                                   (BattData.ADCSteps * HaltParameters.TemperatureRise)) {\r
675 ??HaltNow_10:\r
676         SUB     R8, R16\r
677         SBC     R9, R17\r
678         MOVW    R31:R30, R5:R4\r
679         LDD     R20, Z+3\r
680         LDI     R21, 0\r
681         MOVW    R31:R30, R27:R26\r
682         LDD     R16, Z+11\r
683         LDD     R17, Z+12\r
684         RCALL   ?S_MUL_L02\r
685         CP      R8, R0\r
686         CPC     R9, R1\r
687         BRCS    ??HaltNow_1\r
688 //  295                                         \r
689 //  296                                         // If this happened within a timeframe of 30 seconds, the \r
690 //  297                                         // temperature is rising faster than we want.\r
691 //  298                                         // If not, update LastNTC and reset timer.\r
692 //  299                                         if (Time_Left(TIMER_TEMP))  {\r
693         LDI     R16, 3\r
694         RCALL   Time_Left\r
695         TST     R16\r
696         BRNE    ??HaltNow_8\r
697         RJMP    ??HaltNow_11\r
698 //  300                                                 halt = TRUE;\r
699 //  301                                         } else {\r
700 //  302                                                 HaltParameters.LastNTC = ADCS.rawNTC;\r
701 //  303                                                 Time_Set(TIMER_TEMP,0,30,0);\r
702 //  304                                         }\r
703 //  305                                 }\r
704 //  306                         break;\r
705 //  307         \r
706 //  308                         \r
707 //  309                         // Is there any time left?\r
708 //  310                         case HALT_TIME:  \r
709 //  311                                 \r
710 //  312                                 if (!Time_Left(TIMER_CHG)) {\r
711 ??HaltNow_6:\r
712         LDI     R16, 1\r
713         RCALL   Time_Left\r
714         TST     R16\r
715         BRNE    ??HaltNow_1\r
716 //  313                                         halt = TRUE;\r
717         CLR     R7\r
718         INC     R7\r
719 //  314                                         \r
720 //  315                                         // If exhaustion flagging is selected, stop the PWM, disable the \r
721 //  316                                         // battery and flag it as exhausted. Make ST_ERROR next state.\r
722 //  317                                         if (HaltParameters.HaltFlags & HALT_FLAG_EXHAUSTION) {\r
723         LD      R16, X\r
724         SBRS    R16, 5\r
725         RJMP    ??HaltNow_1\r
726 //  318                                                         PWM_Stop();\r
727         RCALL   PWM_Stop\r
728 //  319                                                         BattControl[BattActive].Enabled = FALSE;\r
729         LDS     R16, BattActive\r
730         LDI     R17, 0\r
731         LDI     R20, LOW(BattControl)\r
732         LDI     R21, (BattControl) >> 8\r
733         ADD     R20, R16\r
734         ADC     R21, R17\r
735         RCALL   __eeget8_16\r
736         ANDI    R16, 0xFE\r
737         RCALL   __eeput8_16\r
738 //  320                                                         BattData.Exhausted = TRUE;\r
739         MOVW    R31:R30, R5:R4\r
740         LD      R16, Z\r
741         ORI     R16, 0x08\r
742         ST      Z, R16\r
743 //  321                                                         SetErrorFlag(ERR_BATTERY_EXHAUSTED);\r
744         LDI     R16, 16\r
745         RCALL   SetErrorFlag\r
746 //  322                                                         ChargeParameters.NextState = ST_ERROR;\r
747         LDI     R16, 90\r
748         MOVW    R31:R30, R27:R26\r
749         STD     Z+21, R16\r
750 //  323                                         }\r
751 //  324                                 }\r
752 //  325                         break;\r
753 //  326                         \r
754 //  327                         \r
755 //  328                         default:  // Shouldn't end up here, but is needed for MISRA compliance.\r
756 //  329                         break;\r
757 //  330                         }\r
758 //  331                 }\r
759 //  332         }\r
760 ??HaltNow_1:\r
761         LSL     R6\r
762         BREQ    $+2+2\r
763         RJMP    ??HaltNow_0\r
764 //  333 \r
765 //  334         // Standard checks:\r
766 //  335 \r
767 //  336         // Battery too cold or hot?\r
768 //  337         if ((BattData.Temperature <= HaltParameters.TemperatureMin) ||\r
769 //  338             (BattData.Temperature >= HaltParameters.TemperatureMax)) {\r
770         LDI     R30, LOW(BattData)\r
771         LDI     R31, (BattData) >> 8\r
772         LDD     R16, Z+2\r
773         MOVW    R31:R30, R27:R26\r
774         LDD     R18, Z+9\r
775         LDD     R19, Z+10\r
776         MOV     R17, R16\r
777         LSL     R17\r
778         SBC     R17, R17\r
779         CP      R18, R16\r
780         CPC     R19, R17\r
781         BRGE    ??HaltNow_12\r
782         MOV     R17, R16\r
783         LSL     R17\r
784         SBC     R17, R17\r
785         LDD     R18, Z+7\r
786         LDD     R19, Z+8\r
787         CP      R16, R18\r
788         CPC     R17, R19\r
789         BRCS    ??HaltNow_13\r
790 //  339                         \r
791 //  340                 PWM_Stop();\r
792 ??HaltNow_12:\r
793         RCALL   PWM_Stop\r
794 //  341                 SetErrorFlag(ERR_BATTERY_TEMPERATURE);\r
795         LDI     R16, 8\r
796         RCALL   SetErrorFlag\r
797 //  342                 ChargeParameters.NextState = ST_ERROR;\r
798         LDI     R16, 90\r
799         MOVW    R31:R30, R27:R26\r
800         STD     Z+21, R16\r
801 //  343                 halt = TRUE;\r
802         CLR     R7\r
803         INC     R7\r
804 //  344         }\r
805 //  345 \r
806 //  346         // Battery not OK?\r
807 //  347         if (!BatteryCheck()) {\r
808 ??HaltNow_13:\r
809         RCALL   BatteryCheck\r
810         TST     R16\r
811         BRNE    ??HaltNow_14\r
812 //  348                 PWM_Stop();\r
813         RCALL   PWM_Stop\r
814 //  349                 ChargeParameters.NextState = ST_INIT;\r
815         LDI     R16, 10\r
816         MOVW    R31:R30, R27:R26\r
817         STD     Z+21, R16\r
818 //  350                 halt = TRUE;\r
819         CLR     R7\r
820         INC     R7\r
821 //  351         }\r
822 //  352 \r
823 //  353         // Is mains voltage OK?\r
824 //  354         if (!ADCS.Mains) {\r
825 ??HaltNow_14:\r
826         LDS     R16, ADCS\r
827         SBRC    R16, 6\r
828         RJMP    ??HaltNow_15\r
829 //  355                 PWM_Stop();\r
830         RCALL   PWM_Stop\r
831 //  356                 ChargeParameters.NextState = ST_SLEEP;\r
832         LDI     R16, 40\r
833         MOVW    R31:R30, R27:R26\r
834         STD     Z+21, R16\r
835 //  357                 halt = TRUE;\r
836         CLR     R7\r
837         INC     R7\r
838 //  358         }\r
839 //  359 \r
840 //  360         return(halt);\r
841 ??HaltNow_15:\r
842         MOV     R16, R7\r
843         LD      R24, Y+\r
844         LD      R25, Y+\r
845         LD      R26, Y+\r
846         LD      R27, Y+\r
847         LD      R4, Y+\r
848         LD      R5, Y+\r
849         LD      R6, Y+\r
850         LD      R7, Y+\r
851         LD      R8, Y+\r
852         LD      R9, Y+\r
853         RET\r
854 //  361 }\r
855 \r
856         ASEGN ABSOLUTE:DATA:NOROOT,01cH\r
857 __?EECR:\r
858 \r
859         ASEGN ABSOLUTE:DATA:NOROOT,01dH\r
860 __?EEDR:\r
861 \r
862         ASEGN ABSOLUTE:DATA:NOROOT,01eH\r
863 __?EEARL:\r
864 \r
865         ASEGN ABSOLUTE:DATA:NOROOT,01fH\r
866 __?EEARH:\r
867 \r
868         RSEG INITTAB:CODE:NOROOT(0)\r
869 `?<Segment init: NEAR_Z>`:\r
870         DW      SFE(NEAR_Z) - SFB(NEAR_Z)\r
871         DW      SFB(NEAR_Z)\r
872         DW      0\r
873         REQUIRE ?need_segment_init\r
874 \r
875         END\r
876 // \r
877 //   1 byte  in segment ABSOLUTE\r
878 // 716 bytes in segment CODE\r
879 //   6 bytes in segment INITTAB\r
880 //  22 bytes in segment NEAR_Z\r
881 // \r
882 // 716 bytes of CODE memory (+ 6 bytes shared)\r
883 //  22 bytes of DATA memory (+ 1 byte  shared)\r
884 //\r
885 //Errors: none\r
886 //Warnings: none\r