/////////////////////////////////////////////////////////////////////////////// // / // 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\bc1 / // 00\IAR\Release\Obj\ -D NDEBUG -lCN / // C:\home\kevin\pub\src\bc100\IAR\Release\List\ / // -lB C:\home\kevin\pub\src\bc100\IAR\Release\Li / // st\ --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\c / // hargefunc.s90 / // / // / /////////////////////////////////////////////////////////////////////////////// NAME chargefunc RSEG CSTACK:DATA:NOROOT(0) RSEG RSTACK:DATA:NOROOT(0) EXTERN ?Register_R4_is_cg_reg EXTERN ?Register_R5_is_cg_reg EXTERN ?Register_R6_is_cg_reg EXTERN ?Register_R7_is_cg_reg EXTERN ?Register_R8_is_cg_reg EXTERN ?Register_R9_is_cg_reg EXTERN ?S_MUL_L02 EXTERN ?need_segment_init EXTERN __eeget8_16 EXTERN __eeput8_16 PUBWEAK `?` PUBLIC ChargeParameters PUBLIC ConstantCurrent PUBLIC ConstantVoltage PUBLIC HaltNow PUBLIC HaltParameters PUBWEAK _A_OCR1B PUBWEAK __?EEARH PUBWEAK __?EEARL PUBWEAK __?EECR PUBWEAK __?EEDR EXTERN ADC_Wait EXTERN Time_Stop EXTERN Time_Start EXTERN PWM_IncrementDutyCycle EXTERN SetErrorFlag EXTERN PWM_DecrementDutyCycle EXTERN Time_Set EXTERN Time_Left EXTERN PWM_Stop EXTERN BatteryCheck EXTERN ADCS EXTERN BattActive EXTERN BattControl EXTERN BattData // 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 ASEGN ABSOLUTE:DATA:NOROOT,04cH // volatile __io _A_OCR1B _A_OCR1B: 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(). RSEG NEAR_Z:DATA:NOROOT(0) REQUIRE `?` // 57 ChargeParameters_t ChargeParameters; // 58 // 59 //! Struct that holds parameters for HaltNow(). // 60 HaltParameters_t HaltParameters; HaltParameters: DS 17 ChargeParameters: 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 */ RSEG CODE:CODE:NOROOT(1) // 80 unsigned char ConstantCurrent(void) ConstantCurrent: // 81 { ST -Y, R5 ST -Y, R4 ST -Y, R27 ST -Y, R26 ST -Y, R25 ST -Y, R24 REQUIRE ?Register_R4_is_cg_reg REQUIRE ?Register_R5_is_cg_reg // 82 unsigned char error = FALSE, CLR R5 // 83 wasStopped = FALSE; CLR R4 // 84 // 85 do { // 86 // Wait for ADC conversions to complete. // 87 ADC_Wait(); ??ConstantCurrent_0: 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) { LDS R16, BattActive LDI R17, 0 LDI R20, LOW(BattControl) LDI R21, (BattControl) >> 8 ADD R20, R16 ADC R21, R17 RCALL __eeget8_16 ANDI R16, 0x04 BREQ ??ConstantCurrent_1 // 92 wasStopped = TRUE; CLR R4 INC R4 // 93 Time_Stop(); RCALL Time_Stop // 94 OCR1B = 0; LDI R16, 0 OUT 0x2C, R16 RJMP ??ConstantCurrent_2 // 95 } else { // 96 // Continue charging! // 97 if (wasStopped) { ??ConstantCurrent_1: TST R4 BREQ ??ConstantCurrent_3 // 98 wasStopped = FALSE; CLR R4 // 99 // 100 // Timer variables are not reset by this. // 101 Time_Start(); 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: LDI R30, LOW(ADCS) LDI R31, (ADCS) >> 8 LDD R16, Z+22 LDD R17, Z+23 TST R17 BRMI ??ConstantCurrent_4 LDI R26, LOW((HaltParameters + 19)) LDI R27, HIGH((HaltParameters + 19)) LD R30, X+ LD R31, X MOVW R25:R24, R31:R30 SBIW R25:R24, 3 CP R16, R24 CPC R17, R25 BRCC ??ConstantCurrent_5 // 108 // 109 if(!PWM_IncrementDutyCycle()) { ??ConstantCurrent_4: RCALL PWM_IncrementDutyCycle TST R16 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: LDI R16, 4 RCALL SetErrorFlag // 114 ChargeParameters.NextState = ST_ERROR; LDI R16, 90 STS (HaltParameters + 21), R16 // 115 error = TRUE; CLR R5 INC R5 RJMP ??ConstantCurrent_2 // 116 #endif // 117 } // 118 } else if ((ADCS.avgIBAT >= 0) && ??ConstantCurrent_5: ADIW R31:R30, 3 CP R30, R16 CPC R31, R17 BRCC ??ConstantCurrent_2 // 119 (ADCS.avgIBAT > (ChargeParameters.Current + BAT_CURRENT_HYST))) { // 120 // 121 if(!PWM_DecrementDutyCycle()) { RCALL PWM_DecrementDutyCycle TST R16 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: RCALL HaltNow TST R16 BRNE ??ConstantCurrent_7 TST R5 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: LDS R16, (HaltParameters + 21) LD R24, Y+ LD R25, Y+ LD R26, Y+ LD R27, Y+ LD R4, Y+ LD R5, Y+ RET 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 */ RSEG CODE:CODE:NOROOT(1) // 154 unsigned char ConstantVoltage(void) ConstantVoltage: // 155 { ST -Y, R27 ST -Y, R26 ST -Y, R25 ST -Y, R24 // 156 unsigned char error = FALSE, LDI R25, 0 // 157 wasStopped = FALSE; LDI R24, 0 // 158 // 159 do{ // 160 // 161 // Wait for ADC conversions to complete. // 162 ADC_Wait(); ??ConstantVoltage_0: 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) { LDS R16, BattActive LDI R17, 0 LDI R20, LOW(BattControl) LDI R21, (BattControl) >> 8 ADD R20, R16 ADC R21, R17 RCALL __eeget8_16 ANDI R16, 0x04 BREQ ??ConstantVoltage_1 // 167 wasStopped = TRUE; LDI R24, 1 // 168 Time_Stop(); RCALL Time_Stop // 169 OCR1B = 0; LDI R16, 0 OUT 0x2C, R16 RJMP ??ConstantVoltage_2 // 170 } // 171 // 172 else { // 173 // Continue charging! // 174 if (wasStopped) { ??ConstantVoltage_1: TST R24 BREQ ??ConstantVoltage_3 // 175 wasStopped = FALSE; LDI R24, 0 // 176 // 177 // Timer variables aren't reset by this. // 178 Time_Start(); 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: LDI R26, LOW(HaltParameters) LDI R27, (HaltParameters) >> 8 MOVW R31:R30, R27:R26 LDD R16, Z+17 LDD R17, Z+18 LDI R30, LOW(ADCS) LDI R31, (ADCS) >> 8 LDD R18, Z+10 LDD R19, Z+11 MOVW R31:R30, R17:R16 SBIW R31:R30, 10 CP R18, R30 CPC R19, R31 BRCC ??ConstantVoltage_4 // 184 // 185 if(!PWM_IncrementDutyCycle()) { RCALL PWM_IncrementDutyCycle TST R16 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: LDI R16, 4 RCALL SetErrorFlag // 190 ChargeParameters.NextState = ST_ERROR; LDI R16, 90 MOVW R31:R30, R27:R26 STD Z+21, R16 // 191 error = TRUE; LDI R25, 1 RJMP ??ConstantVoltage_2 // 192 #endif // 193 } // 194 } else if (ADCS.VBAT > (ChargeParameters.Voltage + BAT_VOLTAGE_HYST)) { ??ConstantVoltage_4: SUBI R16, 246 SBCI R17, 255 CP R16, R18 CPC R17, R19 BRCC ??ConstantVoltage_2 // 195 // 196 if(!PWM_DecrementDutyCycle()) { RCALL PWM_DecrementDutyCycle TST R16 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: RCALL HaltNow TST R16 BRNE ??ConstantVoltage_6 TST R25 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: LDS R16, (HaltParameters + 21) LD R24, Y+ LD R25, Y+ LD R26, Y+ LD R27, Y+ RET 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 */ RSEG CODE:CODE:NOROOT(1) // 238 unsigned char HaltNow(void) HaltNow: // 239 { ST -Y, R9 ST -Y, R8 ST -Y, R7 ST -Y, R6 ST -Y, R5 ST -Y, R4 ST -Y, R27 ST -Y, R26 ST -Y, R25 ST -Y, R24 REQUIRE ?Register_R4_is_cg_reg REQUIRE ?Register_R5_is_cg_reg REQUIRE ?Register_R6_is_cg_reg REQUIRE ?Register_R7_is_cg_reg REQUIRE ?Register_R8_is_cg_reg REQUIRE ?Register_R9_is_cg_reg // 240 unsigned char i, halt = FALSE; CLR R7 // 241 // 242 // Wait for a full ADC-cycle to finish. // 243 ADC_Wait(); 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) { CLR R6 INC R6 LDI R24, LOW(ADCS) LDI R25, (ADCS) >> 8 LDI R16, LOW(BattData) MOV R4, R16 LDI R16, (BattData) >> 8 MOV R5, R16 LDI R26, LOW(HaltParameters) LDI R27, (HaltParameters) >> 8 // 249 if (HaltParameters.HaltFlags & i) { ??HaltNow_0: LD R16, X AND R16, R6 BRNE $+2+2 RJMP ??HaltNow_1 // 250 switch (i) { MOV R16, R6 DEC R16 BREQ ??HaltNow_2 DEC R16 BREQ ??HaltNow_3 SUBI R16, 2 BREQ ??HaltNow_4 SUBI R16, 4 BREQ ??HaltNow_5 SUBI R16, 8 BRNE $+2+2 RJMP ??HaltNow_6 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: MOVW R31:R30, R27:R26 LDD R16, Z+13 LDD R17, Z+14 MOVW R31:R30, R25:R24 LDD R18, Z+10 LDD R19, Z+11 CP R16, R18 CPC R17, R19 BRCC ??HaltNow_7 // 256 HaltParameters.VBATMax = ADCS.VBAT; MOVW R31:R30, R27:R26 STD Z+13, R18 STD Z+14, R19 RJMP ??HaltNow_1 // 257 } else if((HaltParameters.VBATMax - ADCS.VBAT) >= // 258 HaltParameters.VoltageDrop) { ??HaltNow_7: SUB R16, R18 SBC R17, R19 MOVW R31:R30, R27:R26 LDD R18, Z+1 LDD R19, Z+2 CP R16, R18 CPC R17, R19 BRCC $+2+2 RJMP ??HaltNow_1 // 259 halt = TRUE; ??HaltNow_8: CLR R7 INC R7 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: MOVW R31:R30, R25:R24 LDD R16, Z+10 LDD R17, Z+11 MOVW R31:R30, R27:R26 LDD R18, Z+3 LDD R19, Z+4 ??HaltNow_9: CP R16, R18 CPC R17, R19 BRCC $+2+2 RJMP ??HaltNow_1 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: MOVW R31:R30, R27:R26 LDD R16, Z+5 LDD R17, Z+6 MOVW R31:R30, R25:R24 LDD R18, Z+22 LDD R19, Z+23 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: MOVW R31:R30, R25:R24 LDD R16, Z+4 LDD R17, Z+5 MOVW R31:R30, R27:R26 LDD R8, Z+15 LDD R9, Z+16 CP R8, R16 CPC R9, R17 BRCC ??HaltNow_10 // 289 HaltParameters.LastNTC = ADCS.rawNTC; ??HaltNow_11: MOVW R31:R30, R25:R24 LDD R16, Z+4 LDD R17, Z+5 MOVW R31:R30, R27:R26 STD Z+15, R16 STD Z+16, R17 // 290 Time_Set(TIMER_TEMP,0,30,0); LDI R20, 0 LDI R17, 30 LDI R18, 0 LDI R19, 0 LDI R16, 3 RCALL Time_Set 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: SUB R8, R16 SBC R9, R17 MOVW R31:R30, R5:R4 LDD R20, Z+3 LDI R21, 0 MOVW R31:R30, R27:R26 LDD R16, Z+11 LDD R17, Z+12 RCALL ?S_MUL_L02 CP R8, R0 CPC R9, R1 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)) { LDI R16, 3 RCALL Time_Left TST R16 BRNE ??HaltNow_8 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: LDI R16, 1 RCALL Time_Left TST R16 BRNE ??HaltNow_1 // 313 halt = TRUE; CLR R7 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) { LD R16, X SBRS R16, 5 RJMP ??HaltNow_1 // 318 PWM_Stop(); RCALL PWM_Stop // 319 BattControl[BattActive].Enabled = FALSE; LDS R16, BattActive LDI R17, 0 LDI R20, LOW(BattControl) LDI R21, (BattControl) >> 8 ADD R20, R16 ADC R21, R17 RCALL __eeget8_16 ANDI R16, 0xFE RCALL __eeput8_16 // 320 BattData.Exhausted = TRUE; MOVW R31:R30, R5:R4 LD R16, Z ORI R16, 0x08 ST Z, R16 // 321 SetErrorFlag(ERR_BATTERY_EXHAUSTED); LDI R16, 16 RCALL SetErrorFlag // 322 ChargeParameters.NextState = ST_ERROR; LDI R16, 90 MOVW R31:R30, R27:R26 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: LSL R6 BREQ $+2+2 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)) { LDI R30, LOW(BattData) LDI R31, (BattData) >> 8 LDD R16, Z+2 MOVW R31:R30, R27:R26 LDD R18, Z+9 LDD R19, Z+10 MOV R17, R16 LSL R17 SBC R17, R17 CP R18, R16 CPC R19, R17 BRGE ??HaltNow_12 MOV R17, R16 LSL R17 SBC R17, R17 LDD R18, Z+7 LDD R19, Z+8 CP R16, R18 CPC R17, R19 BRCS ??HaltNow_13 // 339 // 340 PWM_Stop(); ??HaltNow_12: RCALL PWM_Stop // 341 SetErrorFlag(ERR_BATTERY_TEMPERATURE); LDI R16, 8 RCALL SetErrorFlag // 342 ChargeParameters.NextState = ST_ERROR; LDI R16, 90 MOVW R31:R30, R27:R26 STD Z+21, R16 // 343 halt = TRUE; CLR R7 INC R7 // 344 } // 345 // 346 // Battery not OK? // 347 if (!BatteryCheck()) { ??HaltNow_13: RCALL BatteryCheck TST R16 BRNE ??HaltNow_14 // 348 PWM_Stop(); RCALL PWM_Stop // 349 ChargeParameters.NextState = ST_INIT; LDI R16, 10 MOVW R31:R30, R27:R26 STD Z+21, R16 // 350 halt = TRUE; CLR R7 INC R7 // 351 } // 352 // 353 // Is mains voltage OK? // 354 if (!ADCS.Mains) { ??HaltNow_14: LDS R16, ADCS SBRC R16, 6 RJMP ??HaltNow_15 // 355 PWM_Stop(); RCALL PWM_Stop // 356 ChargeParameters.NextState = ST_SLEEP; LDI R16, 40 MOVW R31:R30, R27:R26 STD Z+21, R16 // 357 halt = TRUE; CLR R7 INC R7 // 358 } // 359 // 360 return(halt); ??HaltNow_15: MOV R16, R7 LD R24, Y+ LD R25, Y+ LD R26, Y+ LD R27, Y+ LD R4, Y+ LD R5, Y+ LD R6, Y+ LD R7, Y+ LD R8, Y+ LD R9, Y+ RET // 361 } ASEGN ABSOLUTE:DATA:NOROOT,01cH __?EECR: ASEGN ABSOLUTE:DATA:NOROOT,01dH __?EEDR: ASEGN ABSOLUTE:DATA:NOROOT,01eH __?EEARL: ASEGN ABSOLUTE:DATA:NOROOT,01fH __?EEARH: RSEG INITTAB:CODE:NOROOT(0) `?`: DW SFE(NEAR_Z) - SFB(NEAR_Z) DW SFB(NEAR_Z) DW 0 REQUIRE ?need_segment_init END // // 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