chargefunc.c

Go to the documentation of this file.
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 }

Generated on Tue Sep 4 19:17:55 2007 for AVR463 Charging NiMH Batteries with ATAVRBC100 by  doxygen 1.5.2