############################################################################### # # # IAR Atmel AVR C/C++ Compiler V4.30F/W32 13/Mar/2008 04:52:01 # # Copyright 1996-2007 IAR Systems. All rights reserved. # # # # Source file = C:\home\kevin\pub\src\bc100\IAR\chargefunc.c # # Command line = C:\home\kevin\pub\src\bc100\IAR\chargefunc.c # # --cpu=tiny861 -ms -o C:\home\kevin\pub\src\bc10 # # 0\IAR\Release\Obj\ -D NDEBUG -lCN # # C:\home\kevin\pub\src\bc100\IAR\Release\List\ # # -lB C:\home\kevin\pub\src\bc100\IAR\Release\Lis # # t\ --initializers_in_flash -s9 --no_cross_call # # --no_tbaa -DENABLE_BIT_DEFINITIONS -e -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 # # --misrac=5-9,11-12,14,16-17,19-21,24-26,29-32, # # 34-35,38-39,42-43,46,50,52-54,56-59,61-62, # # 64-65,68-80,83-84,87-91,94-95,98-100,103-110, # # 112-126 # # Enabled MISRA C rules = 5-9,11-12,14,16-17,19-21,24-26,29-32,34-35, # # 38-39,42-43,46,50,52-54,56-59,61-62,64-65, # # 68-80,83-84,87-91,94-95,98-100,103-110,112-126 # # Checked = 5,7-9,11-12,14,17,19-21,24,29-32,34-35,38-39, # # 42,46,50,52-54,56-59,61-62,64,68-69,71-80, # # 83-84,87-89,91,94-95,98,100,104-105,108-109, # # 112-115,118-126 # # Not checked = 6,16,25-26,43,65,70,90,99,103,106-107,110, # # 116-117 # # List file = C:\home\kevin\pub\src\bc100\IAR\Release\List\ch # # argefunc.lst # # Object file = C:\home\kevin\pub\src\bc100\IAR\Release\Obj\cha # # rgefunc.r90 # # # # # ############################################################################### C:\home\kevin\pub\src\bc100\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; 58 59 //! Struct that holds parameters for HaltNow(). 60 HaltParameters_t HaltParameters; \ HaltParameters: \ 00000000 DS 17 \ ChargeParameters: \ 00000011 DS 5 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 925A ST -Y, R5 \ 00000002 924A ST -Y, R4 \ 00000004 93BA ST -Y, R27 \ 00000006 93AA ST -Y, R26 \ 00000008 939A ST -Y, R25 \ 0000000A 938A ST -Y, R24 \ 0000000C REQUIRE ?Register_R4_is_cg_reg \ 0000000C REQUIRE ?Register_R5_is_cg_reg 82 unsigned char error = FALSE, \ 0000000C 2455 CLR R5 83 wasStopped = FALSE; \ 0000000E 2444 CLR R4 84 85 do { 86 // Wait for ADC conversions to complete. 87 ADC_Wait(); \ ??ConstantCurrent_0: \ 00000010 .... 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) { \ 00000012 9100.... LDS R16, BattActive \ 00000016 E010 LDI R17, 0 \ 00000018 .... LDI R20, LOW(BattControl) \ 0000001A .... LDI R21, (BattControl) >> 8 \ 0000001C 0F40 ADD R20, R16 \ 0000001E 1F51 ADC R21, R17 \ 00000020 .... RCALL __eeget8_16 \ 00000022 7004 ANDI R16, 0x04 \ 00000024 F031 BREQ ??ConstantCurrent_1 92 wasStopped = TRUE; \ 00000026 2444 CLR R4 \ 00000028 9443 INC R4 93 Time_Stop(); \ 0000002A .... RCALL Time_Stop 94 OCR1B = 0; \ 0000002C E000 LDI R16, 0 \ 0000002E BD0C OUT 0x2C, R16 \ 00000030 C025 RJMP ??ConstantCurrent_2 95 } else { 96 // Continue charging! 97 if (wasStopped) { \ ??ConstantCurrent_1: \ 00000032 2044 TST R4 \ 00000034 F011 BREQ ??ConstantCurrent_3 98 wasStopped = FALSE; \ 00000036 2444 CLR R4 99 100 // Timer variables are not reset by this. 101 Time_Start(); \ 00000038 .... 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: \ 0000003A .... LDI R30, LOW(ADCS) \ 0000003C .... LDI R31, (ADCS) >> 8 \ 0000003E 8906 LDD R16, Z+22 \ 00000040 8917 LDD R17, Z+23 \ 00000042 2311 TST R17 \ 00000044 F04A BRMI ??ConstantCurrent_4 \ 00000046 .... LDI R26, LOW((HaltParameters + 19)) \ 00000048 .... LDI R27, HIGH((HaltParameters + 19)) \ 0000004A 91ED LD R30, X+ \ 0000004C 91FC LD R31, X \ 0000004E 01CF MOVW R25:R24, R31:R30 \ 00000050 9703 SBIW R25:R24, 3 \ 00000052 1708 CP R16, R24 \ 00000054 0719 CPC R17, R25 \ 00000056 F458 BRCC ??ConstantCurrent_5 108 109 if(!PWM_IncrementDutyCycle()) { \ ??ConstantCurrent_4: \ 00000058 .... RCALL PWM_IncrementDutyCycle \ 0000005A 2300 TST R16 \ 0000005C F479 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); \ ??ConstantCurrent_6: \ 0000005E E004 LDI R16, 4 \ 00000060 .... RCALL SetErrorFlag 114 ChargeParameters.NextState = ST_ERROR; \ 00000062 E50A LDI R16, 90 \ 00000064 9300.... STS (HaltParameters + 21), R16 115 error = TRUE; \ 00000068 2455 CLR R5 \ 0000006A 9453 INC R5 \ 0000006C C007 RJMP ??ConstantCurrent_2 116 #endif 117 } 118 } else if ((ADCS.avgIBAT >= 0) && \ ??ConstantCurrent_5: \ 0000006E 9633 ADIW R31:R30, 3 \ 00000070 17E0 CP R30, R16 \ 00000072 07F1 CPC R31, R17 \ 00000074 F418 BRCC ??ConstantCurrent_2 119 (ADCS.avgIBAT > (ChargeParameters.Current + BAT_CURRENT_HYST))) { 120 121 if(!PWM_DecrementDutyCycle()) { \ 00000076 .... RCALL PWM_DecrementDutyCycle \ 00000078 2300 TST R16 \ 0000007A F389 BREQ ??ConstantCurrent_6 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); 126 ChargeParameters.NextState = ST_ERROR; 127 error = TRUE; 128 #endif 129 } 130 } 131 } 132 } while ((!HaltNow()) && (!error)); \ ??ConstantCurrent_2: \ 0000007C .... RCALL HaltNow \ 0000007E 2300 TST R16 \ 00000080 F411 BRNE ??ConstantCurrent_7 \ 00000082 2055 TST R5 \ 00000084 F229 BREQ ??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_7: \ 00000086 9100.... LDS R16, (HaltParameters + 21) \ 0000008A 9189 LD R24, Y+ \ 0000008C 9199 LD R25, Y+ \ 0000008E 91A9 LD R26, Y+ \ 00000090 91B9 LD R27, Y+ \ 00000092 9049 LD R4, Y+ \ 00000094 9059 LD R5, Y+ \ 00000096 9508 RET \ 00000098 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 93BA ST -Y, R27 \ 00000002 93AA ST -Y, R26 \ 00000004 939A ST -Y, R25 \ 00000006 938A ST -Y, R24 156 unsigned char error = FALSE, \ 00000008 E090 LDI R25, 0 157 wasStopped = FALSE; \ 0000000A E080 LDI R24, 0 158 159 do{ 160 161 // Wait for ADC conversions to complete. 162 ADC_Wait(); \ ??ConstantVoltage_0: \ 0000000C .... 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) { \ 0000000E 9100.... LDS R16, BattActive \ 00000012 E010 LDI R17, 0 \ 00000014 .... LDI R20, LOW(BattControl) \ 00000016 .... LDI R21, (BattControl) >> 8 \ 00000018 0F40 ADD R20, R16 \ 0000001A 1F51 ADC R21, R17 \ 0000001C .... RCALL __eeget8_16 \ 0000001E 7004 ANDI R16, 0x04 \ 00000020 F029 BREQ ??ConstantVoltage_1 167 wasStopped = TRUE; \ 00000022 E081 LDI R24, 1 168 Time_Stop(); \ 00000024 .... RCALL Time_Stop 169 OCR1B = 0; \ 00000026 E000 LDI R16, 0 \ 00000028 BD0C OUT 0x2C, R16 \ 0000002A C024 RJMP ??ConstantVoltage_2 170 } 171 172 else { 173 // Continue charging! 174 if (wasStopped) { \ ??ConstantVoltage_1: \ 0000002C 2388 TST R24 \ 0000002E F011 BREQ ??ConstantVoltage_3 175 wasStopped = FALSE; \ 00000030 E080 LDI R24, 0 176 177 // Timer variables aren't reset by this. 178 Time_Start(); \ 00000032 .... 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: \ 00000034 .... LDI R26, LOW(HaltParameters) \ 00000036 .... LDI R27, (HaltParameters) >> 8 \ 00000038 01FD MOVW R31:R30, R27:R26 \ 0000003A 8901 LDD R16, Z+17 \ 0000003C 8912 LDD R17, Z+18 \ 0000003E .... LDI R30, LOW(ADCS) \ 00000040 .... LDI R31, (ADCS) >> 8 \ 00000042 8522 LDD R18, Z+10 \ 00000044 8533 LDD R19, Z+11 \ 00000046 01F8 MOVW R31:R30, R17:R16 \ 00000048 973A SBIW R31:R30, 10 \ 0000004A 172E CP R18, R30 \ 0000004C 073F CPC R19, R31 \ 0000004E F450 BRCC ??ConstantVoltage_4 184 185 if(!PWM_IncrementDutyCycle()) { \ 00000050 .... RCALL PWM_IncrementDutyCycle \ 00000052 2300 TST R16 \ 00000054 F479 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); \ ??ConstantVoltage_5: \ 00000056 E004 LDI R16, 4 \ 00000058 .... RCALL SetErrorFlag 190 ChargeParameters.NextState = ST_ERROR; \ 0000005A E50A LDI R16, 90 \ 0000005C 01FD MOVW R31:R30, R27:R26 \ 0000005E 8B05 STD Z+21, R16 191 error = TRUE; \ 00000060 E091 LDI R25, 1 \ 00000062 C008 RJMP ??ConstantVoltage_2 192 #endif 193 } 194 } else if (ADCS.VBAT > (ChargeParameters.Voltage + BAT_VOLTAGE_HYST)) { \ ??ConstantVoltage_4: \ 00000064 5F06 SUBI R16, 246 \ 00000066 4F1F SBCI R17, 255 \ 00000068 1702 CP R16, R18 \ 0000006A 0713 CPC R17, R19 \ 0000006C F418 BRCC ??ConstantVoltage_2 195 196 if(!PWM_DecrementDutyCycle()) { \ 0000006E .... RCALL PWM_DecrementDutyCycle \ 00000070 2300 TST R16 \ 00000072 F389 BREQ ??ConstantVoltage_5 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); 201 ChargeParameters.NextState = ST_ERROR; 202 error = TRUE; 203 #endif 204 } 205 } 206 } 207 208 } while ((!HaltNow()) && (!error)); \ ??ConstantVoltage_2: \ 00000074 .... RCALL HaltNow \ 00000076 2300 TST R16 \ 00000078 F411 BRNE ??ConstantVoltage_6 \ 0000007A 2399 TST R25 \ 0000007C F239 BREQ ??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_6: \ 0000007E 9100.... LDS R16, (HaltParameters + 21) \ 00000082 9189 LD R24, Y+ \ 00000084 9199 LD R25, Y+ \ 00000086 91A9 LD R26, Y+ \ 00000088 91B9 LD R27, Y+ \ 0000008A 9508 RET \ 0000008C 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 929A ST -Y, R9 \ 00000002 928A ST -Y, R8 \ 00000004 927A ST -Y, R7 \ 00000006 926A ST -Y, R6 \ 00000008 925A ST -Y, R5 \ 0000000A 924A ST -Y, R4 \ 0000000C 93BA ST -Y, R27 \ 0000000E 93AA ST -Y, R26 \ 00000010 939A ST -Y, R25 \ 00000012 938A ST -Y, R24 \ 00000014 REQUIRE ?Register_R4_is_cg_reg \ 00000014 REQUIRE ?Register_R5_is_cg_reg \ 00000014 REQUIRE ?Register_R6_is_cg_reg \ 00000014 REQUIRE ?Register_R7_is_cg_reg \ 00000014 REQUIRE ?Register_R8_is_cg_reg \ 00000014 REQUIRE ?Register_R9_is_cg_reg 240 unsigned char i, halt = FALSE; \ 00000014 2477 CLR R7 241 242 // Wait for a full ADC-cycle to finish. 243 ADC_Wait(); \ 00000016 .... 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) { \ 00000018 2466 CLR R6 \ 0000001A 9463 INC R6 \ 0000001C .... LDI R24, LOW(ADCS) \ 0000001E .... LDI R25, (ADCS) >> 8 \ 00000020 .... LDI R16, LOW(BattData) \ 00000022 2E40 MOV R4, R16 \ 00000024 .... LDI R16, (BattData) >> 8 \ 00000026 2E50 MOV R5, R16 \ 00000028 .... LDI R26, LOW(HaltParameters) \ 0000002A .... LDI R27, (HaltParameters) >> 8 249 if (HaltParameters.HaltFlags & i) { \ ??HaltNow_0: \ 0000002C 910C LD R16, X \ 0000002E 2106 AND R16, R6 \ 00000030 F409 BRNE $+2+2 \ 00000032 C07C RJMP ??HaltNow_1 250 switch (i) { \ 00000034 2D06 MOV R16, R6 \ 00000036 950A DEC R16 \ 00000038 F051 BREQ ??HaltNow_2 \ 0000003A 950A DEC R16 \ 0000003C F109 BREQ ??HaltNow_3 \ 0000003E 5002 SUBI R16, 2 \ 00000040 F151 BREQ ??HaltNow_4 \ 00000042 5004 SUBI R16, 4 \ 00000044 F179 BREQ ??HaltNow_5 \ 00000046 5008 SUBI R16, 8 \ 00000048 F409 BRNE $+2+2 \ 0000004A C053 RJMP ??HaltNow_6 \ 0000004C C06F RJMP ??HaltNow_1 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_2: \ 0000004E 01FD MOVW R31:R30, R27:R26 \ 00000050 8505 LDD R16, Z+13 \ 00000052 8516 LDD R17, Z+14 \ 00000054 01FC MOVW R31:R30, R25:R24 \ 00000056 8522 LDD R18, Z+10 \ 00000058 8533 LDD R19, Z+11 \ 0000005A 1702 CP R16, R18 \ 0000005C 0713 CPC R17, R19 \ 0000005E F420 BRCC ??HaltNow_7 256 HaltParameters.VBATMax = ADCS.VBAT; \ 00000060 01FD MOVW R31:R30, R27:R26 \ 00000062 8725 STD Z+13, R18 \ 00000064 8736 STD Z+14, R19 \ 00000066 C062 RJMP ??HaltNow_1 257 } else if((HaltParameters.VBATMax - ADCS.VBAT) >= 258 HaltParameters.VoltageDrop) { \ ??HaltNow_7: \ 00000068 1B02 SUB R16, R18 \ 0000006A 0B13 SBC R17, R19 \ 0000006C 01FD MOVW R31:R30, R27:R26 \ 0000006E 8121 LDD R18, Z+1 \ 00000070 8132 LDD R19, Z+2 \ 00000072 1702 CP R16, R18 \ 00000074 0713 CPC R17, R19 \ 00000076 F408 BRCC $+2+2 \ 00000078 C059 RJMP ??HaltNow_1 259 halt = TRUE; \ ??HaltNow_8: \ 0000007A 2477 CLR R7 \ 0000007C 9473 INC R7 \ 0000007E C056 RJMP ??HaltNow_1 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_3: \ 00000080 01FC MOVW R31:R30, R25:R24 \ 00000082 8502 LDD R16, Z+10 \ 00000084 8513 LDD R17, Z+11 \ 00000086 01FD MOVW R31:R30, R27:R26 \ 00000088 8123 LDD R18, Z+3 \ 0000008A 8134 LDD R19, Z+4 \ ??HaltNow_9: \ 0000008C 1702 CP R16, R18 \ 0000008E 0713 CPC R17, R19 \ 00000090 F408 BRCC $+2+2 \ 00000092 C04C RJMP ??HaltNow_1 \ 00000094 CFF2 RJMP ??HaltNow_8 268 halt = TRUE; 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_4: \ 00000096 01FD MOVW R31:R30, R27:R26 \ 00000098 8105 LDD R16, Z+5 \ 0000009A 8116 LDD R17, Z+6 \ 0000009C 01FC MOVW R31:R30, R25:R24 \ 0000009E 8926 LDD R18, Z+22 \ 000000A0 8937 LDD R19, Z+23 \ 000000A2 CFF4 RJMP ??HaltNow_9 277 halt = TRUE; 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_5: \ 000000A4 01FC MOVW R31:R30, R25:R24 \ 000000A6 8104 LDD R16, Z+4 \ 000000A8 8115 LDD R17, Z+5 \ 000000AA 01FD MOVW R31:R30, R27:R26 \ 000000AC 8487 LDD R8, Z+15 \ 000000AE 8890 LDD R9, Z+16 \ 000000B0 1680 CP R8, R16 \ 000000B2 0691 CPC R9, R17 \ 000000B4 F468 BRCC ??HaltNow_10 289 HaltParameters.LastNTC = ADCS.rawNTC; \ ??HaltNow_11: \ 000000B6 01FC MOVW R31:R30, R25:R24 \ 000000B8 8104 LDD R16, Z+4 \ 000000BA 8115 LDD R17, Z+5 \ 000000BC 01FD MOVW R31:R30, R27:R26 \ 000000BE 8707 STD Z+15, R16 \ 000000C0 8B10 STD Z+16, R17 290 Time_Set(TIMER_TEMP,0,30,0); \ 000000C2 E040 LDI R20, 0 \ 000000C4 E11E LDI R17, 30 \ 000000C6 E020 LDI R18, 0 \ 000000C8 E030 LDI R19, 0 \ 000000CA E003 LDI R16, 3 \ 000000CC .... RCALL Time_Set \ 000000CE C02E RJMP ??HaltNow_1 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_10: \ 000000D0 1A80 SUB R8, R16 \ 000000D2 0A91 SBC R9, R17 \ 000000D4 01F2 MOVW R31:R30, R5:R4 \ 000000D6 8143 LDD R20, Z+3 \ 000000D8 E050 LDI R21, 0 \ 000000DA 01FD MOVW R31:R30, R27:R26 \ 000000DC 8503 LDD R16, Z+11 \ 000000DE 8514 LDD R17, Z+12 \ 000000E0 .... RCALL ?S_MUL_L02 \ 000000E2 1480 CP R8, R0 \ 000000E4 0491 CPC R9, R1 \ 000000E6 F110 BRCS ??HaltNow_1 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)) { \ 000000E8 E003 LDI R16, 3 \ 000000EA .... RCALL Time_Left \ 000000EC 2300 TST R16 \ 000000EE F629 BRNE ??HaltNow_8 \ 000000F0 CFE2 RJMP ??HaltNow_11 300 halt = TRUE; 301 } else { 302 HaltParameters.LastNTC = ADCS.rawNTC; 303 Time_Set(TIMER_TEMP,0,30,0); 304 } 305 } 306 break; 307 308 309 // Is there any time left? 310 case HALT_TIME: 311 312 if (!Time_Left(TIMER_CHG)) { \ ??HaltNow_6: \ 000000F2 E001 LDI R16, 1 \ 000000F4 .... RCALL Time_Left \ 000000F6 2300 TST R16 \ 000000F8 F4C9 BRNE ??HaltNow_1 313 halt = TRUE; \ 000000FA 2477 CLR R7 \ 000000FC 9473 INC R7 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) { \ 000000FE 910C LD R16, X \ 00000100 FF05 SBRS R16, 5 \ 00000102 C014 RJMP ??HaltNow_1 318 PWM_Stop(); \ 00000104 .... RCALL PWM_Stop 319 BattControl[BattActive].Enabled = FALSE; \ 00000106 9100.... LDS R16, BattActive \ 0000010A E010 LDI R17, 0 \ 0000010C .... LDI R20, LOW(BattControl) \ 0000010E .... LDI R21, (BattControl) >> 8 \ 00000110 0F40 ADD R20, R16 \ 00000112 1F51 ADC R21, R17 \ 00000114 .... RCALL __eeget8_16 \ 00000116 7F0E ANDI R16, 0xFE \ 00000118 .... RCALL __eeput8_16 320 BattData.Exhausted = TRUE; \ 0000011A 01F2 MOVW R31:R30, R5:R4 \ 0000011C 8100 LD R16, Z \ 0000011E 6008 ORI R16, 0x08 \ 00000120 8300 ST Z, R16 321 SetErrorFlag(ERR_BATTERY_EXHAUSTED); \ 00000122 E100 LDI R16, 16 \ 00000124 .... RCALL SetErrorFlag 322 ChargeParameters.NextState = ST_ERROR; \ 00000126 E50A LDI R16, 90 \ 00000128 01FD MOVW R31:R30, R27:R26 \ 0000012A 8B05 STD Z+21, 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_1: \ 0000012C 0C66 LSL R6 \ 0000012E F009 BREQ $+2+2 \ 00000130 CF7D 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)) { \ 00000132 .... LDI R30, LOW(BattData) \ 00000134 .... LDI R31, (BattData) >> 8 \ 00000136 8102 LDD R16, Z+2 \ 00000138 01FD MOVW R31:R30, R27:R26 \ 0000013A 8521 LDD R18, Z+9 \ 0000013C 8532 LDD R19, Z+10 \ 0000013E 2F10 MOV R17, R16 \ 00000140 0F11 LSL R17 \ 00000142 0B11 SBC R17, R17 \ 00000144 1720 CP R18, R16 \ 00000146 0731 CPC R19, R17 \ 00000148 F444 BRGE ??HaltNow_12 \ 0000014A 2F10 MOV R17, R16 \ 0000014C 0F11 LSL R17 \ 0000014E 0B11 SBC R17, R17 \ 00000150 8127 LDD R18, Z+7 \ 00000152 8530 LDD R19, Z+8 \ 00000154 1702 CP R16, R18 \ 00000156 0713 CPC R17, R19 \ 00000158 F040 BRCS ??HaltNow_13 339 340 PWM_Stop(); \ ??HaltNow_12: \ 0000015A .... RCALL PWM_Stop 341 SetErrorFlag(ERR_BATTERY_TEMPERATURE); \ 0000015C E008 LDI R16, 8 \ 0000015E .... RCALL SetErrorFlag 342 ChargeParameters.NextState = ST_ERROR; \ 00000160 E50A LDI R16, 90 \ 00000162 01FD MOVW R31:R30, R27:R26 \ 00000164 8B05 STD Z+21, R16 343 halt = TRUE; \ 00000166 2477 CLR R7 \ 00000168 9473 INC R7 344 } 345 346 // Battery not OK? 347 if (!BatteryCheck()) { \ ??HaltNow_13: \ 0000016A .... RCALL BatteryCheck \ 0000016C 2300 TST R16 \ 0000016E F431 BRNE ??HaltNow_14 348 PWM_Stop(); \ 00000170 .... RCALL PWM_Stop 349 ChargeParameters.NextState = ST_INIT; \ 00000172 E00A LDI R16, 10 \ 00000174 01FD MOVW R31:R30, R27:R26 \ 00000176 8B05 STD Z+21, R16 350 halt = TRUE; \ 00000178 2477 CLR R7 \ 0000017A 9473 INC R7 351 } 352 353 // Is mains voltage OK? 354 if (!ADCS.Mains) { \ ??HaltNow_14: \ 0000017C 9100.... LDS R16, ADCS \ 00000180 FD06 SBRC R16, 6 \ 00000182 C006 RJMP ??HaltNow_15 355 PWM_Stop(); \ 00000184 .... RCALL PWM_Stop 356 ChargeParameters.NextState = ST_SLEEP; \ 00000186 E208 LDI R16, 40 \ 00000188 01FD MOVW R31:R30, R27:R26 \ 0000018A 8B05 STD Z+21, R16 357 halt = TRUE; \ 0000018C 2477 CLR R7 \ 0000018E 9473 INC R7 358 } 359 360 return(halt); \ ??HaltNow_15: \ 00000190 2D07 MOV R16, R7 \ 00000192 9189 LD R24, Y+ \ 00000194 9199 LD R25, Y+ \ 00000196 91A9 LD R26, Y+ \ 00000198 91B9 LD R27, Y+ \ 0000019A 9049 LD R4, Y+ \ 0000019C 9059 LD R5, Y+ \ 0000019E 9069 LD R6, Y+ \ 000001A0 9079 LD R7, Y+ \ 000001A2 9089 LD R8, Y+ \ 000001A4 9099 LD R9, Y+ \ 000001A6 9508 RET 361 } Maximum stack usage in bytes: Function CSTACK RSTACK -------- ------ ------ ConstantCurrent 6 4 -> ADC_Wait 6 2 -> Time_Stop 6 2 -> Time_Start 6 2 -> PWM_IncrementDutyCycle 6 2 -> SetErrorFlag 6 2 -> PWM_DecrementDutyCycle 6 2 -> HaltNow 6 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 -> HaltNow 4 2 HaltNow 10 4 -> ADC_Wait 10 2 -> Time_Set 10 2 -> Time_Left 10 2 -> Time_Left 10 2 -> PWM_Stop 10 2 -> SetErrorFlag 10 2 -> PWM_Stop 10 2 -> SetErrorFlag 10 2 -> BatteryCheck 10 2 -> PWM_Stop 10 2 -> PWM_Stop 10 2 Segment part sizes: Function/Label Bytes -------------- ----- _A_OCR1B 1 HaltParameters 22 ConstantCurrent 152 ConstantVoltage 140 HaltNow 424 Others 6 1 byte in segment ABSOLUTE 716 bytes in segment CODE 6 bytes in segment INITTAB 22 bytes in segment NEAR_Z 716 bytes of CODE memory (+ 6 bytes shared) 22 bytes of DATA memory (+ 1 byte shared) Errors: none Warnings: none