1 ###############################################################################
\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
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\IAR #
\r
9 # \Debug\Obj\ -lC C:\home\kevin\pub\src\bc100_cal\IAR\Debu #
\r
10 # g\List\ -lB C:\home\kevin\pub\src\bc100_cal\IAR\Debug\Li #
\r
11 # st\ --initializers_in_flash -z2 --no_cse --no_inline #
\r
12 # --no_code_motion --no_cross_call --no_clustering #
\r
13 # --no_tbaa --debug -DENABLE_BIT_DEFINITIONS -e #
\r
14 # --require_prototypes -I "C:\Program Files\IAR #
\r
15 # Systems\Embedded Workbench 4.0\avr\INC\" -I "C:\Program #
\r
16 # Files\IAR Systems\Embedded Workbench 4.0\avr\INC\CLIB\" #
\r
17 # --eeprom_size 512 #
\r
18 # List file = C:\home\kevin\pub\src\bc100_cal\IAR\Debug\List\chargefun #
\r
20 # Object file = C:\home\kevin\pub\src\bc100_cal\IAR\Debug\Obj\chargefunc #
\r
24 ###############################################################################
\r
26 C:\home\kevin\pub\src\bc100_cal\IAR\chargefunc.c
\r
27 1 /* This file has been prepared for Doxygen automatic documentation generation.*/
\r
28 2 /*! \file *********************************************************************
\r
31 5 * Charge functions
\r
33 7 * Contains the functions for charging with constant current and voltage,
\r
34 8 * and for deciding when to halt.
\r
36 10 * \par Application note:
\r
37 11 * AVR458: Charging Li-Ion Batteries with BC100 \n
\r
38 12 * AVR463: Charging NiMH Batteries with BC100
\r
40 14 * \par Documentation
\r
41 15 * For comprehensive code documentation, supported compilers, compiler
\r
42 16 * settings and supported devices see readme.html
\r
45 19 * Atmel Corporation: http://www.atmel.com \n
\r
46 20 * Support email: avr@atmel.com
\r
50 24 * $Revision: 2299 $
\r
52 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
53 27 * $Date: 2007-08-23 12:55:51 +0200 (to, 23 aug 2007) $\n
\r
54 28 ******************************************************************************/
\r
56 30 #include <ioavr.h>
\r
58 \ In segment ABSOLUTE, at 0x4c
\r
59 \ <unnamed> volatile __io _A_OCR1B
\r
63 32 #include "enums.h"
\r
64 33 #include "structs.h"
\r
67 36 #include "battery.h"
\r
68 37 #include "chargefunc.h"
\r
69 38 #include "main.h"
\r
70 39 #include "menu.h"
\r
72 41 #include "statefunc.h"
\r
73 42 #include "time.h"
\r
76 45 #include "NIMHspecs.h"
\r
80 49 #include "LIIONspecs.h"
\r
84 53 //******************************************************************************
\r
86 55 //******************************************************************************
\r
87 56 //! Struct that holds parameters for ConstantCurrent() and ConstantVoltage().
\r
89 \ In segment NEAR_Z, align 1, keep-with-next
\r
90 \ 00000000 REQUIRE `?<Segment init: NEAR_Z>`
\r
91 57 ChargeParameters_t ChargeParameters;
\r
95 59 //! Struct that holds parameters for HaltNow().
\r
97 \ In segment NEAR_Z, align 1, keep-with-next
\r
98 \ 00000000 REQUIRE `?<Segment init: NEAR_Z>`
\r
99 60 HaltParameters_t HaltParameters;
\r
104 63 //******************************************************************************
\r
106 65 //******************************************************************************
\r
107 66 /*! \brief Charges battery with a constant current.
\r
109 68 * This function applies a constant current (set in ChargeParameters.Current)
\r
110 69 * to the battery until HaltNow() returns TRUE, or a PWM error occurs and
\r
111 70 * \ref ABORT_IF_PWM_MIN or \ref ABORT_IF_PWM_MAX is defined.\n
\r
112 71 * The charge current can vary with +/- \ref BAT_CURRENT_HYST.\n
\r
113 72 * If the Master inhibits charging, timers are stopped and PWM output dropped.
\r
114 73 * Once the battery is no longer flagged for charge inhibit, timers are
\r
115 74 * started again and charging resumed.
\r
117 76 * \retval ChargeParameters.NextState Next state once this stage is done.
\r
118 77 * If no errors occured, this will be whatever was set in Charge(). Otherwise,
\r
119 78 * HaltNow() will have set a new next state.
\r
122 \ In segment CODE, align 2, keep-with-next
\r
123 80 unsigned char ConstantCurrent(void)
\r
126 \ 00000000 .... RCALL ?PROLOGUE4_L09
\r
127 82 unsigned char error = FALSE,
\r
128 \ 00000002 E080 LDI R24, 0
\r
129 83 wasStopped = FALSE;
\r
130 \ 00000004 E090 LDI R25, 0
\r
133 86 // Wait for ADC conversions to complete.
\r
135 \ ??ConstantCurrent_0:
\r
136 \ 00000006 .... RCALL ADC_Wait
\r
138 89 // If Master has flagged for a charge inhibit, pause charging.
\r
139 90 // (This is to prevent damage during prolonged serial communication.)
\r
140 91 if (BattControl[BattActive].ChargeInhibit) {
\r
141 \ 00000008 9100.... LDS R16, BattActive
\r
142 \ 0000000C E010 LDI R17, 0
\r
143 \ 0000000E .... LDI R20, LOW(BattControl)
\r
144 \ 00000010 .... LDI R21, (BattControl) >> 8
\r
145 \ 00000012 0F40 ADD R20, R16
\r
146 \ 00000014 1F51 ADC R21, R17
\r
147 \ 00000016 .... RCALL __eeget8_16
\r
148 \ 00000018 7004 ANDI R16, 0x04
\r
149 \ 0000001A 2300 TST R16
\r
150 \ 0000001C F029 BREQ ??ConstantCurrent_1
\r
151 92 wasStopped = TRUE;
\r
152 \ 0000001E E091 LDI R25, 1
\r
154 \ 00000020 .... RCALL Time_Stop
\r
156 \ 00000022 E000 LDI R16, 0
\r
157 \ 00000024 BD0C OUT 0x2C, R16
\r
158 \ 00000026 C03C RJMP ??ConstantCurrent_2
\r
160 96 // Continue charging!
\r
161 97 if (wasStopped) {
\r
162 \ ??ConstantCurrent_1:
\r
163 \ 00000028 2399 TST R25
\r
164 \ 0000002A F011 BREQ ??ConstantCurrent_3
\r
165 98 wasStopped = FALSE;
\r
166 \ 0000002C E090 LDI R25, 0
\r
168 100 // Timer variables are not reset by this.
\r
170 \ 0000002E .... RCALL Time_Start
\r
173 104 // Adjust the charge current to within ChargeParameters.Current
\r
174 105 // +/- BAT_CURRENT_HYST.
\r
175 106 if ((ADCS.avgIBAT < 0) ||
\r
176 107 (ADCS.avgIBAT < (ChargeParameters.Current - BAT_CURRENT_HYST))) {
\r
177 \ ??ConstantCurrent_3:
\r
178 \ 00000030 .... LDI R30, LOW(ADCS)
\r
179 \ 00000032 .... LDI R31, (ADCS) >> 8
\r
180 \ 00000034 8906 LDD R16, Z+22
\r
181 \ 00000036 8917 LDD R17, Z+23
\r
182 \ 00000038 2311 TST R17
\r
183 \ 0000003A F06A BRMI ??ConstantCurrent_4
\r
184 \ 0000003C .... LDI R30, LOW(ADCS)
\r
185 \ 0000003E .... LDI R31, (ADCS) >> 8
\r
186 \ 00000040 8926 LDD R18, Z+22
\r
187 \ 00000042 8937 LDD R19, Z+23
\r
188 \ 00000044 .... LDI R30, LOW(ChargeParameters)
\r
189 \ 00000046 .... LDI R31, (ChargeParameters) >> 8
\r
190 \ 00000048 8102 LDD R16, Z+2
\r
191 \ 0000004A 8113 LDD R17, Z+3
\r
192 \ 0000004C 5003 SUBI R16, 3
\r
193 \ 0000004E 4010 SBCI R17, 0
\r
194 \ 00000050 1720 CP R18, R16
\r
195 \ 00000052 0731 CPC R19, R17
\r
196 \ 00000054 F450 BRCC ??ConstantCurrent_5
\r
198 109 if(!PWM_IncrementDutyCycle()) {
\r
199 \ ??ConstantCurrent_4:
\r
200 \ 00000056 .... RCALL PWM_IncrementDutyCycle
\r
201 \ 00000058 2300 TST R16
\r
202 \ 0000005A F511 BRNE ??ConstantCurrent_2
\r
203 110 #ifdef ABORT_IF_PWM_MAX
\r
204 111 // If the duty cycle cannot be incremented, flag error and
\r
205 112 // go to error state.
\r
206 113 SetErrorFlag(ERR_PWM_CONTROL);
\r
207 \ 0000005C E004 LDI R16, 4
\r
208 \ 0000005E .... RCALL SetErrorFlag
\r
209 114 ChargeParameters.NextState = ST_ERROR;
\r
210 \ 00000060 E50A LDI R16, 90
\r
211 \ 00000062 9300.... STS (ChargeParameters + 4), R16
\r
213 \ 00000066 E081 LDI R24, 1
\r
214 \ 00000068 C01B RJMP ??ConstantCurrent_2
\r
217 118 } else if ((ADCS.avgIBAT >= 0) &&
\r
218 119 (ADCS.avgIBAT > (ChargeParameters.Current + BAT_CURRENT_HYST))) {
\r
219 \ ??ConstantCurrent_5:
\r
220 \ 0000006A .... LDI R30, LOW(ADCS)
\r
221 \ 0000006C .... LDI R31, (ADCS) >> 8
\r
222 \ 0000006E 8906 LDD R16, Z+22
\r
223 \ 00000070 8917 LDD R17, Z+23
\r
224 \ 00000072 2311 TST R17
\r
225 \ 00000074 F0AA BRMI ??ConstantCurrent_2
\r
226 \ 00000076 .... LDI R30, LOW(ChargeParameters)
\r
227 \ 00000078 .... LDI R31, (ChargeParameters) >> 8
\r
228 \ 0000007A 81A2 LDD R26, Z+2
\r
229 \ 0000007C 81B3 LDD R27, Z+3
\r
230 \ 0000007E 9613 ADIW R27:R26, 3
\r
231 \ 00000080 .... LDI R30, LOW(ADCS)
\r
232 \ 00000082 .... LDI R31, (ADCS) >> 8
\r
233 \ 00000084 8906 LDD R16, Z+22
\r
234 \ 00000086 8917 LDD R17, Z+23
\r
235 \ 00000088 17A0 CP R26, R16
\r
236 \ 0000008A 07B1 CPC R27, R17
\r
237 \ 0000008C F448 BRCC ??ConstantCurrent_2
\r
239 121 if(!PWM_DecrementDutyCycle()) {
\r
240 \ 0000008E .... RCALL PWM_DecrementDutyCycle
\r
241 \ 00000090 2300 TST R16
\r
242 \ 00000092 F431 BRNE ??ConstantCurrent_2
\r
243 122 #ifdef ABORT_IF_PWM_MIN
\r
244 123 // If the duty cycle cannot be decremented, flag error and
\r
245 124 // go to error state.
\r
246 125 SetErrorFlag(ERR_PWM_CONTROL);
\r
247 \ 00000094 E004 LDI R16, 4
\r
248 \ 00000096 .... RCALL SetErrorFlag
\r
249 126 ChargeParameters.NextState = ST_ERROR;
\r
250 \ 00000098 E50A LDI R16, 90
\r
251 \ 0000009A 9300.... STS (ChargeParameters + 4), R16
\r
253 \ 0000009E E081 LDI R24, 1
\r
258 132 } while (!HaltNow() && !error);
\r
259 \ ??ConstantCurrent_2:
\r
260 \ 000000A0 .... RCALL HaltNow
\r
261 \ 000000A2 2300 TST R16
\r
262 \ 000000A4 F419 BRNE ??ConstantCurrent_6
\r
263 \ 000000A6 2388 TST R24
\r
264 \ 000000A8 F409 BRNE $+2+2
\r
265 \ 000000AA CFAD RJMP ??ConstantCurrent_0
\r
267 134 // Return the next state to Charge(). If an error has occured, this will
\r
268 135 // point to some other state than the next state of charging.
\r
269 136 return(ChargeParameters.NextState);
\r
270 \ ??ConstantCurrent_6:
\r
271 \ 000000AC 9100.... LDS R16, (ChargeParameters + 4)
\r
272 \ 000000B0 E0E4 LDI R30, 4
\r
273 \ 000000B2 .... RJMP ?EPILOGUE_B4_L09
\r
274 \ 000000B4 REQUIRE _A_OCR1B
\r
278 140 /*! \brief Charges battery with a constant voltage
\r
280 142 * This function applies a constant voltage (set in ChargeParameters.Voltage)
\r
281 143 * to the battery until HaltNow() returns TRUE, or a PWM error occurs and
\r
282 144 * \ref ABORT_IF_PWM_MIN or \ref ABORT_IF_PWM_MAX is defined.\n
\r
283 145 * The charge voltage can vary with +/- \ref BAT_VOLTAGE_HYST.\n
\r
284 146 * If the Master inhibits charging, timers are stopped and PWM output dropped.
\r
285 147 * Once the battery is no longer flagged for charge inhibit, timers are
\r
286 148 * started again and charging resumed.
\r
288 150 * \retval ChargeParameters.NextState Next state once this stage is done.
\r
289 151 * If no errors occured, this will be whatever was set in Charge(). Otherwise,
\r
290 152 * HaltNow() will have set a new next state.
\r
293 \ In segment CODE, align 2, keep-with-next
\r
294 154 unsigned char ConstantVoltage(void)
\r
297 \ 00000000 .... RCALL ?PROLOGUE4_L09
\r
298 156 unsigned char error = FALSE,
\r
299 \ 00000002 E080 LDI R24, 0
\r
300 157 wasStopped = FALSE;
\r
301 \ 00000004 E090 LDI R25, 0
\r
305 161 // Wait for ADC conversions to complete.
\r
307 \ ??ConstantVoltage_0:
\r
308 \ 00000006 .... RCALL ADC_Wait
\r
310 164 // If Master has flagged for a charge inhibit, pause charging.
\r
311 165 // (This is to prevent damage during prolonged serial communication.)
\r
312 166 if (BattControl[BattActive].ChargeInhibit) {
\r
313 \ 00000008 9100.... LDS R16, BattActive
\r
314 \ 0000000C E010 LDI R17, 0
\r
315 \ 0000000E .... LDI R20, LOW(BattControl)
\r
316 \ 00000010 .... LDI R21, (BattControl) >> 8
\r
317 \ 00000012 0F40 ADD R20, R16
\r
318 \ 00000014 1F51 ADC R21, R17
\r
319 \ 00000016 .... RCALL __eeget8_16
\r
320 \ 00000018 7004 ANDI R16, 0x04
\r
321 \ 0000001A 2300 TST R16
\r
322 \ 0000001C F029 BREQ ??ConstantVoltage_1
\r
323 167 wasStopped = TRUE;
\r
324 \ 0000001E E091 LDI R25, 1
\r
326 \ 00000020 .... RCALL Time_Stop
\r
328 \ 00000022 E000 LDI R16, 0
\r
329 \ 00000024 BD0C OUT 0x2C, R16
\r
330 \ 00000026 C030 RJMP ??ConstantVoltage_2
\r
334 173 // Continue charging!
\r
335 174 if (wasStopped) {
\r
336 \ ??ConstantVoltage_1:
\r
337 \ 00000028 2399 TST R25
\r
338 \ 0000002A F011 BREQ ??ConstantVoltage_3
\r
339 175 wasStopped = FALSE;
\r
340 \ 0000002C E090 LDI R25, 0
\r
342 177 // Timer variables aren't reset by this.
\r
344 \ 0000002E .... RCALL Time_Start
\r
347 181 // Adjust the charge voltage to within ChargeParameters.Voltage
\r
348 182 // +/- BAT_VOLTAGE_HYST.
\r
349 183 if (ADCS.VBAT < (ChargeParameters.Voltage - BAT_VOLTAGE_HYST)) {
\r
350 \ ??ConstantVoltage_3:
\r
351 \ 00000030 .... LDI R30, LOW(ADCS)
\r
352 \ 00000032 .... LDI R31, (ADCS) >> 8
\r
353 \ 00000034 8522 LDD R18, Z+10
\r
354 \ 00000036 8533 LDD R19, Z+11
\r
355 \ 00000038 .... LDI R30, LOW(ChargeParameters)
\r
356 \ 0000003A .... LDI R31, (ChargeParameters) >> 8
\r
357 \ 0000003C 8100 LD R16, Z
\r
358 \ 0000003E 8111 LDD R17, Z+1
\r
359 \ 00000040 500A SUBI R16, 10
\r
360 \ 00000042 4010 SBCI R17, 0
\r
361 \ 00000044 1720 CP R18, R16
\r
362 \ 00000046 0731 CPC R19, R17
\r
363 \ 00000048 F450 BRCC ??ConstantVoltage_4
\r
365 185 if(!PWM_IncrementDutyCycle()) {
\r
366 \ 0000004A .... RCALL PWM_IncrementDutyCycle
\r
367 \ 0000004C 2300 TST R16
\r
368 \ 0000004E F4E1 BRNE ??ConstantVoltage_2
\r
369 186 #ifdef ABORT_IF_PWM_MAX
\r
370 187 // Flag PWM control error and go to error-state if the duty
\r
371 188 // cycle cannot be incremented.
\r
372 189 SetErrorFlag(ERR_PWM_CONTROL);
\r
373 \ 00000050 E004 LDI R16, 4
\r
374 \ 00000052 .... RCALL SetErrorFlag
\r
375 190 ChargeParameters.NextState = ST_ERROR;
\r
376 \ 00000054 E50A LDI R16, 90
\r
377 \ 00000056 9300.... STS (ChargeParameters + 4), R16
\r
379 \ 0000005A E081 LDI R24, 1
\r
380 \ 0000005C C015 RJMP ??ConstantVoltage_2
\r
383 194 } else if (ADCS.VBAT > (ChargeParameters.Voltage + BAT_VOLTAGE_HYST)) {
\r
384 \ ??ConstantVoltage_4:
\r
385 \ 0000005E .... LDI R30, LOW(ChargeParameters)
\r
386 \ 00000060 .... LDI R31, (ChargeParameters) >> 8
\r
387 \ 00000062 81A0 LD R26, Z
\r
388 \ 00000064 81B1 LDD R27, Z+1
\r
389 \ 00000066 961A ADIW R27:R26, 10
\r
390 \ 00000068 .... LDI R30, LOW(ADCS)
\r
391 \ 0000006A .... LDI R31, (ADCS) >> 8
\r
392 \ 0000006C 8502 LDD R16, Z+10
\r
393 \ 0000006E 8513 LDD R17, Z+11
\r
394 \ 00000070 17A0 CP R26, R16
\r
395 \ 00000072 07B1 CPC R27, R17
\r
396 \ 00000074 F448 BRCC ??ConstantVoltage_2
\r
398 196 if(!PWM_DecrementDutyCycle()) {
\r
399 \ 00000076 .... RCALL PWM_DecrementDutyCycle
\r
400 \ 00000078 2300 TST R16
\r
401 \ 0000007A F431 BRNE ??ConstantVoltage_2
\r
402 197 #ifdef ABORT_IF_PWM_MIN
\r
403 198 // Flag PWM control error and go to error-state if duty
\r
404 199 // cycle cannot be decremented.
\r
405 200 SetErrorFlag(ERR_PWM_CONTROL);
\r
406 \ 0000007C E004 LDI R16, 4
\r
407 \ 0000007E .... RCALL SetErrorFlag
\r
408 201 ChargeParameters.NextState = ST_ERROR;
\r
409 \ 00000080 E50A LDI R16, 90
\r
410 \ 00000082 9300.... STS (ChargeParameters + 4), R16
\r
412 \ 00000086 E081 LDI R24, 1
\r
418 208 } while (!HaltNow() && !error);
\r
419 \ ??ConstantVoltage_2:
\r
420 \ 00000088 .... RCALL HaltNow
\r
421 \ 0000008A 2300 TST R16
\r
422 \ 0000008C F419 BRNE ??ConstantVoltage_5
\r
423 \ 0000008E 2388 TST R24
\r
424 \ 00000090 F409 BRNE $+2+2
\r
425 \ 00000092 CFB9 RJMP ??ConstantVoltage_0
\r
427 210 // Return the next state to Charge(). If an error has occured, this will
\r
428 211 // point to some other state than the next state of charging.
\r
429 212 return(ChargeParameters.NextState);
\r
430 \ ??ConstantVoltage_5:
\r
431 \ 00000094 9100.... LDS R16, (ChargeParameters + 4)
\r
432 \ 00000098 E0E4 LDI R30, 4
\r
433 \ 0000009A .... RJMP ?EPILOGUE_B4_L09
\r
434 \ 0000009C REQUIRE _A_OCR1B
\r
438 216 /*! \brief Determines when to halt charging.
\r
440 218 * This function evaluates parameters depending on what has been flagged in
\r
441 219 * HaltParameters.HaltFlags, and returns TRUE or FALSE if the charging should
\r
442 220 * halt or not.\n
\r
443 221 * In addition, error flagging on timeout (battery exhaustion) can be set.\n
\r
445 223 * The function also checks if the battery temperature is within limits,
\r
446 224 * if mains is OK, and if BatteryCheck() returns TRUE.
\r
447 225 * If an error is detected, the associated errorflag is set and
\r
448 226 * ChargeParameters.NextState is changed to an appropriate state.
\r
450 228 * \retval TRUE Halt now.
\r
451 229 * \retval FALSE Don't halt now.
\r
453 231 * \note See chargefunc.h for definitions of halt flags.
\r
454 232 * \note It is generally a bad idea not to halt on a timeout.
\r
455 233 * \note If HALT_ON_VOLTAGE_DROP is set, HaltParameters.VBATMax should be
\r
456 234 * reset in Charge() before calling a charging-function.
\r
458 236 * \todo "Priorities" of standard error checks OK?
\r
461 \ In segment CODE, align 2, keep-with-next
\r
462 238 unsigned char HaltNow(void)
\r
465 \ 00000000 .... RCALL ?PROLOGUE4_L09
\r
466 240 unsigned char i, halt = FALSE;
\r
467 \ 00000002 E080 LDI R24, 0
\r
469 242 // Wait for a full ADC-cycle to finish.
\r
471 \ 00000004 .... RCALL ADC_Wait
\r
473 245 // Evaluate ADC readings according to HaltFlags. Flag errors if selected.
\r
474 246 // If an error is flagged, ChargeParameters.NextState is set to ST_ERROR.
\r
475 247 // (Gets overridden if either mains is failing, or the battery changes.)
\r
476 248 for (i = 0x01; i != 0; i <<= 1) {
\r
477 \ 00000006 E091 LDI R25, 1
\r
479 \ 00000008 2399 TST R25
\r
480 \ 0000000A F409 BRNE $+2+2
\r
481 \ 0000000C C0C4 RJMP ??HaltNow_1
\r
482 249 if (HaltParameters.HaltFlags & i) {
\r
483 \ 0000000E 9100.... LDS R16, HaltParameters
\r
484 \ 00000012 2309 AND R16, R25
\r
485 \ 00000014 2300 TST R16
\r
486 \ 00000016 F409 BRNE $+2+2
\r
487 \ 00000018 C0BC RJMP ??HaltNow_2
\r
489 \ 0000001A 2F09 MOV R16, R25
\r
490 \ 0000001C 5001 SUBI R16, 1
\r
491 \ 0000001E F059 BREQ ??HaltNow_3
\r
492 \ 00000020 950A DEC R16
\r
493 \ 00000022 F189 BREQ ??HaltNow_4
\r
494 \ 00000024 5002 SUBI R16, 2
\r
495 \ 00000026 F1E9 BREQ ??HaltNow_5
\r
496 \ 00000028 5004 SUBI R16, 4
\r
497 \ 0000002A F409 BRNE $+2+2
\r
498 \ 0000002C C048 RJMP ??HaltNow_6
\r
499 \ 0000002E 5008 SUBI R16, 8
\r
500 \ 00000030 F409 BRNE $+2+2
\r
501 \ 00000032 C089 RJMP ??HaltNow_7
\r
502 \ 00000034 C0AE RJMP ??HaltNow_2
\r
503 251 // Is VBAT less than the recorded maximum?
\r
504 252 case HALT_VOLTAGE_DROP:
\r
506 254 // Update VBATMax if VBAT is higher. Evaluate for halt otherwise.
\r
507 255 if (ADCS.VBAT > HaltParameters.VBATMax) {
\r
509 \ 00000036 .... LDI R30, LOW(HaltParameters)
\r
510 \ 00000038 .... LDI R31, (HaltParameters) >> 8
\r
511 \ 0000003A 8505 LDD R16, Z+13
\r
512 \ 0000003C 8516 LDD R17, Z+14
\r
513 \ 0000003E .... LDI R30, LOW(ADCS)
\r
514 \ 00000040 .... LDI R31, (ADCS) >> 8
\r
515 \ 00000042 8522 LDD R18, Z+10
\r
516 \ 00000044 8533 LDD R19, Z+11
\r
517 \ 00000046 1702 CP R16, R18
\r
518 \ 00000048 0713 CPC R17, R19
\r
519 \ 0000004A F448 BRCC ??HaltNow_8
\r
520 256 HaltParameters.VBATMax = ADCS.VBAT;
\r
521 \ 0000004C .... LDI R30, LOW(ADCS)
\r
522 \ 0000004E .... LDI R31, (ADCS) >> 8
\r
523 \ 00000050 8502 LDD R16, Z+10
\r
524 \ 00000052 8513 LDD R17, Z+11
\r
525 \ 00000054 .... LDI R30, LOW(HaltParameters)
\r
526 \ 00000056 .... LDI R31, (HaltParameters) >> 8
\r
527 \ 00000058 8705 STD Z+13, R16
\r
528 \ 0000005A 8716 STD Z+14, R17
\r
529 \ 0000005C C09A RJMP ??HaltNow_2
\r
530 257 } else if((HaltParameters.VBATMax - ADCS.VBAT) >=
\r
531 258 HaltParameters.VoltageDrop) {
\r
533 \ 0000005E .... LDI R30, LOW(HaltParameters)
\r
534 \ 00000060 .... LDI R31, (HaltParameters) >> 8
\r
535 \ 00000062 8505 LDD R16, Z+13
\r
536 \ 00000064 8516 LDD R17, Z+14
\r
537 \ 00000066 .... LDI R30, LOW(ADCS)
\r
538 \ 00000068 .... LDI R31, (ADCS) >> 8
\r
539 \ 0000006A 8522 LDD R18, Z+10
\r
540 \ 0000006C 8533 LDD R19, Z+11
\r
541 \ 0000006E 1B02 SUB R16, R18
\r
542 \ 00000070 0B13 SBC R17, R19
\r
543 \ 00000072 .... LDI R30, LOW(HaltParameters)
\r
544 \ 00000074 .... LDI R31, (HaltParameters) >> 8
\r
545 \ 00000076 8121 LDD R18, Z+1
\r
546 \ 00000078 8132 LDD R19, Z+2
\r
547 \ 0000007A 1702 CP R16, R18
\r
548 \ 0000007C 0713 CPC R17, R19
\r
549 \ 0000007E F408 BRCC $+2+2
\r
550 \ 00000080 C088 RJMP ??HaltNow_2
\r
552 \ 00000082 E081 LDI R24, 1
\r
553 \ 00000084 C086 RJMP ??HaltNow_2
\r
558 264 // Has VBAT reached the maximum limit?
\r
559 265 case HALT_VOLTAGE_MAX:
\r
561 267 if (ADCS.VBAT >= HaltParameters.VoltageMax) {
\r
563 \ 00000086 .... LDI R30, LOW(ADCS)
\r
564 \ 00000088 .... LDI R31, (ADCS) >> 8
\r
565 \ 0000008A 8502 LDD R16, Z+10
\r
566 \ 0000008C 8513 LDD R17, Z+11
\r
567 \ 0000008E .... LDI R30, LOW(HaltParameters)
\r
568 \ 00000090 .... LDI R31, (HaltParameters) >> 8
\r
569 \ 00000092 8123 LDD R18, Z+3
\r
570 \ 00000094 8134 LDD R19, Z+4
\r
571 \ 00000096 1702 CP R16, R18
\r
572 \ 00000098 0713 CPC R17, R19
\r
573 \ 0000009A F408 BRCC $+2+2
\r
574 \ 0000009C C07A RJMP ??HaltNow_2
\r
576 \ 0000009E E081 LDI R24, 1
\r
577 \ 000000A0 C078 RJMP ??HaltNow_2
\r
582 273 // Has IBAT reached the minimum limit?
\r
583 274 case HALT_CURRENT_MIN:
\r
585 276 if (ADCS.avgIBAT <= HaltParameters.CurrentMin) {
\r
587 \ 000000A2 .... LDI R30, LOW(HaltParameters)
\r
588 \ 000000A4 .... LDI R31, (HaltParameters) >> 8
\r
589 \ 000000A6 8105 LDD R16, Z+5
\r
590 \ 000000A8 8116 LDD R17, Z+6
\r
591 \ 000000AA .... LDI R30, LOW(ADCS)
\r
592 \ 000000AC .... LDI R31, (ADCS) >> 8
\r
593 \ 000000AE 8926 LDD R18, Z+22
\r
594 \ 000000B0 8937 LDD R19, Z+23
\r
595 \ 000000B2 1702 CP R16, R18
\r
596 \ 000000B4 0713 CPC R17, R19
\r
597 \ 000000B6 F408 BRCC $+2+2
\r
598 \ 000000B8 C06C RJMP ??HaltNow_2
\r
600 \ 000000BA E081 LDI R24, 1
\r
601 \ 000000BC C06A RJMP ??HaltNow_2
\r
606 282 // Is the temperature rising too fast?
\r
607 283 case HALT_TEMPERATURE_RISE:
\r
609 285 // If rawNTC has increased, the temperature has dropped.
\r
610 286 // We can store this value for now, and start the timer.
\r
611 287 // Otherwise, check if NTC has changed too fast.
\r
612 288 if (ADCS.rawNTC > HaltParameters.LastNTC) {
\r
614 \ 000000BE .... LDI R30, LOW(HaltParameters)
\r
615 \ 000000C0 .... LDI R31, (HaltParameters) >> 8
\r
616 \ 000000C2 8507 LDD R16, Z+15
\r
617 \ 000000C4 8910 LDD R17, Z+16
\r
618 \ 000000C6 .... LDI R30, LOW(ADCS)
\r
619 \ 000000C8 .... LDI R31, (ADCS) >> 8
\r
620 \ 000000CA 8124 LDD R18, Z+4
\r
621 \ 000000CC 8135 LDD R19, Z+5
\r
622 \ 000000CE 1702 CP R16, R18
\r
623 \ 000000D0 0713 CPC R17, R19
\r
624 \ 000000D2 F478 BRCC ??HaltNow_9
\r
625 289 HaltParameters.LastNTC = ADCS.rawNTC;
\r
626 \ 000000D4 .... LDI R30, LOW(ADCS)
\r
627 \ 000000D6 .... LDI R31, (ADCS) >> 8
\r
628 \ 000000D8 8104 LDD R16, Z+4
\r
629 \ 000000DA 8115 LDD R17, Z+5
\r
630 \ 000000DC .... LDI R30, LOW(HaltParameters)
\r
631 \ 000000DE .... LDI R31, (HaltParameters) >> 8
\r
632 \ 000000E0 8707 STD Z+15, R16
\r
633 \ 000000E2 8B10 STD Z+16, R17
\r
634 290 Time_Set(TIMER_TEMP,0,30,0);
\r
635 \ 000000E4 E040 LDI R20, 0
\r
636 \ 000000E6 E11E LDI R17, 30
\r
637 \ 000000E8 E020 LDI R18, 0
\r
638 \ 000000EA E030 LDI R19, 0
\r
639 \ 000000EC E003 LDI R16, 3
\r
640 \ 000000EE .... RCALL Time_Set
\r
641 \ 000000F0 C050 RJMP ??HaltNow_2
\r
643 292 // Is the increase in temperature greater than the set threshold?
\r
644 293 } else if ((HaltParameters.LastNTC - ADCS.rawNTC) >=
\r
645 294 (BattData.ADCSteps * HaltParameters.TemperatureRise)) {
\r
647 \ 000000F2 .... LDI R30, LOW(HaltParameters)
\r
648 \ 000000F4 .... LDI R31, (HaltParameters) >> 8
\r
649 \ 000000F6 85A7 LDD R26, Z+15
\r
650 \ 000000F8 89B0 LDD R27, Z+16
\r
651 \ 000000FA .... LDI R30, LOW(ADCS)
\r
652 \ 000000FC .... LDI R31, (ADCS) >> 8
\r
653 \ 000000FE 8104 LDD R16, Z+4
\r
654 \ 00000100 8115 LDD R17, Z+5
\r
655 \ 00000102 1BA0 SUB R26, R16
\r
656 \ 00000104 0BB1 SBC R27, R17
\r
657 \ 00000106 9140.... LDS R20, (BattData + 3)
\r
658 \ 0000010A E050 LDI R21, 0
\r
659 \ 0000010C .... LDI R30, LOW(HaltParameters)
\r
660 \ 0000010E .... LDI R31, (HaltParameters) >> 8
\r
661 \ 00000110 8503 LDD R16, Z+11
\r
662 \ 00000112 8514 LDD R17, Z+12
\r
663 \ 00000114 .... RCALL ?S_MUL_L02
\r
664 \ 00000116 17A0 CP R26, R16
\r
665 \ 00000118 07B1 CPC R27, R17
\r
666 \ 0000011A F1D8 BRCS ??HaltNow_2
\r
668 296 // If this happened within a timeframe of 30 seconds, the
\r
669 297 // temperature is rising faster than we want.
\r
670 298 // If not, update LastNTC and reset timer.
\r
671 299 if (Time_Left(TIMER_TEMP)) {
\r
672 \ 0000011C E003 LDI R16, 3
\r
673 \ 0000011E .... RCALL Time_Left
\r
674 \ 00000120 2300 TST R16
\r
675 \ 00000122 F011 BREQ ??HaltNow_10
\r
677 \ 00000124 E081 LDI R24, 1
\r
678 \ 00000126 C035 RJMP ??HaltNow_2
\r
680 302 HaltParameters.LastNTC = ADCS.rawNTC;
\r
682 \ 00000128 .... LDI R30, LOW(ADCS)
\r
683 \ 0000012A .... LDI R31, (ADCS) >> 8
\r
684 \ 0000012C 8104 LDD R16, Z+4
\r
685 \ 0000012E 8115 LDD R17, Z+5
\r
686 \ 00000130 .... LDI R30, LOW(HaltParameters)
\r
687 \ 00000132 .... LDI R31, (HaltParameters) >> 8
\r
688 \ 00000134 8707 STD Z+15, R16
\r
689 \ 00000136 8B10 STD Z+16, R17
\r
690 303 Time_Set(TIMER_TEMP,0,30,0);
\r
691 \ 00000138 E040 LDI R20, 0
\r
692 \ 0000013A E11E LDI R17, 30
\r
693 \ 0000013C E020 LDI R18, 0
\r
694 \ 0000013E E030 LDI R19, 0
\r
695 \ 00000140 E003 LDI R16, 3
\r
696 \ 00000142 .... RCALL Time_Set
\r
697 \ 00000144 C026 RJMP ??HaltNow_2
\r
703 309 // Is there any time left?
\r
704 310 case HALT_TIME:
\r
706 312 if (!Time_Left(TIMER_CHG)) {
\r
708 \ 00000146 E001 LDI R16, 1
\r
709 \ 00000148 .... RCALL Time_Left
\r
710 \ 0000014A 2300 TST R16
\r
711 \ 0000014C F511 BRNE ??HaltNow_2
\r
713 \ 0000014E E081 LDI R24, 1
\r
715 315 // If exhaustion flagging is selected, stop the PWM, disable the
\r
716 316 // battery and flag it as exhausted. Make ST_ERROR next state.
\r
717 317 if (HaltParameters.HaltFlags & HALT_FLAG_EXHAUSTION) {
\r
718 \ 00000150 .... LDI R30, LOW(HaltParameters)
\r
719 \ 00000152 .... LDI R31, (HaltParameters) >> 8
\r
720 \ 00000154 8100 LD R16, Z
\r
721 \ 00000156 FF05 SBRS R16, 5
\r
722 \ 00000158 C01C RJMP ??HaltNow_2
\r
724 \ 0000015A .... RCALL PWM_Stop
\r
725 319 BattControl[BattActive].Enabled = FALSE;
\r
726 \ 0000015C 9100.... LDS R16, BattActive
\r
727 \ 00000160 E010 LDI R17, 0
\r
728 \ 00000162 .... LDI R20, LOW(BattControl)
\r
729 \ 00000164 .... LDI R21, (BattControl) >> 8
\r
730 \ 00000166 0F40 ADD R20, R16
\r
731 \ 00000168 1F51 ADC R21, R17
\r
732 \ 0000016A .... RCALL __eeget8_16
\r
733 \ 0000016C 7F0E ANDI R16, 0xFE
\r
734 \ 0000016E 9120.... LDS R18, BattActive
\r
735 \ 00000172 E030 LDI R19, 0
\r
736 \ 00000174 .... LDI R20, LOW(BattControl)
\r
737 \ 00000176 .... LDI R21, (BattControl) >> 8
\r
738 \ 00000178 0F42 ADD R20, R18
\r
739 \ 0000017A 1F53 ADC R21, R19
\r
740 \ 0000017C .... RCALL __eeput8_16
\r
741 320 BattData.Exhausted = TRUE;
\r
742 \ 0000017E .... LDI R30, LOW(BattData)
\r
743 \ 00000180 .... LDI R31, (BattData) >> 8
\r
744 \ 00000182 8100 LD R16, Z
\r
745 \ 00000184 6008 ORI R16, 0x08
\r
746 \ 00000186 8300 ST Z, R16
\r
747 321 SetErrorFlag(ERR_BATTERY_EXHAUSTED);
\r
748 \ 00000188 E100 LDI R16, 16
\r
749 \ 0000018A .... RCALL SetErrorFlag
\r
750 322 ChargeParameters.NextState = ST_ERROR;
\r
751 \ 0000018C E50A LDI R16, 90
\r
752 \ 0000018E 9300.... STS (ChargeParameters + 4), R16
\r
758 328 default: // Shouldn't end up here, but is needed for MISRA compliance.
\r
764 \ 00000192 0F99 LSL R25
\r
765 \ 00000194 CF39 RJMP ??HaltNow_0
\r
767 334 // Standard checks:
\r
769 336 // Battery too cold or hot?
\r
770 337 if ((BattData.Temperature <= HaltParameters.TemperatureMin) ||
\r
771 338 (BattData.Temperature >= HaltParameters.TemperatureMax)) {
\r
773 \ 00000196 .... LDI R30, LOW(HaltParameters)
\r
774 \ 00000198 .... LDI R31, (HaltParameters) >> 8
\r
775 \ 0000019A 8521 LDD R18, Z+9
\r
776 \ 0000019C 8532 LDD R19, Z+10
\r
777 \ 0000019E 9100.... LDS R16, (BattData + 2)
\r
778 \ 000001A2 2F10 MOV R17, R16
\r
779 \ 000001A4 0F11 LSL R17
\r
780 \ 000001A6 0B11 SBC R17, R17
\r
781 \ 000001A8 1720 CP R18, R16
\r
782 \ 000001AA 0731 CPC R19, R17
\r
783 \ 000001AC F464 BRGE ??HaltNow_11
\r
784 \ 000001AE 9100.... LDS R16, (BattData + 2)
\r
785 \ 000001B2 2F10 MOV R17, R16
\r
786 \ 000001B4 0F11 LSL R17
\r
787 \ 000001B6 0B11 SBC R17, R17
\r
788 \ 000001B8 .... LDI R30, LOW(HaltParameters)
\r
789 \ 000001BA .... LDI R31, (HaltParameters) >> 8
\r
790 \ 000001BC 8127 LDD R18, Z+7
\r
791 \ 000001BE 8530 LDD R19, Z+8
\r
792 \ 000001C0 1702 CP R16, R18
\r
793 \ 000001C2 0713 CPC R17, R19
\r
794 \ 000001C4 F038 BRCS ??HaltNow_12
\r
798 \ 000001C6 .... RCALL PWM_Stop
\r
799 341 SetErrorFlag(ERR_BATTERY_TEMPERATURE);
\r
800 \ 000001C8 E008 LDI R16, 8
\r
801 \ 000001CA .... RCALL SetErrorFlag
\r
802 342 ChargeParameters.NextState = ST_ERROR;
\r
803 \ 000001CC E50A LDI R16, 90
\r
804 \ 000001CE 9300.... STS (ChargeParameters + 4), R16
\r
806 \ 000001D2 E081 LDI R24, 1
\r
809 346 // Battery not OK?
\r
810 347 if (!BatteryCheck()) {
\r
812 \ 000001D4 .... RCALL BatteryCheck
\r
813 \ 000001D6 2300 TST R16
\r
814 \ 000001D8 F429 BRNE ??HaltNow_13
\r
816 \ 000001DA .... RCALL PWM_Stop
\r
817 349 ChargeParameters.NextState = ST_INIT;
\r
818 \ 000001DC E00A LDI R16, 10
\r
819 \ 000001DE 9300.... STS (ChargeParameters + 4), R16
\r
821 \ 000001E2 E081 LDI R24, 1
\r
824 353 // Is mains voltage OK?
\r
825 354 if (!ADCS.Mains) {
\r
827 \ 000001E4 .... LDI R30, LOW(ADCS)
\r
828 \ 000001E6 .... LDI R31, (ADCS) >> 8
\r
829 \ 000001E8 8100 LD R16, Z
\r
830 \ 000001EA FD06 SBRC R16, 6
\r
831 \ 000001EC C005 RJMP ??HaltNow_14
\r
833 \ 000001EE .... RCALL PWM_Stop
\r
834 356 ChargeParameters.NextState = ST_SLEEP;
\r
835 \ 000001F0 E208 LDI R16, 40
\r
836 \ 000001F2 9300.... STS (ChargeParameters + 4), R16
\r
838 \ 000001F6 E081 LDI R24, 1
\r
843 \ 000001F8 2F08 MOV R16, R24
\r
844 \ 000001FA E0E4 LDI R30, 4
\r
845 \ 000001FC .... RJMP ?EPILOGUE_B4_L09
\r
848 Maximum stack usage in bytes:
\r
850 Function CSTACK RSTACK
\r
851 -------- ------ ------
\r
852 ConstantCurrent 4 4
\r
856 -> PWM_IncrementDutyCycle 4 2
\r
857 -> SetErrorFlag 4 2
\r
858 -> PWM_DecrementDutyCycle 4 2
\r
859 -> SetErrorFlag 4 2
\r
861 ConstantVoltage 4 4
\r
865 -> PWM_IncrementDutyCycle 4 2
\r
866 -> SetErrorFlag 4 2
\r
867 -> PWM_DecrementDutyCycle 4 2
\r
868 -> SetErrorFlag 4 2
\r
877 -> SetErrorFlag 4 2
\r
879 -> SetErrorFlag 4 2
\r
880 -> BatteryCheck 4 2
\r
885 Segment part sizes:
\r
887 Function/Label Bytes
\r
888 -------------- -----
\r
892 ConstantCurrent 180
\r
893 ConstantVoltage 156
\r
898 1 byte in segment ABSOLUTE
\r
899 846 bytes in segment CODE
\r
900 6 bytes in segment INITTAB
\r
901 22 bytes in segment NEAR_Z
\r
903 846 bytes of CODE memory (+ 6 bytes shared)
\r
904 22 bytes of DATA memory (+ 1 byte shared)
\r