00001 /* This file has been prepared for Doxygen automatic documentation generation.*/ 00030 #include <ioavr.h> 00031 00032 #include "enums.h" 00033 #include "structs.h" 00034 00035 #include "ADC.h" 00036 #include "battery.h" 00037 #include "chargefunc.h" 00038 #include "main.h" 00039 #include "menu.h" 00040 #include "PWM.h" 00041 #include "statefunc.h" 00042 #include "time.h" 00043 00044 #ifdef NIMH 00045 #include "NIMHspecs.h" 00046 #endif // NIMH 00047 00048 #ifdef LIION 00049 #include "LIIONspecs.h" 00050 #endif // LIION 00051 00052 00053 //****************************************************************************** 00054 // Variables 00055 //****************************************************************************** 00057 ChargeParameters_t ChargeParameters; 00058 00060 HaltParameters_t HaltParameters; 00061 00062 00063 //****************************************************************************** 00064 // Functions 00065 //****************************************************************************** 00080 unsigned char ConstantCurrent(void) 00081 { 00082 unsigned char error = FALSE, 00083 wasStopped = FALSE; 00084 00085 do { 00086 // Wait for ADC conversions to complete. 00087 ADC_Wait(); 00088 00089 // If Master has flagged for a charge inhibit, pause charging. 00090 // (This is to prevent damage during prolonged serial communication.) 00091 if (BattControl[BattActive].ChargeInhibit) { 00092 wasStopped = TRUE; 00093 Time_Stop(); 00094 OCR1B = 0; 00095 } else { 00096 // Continue charging! 00097 if (wasStopped) { 00098 wasStopped = FALSE; 00099 00100 // Timer variables are not reset by this. 00101 Time_Start(); 00102 } 00103 00104 // Adjust the charge current to within ChargeParameters.Current 00105 // +/- BAT_CURRENT_HYST. 00106 if ((ADCS.avgIBAT < 0) || 00107 (ADCS.avgIBAT < (ChargeParameters.Current - BAT_CURRENT_HYST))) { 00108 00109 if(!PWM_IncrementDutyCycle()) { 00110 #ifdef ABORT_IF_PWM_MAX 00111 // If the duty cycle cannot be incremented, flag error and 00112 // go to error state. 00113 SetErrorFlag(ERR_PWM_CONTROL); 00114 ChargeParameters.NextState = ST_ERROR; 00115 error = TRUE; 00116 #endif 00117 } 00118 } else if ((ADCS.avgIBAT >= 0) && 00119 (ADCS.avgIBAT > (ChargeParameters.Current + BAT_CURRENT_HYST))) { 00120 00121 if(!PWM_DecrementDutyCycle()) { 00122 #ifdef ABORT_IF_PWM_MIN 00123 // If the duty cycle cannot be decremented, flag error and 00124 // go to error state. 00125 SetErrorFlag(ERR_PWM_CONTROL); 00126 ChargeParameters.NextState = ST_ERROR; 00127 error = TRUE; 00128 #endif 00129 } 00130 } 00131 } 00132 } while (!HaltNow() && !error); 00133 00134 // Return the next state to Charge(). If an error has occured, this will 00135 // point to some other state than the next state of charging. 00136 return(ChargeParameters.NextState); 00137 } 00138 00139 00154 unsigned char ConstantVoltage(void) 00155 { 00156 unsigned char error = FALSE, 00157 wasStopped = FALSE; 00158 00159 do{ 00160 00161 // Wait for ADC conversions to complete. 00162 ADC_Wait(); 00163 00164 // If Master has flagged for a charge inhibit, pause charging. 00165 // (This is to prevent damage during prolonged serial communication.) 00166 if (BattControl[BattActive].ChargeInhibit) { 00167 wasStopped = TRUE; 00168 Time_Stop(); 00169 OCR1B = 0; 00170 } 00171 00172 else { 00173 // Continue charging! 00174 if (wasStopped) { 00175 wasStopped = FALSE; 00176 00177 // Timer variables aren't reset by this. 00178 Time_Start(); 00179 } 00180 00181 // Adjust the charge voltage to within ChargeParameters.Voltage 00182 // +/- BAT_VOLTAGE_HYST. 00183 if (ADCS.VBAT < (ChargeParameters.Voltage - BAT_VOLTAGE_HYST)) { 00184 00185 if(!PWM_IncrementDutyCycle()) { 00186 #ifdef ABORT_IF_PWM_MAX 00187 // Flag PWM control error and go to error-state if the duty 00188 // cycle cannot be incremented. 00189 SetErrorFlag(ERR_PWM_CONTROL); 00190 ChargeParameters.NextState = ST_ERROR; 00191 error = TRUE; 00192 #endif 00193 } 00194 } else if (ADCS.VBAT > (ChargeParameters.Voltage + BAT_VOLTAGE_HYST)) { 00195 00196 if(!PWM_DecrementDutyCycle()) { 00197 #ifdef ABORT_IF_PWM_MIN 00198 // Flag PWM control error and go to error-state if duty 00199 // cycle cannot be decremented. 00200 SetErrorFlag(ERR_PWM_CONTROL); 00201 ChargeParameters.NextState = ST_ERROR; 00202 error = TRUE; 00203 #endif 00204 } 00205 } 00206 } 00207 00208 } while (!HaltNow() && !error); 00209 00210 // Return the next state to Charge(). If an error has occured, this will 00211 // point to some other state than the next state of charging. 00212 return(ChargeParameters.NextState); 00213 } 00214 00215 00238 unsigned char HaltNow(void) 00239 { 00240 unsigned char i, halt = FALSE; 00241 00242 // Wait for a full ADC-cycle to finish. 00243 ADC_Wait(); 00244 00245 // Evaluate ADC readings according to HaltFlags. Flag errors if selected. 00246 // If an error is flagged, ChargeParameters.NextState is set to ST_ERROR. 00247 // (Gets overridden if either mains is failing, or the battery changes.) 00248 for (i = 0x01; i != 0; i <<= 1) { 00249 if (HaltParameters.HaltFlags & i) { 00250 switch (i) { 00251 // Is VBAT less than the recorded maximum? 00252 case HALT_VOLTAGE_DROP: 00253 00254 // Update VBATMax if VBAT is higher. Evaluate for halt otherwise. 00255 if (ADCS.VBAT > HaltParameters.VBATMax) { 00256 HaltParameters.VBATMax = ADCS.VBAT; 00257 } else if((HaltParameters.VBATMax - ADCS.VBAT) >= 00258 HaltParameters.VoltageDrop) { 00259 halt = TRUE; 00260 } 00261 break; 00262 00263 00264 // Has VBAT reached the maximum limit? 00265 case HALT_VOLTAGE_MAX: 00266 00267 if (ADCS.VBAT >= HaltParameters.VoltageMax) { 00268 halt = TRUE; 00269 } 00270 break; 00271 00272 00273 // Has IBAT reached the minimum limit? 00274 case HALT_CURRENT_MIN: 00275 00276 if (ADCS.avgIBAT <= HaltParameters.CurrentMin) { 00277 halt = TRUE; 00278 } 00279 break; 00280 00281 00282 // Is the temperature rising too fast? 00283 case HALT_TEMPERATURE_RISE: 00284 00285 // If rawNTC has increased, the temperature has dropped. 00286 // We can store this value for now, and start the timer. 00287 // Otherwise, check if NTC has changed too fast. 00288 if (ADCS.rawNTC > HaltParameters.LastNTC) { 00289 HaltParameters.LastNTC = ADCS.rawNTC; 00290 Time_Set(TIMER_TEMP,0,30,0); 00291 00292 // Is the increase in temperature greater than the set threshold? 00293 } else if ((HaltParameters.LastNTC - ADCS.rawNTC) >= 00294 (BattData.ADCSteps * HaltParameters.TemperatureRise)) { 00295 00296 // If this happened within a timeframe of 30 seconds, the 00297 // temperature is rising faster than we want. 00298 // If not, update LastNTC and reset timer. 00299 if (Time_Left(TIMER_TEMP)) { 00300 halt = TRUE; 00301 } else { 00302 HaltParameters.LastNTC = ADCS.rawNTC; 00303 Time_Set(TIMER_TEMP,0,30,0); 00304 } 00305 } 00306 break; 00307 00308 00309 // Is there any time left? 00310 case HALT_TIME: 00311 00312 if (!Time_Left(TIMER_CHG)) { 00313 halt = TRUE; 00314 00315 // If exhaustion flagging is selected, stop the PWM, disable the 00316 // battery and flag it as exhausted. Make ST_ERROR next state. 00317 if (HaltParameters.HaltFlags & HALT_FLAG_EXHAUSTION) { 00318 PWM_Stop(); 00319 BattControl[BattActive].Enabled = FALSE; 00320 BattData.Exhausted = TRUE; 00321 SetErrorFlag(ERR_BATTERY_EXHAUSTED); 00322 ChargeParameters.NextState = ST_ERROR; 00323 } 00324 } 00325 break; 00326 00327 00328 default: // Shouldn't end up here, but is needed for MISRA compliance. 00329 break; 00330 } 00331 } 00332 } 00333 00334 // Standard checks: 00335 00336 // Battery too cold or hot? 00337 if ((BattData.Temperature <= HaltParameters.TemperatureMin) || 00338 (BattData.Temperature >= HaltParameters.TemperatureMax)) { 00339 00340 PWM_Stop(); 00341 SetErrorFlag(ERR_BATTERY_TEMPERATURE); 00342 ChargeParameters.NextState = ST_ERROR; 00343 halt = TRUE; 00344 } 00345 00346 // Battery not OK? 00347 if (!BatteryCheck()) { 00348 PWM_Stop(); 00349 ChargeParameters.NextState = ST_INIT; 00350 halt = TRUE; 00351 } 00352 00353 // Is mains voltage OK? 00354 if (!ADCS.Mains) { 00355 PWM_Stop(); 00356 ChargeParameters.NextState = ST_SLEEP; 00357 halt = TRUE; 00358 } 00359 00360 return(halt); 00361 }
1.5.2