1 ###############################################################################
\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
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\bc10 #
\r
9 # 0\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\Lis #
\r
12 # t\ --initializers_in_flash -s9 --no_cross_call #
\r
13 # --no_tbaa -DENABLE_BIT_DEFINITIONS -e -I #
\r
14 # "C:\Program Files\IAR Systems\Embedded #
\r
15 # Workbench 4.0\avr\INC\" -I "C:\Program #
\r
16 # Files\IAR Systems\Embedded Workbench #
\r
17 # 4.0\avr\INC\CLIB\" --eeprom_size 512 #
\r
18 # --misrac=5-9,11-12,14,16-17,19-21,24-26,29-32, #
\r
19 # 34-35,38-39,42-43,46,50,52-54,56-59,61-62, #
\r
20 # 64-65,68-80,83-84,87-91,94-95,98-100,103-110, #
\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
29 # Not checked = 6,16,25-26,43,65,70,90,99,103,106-107,110, #
\r
31 # List file = C:\home\kevin\pub\src\bc100\IAR\Release\List\ch #
\r
33 # Object file = C:\home\kevin\pub\src\bc100\IAR\Release\Obj\cha #
\r
37 ###############################################################################
\r
39 C:\home\kevin\pub\src\bc100\IAR\chargefunc.c
\r
40 1 /* This file has been prepared for Doxygen automatic documentation generation.*/
\r
41 2 /*! \file *********************************************************************
\r
44 5 * Charge functions
\r
46 7 * Contains the functions for charging with constant current and voltage,
\r
47 8 * and for deciding when to halt.
\r
49 10 * \par Application note:
\r
50 11 * AVR458: Charging Li-Ion Batteries with BC100 \n
\r
51 12 * AVR463: Charging NiMH Batteries with BC100
\r
53 14 * \par Documentation
\r
54 15 * For comprehensive code documentation, supported compilers, compiler
\r
55 16 * settings and supported devices see readme.html
\r
58 19 * Atmel Corporation: http://www.atmel.com \n
\r
59 20 * Support email: avr@atmel.com
\r
63 24 * $Revision: 2299 $
\r
65 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
66 27 * $Date: 2007-08-23 12:55:51 +0200 (to, 23 aug 2007) $\n
\r
67 28 ******************************************************************************/
\r
69 30 #include <ioavr.h>
\r
71 \ In segment ABSOLUTE, at 0x4c
\r
72 \ <unnamed> volatile __io _A_OCR1B
\r
76 32 #include "enums.h"
\r
77 33 #include "structs.h"
\r
80 36 #include "battery.h"
\r
81 37 #include "chargefunc.h"
\r
82 38 #include "main.h"
\r
83 39 #include "menu.h"
\r
85 41 #include "statefunc.h"
\r
86 42 #include "time.h"
\r
89 45 #include "NIMHspecs.h"
\r
93 49 #include "LIIONspecs.h"
\r
97 53 //******************************************************************************
\r
99 55 //******************************************************************************
\r
100 56 //! Struct that holds parameters for ConstantCurrent() and ConstantVoltage().
\r
102 \ In segment NEAR_Z, align 1, keep-with-next
\r
103 \ 00000000 REQUIRE `?<Segment init: NEAR_Z>`
\r
104 57 ChargeParameters_t ChargeParameters;
\r
106 59 //! Struct that holds parameters for HaltNow().
\r
107 60 HaltParameters_t HaltParameters;
\r
110 \ ChargeParameters:
\r
114 63 //******************************************************************************
\r
116 65 //******************************************************************************
\r
117 66 /*! \brief Charges battery with a constant current.
\r
119 68 * This function applies a constant current (set in ChargeParameters.Current)
\r
120 69 * to the battery until HaltNow() returns TRUE, or a PWM error occurs and
\r
121 70 * \ref ABORT_IF_PWM_MIN or \ref ABORT_IF_PWM_MAX is defined.\n
\r
122 71 * The charge current can vary with +/- \ref BAT_CURRENT_HYST.\n
\r
123 72 * If the Master inhibits charging, timers are stopped and PWM output dropped.
\r
124 73 * Once the battery is no longer flagged for charge inhibit, timers are
\r
125 74 * started again and charging resumed.
\r
127 76 * \retval ChargeParameters.NextState Next state once this stage is done.
\r
128 77 * If no errors occured, this will be whatever was set in Charge(). Otherwise,
\r
129 78 * HaltNow() will have set a new next state.
\r
132 \ In segment CODE, align 2, keep-with-next
\r
133 80 unsigned char ConstantCurrent(void)
\r
136 \ 00000000 925A ST -Y, R5
\r
137 \ 00000002 924A ST -Y, R4
\r
138 \ 00000004 93BA ST -Y, R27
\r
139 \ 00000006 93AA ST -Y, R26
\r
140 \ 00000008 939A ST -Y, R25
\r
141 \ 0000000A 938A ST -Y, R24
\r
142 \ 0000000C REQUIRE ?Register_R4_is_cg_reg
\r
143 \ 0000000C REQUIRE ?Register_R5_is_cg_reg
\r
144 82 unsigned char error = FALSE,
\r
145 \ 0000000C 2455 CLR R5
\r
146 83 wasStopped = FALSE;
\r
147 \ 0000000E 2444 CLR R4
\r
150 86 // Wait for ADC conversions to complete.
\r
152 \ ??ConstantCurrent_0:
\r
153 \ 00000010 .... RCALL ADC_Wait
\r
155 89 // If Master has flagged for a charge inhibit, pause charging.
\r
156 90 // (This is to prevent damage during prolonged serial communication.)
\r
157 91 if (BattControl[BattActive].ChargeInhibit) {
\r
158 \ 00000012 9100.... LDS R16, BattActive
\r
159 \ 00000016 E010 LDI R17, 0
\r
160 \ 00000018 .... LDI R20, LOW(BattControl)
\r
161 \ 0000001A .... LDI R21, (BattControl) >> 8
\r
162 \ 0000001C 0F40 ADD R20, R16
\r
163 \ 0000001E 1F51 ADC R21, R17
\r
164 \ 00000020 .... RCALL __eeget8_16
\r
165 \ 00000022 7004 ANDI R16, 0x04
\r
166 \ 00000024 F031 BREQ ??ConstantCurrent_1
\r
167 92 wasStopped = TRUE;
\r
168 \ 00000026 2444 CLR R4
\r
169 \ 00000028 9443 INC R4
\r
171 \ 0000002A .... RCALL Time_Stop
\r
173 \ 0000002C E000 LDI R16, 0
\r
174 \ 0000002E BD0C OUT 0x2C, R16
\r
175 \ 00000030 C025 RJMP ??ConstantCurrent_2
\r
177 96 // Continue charging!
\r
178 97 if (wasStopped) {
\r
179 \ ??ConstantCurrent_1:
\r
180 \ 00000032 2044 TST R4
\r
181 \ 00000034 F011 BREQ ??ConstantCurrent_3
\r
182 98 wasStopped = FALSE;
\r
183 \ 00000036 2444 CLR R4
\r
185 100 // Timer variables are not reset by this.
\r
187 \ 00000038 .... RCALL Time_Start
\r
190 104 // Adjust the charge current to within ChargeParameters.Current
\r
191 105 // +/- BAT_CURRENT_HYST.
\r
192 106 if ((ADCS.avgIBAT < 0) ||
\r
193 107 (ADCS.avgIBAT < (ChargeParameters.Current - BAT_CURRENT_HYST))) {
\r
194 \ ??ConstantCurrent_3:
\r
195 \ 0000003A .... LDI R30, LOW(ADCS)
\r
196 \ 0000003C .... LDI R31, (ADCS) >> 8
\r
197 \ 0000003E 8906 LDD R16, Z+22
\r
198 \ 00000040 8917 LDD R17, Z+23
\r
199 \ 00000042 2311 TST R17
\r
200 \ 00000044 F04A BRMI ??ConstantCurrent_4
\r
201 \ 00000046 .... LDI R26, LOW((HaltParameters + 19))
\r
202 \ 00000048 .... LDI R27, HIGH((HaltParameters + 19))
\r
203 \ 0000004A 91ED LD R30, X+
\r
204 \ 0000004C 91FC LD R31, X
\r
205 \ 0000004E 01CF MOVW R25:R24, R31:R30
\r
206 \ 00000050 9703 SBIW R25:R24, 3
\r
207 \ 00000052 1708 CP R16, R24
\r
208 \ 00000054 0719 CPC R17, R25
\r
209 \ 00000056 F458 BRCC ??ConstantCurrent_5
\r
211 109 if(!PWM_IncrementDutyCycle()) {
\r
212 \ ??ConstantCurrent_4:
\r
213 \ 00000058 .... RCALL PWM_IncrementDutyCycle
\r
214 \ 0000005A 2300 TST R16
\r
215 \ 0000005C F479 BRNE ??ConstantCurrent_2
\r
216 110 #ifdef ABORT_IF_PWM_MAX
\r
217 111 // If the duty cycle cannot be incremented, flag error and
\r
218 112 // go to error state.
\r
219 113 SetErrorFlag(ERR_PWM_CONTROL);
\r
220 \ ??ConstantCurrent_6:
\r
221 \ 0000005E E004 LDI R16, 4
\r
222 \ 00000060 .... RCALL SetErrorFlag
\r
223 114 ChargeParameters.NextState = ST_ERROR;
\r
224 \ 00000062 E50A LDI R16, 90
\r
225 \ 00000064 9300.... STS (HaltParameters + 21), R16
\r
227 \ 00000068 2455 CLR R5
\r
228 \ 0000006A 9453 INC R5
\r
229 \ 0000006C C007 RJMP ??ConstantCurrent_2
\r
232 118 } else if ((ADCS.avgIBAT >= 0) &&
\r
233 \ ??ConstantCurrent_5:
\r
234 \ 0000006E 9633 ADIW R31:R30, 3
\r
235 \ 00000070 17E0 CP R30, R16
\r
236 \ 00000072 07F1 CPC R31, R17
\r
237 \ 00000074 F418 BRCC ??ConstantCurrent_2
\r
238 119 (ADCS.avgIBAT > (ChargeParameters.Current + BAT_CURRENT_HYST))) {
\r
240 121 if(!PWM_DecrementDutyCycle()) {
\r
241 \ 00000076 .... RCALL PWM_DecrementDutyCycle
\r
242 \ 00000078 2300 TST R16
\r
243 \ 0000007A F389 BREQ ??ConstantCurrent_6
\r
244 122 #ifdef ABORT_IF_PWM_MIN
\r
245 123 // If the duty cycle cannot be decremented, flag error and
\r
246 124 // go to error state.
\r
247 125 SetErrorFlag(ERR_PWM_CONTROL);
\r
248 126 ChargeParameters.NextState = ST_ERROR;
\r
254 132 } while ((!HaltNow()) && (!error));
\r
255 \ ??ConstantCurrent_2:
\r
256 \ 0000007C .... RCALL HaltNow
\r
257 \ 0000007E 2300 TST R16
\r
258 \ 00000080 F411 BRNE ??ConstantCurrent_7
\r
259 \ 00000082 2055 TST R5
\r
260 \ 00000084 F229 BREQ ??ConstantCurrent_0
\r
262 134 // Return the next state to Charge(). If an error has occured, this will
\r
263 135 // point to some other state than the next state of charging.
\r
264 136 return(ChargeParameters.NextState);
\r
265 \ ??ConstantCurrent_7:
\r
266 \ 00000086 9100.... LDS R16, (HaltParameters + 21)
\r
267 \ 0000008A 9189 LD R24, Y+
\r
268 \ 0000008C 9199 LD R25, Y+
\r
269 \ 0000008E 91A9 LD R26, Y+
\r
270 \ 00000090 91B9 LD R27, Y+
\r
271 \ 00000092 9049 LD R4, Y+
\r
272 \ 00000094 9059 LD R5, Y+
\r
273 \ 00000096 9508 RET
\r
274 \ 00000098 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 93BA ST -Y, R27
\r
298 \ 00000002 93AA ST -Y, R26
\r
299 \ 00000004 939A ST -Y, R25
\r
300 \ 00000006 938A ST -Y, R24
\r
301 156 unsigned char error = FALSE,
\r
302 \ 00000008 E090 LDI R25, 0
\r
303 157 wasStopped = FALSE;
\r
304 \ 0000000A E080 LDI R24, 0
\r
308 161 // Wait for ADC conversions to complete.
\r
310 \ ??ConstantVoltage_0:
\r
311 \ 0000000C .... RCALL ADC_Wait
\r
313 164 // If Master has flagged for a charge inhibit, pause charging.
\r
314 165 // (This is to prevent damage during prolonged serial communication.)
\r
315 166 if (BattControl[BattActive].ChargeInhibit) {
\r
316 \ 0000000E 9100.... LDS R16, BattActive
\r
317 \ 00000012 E010 LDI R17, 0
\r
318 \ 00000014 .... LDI R20, LOW(BattControl)
\r
319 \ 00000016 .... LDI R21, (BattControl) >> 8
\r
320 \ 00000018 0F40 ADD R20, R16
\r
321 \ 0000001A 1F51 ADC R21, R17
\r
322 \ 0000001C .... RCALL __eeget8_16
\r
323 \ 0000001E 7004 ANDI R16, 0x04
\r
324 \ 00000020 F029 BREQ ??ConstantVoltage_1
\r
325 167 wasStopped = TRUE;
\r
326 \ 00000022 E081 LDI R24, 1
\r
328 \ 00000024 .... RCALL Time_Stop
\r
330 \ 00000026 E000 LDI R16, 0
\r
331 \ 00000028 BD0C OUT 0x2C, R16
\r
332 \ 0000002A C024 RJMP ??ConstantVoltage_2
\r
336 173 // Continue charging!
\r
337 174 if (wasStopped) {
\r
338 \ ??ConstantVoltage_1:
\r
339 \ 0000002C 2388 TST R24
\r
340 \ 0000002E F011 BREQ ??ConstantVoltage_3
\r
341 175 wasStopped = FALSE;
\r
342 \ 00000030 E080 LDI R24, 0
\r
344 177 // Timer variables aren't reset by this.
\r
346 \ 00000032 .... RCALL Time_Start
\r
349 181 // Adjust the charge voltage to within ChargeParameters.Voltage
\r
350 182 // +/- BAT_VOLTAGE_HYST.
\r
351 183 if (ADCS.VBAT < (ChargeParameters.Voltage - BAT_VOLTAGE_HYST)) {
\r
352 \ ??ConstantVoltage_3:
\r
353 \ 00000034 .... LDI R26, LOW(HaltParameters)
\r
354 \ 00000036 .... LDI R27, (HaltParameters) >> 8
\r
355 \ 00000038 01FD MOVW R31:R30, R27:R26
\r
356 \ 0000003A 8901 LDD R16, Z+17
\r
357 \ 0000003C 8912 LDD R17, Z+18
\r
358 \ 0000003E .... LDI R30, LOW(ADCS)
\r
359 \ 00000040 .... LDI R31, (ADCS) >> 8
\r
360 \ 00000042 8522 LDD R18, Z+10
\r
361 \ 00000044 8533 LDD R19, Z+11
\r
362 \ 00000046 01F8 MOVW R31:R30, R17:R16
\r
363 \ 00000048 973A SBIW R31:R30, 10
\r
364 \ 0000004A 172E CP R18, R30
\r
365 \ 0000004C 073F CPC R19, R31
\r
366 \ 0000004E F450 BRCC ??ConstantVoltage_4
\r
368 185 if(!PWM_IncrementDutyCycle()) {
\r
369 \ 00000050 .... RCALL PWM_IncrementDutyCycle
\r
370 \ 00000052 2300 TST R16
\r
371 \ 00000054 F479 BRNE ??ConstantVoltage_2
\r
372 186 #ifdef ABORT_IF_PWM_MAX
\r
373 187 // Flag PWM control error and go to error-state if the duty
\r
374 188 // cycle cannot be incremented.
\r
375 189 SetErrorFlag(ERR_PWM_CONTROL);
\r
376 \ ??ConstantVoltage_5:
\r
377 \ 00000056 E004 LDI R16, 4
\r
378 \ 00000058 .... RCALL SetErrorFlag
\r
379 190 ChargeParameters.NextState = ST_ERROR;
\r
380 \ 0000005A E50A LDI R16, 90
\r
381 \ 0000005C 01FD MOVW R31:R30, R27:R26
\r
382 \ 0000005E 8B05 STD Z+21, R16
\r
384 \ 00000060 E091 LDI R25, 1
\r
385 \ 00000062 C008 RJMP ??ConstantVoltage_2
\r
388 194 } else if (ADCS.VBAT > (ChargeParameters.Voltage + BAT_VOLTAGE_HYST)) {
\r
389 \ ??ConstantVoltage_4:
\r
390 \ 00000064 5F06 SUBI R16, 246
\r
391 \ 00000066 4F1F SBCI R17, 255
\r
392 \ 00000068 1702 CP R16, R18
\r
393 \ 0000006A 0713 CPC R17, R19
\r
394 \ 0000006C F418 BRCC ??ConstantVoltage_2
\r
396 196 if(!PWM_DecrementDutyCycle()) {
\r
397 \ 0000006E .... RCALL PWM_DecrementDutyCycle
\r
398 \ 00000070 2300 TST R16
\r
399 \ 00000072 F389 BREQ ??ConstantVoltage_5
\r
400 197 #ifdef ABORT_IF_PWM_MIN
\r
401 198 // Flag PWM control error and go to error-state if duty
\r
402 199 // cycle cannot be decremented.
\r
403 200 SetErrorFlag(ERR_PWM_CONTROL);
\r
404 201 ChargeParameters.NextState = ST_ERROR;
\r
411 208 } while ((!HaltNow()) && (!error));
\r
412 \ ??ConstantVoltage_2:
\r
413 \ 00000074 .... RCALL HaltNow
\r
414 \ 00000076 2300 TST R16
\r
415 \ 00000078 F411 BRNE ??ConstantVoltage_6
\r
416 \ 0000007A 2399 TST R25
\r
417 \ 0000007C F239 BREQ ??ConstantVoltage_0
\r
419 210 // Return the next state to Charge(). If an error has occured, this will
\r
420 211 // point to some other state than the next state of charging.
\r
421 212 return(ChargeParameters.NextState);
\r
422 \ ??ConstantVoltage_6:
\r
423 \ 0000007E 9100.... LDS R16, (HaltParameters + 21)
\r
424 \ 00000082 9189 LD R24, Y+
\r
425 \ 00000084 9199 LD R25, Y+
\r
426 \ 00000086 91A9 LD R26, Y+
\r
427 \ 00000088 91B9 LD R27, Y+
\r
428 \ 0000008A 9508 RET
\r
429 \ 0000008C REQUIRE _A_OCR1B
\r
433 216 /*! \brief Determines when to halt charging.
\r
435 218 * This function evaluates parameters depending on what has been flagged in
\r
436 219 * HaltParameters.HaltFlags, and returns TRUE or FALSE if the charging should
\r
437 220 * halt or not.\n
\r
438 221 * In addition, error flagging on timeout (battery exhaustion) can be set.\n
\r
440 223 * The function also checks if the battery temperature is within limits,
\r
441 224 * if mains is OK, and if BatteryCheck() returns TRUE.
\r
442 225 * If an error is detected, the associated errorflag is set and
\r
443 226 * ChargeParameters.NextState is changed to an appropriate state.
\r
445 228 * \retval TRUE Halt now.
\r
446 229 * \retval FALSE Don't halt now.
\r
448 231 * \note See chargefunc.h for definitions of halt flags.
\r
449 232 * \note It is generally a bad idea not to halt on a timeout.
\r
450 233 * \note If HALT_ON_VOLTAGE_DROP is set, HaltParameters.VBATMax should be
\r
451 234 * reset in Charge() before calling a charging-function.
\r
453 236 * \todo "Priorities" of standard error checks OK?
\r
456 \ In segment CODE, align 2, keep-with-next
\r
457 238 unsigned char HaltNow(void)
\r
460 \ 00000000 929A ST -Y, R9
\r
461 \ 00000002 928A ST -Y, R8
\r
462 \ 00000004 927A ST -Y, R7
\r
463 \ 00000006 926A ST -Y, R6
\r
464 \ 00000008 925A ST -Y, R5
\r
465 \ 0000000A 924A ST -Y, R4
\r
466 \ 0000000C 93BA ST -Y, R27
\r
467 \ 0000000E 93AA ST -Y, R26
\r
468 \ 00000010 939A ST -Y, R25
\r
469 \ 00000012 938A ST -Y, R24
\r
470 \ 00000014 REQUIRE ?Register_R4_is_cg_reg
\r
471 \ 00000014 REQUIRE ?Register_R5_is_cg_reg
\r
472 \ 00000014 REQUIRE ?Register_R6_is_cg_reg
\r
473 \ 00000014 REQUIRE ?Register_R7_is_cg_reg
\r
474 \ 00000014 REQUIRE ?Register_R8_is_cg_reg
\r
475 \ 00000014 REQUIRE ?Register_R9_is_cg_reg
\r
476 240 unsigned char i, halt = FALSE;
\r
477 \ 00000014 2477 CLR R7
\r
479 242 // Wait for a full ADC-cycle to finish.
\r
481 \ 00000016 .... RCALL ADC_Wait
\r
483 245 // Evaluate ADC readings according to HaltFlags. Flag errors if selected.
\r
484 246 // If an error is flagged, ChargeParameters.NextState is set to ST_ERROR.
\r
485 247 // (Gets overridden if either mains is failing, or the battery changes.)
\r
486 248 for (i = 0x01; i != 0; i <<= 1) {
\r
487 \ 00000018 2466 CLR R6
\r
488 \ 0000001A 9463 INC R6
\r
489 \ 0000001C .... LDI R24, LOW(ADCS)
\r
490 \ 0000001E .... LDI R25, (ADCS) >> 8
\r
491 \ 00000020 .... LDI R16, LOW(BattData)
\r
492 \ 00000022 2E40 MOV R4, R16
\r
493 \ 00000024 .... LDI R16, (BattData) >> 8
\r
494 \ 00000026 2E50 MOV R5, R16
\r
495 \ 00000028 .... LDI R26, LOW(HaltParameters)
\r
496 \ 0000002A .... LDI R27, (HaltParameters) >> 8
\r
497 249 if (HaltParameters.HaltFlags & i) {
\r
499 \ 0000002C 910C LD R16, X
\r
500 \ 0000002E 2106 AND R16, R6
\r
501 \ 00000030 F409 BRNE $+2+2
\r
502 \ 00000032 C07C RJMP ??HaltNow_1
\r
504 \ 00000034 2D06 MOV R16, R6
\r
505 \ 00000036 950A DEC R16
\r
506 \ 00000038 F051 BREQ ??HaltNow_2
\r
507 \ 0000003A 950A DEC R16
\r
508 \ 0000003C F109 BREQ ??HaltNow_3
\r
509 \ 0000003E 5002 SUBI R16, 2
\r
510 \ 00000040 F151 BREQ ??HaltNow_4
\r
511 \ 00000042 5004 SUBI R16, 4
\r
512 \ 00000044 F179 BREQ ??HaltNow_5
\r
513 \ 00000046 5008 SUBI R16, 8
\r
514 \ 00000048 F409 BRNE $+2+2
\r
515 \ 0000004A C053 RJMP ??HaltNow_6
\r
516 \ 0000004C C06F RJMP ??HaltNow_1
\r
517 251 // Is VBAT less than the recorded maximum?
\r
518 252 case HALT_VOLTAGE_DROP:
\r
520 254 // Update VBATMax if VBAT is higher. Evaluate for halt otherwise.
\r
521 255 if (ADCS.VBAT > HaltParameters.VBATMax) {
\r
523 \ 0000004E 01FD MOVW R31:R30, R27:R26
\r
524 \ 00000050 8505 LDD R16, Z+13
\r
525 \ 00000052 8516 LDD R17, Z+14
\r
526 \ 00000054 01FC MOVW R31:R30, R25:R24
\r
527 \ 00000056 8522 LDD R18, Z+10
\r
528 \ 00000058 8533 LDD R19, Z+11
\r
529 \ 0000005A 1702 CP R16, R18
\r
530 \ 0000005C 0713 CPC R17, R19
\r
531 \ 0000005E F420 BRCC ??HaltNow_7
\r
532 256 HaltParameters.VBATMax = ADCS.VBAT;
\r
533 \ 00000060 01FD MOVW R31:R30, R27:R26
\r
534 \ 00000062 8725 STD Z+13, R18
\r
535 \ 00000064 8736 STD Z+14, R19
\r
536 \ 00000066 C062 RJMP ??HaltNow_1
\r
537 257 } else if((HaltParameters.VBATMax - ADCS.VBAT) >=
\r
538 258 HaltParameters.VoltageDrop) {
\r
540 \ 00000068 1B02 SUB R16, R18
\r
541 \ 0000006A 0B13 SBC R17, R19
\r
542 \ 0000006C 01FD MOVW R31:R30, R27:R26
\r
543 \ 0000006E 8121 LDD R18, Z+1
\r
544 \ 00000070 8132 LDD R19, Z+2
\r
545 \ 00000072 1702 CP R16, R18
\r
546 \ 00000074 0713 CPC R17, R19
\r
547 \ 00000076 F408 BRCC $+2+2
\r
548 \ 00000078 C059 RJMP ??HaltNow_1
\r
551 \ 0000007A 2477 CLR R7
\r
552 \ 0000007C 9473 INC R7
\r
553 \ 0000007E C056 RJMP ??HaltNow_1
\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 \ 00000080 01FC MOVW R31:R30, R25:R24
\r
564 \ 00000082 8502 LDD R16, Z+10
\r
565 \ 00000084 8513 LDD R17, Z+11
\r
566 \ 00000086 01FD MOVW R31:R30, R27:R26
\r
567 \ 00000088 8123 LDD R18, Z+3
\r
568 \ 0000008A 8134 LDD R19, Z+4
\r
570 \ 0000008C 1702 CP R16, R18
\r
571 \ 0000008E 0713 CPC R17, R19
\r
572 \ 00000090 F408 BRCC $+2+2
\r
573 \ 00000092 C04C RJMP ??HaltNow_1
\r
574 \ 00000094 CFF2 RJMP ??HaltNow_8
\r
580 273 // Has IBAT reached the minimum limit?
\r
581 274 case HALT_CURRENT_MIN:
\r
583 276 if (ADCS.avgIBAT <= HaltParameters.CurrentMin) {
\r
585 \ 00000096 01FD MOVW R31:R30, R27:R26
\r
586 \ 00000098 8105 LDD R16, Z+5
\r
587 \ 0000009A 8116 LDD R17, Z+6
\r
588 \ 0000009C 01FC MOVW R31:R30, R25:R24
\r
589 \ 0000009E 8926 LDD R18, Z+22
\r
590 \ 000000A0 8937 LDD R19, Z+23
\r
591 \ 000000A2 CFF4 RJMP ??HaltNow_9
\r
597 282 // Is the temperature rising too fast?
\r
598 283 case HALT_TEMPERATURE_RISE:
\r
600 285 // If rawNTC has increased, the temperature has dropped.
\r
601 286 // We can store this value for now, and start the timer.
\r
602 287 // Otherwise, check if NTC has changed too fast.
\r
603 288 if (ADCS.rawNTC > HaltParameters.LastNTC) {
\r
605 \ 000000A4 01FC MOVW R31:R30, R25:R24
\r
606 \ 000000A6 8104 LDD R16, Z+4
\r
607 \ 000000A8 8115 LDD R17, Z+5
\r
608 \ 000000AA 01FD MOVW R31:R30, R27:R26
\r
609 \ 000000AC 8487 LDD R8, Z+15
\r
610 \ 000000AE 8890 LDD R9, Z+16
\r
611 \ 000000B0 1680 CP R8, R16
\r
612 \ 000000B2 0691 CPC R9, R17
\r
613 \ 000000B4 F468 BRCC ??HaltNow_10
\r
614 289 HaltParameters.LastNTC = ADCS.rawNTC;
\r
616 \ 000000B6 01FC MOVW R31:R30, R25:R24
\r
617 \ 000000B8 8104 LDD R16, Z+4
\r
618 \ 000000BA 8115 LDD R17, Z+5
\r
619 \ 000000BC 01FD MOVW R31:R30, R27:R26
\r
620 \ 000000BE 8707 STD Z+15, R16
\r
621 \ 000000C0 8B10 STD Z+16, R17
\r
622 290 Time_Set(TIMER_TEMP,0,30,0);
\r
623 \ 000000C2 E040 LDI R20, 0
\r
624 \ 000000C4 E11E LDI R17, 30
\r
625 \ 000000C6 E020 LDI R18, 0
\r
626 \ 000000C8 E030 LDI R19, 0
\r
627 \ 000000CA E003 LDI R16, 3
\r
628 \ 000000CC .... RCALL Time_Set
\r
629 \ 000000CE C02E RJMP ??HaltNow_1
\r
631 292 // Is the increase in temperature greater than the set threshold?
\r
632 293 } else if ((HaltParameters.LastNTC - ADCS.rawNTC) >=
\r
633 294 (BattData.ADCSteps * HaltParameters.TemperatureRise)) {
\r
635 \ 000000D0 1A80 SUB R8, R16
\r
636 \ 000000D2 0A91 SBC R9, R17
\r
637 \ 000000D4 01F2 MOVW R31:R30, R5:R4
\r
638 \ 000000D6 8143 LDD R20, Z+3
\r
639 \ 000000D8 E050 LDI R21, 0
\r
640 \ 000000DA 01FD MOVW R31:R30, R27:R26
\r
641 \ 000000DC 8503 LDD R16, Z+11
\r
642 \ 000000DE 8514 LDD R17, Z+12
\r
643 \ 000000E0 .... RCALL ?S_MUL_L02
\r
644 \ 000000E2 1480 CP R8, R0
\r
645 \ 000000E4 0491 CPC R9, R1
\r
646 \ 000000E6 F110 BRCS ??HaltNow_1
\r
648 296 // If this happened within a timeframe of 30 seconds, the
\r
649 297 // temperature is rising faster than we want.
\r
650 298 // If not, update LastNTC and reset timer.
\r
651 299 if (Time_Left(TIMER_TEMP)) {
\r
652 \ 000000E8 E003 LDI R16, 3
\r
653 \ 000000EA .... RCALL Time_Left
\r
654 \ 000000EC 2300 TST R16
\r
655 \ 000000EE F629 BRNE ??HaltNow_8
\r
656 \ 000000F0 CFE2 RJMP ??HaltNow_11
\r
659 302 HaltParameters.LastNTC = ADCS.rawNTC;
\r
660 303 Time_Set(TIMER_TEMP,0,30,0);
\r
666 309 // Is there any time left?
\r
667 310 case HALT_TIME:
\r
669 312 if (!Time_Left(TIMER_CHG)) {
\r
671 \ 000000F2 E001 LDI R16, 1
\r
672 \ 000000F4 .... RCALL Time_Left
\r
673 \ 000000F6 2300 TST R16
\r
674 \ 000000F8 F4C9 BRNE ??HaltNow_1
\r
676 \ 000000FA 2477 CLR R7
\r
677 \ 000000FC 9473 INC R7
\r
679 315 // If exhaustion flagging is selected, stop the PWM, disable the
\r
680 316 // battery and flag it as exhausted. Make ST_ERROR next state.
\r
681 317 if (HaltParameters.HaltFlags & HALT_FLAG_EXHAUSTION) {
\r
682 \ 000000FE 910C LD R16, X
\r
683 \ 00000100 FF05 SBRS R16, 5
\r
684 \ 00000102 C014 RJMP ??HaltNow_1
\r
686 \ 00000104 .... RCALL PWM_Stop
\r
687 319 BattControl[BattActive].Enabled = FALSE;
\r
688 \ 00000106 9100.... LDS R16, BattActive
\r
689 \ 0000010A E010 LDI R17, 0
\r
690 \ 0000010C .... LDI R20, LOW(BattControl)
\r
691 \ 0000010E .... LDI R21, (BattControl) >> 8
\r
692 \ 00000110 0F40 ADD R20, R16
\r
693 \ 00000112 1F51 ADC R21, R17
\r
694 \ 00000114 .... RCALL __eeget8_16
\r
695 \ 00000116 7F0E ANDI R16, 0xFE
\r
696 \ 00000118 .... RCALL __eeput8_16
\r
697 320 BattData.Exhausted = TRUE;
\r
698 \ 0000011A 01F2 MOVW R31:R30, R5:R4
\r
699 \ 0000011C 8100 LD R16, Z
\r
700 \ 0000011E 6008 ORI R16, 0x08
\r
701 \ 00000120 8300 ST Z, R16
\r
702 321 SetErrorFlag(ERR_BATTERY_EXHAUSTED);
\r
703 \ 00000122 E100 LDI R16, 16
\r
704 \ 00000124 .... RCALL SetErrorFlag
\r
705 322 ChargeParameters.NextState = ST_ERROR;
\r
706 \ 00000126 E50A LDI R16, 90
\r
707 \ 00000128 01FD MOVW R31:R30, R27:R26
\r
708 \ 0000012A 8B05 STD Z+21, R16
\r
714 328 default: // Shouldn't end up here, but is needed for MISRA compliance.
\r
720 \ 0000012C 0C66 LSL R6
\r
721 \ 0000012E F009 BREQ $+2+2
\r
722 \ 00000130 CF7D RJMP ??HaltNow_0
\r
724 334 // Standard checks:
\r
726 336 // Battery too cold or hot?
\r
727 337 if ((BattData.Temperature <= HaltParameters.TemperatureMin) ||
\r
728 338 (BattData.Temperature >= HaltParameters.TemperatureMax)) {
\r
729 \ 00000132 .... LDI R30, LOW(BattData)
\r
730 \ 00000134 .... LDI R31, (BattData) >> 8
\r
731 \ 00000136 8102 LDD R16, Z+2
\r
732 \ 00000138 01FD MOVW R31:R30, R27:R26
\r
733 \ 0000013A 8521 LDD R18, Z+9
\r
734 \ 0000013C 8532 LDD R19, Z+10
\r
735 \ 0000013E 2F10 MOV R17, R16
\r
736 \ 00000140 0F11 LSL R17
\r
737 \ 00000142 0B11 SBC R17, R17
\r
738 \ 00000144 1720 CP R18, R16
\r
739 \ 00000146 0731 CPC R19, R17
\r
740 \ 00000148 F444 BRGE ??HaltNow_12
\r
741 \ 0000014A 2F10 MOV R17, R16
\r
742 \ 0000014C 0F11 LSL R17
\r
743 \ 0000014E 0B11 SBC R17, R17
\r
744 \ 00000150 8127 LDD R18, Z+7
\r
745 \ 00000152 8530 LDD R19, Z+8
\r
746 \ 00000154 1702 CP R16, R18
\r
747 \ 00000156 0713 CPC R17, R19
\r
748 \ 00000158 F040 BRCS ??HaltNow_13
\r
752 \ 0000015A .... RCALL PWM_Stop
\r
753 341 SetErrorFlag(ERR_BATTERY_TEMPERATURE);
\r
754 \ 0000015C E008 LDI R16, 8
\r
755 \ 0000015E .... RCALL SetErrorFlag
\r
756 342 ChargeParameters.NextState = ST_ERROR;
\r
757 \ 00000160 E50A LDI R16, 90
\r
758 \ 00000162 01FD MOVW R31:R30, R27:R26
\r
759 \ 00000164 8B05 STD Z+21, R16
\r
761 \ 00000166 2477 CLR R7
\r
762 \ 00000168 9473 INC R7
\r
765 346 // Battery not OK?
\r
766 347 if (!BatteryCheck()) {
\r
768 \ 0000016A .... RCALL BatteryCheck
\r
769 \ 0000016C 2300 TST R16
\r
770 \ 0000016E F431 BRNE ??HaltNow_14
\r
772 \ 00000170 .... RCALL PWM_Stop
\r
773 349 ChargeParameters.NextState = ST_INIT;
\r
774 \ 00000172 E00A LDI R16, 10
\r
775 \ 00000174 01FD MOVW R31:R30, R27:R26
\r
776 \ 00000176 8B05 STD Z+21, R16
\r
778 \ 00000178 2477 CLR R7
\r
779 \ 0000017A 9473 INC R7
\r
782 353 // Is mains voltage OK?
\r
783 354 if (!ADCS.Mains) {
\r
785 \ 0000017C 9100.... LDS R16, ADCS
\r
786 \ 00000180 FD06 SBRC R16, 6
\r
787 \ 00000182 C006 RJMP ??HaltNow_15
\r
789 \ 00000184 .... RCALL PWM_Stop
\r
790 356 ChargeParameters.NextState = ST_SLEEP;
\r
791 \ 00000186 E208 LDI R16, 40
\r
792 \ 00000188 01FD MOVW R31:R30, R27:R26
\r
793 \ 0000018A 8B05 STD Z+21, R16
\r
795 \ 0000018C 2477 CLR R7
\r
796 \ 0000018E 9473 INC R7
\r
801 \ 00000190 2D07 MOV R16, R7
\r
802 \ 00000192 9189 LD R24, Y+
\r
803 \ 00000194 9199 LD R25, Y+
\r
804 \ 00000196 91A9 LD R26, Y+
\r
805 \ 00000198 91B9 LD R27, Y+
\r
806 \ 0000019A 9049 LD R4, Y+
\r
807 \ 0000019C 9059 LD R5, Y+
\r
808 \ 0000019E 9069 LD R6, Y+
\r
809 \ 000001A0 9079 LD R7, Y+
\r
810 \ 000001A2 9089 LD R8, Y+
\r
811 \ 000001A4 9099 LD R9, Y+
\r
812 \ 000001A6 9508 RET
\r
815 Maximum stack usage in bytes:
\r
817 Function CSTACK RSTACK
\r
818 -------- ------ ------
\r
819 ConstantCurrent 6 4
\r
823 -> PWM_IncrementDutyCycle 6 2
\r
824 -> SetErrorFlag 6 2
\r
825 -> PWM_DecrementDutyCycle 6 2
\r
827 ConstantVoltage 4 4
\r
831 -> PWM_IncrementDutyCycle 4 2
\r
832 -> SetErrorFlag 4 2
\r
833 -> PWM_DecrementDutyCycle 4 2
\r
841 -> SetErrorFlag 10 2
\r
843 -> SetErrorFlag 10 2
\r
844 -> BatteryCheck 10 2
\r
849 Segment part sizes:
\r
851 Function/Label Bytes
\r
852 -------------- -----
\r
855 ConstantCurrent 152
\r
856 ConstantVoltage 140
\r
861 1 byte in segment ABSOLUTE
\r
862 716 bytes in segment CODE
\r
863 6 bytes in segment INITTAB
\r
864 22 bytes in segment NEAR_Z
\r
866 716 bytes of CODE memory (+ 6 bytes shared)
\r
867 22 bytes of DATA memory (+ 1 byte shared)
\r