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