/////////////////////////////////////////////////////////////////////////////// // / // 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\IA / // R\Debug\Obj\ -lC C:\home\kevin\pub\src\bc100_cal\IAR\De / // bug\List\ -lB C:\home\kevin\pub\src\bc100_cal\IAR\Debug / // \List\ --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\chargefu / // nc.s90 / // / // / /////////////////////////////////////////////////////////////////////////////// NAME chargefunc RSEG CSTACK:DATA:NOROOT(0) RSEG RSTACK:DATA:NOROOT(0) EXTERN ?EPILOGUE_B4_L09 EXTERN ?PROLOGUE4_L09 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_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 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; ChargeParameters: DS 5 // 58 // 59 //! Struct that holds parameters for HaltNow(). RSEG NEAR_Z:DATA:NOROOT(0) REQUIRE `?` // 60 HaltParameters_t HaltParameters; HaltParameters: 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 */ RSEG CODE:CODE:NOROOT(1) // 80 unsigned char ConstantCurrent(void) ConstantCurrent: // 81 { RCALL ?PROLOGUE4_L09 // 82 unsigned char error = FALSE, LDI R24, 0 // 83 wasStopped = FALSE; LDI R25, 0 // 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 TST R16 BREQ ??ConstantCurrent_1 // 92 wasStopped = TRUE; LDI R25, 1 // 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 R25 BREQ ??ConstantCurrent_3 // 98 wasStopped = FALSE; LDI R25, 0 // 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 R30, LOW(ADCS) LDI R31, (ADCS) >> 8 LDD R18, Z+22 LDD R19, Z+23 LDI R30, LOW(ChargeParameters) LDI R31, (ChargeParameters) >> 8 LDD R16, Z+2 LDD R17, Z+3 SUBI R16, 3 SBCI R17, 0 CP R18, R16 CPC R19, R17 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); LDI R16, 4 RCALL SetErrorFlag // 114 ChargeParameters.NextState = ST_ERROR; LDI R16, 90 STS (ChargeParameters + 4), R16 // 115 error = TRUE; LDI R24, 1 RJMP ??ConstantCurrent_2 // 116 #endif // 117 } // 118 } else if ((ADCS.avgIBAT >= 0) && // 119 (ADCS.avgIBAT > (ChargeParameters.Current + BAT_CURRENT_HYST))) { ??ConstantCurrent_5: LDI R30, LOW(ADCS) LDI R31, (ADCS) >> 8 LDD R16, Z+22 LDD R17, Z+23 TST R17 BRMI ??ConstantCurrent_2 LDI R30, LOW(ChargeParameters) LDI R31, (ChargeParameters) >> 8 LDD R26, Z+2 LDD R27, Z+3 ADIW R27:R26, 3 LDI R30, LOW(ADCS) LDI R31, (ADCS) >> 8 LDD R16, Z+22 LDD R17, Z+23 CP R26, R16 CPC R27, R17 BRCC ??ConstantCurrent_2 // 120 // 121 if(!PWM_DecrementDutyCycle()) { RCALL PWM_DecrementDutyCycle TST R16 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); LDI R16, 4 RCALL SetErrorFlag // 126 ChargeParameters.NextState = ST_ERROR; LDI R16, 90 STS (ChargeParameters + 4), R16 // 127 error = TRUE; LDI R24, 1 // 128 #endif // 129 } // 130 } // 131 } // 132 } while (!HaltNow() && !error); ??ConstantCurrent_2: RCALL HaltNow TST R16 BRNE ??ConstantCurrent_6 TST R24 BRNE $+2+2 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: LDS R16, (ChargeParameters + 4) LDI R30, 4 RJMP ?EPILOGUE_B4_L09 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 { RCALL ?PROLOGUE4_L09 // 156 unsigned char error = FALSE, LDI R24, 0 // 157 wasStopped = FALSE; LDI R25, 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 TST R16 BREQ ??ConstantVoltage_1 // 167 wasStopped = TRUE; LDI R25, 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 R25 BREQ ??ConstantVoltage_3 // 175 wasStopped = FALSE; LDI R25, 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 R30, LOW(ADCS) LDI R31, (ADCS) >> 8 LDD R18, Z+10 LDD R19, Z+11 LDI R30, LOW(ChargeParameters) LDI R31, (ChargeParameters) >> 8 LD R16, Z LDD R17, Z+1 SUBI R16, 10 SBCI R17, 0 CP R18, R16 CPC R19, R17 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); LDI R16, 4 RCALL SetErrorFlag // 190 ChargeParameters.NextState = ST_ERROR; LDI R16, 90 STS (ChargeParameters + 4), R16 // 191 error = TRUE; LDI R24, 1 RJMP ??ConstantVoltage_2 // 192 #endif // 193 } // 194 } else if (ADCS.VBAT > (ChargeParameters.Voltage + BAT_VOLTAGE_HYST)) { ??ConstantVoltage_4: LDI R30, LOW(ChargeParameters) LDI R31, (ChargeParameters) >> 8 LD R26, Z LDD R27, Z+1 ADIW R27:R26, 10 LDI R30, LOW(ADCS) LDI R31, (ADCS) >> 8 LDD R16, Z+10 LDD R17, Z+11 CP R26, R16 CPC R27, R17 BRCC ??ConstantVoltage_2 // 195 // 196 if(!PWM_DecrementDutyCycle()) { RCALL PWM_DecrementDutyCycle TST R16 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); LDI R16, 4 RCALL SetErrorFlag // 201 ChargeParameters.NextState = ST_ERROR; LDI R16, 90 STS (ChargeParameters + 4), R16 // 202 error = TRUE; LDI R24, 1 // 203 #endif // 204 } // 205 } // 206 } // 207 // 208 } while (!HaltNow() && !error); ??ConstantVoltage_2: RCALL HaltNow TST R16 BRNE ??ConstantVoltage_5 TST R24 BRNE $+2+2 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: LDS R16, (ChargeParameters + 4) LDI R30, 4 RJMP ?EPILOGUE_B4_L09 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 { RCALL ?PROLOGUE4_L09 // 240 unsigned char i, halt = FALSE; LDI R24, 0 // 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) { LDI R25, 1 ??HaltNow_0: TST R25 BRNE $+2+2 RJMP ??HaltNow_1 // 249 if (HaltParameters.HaltFlags & i) { LDS R16, HaltParameters AND R16, R25 TST R16 BRNE $+2+2 RJMP ??HaltNow_2 // 250 switch (i) { MOV R16, R25 SUBI R16, 1 BREQ ??HaltNow_3 DEC R16 BREQ ??HaltNow_4 SUBI R16, 2 BREQ ??HaltNow_5 SUBI R16, 4 BRNE $+2+2 RJMP ??HaltNow_6 SUBI R16, 8 BRNE $+2+2 RJMP ??HaltNow_7 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: LDI R30, LOW(HaltParameters) LDI R31, (HaltParameters) >> 8 LDD R16, Z+13 LDD R17, Z+14 LDI R30, LOW(ADCS) LDI R31, (ADCS) >> 8 LDD R18, Z+10 LDD R19, Z+11 CP R16, R18 CPC R17, R19 BRCC ??HaltNow_8 // 256 HaltParameters.VBATMax = ADCS.VBAT; LDI R30, LOW(ADCS) LDI R31, (ADCS) >> 8 LDD R16, Z+10 LDD R17, Z+11 LDI R30, LOW(HaltParameters) LDI R31, (HaltParameters) >> 8 STD Z+13, R16 STD Z+14, R17 RJMP ??HaltNow_2 // 257 } else if((HaltParameters.VBATMax - ADCS.VBAT) >= // 258 HaltParameters.VoltageDrop) { ??HaltNow_8: LDI R30, LOW(HaltParameters) LDI R31, (HaltParameters) >> 8 LDD R16, Z+13 LDD R17, Z+14 LDI R30, LOW(ADCS) LDI R31, (ADCS) >> 8 LDD R18, Z+10 LDD R19, Z+11 SUB R16, R18 SBC R17, R19 LDI R30, LOW(HaltParameters) LDI R31, (HaltParameters) >> 8 LDD R18, Z+1 LDD R19, Z+2 CP R16, R18 CPC R17, R19 BRCC $+2+2 RJMP ??HaltNow_2 // 259 halt = TRUE; LDI R24, 1 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: LDI R30, LOW(ADCS) LDI R31, (ADCS) >> 8 LDD R16, Z+10 LDD R17, Z+11 LDI R30, LOW(HaltParameters) LDI R31, (HaltParameters) >> 8 LDD R18, Z+3 LDD R19, Z+4 CP R16, R18 CPC R17, R19 BRCC $+2+2 RJMP ??HaltNow_2 // 268 halt = TRUE; LDI R24, 1 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: LDI R30, LOW(HaltParameters) LDI R31, (HaltParameters) >> 8 LDD R16, Z+5 LDD R17, Z+6 LDI R30, LOW(ADCS) LDI R31, (ADCS) >> 8 LDD R18, Z+22 LDD R19, Z+23 CP R16, R18 CPC R17, R19 BRCC $+2+2 RJMP ??HaltNow_2 // 277 halt = TRUE; LDI R24, 1 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: LDI R30, LOW(HaltParameters) LDI R31, (HaltParameters) >> 8 LDD R16, Z+15 LDD R17, Z+16 LDI R30, LOW(ADCS) LDI R31, (ADCS) >> 8 LDD R18, Z+4 LDD R19, Z+5 CP R16, R18 CPC R17, R19 BRCC ??HaltNow_9 // 289 HaltParameters.LastNTC = ADCS.rawNTC; LDI R30, LOW(ADCS) LDI R31, (ADCS) >> 8 LDD R16, Z+4 LDD R17, Z+5 LDI R30, LOW(HaltParameters) LDI R31, (HaltParameters) >> 8 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_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: LDI R30, LOW(HaltParameters) LDI R31, (HaltParameters) >> 8 LDD R26, Z+15 LDD R27, Z+16 LDI R30, LOW(ADCS) LDI R31, (ADCS) >> 8 LDD R16, Z+4 LDD R17, Z+5 SUB R26, R16 SBC R27, R17 LDS R20, (BattData + 3) LDI R21, 0 LDI R30, LOW(HaltParameters) LDI R31, (HaltParameters) >> 8 LDD R16, Z+11 LDD R17, Z+12 RCALL ?S_MUL_L02 CP R26, R16 CPC R27, R17 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)) { LDI R16, 3 RCALL Time_Left TST R16 BREQ ??HaltNow_10 // 300 halt = TRUE; LDI R24, 1 RJMP ??HaltNow_2 // 301 } else { // 302 HaltParameters.LastNTC = ADCS.rawNTC; ??HaltNow_10: LDI R30, LOW(ADCS) LDI R31, (ADCS) >> 8 LDD R16, Z+4 LDD R17, Z+5 LDI R30, LOW(HaltParameters) LDI R31, (HaltParameters) >> 8 STD Z+15, R16 STD Z+16, R17 // 303 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_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: LDI R16, 1 RCALL Time_Left TST R16 BRNE ??HaltNow_2 // 313 halt = TRUE; 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) { LDI R30, LOW(HaltParameters) LDI R31, (HaltParameters) >> 8 LD R16, Z SBRS R16, 5 RJMP ??HaltNow_2 // 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 LDS R18, BattActive LDI R19, 0 LDI R20, LOW(BattControl) LDI R21, (BattControl) >> 8 ADD R20, R18 ADC R21, R19 RCALL __eeput8_16 // 320 BattData.Exhausted = TRUE; LDI R30, LOW(BattData) LDI R31, (BattData) >> 8 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 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: LSL R25 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: LDI R30, LOW(HaltParameters) LDI R31, (HaltParameters) >> 8 LDD R18, Z+9 LDD R19, Z+10 LDS R16, (BattData + 2) MOV R17, R16 LSL R17 SBC R17, R17 CP R18, R16 CPC R19, R17 BRGE ??HaltNow_11 LDS R16, (BattData + 2) MOV R17, R16 LSL R17 SBC R17, R17 LDI R30, LOW(HaltParameters) LDI R31, (HaltParameters) >> 8 LDD R18, Z+7 LDD R19, Z+8 CP R16, R18 CPC R17, R19 BRCS ??HaltNow_12 // 339 // 340 PWM_Stop(); ??HaltNow_11: RCALL PWM_Stop // 341 SetErrorFlag(ERR_BATTERY_TEMPERATURE); LDI R16, 8 RCALL SetErrorFlag // 342 ChargeParameters.NextState = ST_ERROR; LDI R16, 90 STS (ChargeParameters + 4), R16 // 343 halt = TRUE; LDI R24, 1 // 344 } // 345 // 346 // Battery not OK? // 347 if (!BatteryCheck()) { ??HaltNow_12: RCALL BatteryCheck TST R16 BRNE ??HaltNow_13 // 348 PWM_Stop(); RCALL PWM_Stop // 349 ChargeParameters.NextState = ST_INIT; LDI R16, 10 STS (ChargeParameters + 4), R16 // 350 halt = TRUE; LDI R24, 1 // 351 } // 352 // 353 // Is mains voltage OK? // 354 if (!ADCS.Mains) { ??HaltNow_13: LDI R30, LOW(ADCS) LDI R31, (ADCS) >> 8 LD R16, Z SBRC R16, 6 RJMP ??HaltNow_14 // 355 PWM_Stop(); RCALL PWM_Stop // 356 ChargeParameters.NextState = ST_SLEEP; LDI R16, 40 STS (ChargeParameters + 4), R16 // 357 halt = TRUE; LDI R24, 1 // 358 } // 359 // 360 return(halt); ??HaltNow_14: MOV R16, R24 LDI R30, 4 RJMP ?EPILOGUE_B4_L09 // 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 // 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