############################################################################### # # # IAR Atmel AVR C/C++ Compiler V4.30F/W32 12/Mar/2008 23:01:39 # # Copyright 1996-2007 IAR Systems. All rights reserved. # # # # Source file = C:\home\kevin\pub\src\bc100_cal\IAR\chargefunc.c # # Command line = C:\home\kevin\pub\src\bc100_cal\IAR\chargefunc.c # # --cpu=tiny861 -ms -o C:\home\kevin\pub\src\bc100_cal\IAR # # \Debug\Obj\ -lC C:\home\kevin\pub\src\bc100_cal\IAR\Debu # # g\List\ -lB C:\home\kevin\pub\src\bc100_cal\IAR\Debug\Li # # st\ --initializers_in_flash -z2 --no_cse --no_inline # # --no_code_motion --no_cross_call --no_clustering # # --no_tbaa --debug -DENABLE_BIT_DEFINITIONS -e # # --require_prototypes -I "C:\Program Files\IAR # # Systems\Embedded Workbench 4.0\avr\INC\" -I "C:\Program # # Files\IAR Systems\Embedded Workbench 4.0\avr\INC\CLIB\" # # --eeprom_size 512 # # List file = C:\home\kevin\pub\src\bc100_cal\IAR\Debug\List\chargefun # # c.lst # # Object file = C:\home\kevin\pub\src\bc100_cal\IAR\Debug\Obj\chargefunc # # .r90 # # # # # ############################################################################### C:\home\kevin\pub\src\bc100_cal\IAR\chargefunc.c 1 /* This file has been prepared for Doxygen automatic documentation generation.*/ 2 /*! \file ********************************************************************* 3 * 4 * \brief 5 * Charge functions 6 * 7 * Contains the functions for charging with constant current and voltage, 8 * and for deciding when to halt. 9 * 10 * \par Application note: 11 * AVR458: Charging Li-Ion Batteries with BC100 \n 12 * AVR463: Charging NiMH Batteries with BC100 13 * 14 * \par Documentation 15 * For comprehensive code documentation, supported compilers, compiler 16 * settings and supported devices see readme.html 17 * 18 * \author 19 * Atmel Corporation: http://www.atmel.com \n 20 * Support email: avr@atmel.com 21 * 22 * 23 * $Name$ 24 * $Revision: 2299 $ 25 * $RCSfile$ 26 * $URL: http://svn.norway.atmel.com/AppsAVR8/avr458_Charging_Li-Ion_Batteries_with_BC100/tag/20070904_release_1.0/code/IAR/chargefunc.c $ 27 * $Date: 2007-08-23 12:55:51 +0200 (to, 23 aug 2007) $\n 28 ******************************************************************************/ 29 30 #include \ In segment ABSOLUTE, at 0x4c \ volatile __io _A_OCR1B \ _A_OCR1B: \ 00000000 DS 1 31 32 #include "enums.h" 33 #include "structs.h" 34 35 #include "ADC.h" 36 #include "battery.h" 37 #include "chargefunc.h" 38 #include "main.h" 39 #include "menu.h" 40 #include "PWM.h" 41 #include "statefunc.h" 42 #include "time.h" 43 44 #ifdef NIMH 45 #include "NIMHspecs.h" 46 #endif // NIMH 47 48 #ifdef LIION 49 #include "LIIONspecs.h" 50 #endif // LIION 51 52 53 //****************************************************************************** 54 // Variables 55 //****************************************************************************** 56 //! Struct that holds parameters for ConstantCurrent() and ConstantVoltage(). \ In segment NEAR_Z, align 1, keep-with-next \ 00000000 REQUIRE `?` 57 ChargeParameters_t ChargeParameters; \ ChargeParameters: \ 00000000 DS 5 58 59 //! Struct that holds parameters for HaltNow(). \ In segment NEAR_Z, align 1, keep-with-next \ 00000000 REQUIRE `?` 60 HaltParameters_t HaltParameters; \ HaltParameters: \ 00000000 DS 17 61 62 63 //****************************************************************************** 64 // Functions 65 //****************************************************************************** 66 /*! \brief Charges battery with a constant current. 67 * 68 * This function applies a constant current (set in ChargeParameters.Current) 69 * to the battery until HaltNow() returns TRUE, or a PWM error occurs and 70 * \ref ABORT_IF_PWM_MIN or \ref ABORT_IF_PWM_MAX is defined.\n 71 * The charge current can vary with +/- \ref BAT_CURRENT_HYST.\n 72 * If the Master inhibits charging, timers are stopped and PWM output dropped. 73 * Once the battery is no longer flagged for charge inhibit, timers are 74 * started again and charging resumed. 75 * 76 * \retval ChargeParameters.NextState Next state once this stage is done. 77 * If no errors occured, this will be whatever was set in Charge(). Otherwise, 78 * HaltNow() will have set a new next state. 79 */ \ In segment CODE, align 2, keep-with-next 80 unsigned char ConstantCurrent(void) \ ConstantCurrent: 81 { \ 00000000 .... RCALL ?PROLOGUE4_L09 82 unsigned char error = FALSE, \ 00000002 E080 LDI R24, 0 83 wasStopped = FALSE; \ 00000004 E090 LDI R25, 0 84 85 do { 86 // Wait for ADC conversions to complete. 87 ADC_Wait(); \ ??ConstantCurrent_0: \ 00000006 .... RCALL ADC_Wait 88 89 // If Master has flagged for a charge inhibit, pause charging. 90 // (This is to prevent damage during prolonged serial communication.) 91 if (BattControl[BattActive].ChargeInhibit) { \ 00000008 9100.... LDS R16, BattActive \ 0000000C E010 LDI R17, 0 \ 0000000E .... LDI R20, LOW(BattControl) \ 00000010 .... LDI R21, (BattControl) >> 8 \ 00000012 0F40 ADD R20, R16 \ 00000014 1F51 ADC R21, R17 \ 00000016 .... RCALL __eeget8_16 \ 00000018 7004 ANDI R16, 0x04 \ 0000001A 2300 TST R16 \ 0000001C F029 BREQ ??ConstantCurrent_1 92 wasStopped = TRUE; \ 0000001E E091 LDI R25, 1 93 Time_Stop(); \ 00000020 .... RCALL Time_Stop 94 OCR1B = 0; \ 00000022 E000 LDI R16, 0 \ 00000024 BD0C OUT 0x2C, R16 \ 00000026 C03C RJMP ??ConstantCurrent_2 95 } else { 96 // Continue charging! 97 if (wasStopped) { \ ??ConstantCurrent_1: \ 00000028 2399 TST R25 \ 0000002A F011 BREQ ??ConstantCurrent_3 98 wasStopped = FALSE; \ 0000002C E090 LDI R25, 0 99 100 // Timer variables are not reset by this. 101 Time_Start(); \ 0000002E .... RCALL Time_Start 102 } 103 104 // Adjust the charge current to within ChargeParameters.Current 105 // +/- BAT_CURRENT_HYST. 106 if ((ADCS.avgIBAT < 0) || 107 (ADCS.avgIBAT < (ChargeParameters.Current - BAT_CURRENT_HYST))) { \ ??ConstantCurrent_3: \ 00000030 .... LDI R30, LOW(ADCS) \ 00000032 .... LDI R31, (ADCS) >> 8 \ 00000034 8906 LDD R16, Z+22 \ 00000036 8917 LDD R17, Z+23 \ 00000038 2311 TST R17 \ 0000003A F06A BRMI ??ConstantCurrent_4 \ 0000003C .... LDI R30, LOW(ADCS) \ 0000003E .... LDI R31, (ADCS) >> 8 \ 00000040 8926 LDD R18, Z+22 \ 00000042 8937 LDD R19, Z+23 \ 00000044 .... LDI R30, LOW(ChargeParameters) \ 00000046 .... LDI R31, (ChargeParameters) >> 8 \ 00000048 8102 LDD R16, Z+2 \ 0000004A 8113 LDD R17, Z+3 \ 0000004C 5003 SUBI R16, 3 \ 0000004E 4010 SBCI R17, 0 \ 00000050 1720 CP R18, R16 \ 00000052 0731 CPC R19, R17 \ 00000054 F450 BRCC ??ConstantCurrent_5 108 109 if(!PWM_IncrementDutyCycle()) { \ ??ConstantCurrent_4: \ 00000056 .... RCALL PWM_IncrementDutyCycle \ 00000058 2300 TST R16 \ 0000005A F511 BRNE ??ConstantCurrent_2 110 #ifdef ABORT_IF_PWM_MAX 111 // If the duty cycle cannot be incremented, flag error and 112 // go to error state. 113 SetErrorFlag(ERR_PWM_CONTROL); \ 0000005C E004 LDI R16, 4 \ 0000005E .... RCALL SetErrorFlag 114 ChargeParameters.NextState = ST_ERROR; \ 00000060 E50A LDI R16, 90 \ 00000062 9300.... STS (ChargeParameters + 4), R16 115 error = TRUE; \ 00000066 E081 LDI R24, 1 \ 00000068 C01B RJMP ??ConstantCurrent_2 116 #endif 117 } 118 } else if ((ADCS.avgIBAT >= 0) && 119 (ADCS.avgIBAT > (ChargeParameters.Current + BAT_CURRENT_HYST))) { \ ??ConstantCurrent_5: \ 0000006A .... LDI R30, LOW(ADCS) \ 0000006C .... LDI R31, (ADCS) >> 8 \ 0000006E 8906 LDD R16, Z+22 \ 00000070 8917 LDD R17, Z+23 \ 00000072 2311 TST R17 \ 00000074 F0AA BRMI ??ConstantCurrent_2 \ 00000076 .... LDI R30, LOW(ChargeParameters) \ 00000078 .... LDI R31, (ChargeParameters) >> 8 \ 0000007A 81A2 LDD R26, Z+2 \ 0000007C 81B3 LDD R27, Z+3 \ 0000007E 9613 ADIW R27:R26, 3 \ 00000080 .... LDI R30, LOW(ADCS) \ 00000082 .... LDI R31, (ADCS) >> 8 \ 00000084 8906 LDD R16, Z+22 \ 00000086 8917 LDD R17, Z+23 \ 00000088 17A0 CP R26, R16 \ 0000008A 07B1 CPC R27, R17 \ 0000008C F448 BRCC ??ConstantCurrent_2 120 121 if(!PWM_DecrementDutyCycle()) { \ 0000008E .... RCALL PWM_DecrementDutyCycle \ 00000090 2300 TST R16 \ 00000092 F431 BRNE ??ConstantCurrent_2 122 #ifdef ABORT_IF_PWM_MIN 123 // If the duty cycle cannot be decremented, flag error and 124 // go to error state. 125 SetErrorFlag(ERR_PWM_CONTROL); \ 00000094 E004 LDI R16, 4 \ 00000096 .... RCALL SetErrorFlag 126 ChargeParameters.NextState = ST_ERROR; \ 00000098 E50A LDI R16, 90 \ 0000009A 9300.... STS (ChargeParameters + 4), R16 127 error = TRUE; \ 0000009E E081 LDI R24, 1 128 #endif 129 } 130 } 131 } 132 } while (!HaltNow() && !error); \ ??ConstantCurrent_2: \ 000000A0 .... RCALL HaltNow \ 000000A2 2300 TST R16 \ 000000A4 F419 BRNE ??ConstantCurrent_6 \ 000000A6 2388 TST R24 \ 000000A8 F409 BRNE $+2+2 \ 000000AA CFAD RJMP ??ConstantCurrent_0 133 134 // Return the next state to Charge(). If an error has occured, this will 135 // point to some other state than the next state of charging. 136 return(ChargeParameters.NextState); \ ??ConstantCurrent_6: \ 000000AC 9100.... LDS R16, (ChargeParameters + 4) \ 000000B0 E0E4 LDI R30, 4 \ 000000B2 .... RJMP ?EPILOGUE_B4_L09 \ 000000B4 REQUIRE _A_OCR1B 137 } 138 139 140 /*! \brief Charges battery with a constant voltage 141 * 142 * This function applies a constant voltage (set in ChargeParameters.Voltage) 143 * to the battery until HaltNow() returns TRUE, or a PWM error occurs and 144 * \ref ABORT_IF_PWM_MIN or \ref ABORT_IF_PWM_MAX is defined.\n 145 * The charge voltage can vary with +/- \ref BAT_VOLTAGE_HYST.\n 146 * If the Master inhibits charging, timers are stopped and PWM output dropped. 147 * Once the battery is no longer flagged for charge inhibit, timers are 148 * started again and charging resumed. 149 * 150 * \retval ChargeParameters.NextState Next state once this stage is done. 151 * If no errors occured, this will be whatever was set in Charge(). Otherwise, 152 * HaltNow() will have set a new next state. 153 */ \ In segment CODE, align 2, keep-with-next 154 unsigned char ConstantVoltage(void) \ ConstantVoltage: 155 { \ 00000000 .... RCALL ?PROLOGUE4_L09 156 unsigned char error = FALSE, \ 00000002 E080 LDI R24, 0 157 wasStopped = FALSE; \ 00000004 E090 LDI R25, 0 158 159 do{ 160 161 // Wait for ADC conversions to complete. 162 ADC_Wait(); \ ??ConstantVoltage_0: \ 00000006 .... RCALL ADC_Wait 163 164 // If Master has flagged for a charge inhibit, pause charging. 165 // (This is to prevent damage during prolonged serial communication.) 166 if (BattControl[BattActive].ChargeInhibit) { \ 00000008 9100.... LDS R16, BattActive \ 0000000C E010 LDI R17, 0 \ 0000000E .... LDI R20, LOW(BattControl) \ 00000010 .... LDI R21, (BattControl) >> 8 \ 00000012 0F40 ADD R20, R16 \ 00000014 1F51 ADC R21, R17 \ 00000016 .... RCALL __eeget8_16 \ 00000018 7004 ANDI R16, 0x04 \ 0000001A 2300 TST R16 \ 0000001C F029 BREQ ??ConstantVoltage_1 167 wasStopped = TRUE; \ 0000001E E091 LDI R25, 1 168 Time_Stop(); \ 00000020 .... RCALL Time_Stop 169 OCR1B = 0; \ 00000022 E000 LDI R16, 0 \ 00000024 BD0C OUT 0x2C, R16 \ 00000026 C030 RJMP ??ConstantVoltage_2 170 } 171 172 else { 173 // Continue charging! 174 if (wasStopped) { \ ??ConstantVoltage_1: \ 00000028 2399 TST R25 \ 0000002A F011 BREQ ??ConstantVoltage_3 175 wasStopped = FALSE; \ 0000002C E090 LDI R25, 0 176 177 // Timer variables aren't reset by this. 178 Time_Start(); \ 0000002E .... RCALL Time_Start 179 } 180 181 // Adjust the charge voltage to within ChargeParameters.Voltage 182 // +/- BAT_VOLTAGE_HYST. 183 if (ADCS.VBAT < (ChargeParameters.Voltage - BAT_VOLTAGE_HYST)) { \ ??ConstantVoltage_3: \ 00000030 .... LDI R30, LOW(ADCS) \ 00000032 .... LDI R31, (ADCS) >> 8 \ 00000034 8522 LDD R18, Z+10 \ 00000036 8533 LDD R19, Z+11 \ 00000038 .... LDI R30, LOW(ChargeParameters) \ 0000003A .... LDI R31, (ChargeParameters) >> 8 \ 0000003C 8100 LD R16, Z \ 0000003E 8111 LDD R17, Z+1 \ 00000040 500A SUBI R16, 10 \ 00000042 4010 SBCI R17, 0 \ 00000044 1720 CP R18, R16 \ 00000046 0731 CPC R19, R17 \ 00000048 F450 BRCC ??ConstantVoltage_4 184 185 if(!PWM_IncrementDutyCycle()) { \ 0000004A .... RCALL PWM_IncrementDutyCycle \ 0000004C 2300 TST R16 \ 0000004E F4E1 BRNE ??ConstantVoltage_2 186 #ifdef ABORT_IF_PWM_MAX 187 // Flag PWM control error and go to error-state if the duty 188 // cycle cannot be incremented. 189 SetErrorFlag(ERR_PWM_CONTROL); \ 00000050 E004 LDI R16, 4 \ 00000052 .... RCALL SetErrorFlag 190 ChargeParameters.NextState = ST_ERROR; \ 00000054 E50A LDI R16, 90 \ 00000056 9300.... STS (ChargeParameters + 4), R16 191 error = TRUE; \ 0000005A E081 LDI R24, 1 \ 0000005C C015 RJMP ??ConstantVoltage_2 192 #endif 193 } 194 } else if (ADCS.VBAT > (ChargeParameters.Voltage + BAT_VOLTAGE_HYST)) { \ ??ConstantVoltage_4: \ 0000005E .... LDI R30, LOW(ChargeParameters) \ 00000060 .... LDI R31, (ChargeParameters) >> 8 \ 00000062 81A0 LD R26, Z \ 00000064 81B1 LDD R27, Z+1 \ 00000066 961A ADIW R27:R26, 10 \ 00000068 .... LDI R30, LOW(ADCS) \ 0000006A .... LDI R31, (ADCS) >> 8 \ 0000006C 8502 LDD R16, Z+10 \ 0000006E 8513 LDD R17, Z+11 \ 00000070 17A0 CP R26, R16 \ 00000072 07B1 CPC R27, R17 \ 00000074 F448 BRCC ??ConstantVoltage_2 195 196 if(!PWM_DecrementDutyCycle()) { \ 00000076 .... RCALL PWM_DecrementDutyCycle \ 00000078 2300 TST R16 \ 0000007A F431 BRNE ??ConstantVoltage_2 197 #ifdef ABORT_IF_PWM_MIN 198 // Flag PWM control error and go to error-state if duty 199 // cycle cannot be decremented. 200 SetErrorFlag(ERR_PWM_CONTROL); \ 0000007C E004 LDI R16, 4 \ 0000007E .... RCALL SetErrorFlag 201 ChargeParameters.NextState = ST_ERROR; \ 00000080 E50A LDI R16, 90 \ 00000082 9300.... STS (ChargeParameters + 4), R16 202 error = TRUE; \ 00000086 E081 LDI R24, 1 203 #endif 204 } 205 } 206 } 207 208 } while (!HaltNow() && !error); \ ??ConstantVoltage_2: \ 00000088 .... RCALL HaltNow \ 0000008A 2300 TST R16 \ 0000008C F419 BRNE ??ConstantVoltage_5 \ 0000008E 2388 TST R24 \ 00000090 F409 BRNE $+2+2 \ 00000092 CFB9 RJMP ??ConstantVoltage_0 209 210 // Return the next state to Charge(). If an error has occured, this will 211 // point to some other state than the next state of charging. 212 return(ChargeParameters.NextState); \ ??ConstantVoltage_5: \ 00000094 9100.... LDS R16, (ChargeParameters + 4) \ 00000098 E0E4 LDI R30, 4 \ 0000009A .... RJMP ?EPILOGUE_B4_L09 \ 0000009C REQUIRE _A_OCR1B 213 } 214 215 216 /*! \brief Determines when to halt charging. 217 * 218 * This function evaluates parameters depending on what has been flagged in 219 * HaltParameters.HaltFlags, and returns TRUE or FALSE if the charging should 220 * halt or not.\n 221 * In addition, error flagging on timeout (battery exhaustion) can be set.\n 222 * 223 * The function also checks if the battery temperature is within limits, 224 * if mains is OK, and if BatteryCheck() returns TRUE. 225 * If an error is detected, the associated errorflag is set and 226 * ChargeParameters.NextState is changed to an appropriate state. 227 * 228 * \retval TRUE Halt now. 229 * \retval FALSE Don't halt now. 230 * 231 * \note See chargefunc.h for definitions of halt flags. 232 * \note It is generally a bad idea not to halt on a timeout. 233 * \note If HALT_ON_VOLTAGE_DROP is set, HaltParameters.VBATMax should be 234 * reset in Charge() before calling a charging-function. 235 * 236 * \todo "Priorities" of standard error checks OK? 237 */ \ In segment CODE, align 2, keep-with-next 238 unsigned char HaltNow(void) \ HaltNow: 239 { \ 00000000 .... RCALL ?PROLOGUE4_L09 240 unsigned char i, halt = FALSE; \ 00000002 E080 LDI R24, 0 241 242 // Wait for a full ADC-cycle to finish. 243 ADC_Wait(); \ 00000004 .... RCALL ADC_Wait 244 245 // Evaluate ADC readings according to HaltFlags. Flag errors if selected. 246 // If an error is flagged, ChargeParameters.NextState is set to ST_ERROR. 247 // (Gets overridden if either mains is failing, or the battery changes.) 248 for (i = 0x01; i != 0; i <<= 1) { \ 00000006 E091 LDI R25, 1 \ ??HaltNow_0: \ 00000008 2399 TST R25 \ 0000000A F409 BRNE $+2+2 \ 0000000C C0C4 RJMP ??HaltNow_1 249 if (HaltParameters.HaltFlags & i) { \ 0000000E 9100.... LDS R16, HaltParameters \ 00000012 2309 AND R16, R25 \ 00000014 2300 TST R16 \ 00000016 F409 BRNE $+2+2 \ 00000018 C0BC RJMP ??HaltNow_2 250 switch (i) { \ 0000001A 2F09 MOV R16, R25 \ 0000001C 5001 SUBI R16, 1 \ 0000001E F059 BREQ ??HaltNow_3 \ 00000020 950A DEC R16 \ 00000022 F189 BREQ ??HaltNow_4 \ 00000024 5002 SUBI R16, 2 \ 00000026 F1E9 BREQ ??HaltNow_5 \ 00000028 5004 SUBI R16, 4 \ 0000002A F409 BRNE $+2+2 \ 0000002C C048 RJMP ??HaltNow_6 \ 0000002E 5008 SUBI R16, 8 \ 00000030 F409 BRNE $+2+2 \ 00000032 C089 RJMP ??HaltNow_7 \ 00000034 C0AE RJMP ??HaltNow_2 251 // Is VBAT less than the recorded maximum? 252 case HALT_VOLTAGE_DROP: 253 254 // Update VBATMax if VBAT is higher. Evaluate for halt otherwise. 255 if (ADCS.VBAT > HaltParameters.VBATMax) { \ ??HaltNow_3: \ 00000036 .... LDI R30, LOW(HaltParameters) \ 00000038 .... LDI R31, (HaltParameters) >> 8 \ 0000003A 8505 LDD R16, Z+13 \ 0000003C 8516 LDD R17, Z+14 \ 0000003E .... LDI R30, LOW(ADCS) \ 00000040 .... LDI R31, (ADCS) >> 8 \ 00000042 8522 LDD R18, Z+10 \ 00000044 8533 LDD R19, Z+11 \ 00000046 1702 CP R16, R18 \ 00000048 0713 CPC R17, R19 \ 0000004A F448 BRCC ??HaltNow_8 256 HaltParameters.VBATMax = ADCS.VBAT; \ 0000004C .... LDI R30, LOW(ADCS) \ 0000004E .... LDI R31, (ADCS) >> 8 \ 00000050 8502 LDD R16, Z+10 \ 00000052 8513 LDD R17, Z+11 \ 00000054 .... LDI R30, LOW(HaltParameters) \ 00000056 .... LDI R31, (HaltParameters) >> 8 \ 00000058 8705 STD Z+13, R16 \ 0000005A 8716 STD Z+14, R17 \ 0000005C C09A RJMP ??HaltNow_2 257 } else if((HaltParameters.VBATMax - ADCS.VBAT) >= 258 HaltParameters.VoltageDrop) { \ ??HaltNow_8: \ 0000005E .... LDI R30, LOW(HaltParameters) \ 00000060 .... LDI R31, (HaltParameters) >> 8 \ 00000062 8505 LDD R16, Z+13 \ 00000064 8516 LDD R17, Z+14 \ 00000066 .... LDI R30, LOW(ADCS) \ 00000068 .... LDI R31, (ADCS) >> 8 \ 0000006A 8522 LDD R18, Z+10 \ 0000006C 8533 LDD R19, Z+11 \ 0000006E 1B02 SUB R16, R18 \ 00000070 0B13 SBC R17, R19 \ 00000072 .... LDI R30, LOW(HaltParameters) \ 00000074 .... LDI R31, (HaltParameters) >> 8 \ 00000076 8121 LDD R18, Z+1 \ 00000078 8132 LDD R19, Z+2 \ 0000007A 1702 CP R16, R18 \ 0000007C 0713 CPC R17, R19 \ 0000007E F408 BRCC $+2+2 \ 00000080 C088 RJMP ??HaltNow_2 259 halt = TRUE; \ 00000082 E081 LDI R24, 1 \ 00000084 C086 RJMP ??HaltNow_2 260 } 261 break; 262 263 264 // Has VBAT reached the maximum limit? 265 case HALT_VOLTAGE_MAX: 266 267 if (ADCS.VBAT >= HaltParameters.VoltageMax) { \ ??HaltNow_4: \ 00000086 .... LDI R30, LOW(ADCS) \ 00000088 .... LDI R31, (ADCS) >> 8 \ 0000008A 8502 LDD R16, Z+10 \ 0000008C 8513 LDD R17, Z+11 \ 0000008E .... LDI R30, LOW(HaltParameters) \ 00000090 .... LDI R31, (HaltParameters) >> 8 \ 00000092 8123 LDD R18, Z+3 \ 00000094 8134 LDD R19, Z+4 \ 00000096 1702 CP R16, R18 \ 00000098 0713 CPC R17, R19 \ 0000009A F408 BRCC $+2+2 \ 0000009C C07A RJMP ??HaltNow_2 268 halt = TRUE; \ 0000009E E081 LDI R24, 1 \ 000000A0 C078 RJMP ??HaltNow_2 269 } 270 break; 271 272 273 // Has IBAT reached the minimum limit? 274 case HALT_CURRENT_MIN: 275 276 if (ADCS.avgIBAT <= HaltParameters.CurrentMin) { \ ??HaltNow_5: \ 000000A2 .... LDI R30, LOW(HaltParameters) \ 000000A4 .... LDI R31, (HaltParameters) >> 8 \ 000000A6 8105 LDD R16, Z+5 \ 000000A8 8116 LDD R17, Z+6 \ 000000AA .... LDI R30, LOW(ADCS) \ 000000AC .... LDI R31, (ADCS) >> 8 \ 000000AE 8926 LDD R18, Z+22 \ 000000B0 8937 LDD R19, Z+23 \ 000000B2 1702 CP R16, R18 \ 000000B4 0713 CPC R17, R19 \ 000000B6 F408 BRCC $+2+2 \ 000000B8 C06C RJMP ??HaltNow_2 277 halt = TRUE; \ 000000BA E081 LDI R24, 1 \ 000000BC C06A RJMP ??HaltNow_2 278 } 279 break; 280 281 282 // Is the temperature rising too fast? 283 case HALT_TEMPERATURE_RISE: 284 285 // If rawNTC has increased, the temperature has dropped. 286 // We can store this value for now, and start the timer. 287 // Otherwise, check if NTC has changed too fast. 288 if (ADCS.rawNTC > HaltParameters.LastNTC) { \ ??HaltNow_6: \ 000000BE .... LDI R30, LOW(HaltParameters) \ 000000C0 .... LDI R31, (HaltParameters) >> 8 \ 000000C2 8507 LDD R16, Z+15 \ 000000C4 8910 LDD R17, Z+16 \ 000000C6 .... LDI R30, LOW(ADCS) \ 000000C8 .... LDI R31, (ADCS) >> 8 \ 000000CA 8124 LDD R18, Z+4 \ 000000CC 8135 LDD R19, Z+5 \ 000000CE 1702 CP R16, R18 \ 000000D0 0713 CPC R17, R19 \ 000000D2 F478 BRCC ??HaltNow_9 289 HaltParameters.LastNTC = ADCS.rawNTC; \ 000000D4 .... LDI R30, LOW(ADCS) \ 000000D6 .... LDI R31, (ADCS) >> 8 \ 000000D8 8104 LDD R16, Z+4 \ 000000DA 8115 LDD R17, Z+5 \ 000000DC .... LDI R30, LOW(HaltParameters) \ 000000DE .... LDI R31, (HaltParameters) >> 8 \ 000000E0 8707 STD Z+15, R16 \ 000000E2 8B10 STD Z+16, R17 290 Time_Set(TIMER_TEMP,0,30,0); \ 000000E4 E040 LDI R20, 0 \ 000000E6 E11E LDI R17, 30 \ 000000E8 E020 LDI R18, 0 \ 000000EA E030 LDI R19, 0 \ 000000EC E003 LDI R16, 3 \ 000000EE .... RCALL Time_Set \ 000000F0 C050 RJMP ??HaltNow_2 291 292 // Is the increase in temperature greater than the set threshold? 293 } else if ((HaltParameters.LastNTC - ADCS.rawNTC) >= 294 (BattData.ADCSteps * HaltParameters.TemperatureRise)) { \ ??HaltNow_9: \ 000000F2 .... LDI R30, LOW(HaltParameters) \ 000000F4 .... LDI R31, (HaltParameters) >> 8 \ 000000F6 85A7 LDD R26, Z+15 \ 000000F8 89B0 LDD R27, Z+16 \ 000000FA .... LDI R30, LOW(ADCS) \ 000000FC .... LDI R31, (ADCS) >> 8 \ 000000FE 8104 LDD R16, Z+4 \ 00000100 8115 LDD R17, Z+5 \ 00000102 1BA0 SUB R26, R16 \ 00000104 0BB1 SBC R27, R17 \ 00000106 9140.... LDS R20, (BattData + 3) \ 0000010A E050 LDI R21, 0 \ 0000010C .... LDI R30, LOW(HaltParameters) \ 0000010E .... LDI R31, (HaltParameters) >> 8 \ 00000110 8503 LDD R16, Z+11 \ 00000112 8514 LDD R17, Z+12 \ 00000114 .... RCALL ?S_MUL_L02 \ 00000116 17A0 CP R26, R16 \ 00000118 07B1 CPC R27, R17 \ 0000011A F1D8 BRCS ??HaltNow_2 295 296 // If this happened within a timeframe of 30 seconds, the 297 // temperature is rising faster than we want. 298 // If not, update LastNTC and reset timer. 299 if (Time_Left(TIMER_TEMP)) { \ 0000011C E003 LDI R16, 3 \ 0000011E .... RCALL Time_Left \ 00000120 2300 TST R16 \ 00000122 F011 BREQ ??HaltNow_10 300 halt = TRUE; \ 00000124 E081 LDI R24, 1 \ 00000126 C035 RJMP ??HaltNow_2 301 } else { 302 HaltParameters.LastNTC = ADCS.rawNTC; \ ??HaltNow_10: \ 00000128 .... LDI R30, LOW(ADCS) \ 0000012A .... LDI R31, (ADCS) >> 8 \ 0000012C 8104 LDD R16, Z+4 \ 0000012E 8115 LDD R17, Z+5 \ 00000130 .... LDI R30, LOW(HaltParameters) \ 00000132 .... LDI R31, (HaltParameters) >> 8 \ 00000134 8707 STD Z+15, R16 \ 00000136 8B10 STD Z+16, R17 303 Time_Set(TIMER_TEMP,0,30,0); \ 00000138 E040 LDI R20, 0 \ 0000013A E11E LDI R17, 30 \ 0000013C E020 LDI R18, 0 \ 0000013E E030 LDI R19, 0 \ 00000140 E003 LDI R16, 3 \ 00000142 .... RCALL Time_Set \ 00000144 C026 RJMP ??HaltNow_2 304 } 305 } 306 break; 307 308 309 // Is there any time left? 310 case HALT_TIME: 311 312 if (!Time_Left(TIMER_CHG)) { \ ??HaltNow_7: \ 00000146 E001 LDI R16, 1 \ 00000148 .... RCALL Time_Left \ 0000014A 2300 TST R16 \ 0000014C F511 BRNE ??HaltNow_2 313 halt = TRUE; \ 0000014E E081 LDI R24, 1 314 315 // If exhaustion flagging is selected, stop the PWM, disable the 316 // battery and flag it as exhausted. Make ST_ERROR next state. 317 if (HaltParameters.HaltFlags & HALT_FLAG_EXHAUSTION) { \ 00000150 .... LDI R30, LOW(HaltParameters) \ 00000152 .... LDI R31, (HaltParameters) >> 8 \ 00000154 8100 LD R16, Z \ 00000156 FF05 SBRS R16, 5 \ 00000158 C01C RJMP ??HaltNow_2 318 PWM_Stop(); \ 0000015A .... RCALL PWM_Stop 319 BattControl[BattActive].Enabled = FALSE; \ 0000015C 9100.... LDS R16, BattActive \ 00000160 E010 LDI R17, 0 \ 00000162 .... LDI R20, LOW(BattControl) \ 00000164 .... LDI R21, (BattControl) >> 8 \ 00000166 0F40 ADD R20, R16 \ 00000168 1F51 ADC R21, R17 \ 0000016A .... RCALL __eeget8_16 \ 0000016C 7F0E ANDI R16, 0xFE \ 0000016E 9120.... LDS R18, BattActive \ 00000172 E030 LDI R19, 0 \ 00000174 .... LDI R20, LOW(BattControl) \ 00000176 .... LDI R21, (BattControl) >> 8 \ 00000178 0F42 ADD R20, R18 \ 0000017A 1F53 ADC R21, R19 \ 0000017C .... RCALL __eeput8_16 320 BattData.Exhausted = TRUE; \ 0000017E .... LDI R30, LOW(BattData) \ 00000180 .... LDI R31, (BattData) >> 8 \ 00000182 8100 LD R16, Z \ 00000184 6008 ORI R16, 0x08 \ 00000186 8300 ST Z, R16 321 SetErrorFlag(ERR_BATTERY_EXHAUSTED); \ 00000188 E100 LDI R16, 16 \ 0000018A .... RCALL SetErrorFlag 322 ChargeParameters.NextState = ST_ERROR; \ 0000018C E50A LDI R16, 90 \ 0000018E 9300.... STS (ChargeParameters + 4), R16 323 } 324 } 325 break; 326 327 328 default: // Shouldn't end up here, but is needed for MISRA compliance. 329 break; 330 } 331 } 332 } \ ??HaltNow_2: \ 00000192 0F99 LSL R25 \ 00000194 CF39 RJMP ??HaltNow_0 333 334 // Standard checks: 335 336 // Battery too cold or hot? 337 if ((BattData.Temperature <= HaltParameters.TemperatureMin) || 338 (BattData.Temperature >= HaltParameters.TemperatureMax)) { \ ??HaltNow_1: \ 00000196 .... LDI R30, LOW(HaltParameters) \ 00000198 .... LDI R31, (HaltParameters) >> 8 \ 0000019A 8521 LDD R18, Z+9 \ 0000019C 8532 LDD R19, Z+10 \ 0000019E 9100.... LDS R16, (BattData + 2) \ 000001A2 2F10 MOV R17, R16 \ 000001A4 0F11 LSL R17 \ 000001A6 0B11 SBC R17, R17 \ 000001A8 1720 CP R18, R16 \ 000001AA 0731 CPC R19, R17 \ 000001AC F464 BRGE ??HaltNow_11 \ 000001AE 9100.... LDS R16, (BattData + 2) \ 000001B2 2F10 MOV R17, R16 \ 000001B4 0F11 LSL R17 \ 000001B6 0B11 SBC R17, R17 \ 000001B8 .... LDI R30, LOW(HaltParameters) \ 000001BA .... LDI R31, (HaltParameters) >> 8 \ 000001BC 8127 LDD R18, Z+7 \ 000001BE 8530 LDD R19, Z+8 \ 000001C0 1702 CP R16, R18 \ 000001C2 0713 CPC R17, R19 \ 000001C4 F038 BRCS ??HaltNow_12 339 340 PWM_Stop(); \ ??HaltNow_11: \ 000001C6 .... RCALL PWM_Stop 341 SetErrorFlag(ERR_BATTERY_TEMPERATURE); \ 000001C8 E008 LDI R16, 8 \ 000001CA .... RCALL SetErrorFlag 342 ChargeParameters.NextState = ST_ERROR; \ 000001CC E50A LDI R16, 90 \ 000001CE 9300.... STS (ChargeParameters + 4), R16 343 halt = TRUE; \ 000001D2 E081 LDI R24, 1 344 } 345 346 // Battery not OK? 347 if (!BatteryCheck()) { \ ??HaltNow_12: \ 000001D4 .... RCALL BatteryCheck \ 000001D6 2300 TST R16 \ 000001D8 F429 BRNE ??HaltNow_13 348 PWM_Stop(); \ 000001DA .... RCALL PWM_Stop 349 ChargeParameters.NextState = ST_INIT; \ 000001DC E00A LDI R16, 10 \ 000001DE 9300.... STS (ChargeParameters + 4), R16 350 halt = TRUE; \ 000001E2 E081 LDI R24, 1 351 } 352 353 // Is mains voltage OK? 354 if (!ADCS.Mains) { \ ??HaltNow_13: \ 000001E4 .... LDI R30, LOW(ADCS) \ 000001E6 .... LDI R31, (ADCS) >> 8 \ 000001E8 8100 LD R16, Z \ 000001EA FD06 SBRC R16, 6 \ 000001EC C005 RJMP ??HaltNow_14 355 PWM_Stop(); \ 000001EE .... RCALL PWM_Stop 356 ChargeParameters.NextState = ST_SLEEP; \ 000001F0 E208 LDI R16, 40 \ 000001F2 9300.... STS (ChargeParameters + 4), R16 357 halt = TRUE; \ 000001F6 E081 LDI R24, 1 358 } 359 360 return(halt); \ ??HaltNow_14: \ 000001F8 2F08 MOV R16, R24 \ 000001FA E0E4 LDI R30, 4 \ 000001FC .... RJMP ?EPILOGUE_B4_L09 361 } Maximum stack usage in bytes: Function CSTACK RSTACK -------- ------ ------ ConstantCurrent 4 4 -> ADC_Wait 4 2 -> Time_Stop 4 2 -> Time_Start 4 2 -> PWM_IncrementDutyCycle 4 2 -> SetErrorFlag 4 2 -> PWM_DecrementDutyCycle 4 2 -> SetErrorFlag 4 2 -> HaltNow 4 2 ConstantVoltage 4 4 -> ADC_Wait 4 2 -> Time_Stop 4 2 -> Time_Start 4 2 -> PWM_IncrementDutyCycle 4 2 -> SetErrorFlag 4 2 -> PWM_DecrementDutyCycle 4 2 -> SetErrorFlag 4 2 -> HaltNow 4 2 HaltNow 4 4 -> ADC_Wait 4 2 -> Time_Set 4 2 -> Time_Left 4 2 -> Time_Set 4 2 -> Time_Left 4 2 -> PWM_Stop 4 2 -> SetErrorFlag 4 2 -> PWM_Stop 4 2 -> SetErrorFlag 4 2 -> BatteryCheck 4 2 -> PWM_Stop 4 2 -> PWM_Stop 4 2 Segment part sizes: Function/Label Bytes -------------- ----- _A_OCR1B 1 ChargeParameters 5 HaltParameters 17 ConstantCurrent 180 ConstantVoltage 156 HaltNow 510 Others 6 1 byte in segment ABSOLUTE 846 bytes in segment CODE 6 bytes in segment INITTAB 22 bytes in segment NEAR_Z 846 bytes of CODE memory (+ 6 bytes shared) 22 bytes of DATA memory (+ 1 byte shared) Errors: none Warnings: none