Contains functions for enabling/disabling batteries, and looking up their status and specifications using the ADC.
Definition in file battery.c.
#include <ioavr.h>
#include <inavr.h>
#include "structs.h"
#include "enums.h"
#include "ADC.h"
#include "battery.h"
#include "main.h"
#include "OWI.h"
#include "time.h"
#include "NIMHspecs.h"
Include dependency graph for battery.c:

Go to the source code of this file.
Functions | |
| unsigned char | BatteryCheck (void) |
| Checks if battery has changed. | |
| unsigned char | BatteryDataRefresh (void) |
| Refreshes battery data in the EEPROM. | |
| unsigned char | BatteryStatusRefresh (void) |
| Refreshes battery status information. | |
| void | DisableBatteries (void) |
| Disables both batteries. | |
| void | EnableBattery (unsigned char bat) |
| Enables specified battery. | |
| void | NTCLookUp (void) |
| Calculates temperature from a lookup table. | |
| unsigned char | RIDLookUp (void) |
| Looks up battery data from RID table. | |
Variables | |
| unsigned char | BattActive |
| Global that indicates current battery (0 = battery A, 1 = B). | |
| __eeprom Battery_t | BattControl [2] |
| Holds control data for both batteries. | |
| Batteries_t | BattData |
| Holds data for the current battery. | |
| __eeprom unsigned char | BattEEPROM [4][32] |
| Storage space for data from the batteries' own EPROMs. | |
| const NTC_Lookup_t | NTC [NTC_TABLE_SIZE] |
| NTC lookup-table. | |
| const RID_Lookup_t | RID [RID_TABLE_SIZE] |
| RID lookup-table. | |
| unsigned char BatteryCheck | ( | void | ) |
Checks if battery has changed.
Stores current capacity, then attempts to refresh battery status.
If the refresh is successful, old capacity is compared with the new one.
| FALSE | Battery is disconnected, or capacity has changed. | |
| TRUE | All OK. |
Definition at line 136 of file battery.c.
References BattData, BatteryStatusRefresh(), Batteries_struct::Capacity, FALSE, and TRUE.
00137 { 00138 unsigned char success = TRUE; 00139 unsigned int oldCapacity; 00140 00141 // Save to see if battery data has changed. 00142 oldCapacity = BattData.Capacity; 00143 00144 if (!BatteryStatusRefresh()) { 00145 success = FALSE; // Battery not present or RID was invalid. 00146 } 00147 00148 if (oldCapacity != BattData.Capacity) { 00149 success = FALSE; // Battery configuration has changed. 00150 } 00151 00152 return(success); 00153 }
Here is the call graph for this function:

| unsigned char BatteryDataRefresh | ( | void | ) |
Refreshes battery data in the EEPROM.
Attempts to read 4 pages of 32 bytes each from the battery's EPROM and store these data in on-chip EEPROM.
If unsuccessful (CRC doesn't check out), the on-chip EEPROM is cleared.
| FALSE | Refresh failed. | |
| TRUE | Refresh successful. |
Definition at line 236 of file battery.c.
References BattData, BattEEPROM, Batteries_struct::Circuit, DS2505_DATA_READ, FALSE, OW_DS2505, OWI_ComputeCRC8(), OWI_DetectPresence(), OWI_ReceiveByte(), OWI_ROM_READ, OWI_SendByte(), OWIBUS, and TRUE.
Referenced by BatteryControl().
00237 { 00238 unsigned char offset; 00239 unsigned char i, crc, family, temp, page; 00240 unsigned char success; 00241 00242 // Look for EPROM and read 4 pages of 32 bytes each worth of data, if found. 00243 for (page = 0; page < 4; page++) { 00244 success = FALSE; 00245 00246 if (OWI_DetectPresence(OWIBUS) == OWIBUS) { 00247 00248 // Presence detected, check type and CRC. 00249 OWI_SendByte(OWI_ROM_READ, OWIBUS); 00250 family = OWI_ReceiveByte(OWIBUS); 00251 crc = OWI_ComputeCRC8(family,0); 00252 00253 for (i = 0; i < 6; i++) { 00254 crc = OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc); 00255 } 00256 00257 // CRC ok, device found. 00258 if (OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc) == 0) { 00259 BattData.Circuit = family; 00260 00261 // For now, we only read data from DS2505 EPROMs. 00262 if (BattData.Circuit == OW_DS2505) { 00263 offset = page*32; 00264 OWI_SendByte(DS2505_DATA_READ, OWIBUS); // Command: read data. 00265 OWI_SendByte(offset, OWIBUS); // Data: low address. 00266 OWI_SendByte(0, OWIBUS); // Data: high address. 00267 00268 // Calculate checksums. 00269 crc = OWI_ComputeCRC8(DS2505_DATA_READ,0); 00270 crc = OWI_ComputeCRC8(offset,crc); 00271 crc = OWI_ComputeCRC8(0,crc); 00272 00273 // Command received succesfully, now start reading data 00274 // and writing it to EEPROM. 00275 if (OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc) == 0) { 00276 crc = 0; 00277 00278 // Fill page with data. 00279 for (i=0; i<32; i++) { 00280 temp = OWI_ReceiveByte(OWIBUS); 00281 crc = OWI_ComputeCRC8(temp, crc); 00282 BattEEPROM[page][i] = temp; 00283 } 00284 00285 if (OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc) == 0) { 00286 success = TRUE; // Data read OK 00287 } 00288 } else { // Not able to start reading data. 00289 } 00290 } else { // Wrong device type. 00291 } 00292 } else { // No device found. 00293 } 00294 } else { // No presence detected on one-wire bus. 00295 } 00296 00297 // Erase local EEPROM page if there were any errors during transfer. 00298 if (!success) { 00299 for (i=0; i<32; i++) { 00300 BattEEPROM[page][i] = 0; 00301 } 00302 } 00303 } 00304 00305 return(success); 00306 }
Here is the call graph for this function:

| unsigned char BatteryStatusRefresh | ( | void | ) |
Refreshes battery status information.
Refreshes battery status information, if it is present, based on RID and NTC (read by ADC).
The battery must have been enabled and a complete set of ADC data must have been collected before calling.
| FALSE | No battery present. | |
| TRUE | Battery present, status refreshed. |
Definition at line 169 of file battery.c.
References ADCS, ADC_Status_struct::avgIBAT, BAT_VOLTAGE_LOW, BAT_VOLTAGE_MIN, BattData, Batteries_struct::Capacity, Batteries_struct::Charged, Batteries_struct::Circuit, FALSE, Batteries_struct::HasRID, Batteries_struct::Low, Batteries_struct::MaxCurrent, Batteries_struct::MaxTime, Batteries_struct::MinCurrent, NTCLookUp(), OW_NONE, Batteries_struct::Present, RIDLookUp(), Batteries_struct::Temperature, TRUE, and ADC_Status_struct::VBAT.
Referenced by BatteryCheck(), BatteryControl(), Initialize(), and Sleep().
00170 { 00171 // Assume the worst.. 00172 unsigned char success = FALSE; 00173 00174 BattData.Present = FALSE; 00175 BattData.Charged = FALSE; 00176 BattData.Low = TRUE; 00177 BattData.Circuit = OW_NONE; 00178 BattData.Temperature = 0; 00179 BattData.Capacity = 0; 00180 BattData.MaxCurrent = 0; 00181 BattData.MaxTime = 0; 00182 BattData.MinCurrent = 0; 00183 00184 NTCLookUp(); 00185 BattData.HasRID = RIDLookUp(); 00186 00187 // Is the battery voltage above minimum safe cell voltage? 00188 if (ADCS.VBAT >= BAT_VOLTAGE_MIN) { 00189 BattData.Low = FALSE; 00190 } 00191 00192 // Is the battery charged? 00193 if (ADCS.VBAT >= BAT_VOLTAGE_LOW) { 00194 BattData.Charged = TRUE; 00195 } 00196 00197 // If we are not charging, yet VBAT is above safe limit, battery is present. 00198 // If we are charging and there's a current flowing, the battery is present. 00199 00205 if (((OCR1B == 0) && (!BattData.Low)) || 00206 ((OCR1B != 0) && (ADCS.avgIBAT > 0))) { 00207 BattData.Present = TRUE; 00208 success = TRUE; 00209 } else { 00210 BattData.Low = FALSE; // (This is just a technicality..) 00211 success = FALSE; 00212 } 00213 00214 #ifndef ALLOW_NO_RID 00215 // Return FALSE if no valid RID entry was found, to stop charging. 00216 if(!BattData.HasRID) { 00217 success = FALSE; 00218 } 00219 #endif 00220 00221 return(success); 00222 }
Here is the call graph for this function:

| void DisableBatteries | ( | void | ) |
Disables both batteries.
Clears PB4 and PB5 in PORTB, disabling both batteries.
Definition at line 340 of file battery.c.
Referenced by BatteryControl(), Error(), Initialize(), JumperCheck(), and Sleep().
00341 { 00342 // Turn off LEDs and disconnect batteries. 00343 PORTB &= ~((1<<PB4)|(1<<PB5)); 00344 }
| void EnableBattery | ( | unsigned char | bat | ) |
Enables specified battery.
Updates BattActive to specified battery, then sets PB4/PB5 and clears PB5/PB4 in PORTB, depending on which battery is specified.
The function takes 100 ms to allow the port switch to settle.
| bat | Specifies which battery to enable (0 = battery A, 1 = B) |
Definition at line 317 of file battery.c.
References BattActive, Time_Left(), Time_Set(), and TIMER_GEN.
Referenced by BatteryControl(), Initialize(), and Sleep().
00318 { 00319 // Use general timer, set timeout to 100ms. 00320 Time_Set(TIMER_GEN,0,0,100); 00321 00322 // Set specified battery as the active one. 00323 BattActive = bat; 00324 00325 // Enable current battery in hardware, light LED & connect battery. 00326 PORTB |= (1 << (PB4+bat)); 00327 00328 // Disconnect other battery. 00329 PORTB &= ~(1<<(PB5-bat)); 00330 00331 do { // Let port switch settle. 00332 } while (Time_Left(TIMER_GEN)); 00333 }
Here is the call graph for this function:

| void NTCLookUp | ( | void | ) |
Calculates temperature from a lookup table.
Looks up the highest NTC value below or equal to the measured one.
With the current lookup table, temperature is calculated with the formula:
4*(index of entry) - 2*(measured NTC - NTC from entry) / (ADCsteps of entry)
If no valid entry is found, battery temperature is set to 80.
Definition at line 398 of file battery.c.
References NTC_Lookup_struct::ADC, ADCS, Batteries_struct::ADCSteps, NTC_Lookup_struct::ADCsteps, BattData, FALSE, NTC, NTC_TABLE_SIZE, ADC_Status_struct::rawNTC, Batteries_struct::Temperature, and TRUE.
Referenced by BatteryStatusRefresh().
00399 { 00400 unsigned char i; 00401 unsigned char found = FALSE; 00402 00403 // Lookup in the NTC-table. Use the first entry which is equal or below 00404 // sampled NTC. Calculate temperature by using the index number, and the 00405 // difference between the measured NTC value and the one in the entry. 00406 for (i=0 ; (i < NTC_TABLE_SIZE) && (!found); i++) { 00407 if (ADCS.rawNTC >= NTC[i].ADC) { 00408 BattData.Temperature = (i<<2) ; 00409 BattData.ADCSteps = NTC[i].ADCsteps; 00410 BattData.Temperature -= ((ADCS.rawNTC - NTC[i].ADC)<<1) / BattData.ADCSteps; 00411 00412 found = TRUE; // Could be done with a break, but that violates MISRA. 00413 } 00414 } 00415 00416 // For safety, is temperature is greater than the NTC 00417 if (!found) { 00418 BattData.Temperature = 80; 00419 } 00420 }
| unsigned char RIDLookUp | ( | void | ) |
Looks up battery data from RID table.
Attempts to find data for the battery from the RID lookup-table.
If no valid entry is found, default data (defined in battery.h) are used.
| TRUE | Entry found, battery data updated. | |
| FALSE | No entry found, using defaults for battery data. |
Definition at line 356 of file battery.c.
References ADCS, BattData, Batteries_struct::Capacity, RID_Lookup_struct::Capacity, FALSE, RID_Lookup_struct::High, RID_Lookup_struct::Icharge, RID_Lookup_struct::ICutOff, RID_Lookup_struct::Low, Batteries_struct::MaxCurrent, Batteries_struct::MaxTime, Batteries_struct::MinCurrent, ADC_Status_struct::rawRID, RID, RID_TABLE_SIZE, RID_Lookup_struct::tCutOff, and TRUE.
Referenced by BatteryStatusRefresh().
00357 { 00358 unsigned char i, found = FALSE; 00359 00360 // Lookup in the RID-table. If measured RID is within the limits 00361 // of an entry, those data are used, and TRUE is returned. 00362 for (i = 0 ; i < RID_TABLE_SIZE; i++) { 00363 if (ADCS.rawRID >= RID[i].Low) { 00364 if (ADCS.rawRID <= RID[i].High) { 00365 BattData.Capacity = RID[i].Capacity; 00366 BattData.MaxCurrent = RID[i].Icharge; 00367 BattData.MaxTime = RID[i].tCutOff; 00368 BattData.MinCurrent = RID[i].ICutOff; 00369 00370 found = TRUE; 00371 } 00372 } 00373 } 00374 00375 // If no valid entry is found, use defaults and return FALSE. 00376 if (!found) { 00377 BattData.Capacity = DEF_BAT_CAPACITY; 00378 BattData.MaxCurrent = DEF_BAT_CURRENT_MAX; 00379 BattData.MaxTime = DEF_BAT_TIME_MAX; 00380 BattData.MinCurrent = DEF_BAT_CURRENT_MIN; 00381 } 00382 00383 return(found); 00384 }
| unsigned char BattActive |
Global that indicates current battery (0 = battery A, 1 = B).
Definition at line 75 of file battery.c.
Referenced by Charge(), ConstantCurrent(), ConstantVoltage(), EnableBattery(), Error(), Initialize(), and USI_OVF_ISR().
| __eeprom Battery_t BattControl[2] |
Initial value:
Holds control data for both batteries.
Definition at line 60 of file battery.c.
Referenced by BatteryControl(), Charge(), ConstantCurrent(), ConstantVoltage(), Error(), and USI_OVF_ISR().
Holds data for the current battery.
Definition at line 64 of file battery.c.
Referenced by BatteryCheck(), BatteryControl(), BatteryDataRefresh(), BatteryStatusRefresh(), Charge(), Error(), NTCLookUp(), RIDLookUp(), Sleep(), and USI_OVF_ISR().
| __eeprom unsigned char BattEEPROM[4][32] |
Storage space for data from the batteries' own EPROMs.
Definition at line 71 of file battery.c.
Referenced by BatteryDataRefresh(), and Initialize().
| const NTC_Lookup_t NTC[NTC_TABLE_SIZE] |
Initial value:
{
{1002, 23}, {953, 25}, {902, 26}, {849, 27}, {796, 27},
{742, 27}, {689, 26}, {637, 26}, {587, 25}, {539, 24},
{494, 22}, {451, 21}, {412, 19}, {375, 18}, {341, 17},
{310, 15}, {282, 14}, {256, 13}, {233, 11}, {212, 10}
}
The first entry is 0 degrees. For every entry after, temperature increases with 4 degrees. With 20 entries, the last one equals (20-1)*4 = 76 degrees.
It must be sorted in descending ADC order.
NTCLookUp() must be modified if this table is changed so that:
Definition at line 106 of file battery.c.
Referenced by NTCLookUp().
| const RID_Lookup_t RID[RID_TABLE_SIZE] |
Initial value:
{
{558, 659, 3900, 550, 260, 300, 10},
{744, 843, 6800, 750, 360, 300, 14},
{869, 958, 10000, 1000, 475, 300, 19},
{1097, 1153, 24000, 2000, 475, 420, 38}
}
Contains Resistor ID data specified by manufacturer.
Definition at line 84 of file battery.c.
Referenced by RIDLookUp().
1.5.2