}\r
myprintf_P("average IBAT %d [mA]\n", ADCS.avgIBAT);\r
\r
+ Batteries_t BattData;\r
+ myprintf_P("Current Battery:\n");\r
+ out = BC100_SLAVE_READ | BC100_SLAVE_SRAM | sizeof(BattData);\r
+ SPI_rw( out );\r
+ out = ADR_BATTDATA;\r
+ in = SPI_rw( out );\r
+ myprintf_P("In1 : 0x%02x (expected 0xcc)\n", in );\r
+ in = SPI_rw( dummy );\r
+ myprintf_P("In2 : 0x%02x (expected 0xbb)\n", in );\r
+ i = sizeof(BattData);\r
+ while ( i-- > 0 ) {\r
+ *( (unsigned char*)&BattData + i ) = SPI_rw(dummy);\r
+ }\r
+ if ( BattData.Present ) {\r
+ myprintf_P("Battery found\n");\r
+ if ( BattData.Charged ) {\r
+ myprintf_P("- fully charged\n");\r
+ }\r
+ if ( BattData.Low ) {\r
+ myprintf_P("- low voltage\n");\r
+ }\r
+ if ( BattData.Exhausted) {\r
+ myprintf_P("- exhausted\n");\r
+ }\r
+ if ( BattData.HasRID) {\r
+ myprintf_P("- has a ID-Resistor\n");\r
+ }\r
+ myprintf_P("Safety circuit ID %d\n", BattData.Circuit );\r
+ myprintf_P("Tempearture %d centi-degree C\n", BattData.Temperature );\r
+ myprintf_P("ADCSteps/half degree %d\n", BattData.ADCSteps);\r
+ myprintf_P("Capacity %d mAh\n", BattData.Capacity);\r
+ myprintf_P("max. Current %d mA\n", BattData.MaxCurrent);\r
+ myprintf_P("max. cut-off Time %d min\n", BattData.MaxTime);\r
+ myprintf_P("min. cut-off Current %d mA\n", BattData.MinCurrent);\r
+ }\r
+ else {\r
+ myprintf_P("Battery not found\n");\r
+ }\r
+\r
SPI_release();\r
\r
return err;\r
\r
// Scale voltage according to jumper setting.\r
ADCS.VBAT = ScaleU(eeprom_read_byte(&VBAT_RANGE), (unsigned int)ADC); // ADC is a short.\r
+ __asm__ __volatile__ ("NOP"::);\r
Next=0x17;\r
// Signed = TRUE; // Next conversion is bipolar. Halves sensitivity!\r
break;\r
#ifndef LIIONSPECS_H\r
#define LIIONSPECS_H\r
\r
+/*\r
+ Information on Varta EasyPack 66590 711 099 collected by M. Thomas:\r
+\r
+ Connections:\r
+ Pad 1 - marked with + : Battery +\r
+ Pad 2 - not marked : ID-Resistor (RID) to Pad 4, 3.9kOhm\r
+ Pad 3 - not marked : NTC to Pad 4, 10kOhm B=3435K\r
+ Pad 4 - marked with - : Battery -\r
+ -> 1Wire not available\r
+\r
+ Capacity: nom. 550mAh (min. 520 mAh) at 0.2C from 4.2V to 3.0V\r
+ Nominal Voltage: 3.7V, Range: 2.75V - 4.2V\r
+ Charging Method: Constant Current + Constant Voltage\r
+ Charge Voltage: 4.2V\r
+ Initial charge Current: std. 260mA, rapid 520mA\r
+ Charging cut of either:\r
+ (a) at time: std. 5h, rapid 3h\r
+ (b) by min current of 10mA\r
+ Temparature 0 to 45degC\r
+ Discharge max. Current: 1040mA\r
+ Protection:\r
+ overcharge : 4.35V (resume at 4.0V)\r
+ discharge : 2.2V\r
+ overcurrent: 3.0A\r
+\r
+ Additional from PoliFlex-Handbook:\r
+ - fast charging in termperatur-range 0 - 45degC\r
+ - max charge current 1C (=550mA here)\r
+ - max charge current has to be limited stricly to 4,2V +/- 50mV\r
+ - stop charge 3h after start of when current is <0.02C (=11mA here)\r
+*/\r
+\r
\r
//******************************************************************************\r
// Cell limits\r
//******************************************************************************\r
// This is for common NiMH batteries.\r
#define CELL_VOLTAGE_SAFETY 0 /*!< \brief Buffer for unmatched batteries.\r
- * \r
+ *\r
* If we are charging a multicell battery and the cells aren't matched, we\r
* may risk overcharging at least one. Therefore, we may subtract this constant\r
* per additional cell in battery to allow for a "buffer".\r
//! Charge voltage hysteresis, in mV.\r
#define BAT_VOLTAGE_HYST 10\r
\r
-//! Maximum battery voltage, in mV. \r
+//! Maximum battery voltage, in mV.\r
#define BAT_VOLTAGE_MAX (CELL_VOLTAGE_MAX * BAT_CELL_NUMBER) - \\r
((BAT_CELL_NUMBER - 1) * CELL_VOLTAGE_SAFETY)\r
\r
CFLAGS += -gdwarf-2 -std=gnu99 -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -ffunction-sections\r
CFLAGS += -fno-inline-small-functions -fno-split-wide-types\r
CFLAGS += -Wall -Wstrict-prototypes -Wundef -Wa,-adhlns=./$(*F).lst\r
+CFLAGS += -fno-inline-small-functions -fno-split-wide-types\r
CFLAGS += -MMD -MP -MF dep/$(@F).d \r
CFLAGS += -DLIION\r
\r
\r
*\r
* \par Documentation\r
- * For comprehensive code documentation, supported compilers, compiler \r
+ * For comprehensive code documentation, supported compilers, compiler\r
* settings and supported devices see readme.html\r
*\r
* \author\r
* Atmel Corporation: http://www.atmel.com \n\r
* Support email: avr@atmel.com\r
*\r
- * \r
+ *\r
* $Name$\r
* $Revision: 2299 $\r
* $RCSfile$\r
};\r
*/\r
\r
- \r
+\r
//******************************************************************************\r
// Functions\r
//******************************************************************************\r
*\r
* Stores current capacity, then attempts to refresh battery status.\n\r
* If the refresh is successful, old capacity is compared with the new one.\r
- * \r
+ *\r
* \retval FALSE Battery is disconnected, or capacity has changed.\r
* \retval TRUE All OK.\r
*/\r
{\r
unsigned char success = TRUE;\r
unsigned int oldCapacity;\r
- \r
+\r
// Save to see if battery data has changed.\r
- oldCapacity = BattData.Capacity; \r
- \r
+ oldCapacity = BattData.Capacity;\r
+\r
if (!BatteryStatusRefresh()) {\r
success = FALSE; // Battery not present or RID was invalid.\r
}\r
- \r
+\r
if (oldCapacity != BattData.Capacity) {\r
success = FALSE; // Battery configuration has changed.\r
}\r
unsigned char sreg_saved;\r
unsigned int adcs_VBAT_tmp;\r
signed int adcs_avgIBAT_tmp;\r
- \r
+\r
BattData.Present = FALSE;\r
BattData.Charged = FALSE;\r
BattData.Low = TRUE;\r
\r
// If we are not charging, yet VBAT is above safe limit, battery is present.\r
// If we are charging and there's a current flowing, the battery is present.\r
- \r
+\r
/*! \todo If ABORT_IF_PWM_MAX is defined this last check battery presence\r
* check is redundant since charging will be aborted due to low current at\r
* max duty cycle. That is preferrable since the charge current reading is\r
unsigned char offset;\r
unsigned char i, crc, family, temp, page;\r
unsigned char success;\r
- \r
+\r
// Look for EPROM and read 4 pages of 32 bytes each worth of data, if found.\r
for (page = 0; page < 4; page++) {\r
success = FALSE;\r
- \r
+\r
if (OWI_DetectPresence(OWIBUS) == OWIBUS) {\r
- \r
+\r
// Presence detected, check type and CRC.\r
OWI_SendByte(OWI_ROM_READ, OWIBUS);\r
family = OWI_ReceiveByte(OWIBUS);\r
// and writing it to EEPROM.\r
if (OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc) == 0) {\r
crc = 0;\r
- \r
+\r
// Fill page with data.\r
for (i=0; i<32; i++) {\r
temp = OWI_ReceiveByte(OWIBUS);\r
crc = OWI_ComputeCRC8(temp, crc);\r
eeprom_write_byte(&BattEEPROM[page][i], temp);\r
}\r
- \r
+\r
if (OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc) == 0) {\r
success = TRUE; // Data read OK\r
}\r
}\r
} else { // Wrong device type.\r
}\r
- } else { // No device found. \r
+ } else { // No device found.\r
}\r
} else { // No presence detected on one-wire bus.\r
}\r
// Erase local EEPROM page if there were any errors during transfer.\r
if (!success) {\r
for (i=0; i<32; i++) {\r
- eeprom_write_byte(&BattEEPROM[page][i], 0);\r
+ // mthomas: avoid unneeded writes\r
+ if ( eeprom_read_byte( &BattEEPROM[page][i] ) != 0 ) {\r
+ eeprom_write_byte(&BattEEPROM[page][i], 0);\r
+ }\r
}\r
}\r
}\r
PORTB |= (1 << (PB4+bat));\r
\r
// Disconnect other battery.\r
- PORTB &= ~(1<<(PB5-bat)); \r
+ PORTB &= ~(1<<(PB5-bat));\r
\r
do { // Let port switch settle.\r
- } while (Time_Left(TIMER_GEN)); \r
+ } while (Time_Left(TIMER_GEN));\r
}\r
\r
\r
void DisableBatteries(void)\r
{\r
// Turn off LEDs and disconnect batteries.\r
- PORTB &= ~((1<<PB4)|(1<<PB5)); \r
+ PORTB &= ~((1<<PB4)|(1<<PB5));\r
}\r
\r
\r
unsigned char i, found = FALSE;\r
unsigned int adcs_rawRID_tmp;\r
unsigned char sreg_saved;\r
- \r
+\r
// Lookup in the RID-table. If measured RID is within the limits\r
// of an entry, those data are used, and TRUE is returned.\r
for (i = 0 ; i < RID_TABLE_SIZE; i++) {\r
BattData.MaxCurrent = RID[i].Icharge;\r
BattData.MaxTime = RID[i].tCutOff;\r
BattData.MinCurrent = RID[i].ICutOff;\r
- \r
+\r
found = TRUE;\r
}\r
}\r
}\r
- \r
+\r
// If no valid entry is found, use defaults and return FALSE.\r
if (!found) {\r
BattData.Capacity = DEF_BAT_CAPACITY;\r
BattData.MaxTime = DEF_BAT_TIME_MAX;\r
BattData.MinCurrent = DEF_BAT_CURRENT_MIN;\r
}\r
- \r
+\r
return(found);\r
}\r
\r
{\r
unsigned char i;\r
unsigned char found = FALSE;\r
- unsigned char adcs_rawNTC_tmp;\r
+ unsigned int adcs_rawNTC_tmp;\r
unsigned char sreg_saved;\r
- \r
+\r
// Lookup in the NTC-table. Use the first entry which is equal or below\r
// sampled NTC. Calculate temperature by using the index number, and the\r
// difference between the measured NTC value and the one in the entry.\r
SREG = sreg_saved;\r
if (adcs_rawNTC_tmp >= NTC[i].ADCV) {\r
BattData.Temperature = (i<<2) ;\r
- BattData.ADCSteps = NTC[i].ADCsteps; \r
+ BattData.ADCSteps = NTC[i].ADCsteps;\r
BattData.Temperature -= ((adcs_rawNTC_tmp - NTC[i].ADCV)<<1) / BattData.ADCSteps;\r
- \r
+\r
found = TRUE; // Could be done with a break, but that violates MISRA.\r
}\r
}\r
- \r
- // For safety, is temperature is greater than the NTC \r
+\r
+ // For safety, is temperature is greater than the NTC\r
if (!found) {\r
BattData.Temperature = 80;\r
}\r
//******************************************************************************\r
// RID-less charging (for BatteryStatusRefresh())\r
//******************************************************************************\r
+\r
+#ifdef EASYPACK550\r
+\r
+#warning "using EasyPack 66590 711 099 (550mAh) settings - mthomas, no warranty!"\r
+// RID not connected\r
+#define ALLOW_NO_RID //!< Use default battery data if no matching entry found.\r
+#define DEF_BAT_CAPACITY 550 //!< Default battery capacity, in mAh.\r
+#define DEF_BAT_CURRENT_MAX 260 //!< Default maximum charge current, in mA.\r
+#define DEF_BAT_TIME_MAX (5*60) //!< Default maximum charge time, in minutes.\r
+//! Default minimum current to stop charge, in mA.\r
+#define DEF_BAT_CURRENT_MIN 10\r
+\r
+#else\r
+\r
//#define ALLOW_NO_RID //!< Use default battery data if no matching entry found.\r
\r
#define DEF_BAT_CAPACITY 0 //!< Default battery capacity, in mAh.\r
//! Default minimum current to stop charge, in mA.\r
#define DEF_BAT_CURRENT_MIN 0\r
\r
+#endif /* EASYPACK550 */\r
\r
\r
//******************************************************************************\r
* AVR463: Charging NiMH Batteries with BC100\r
*\r
* \par Documentation\r
- * For comprehensive code documentation, supported compilers, compiler \r
+ * For comprehensive code documentation, supported compilers, compiler\r
* settings and supported devices see readme.html\r
*\r
* \author\r
* Atmel Corporation: http://www.atmel.com \n\r
* Support email: avr@atmel.com\r
*\r
- * \r
+ *\r
* $Name$\r
* $Revision: 2299 $\r
* $RCSfile$\r
wasStopped = FALSE;\r
unsigned char sreg_saved;\r
signed int adcs_avgIBAT_tmp;\r
- \r
+\r
do {\r
// Wait for ADC conversions to complete.\r
ADC_Wait();\r
// Continue charging!\r
if (wasStopped) {\r
wasStopped = FALSE;\r
- \r
+\r
// Timer variables are not reset by this.\r
Time_Start();\r
}\r
// +/- BAT_CURRENT_HYST.\r
if ((adcs_avgIBAT_tmp < 0) ||\r
(adcs_avgIBAT_tmp < (ChargeParameters.Current - BAT_CURRENT_HYST))) {\r
- \r
+\r
if(!PWM_IncrementDutyCycle()) {\r
#ifdef ABORT_IF_PWM_MAX\r
// If the duty cycle cannot be incremented, flag error and\r
}\r
} else if ((adcs_avgIBAT_tmp >= 0) &&\r
(adcs_avgIBAT_tmp > (ChargeParameters.Current + BAT_CURRENT_HYST))) {\r
- \r
+\r
if(!PWM_DecrementDutyCycle()) {\r
#ifdef ABORT_IF_PWM_MIN\r
// If the duty cycle cannot be decremented, flag error and\r
wasStopped = FALSE;\r
unsigned char sreg_saved;\r
unsigned int adcs_VBAT_tmp;\r
- \r
+\r
do{\r
- \r
+\r
// Wait for ADC conversions to complete.\r
ADC_Wait();\r
- \r
+\r
// If Master has flagged for a charge inhibit, pause charging.\r
// (This is to prevent damage during prolonged serial communication.)\r
if (eeprom_read_byte(&BattControl[BattActive]) & BIT_BATTERY_CHARGE_INHIBIT) {\r
Time_Stop();\r
OCR1B = 0;\r
}\r
- \r
+\r
else {\r
// Continue charging!\r
if (wasStopped) {\r
wasStopped = FALSE;\r
- \r
+\r
// Timer variables aren't reset by this.\r
Time_Start();\r
}\r
- \r
+\r
sreg_saved = SREG;\r
cli();\r
adcs_VBAT_tmp = ADCS.VBAT;\r
*\r
* The function also checks if the battery temperature is within limits,\r
* if mains is OK, and if BatteryCheck() returns TRUE.\r
- * If an error is detected, the associated errorflag is set and \r
+ * If an error is detected, the associated errorflag is set and\r
* ChargeParameters.NextState is changed to an appropriate state.\r
*\r
* \retval TRUE Halt now.\r
unsigned int adcs_rawNTC_tmp, adcs_VBAT_tmp;\r
signed int adcs_avgIBAT_tmp;\r
unsigned char sreg_saved;\r
- \r
+\r
// Wait for a full ADC-cycle to finish.\r
ADC_Wait();\r
\r
// (Gets overridden if either mains is failing, or the battery changes.)\r
for (i = 0x01; i != 0; i <<= 1) {\r
if (HaltParameters.HaltFlags & i) {\r
- \r
+\r
sreg_saved = SREG;\r
cli();\r
adcs_VBAT_tmp = ADCS.VBAT;\r
adcs_avgIBAT_tmp = ADCS.avgIBAT;\r
SREG = sreg_saved;\r
- \r
+\r
switch (i) {\r
// Is VBAT less than the recorded maximum?\r
case HALT_VOLTAGE_DROP:\r
// Update VBATMax if VBAT is higher. Evaluate for halt otherwise.\r
if (adcs_VBAT_tmp > HaltParameters.VBATMax) {\r
HaltParameters.VBATMax = adcs_VBAT_tmp;\r
- } else if((HaltParameters.VBATMax - adcs_VBAT_tmp) >= \r
+ } else if((HaltParameters.VBATMax - adcs_VBAT_tmp) >=\r
HaltParameters.VoltageDrop) {\r
halt = TRUE;\r
}\r
break;\r
\r
- \r
+\r
// Has VBAT reached the maximum limit?\r
- case HALT_VOLTAGE_MAX: \r
- \r
+ case HALT_VOLTAGE_MAX:\r
+\r
if (adcs_VBAT_tmp >= HaltParameters.VoltageMax) {\r
halt = TRUE;\r
}\r
\r
// Has IBAT reached the minimum limit?\r
case HALT_CURRENT_MIN:\r
- \r
+\r
if (adcs_avgIBAT_tmp <= HaltParameters.CurrentMin) {\r
halt = TRUE;\r
}\r
break;\r
- \r
- \r
+\r
+\r
// Is the temperature rising too fast?\r
case HALT_TEMPERATURE_RISE:\r
- \r
+\r
sreg_saved = SREG;\r
cli();\r
adcs_rawNTC_tmp = ADCS.rawNTC;\r
if (adcs_rawNTC_tmp > HaltParameters.LastNTC) {\r
HaltParameters.LastNTC = adcs_rawNTC_tmp;\r
Time_Set(TIMER_TEMP,0,30,0);\r
- \r
+\r
// Is the increase in temperature greater than the set threshold?\r
} else if ((HaltParameters.LastNTC - adcs_rawNTC_tmp) >=\r
(BattData.ADCSteps * HaltParameters.TemperatureRise)) {\r
- \r
- // If this happened within a timeframe of 30 seconds, the \r
+\r
+ // If this happened within a timeframe of 30 seconds, the\r
// temperature is rising faster than we want.\r
// If not, update LastNTC and reset timer.\r
if (Time_Left(TIMER_TEMP)) {\r
}\r
}\r
break;\r
- \r
- \r
+\r
+\r
// Is there any time left?\r
- case HALT_TIME: \r
- \r
+ case HALT_TIME:\r
+\r
if (!Time_Left(TIMER_CHG)) {\r
halt = TRUE;\r
- \r
- // If exhaustion flagging is selected, stop the PWM, disable the \r
+\r
+ // If exhaustion flagging is selected, stop the PWM, disable the\r
// battery and flag it as exhausted. Make ST_ERROR next state.\r
if (HaltParameters.HaltFlags & HALT_FLAG_EXHAUSTION) {\r
PWM_Stop();\r
+\r
Battery_t tmp = eeprom_read_byte(&BattControl[BattActive]);\r
tmp &= ~BIT_BATTERY_ENABLED; // Enabled = FALSE;\r
eeprom_write_byte(&BattControl[BattActive], tmp);\r
+\r
BattData.Exhausted = TRUE;\r
SetErrorFlag(ERR_BATTERY_EXHAUSTED);\r
ChargeParameters.NextState = ST_ERROR;\r
}\r
}\r
break;\r
- \r
- \r
+\r
+\r
default: // Shouldn't end up here, but is needed for MISRA compliance.\r
break;\r
}\r
// Battery too cold or hot?\r
if ((BattData.Temperature <= HaltParameters.TemperatureMin) ||\r
(BattData.Temperature >= HaltParameters.TemperatureMax)) {\r
- \r
+\r
PWM_Stop();\r
SetErrorFlag(ERR_BATTERY_TEMPERATURE);\r
ChargeParameters.NextState = ST_ERROR;\r
sei();\r
\r
// Attempt to get ADC-readings (also gets RID-data) from both batteries.\r
- for (i = 0; i < 2; i++) {\r
+ for (i = 0; i < BATCONN; i++) {\r
EnableBattery(i);\r
ADC_Wait();\r
BatteryStatusRefresh();\r
\r
// Get ADC-readings, try to read EPROM, and start prequalification\r
// of any uncharged battery.\r
- for (i = 0; i < 2; i++) {\r
+ for (i = 0; i < BATCONN; i++) {\r
if (eeprom_read_byte(&BattControl[i]) & BIT_BATTERY_ENABLED) {\r
EnableBattery(i);\r
ADC_Wait();\r
\r
// If any batteries need charging, go to ST_BATCON.\r
// Otherwise, keep sleeping.\r
- for (i = 0; i < 2; i++) {\r
+ for (i = 0; i < BATCONN; i++) {\r
EnableBattery(i);\r
ADC_Wait();\r
- if ((BatteryStatusRefresh()) && (!BattData.Charged)) {\r
- return(ST_BATCON);\r
+ if ( BatteryStatusRefresh() ) {\r
+ if ( !BattData.Charged ) {\r
+ return(ST_BATCON);\r
+ }\r
}\r
}\r
\r
sleep_cpu(); // Go to sleep, wake up by WDT.\r
}\r
else {\r
+ // stay awake if PB6 is pulled low by master\r
do {\r
} while ( !(WatchdogFlag) );\r
}\r
* AVR458: Charging Li-Ion Batteries with BC100\r
*\r
* \par Documentation\r
- * For comprehensive code documentation, supported compilers, compiler \r
+ * For comprehensive code documentation, supported compilers, compiler\r
* settings and supported devices see readme.html\r
*\r
* \author\r
* Atmel Corporation: http://www.atmel.com \n\r
* Support email: avr@atmel.com\r
*\r
- * \r
+ *\r
* $Name$\r
* $Revision: 2261 $\r
* $RCSfile$\r
#ifndef STATEFUNC_H\r
#define STATEFUNC_H\r
\r
+//! number of connectors (1: just process A, 2 process A and B )\r
+#define BATCONN 1\r
+#if ( BATCONN < 1 ) || ( BATCONN > 2 )\r
+#error "Invalid BATCONN. Must be set to 1 or 2."\r
+#endif\r
\r
//******************************************************************************\r
// Wanted SPI-mode\r
#define SPIMODE 0\r
\r
//! Sample on leading _falling_ edge, setup on trailing _rising_ edge.\r
-//#define SPIMODE 1 \r
+//#define SPIMODE 1\r
\r
\r
//******************************************************************************\r
// Error-flag bit identifiers\r
//******************************************************************************\r
//! Wrong jumper settings.\r
-#define ERR_JUMPER_MISMATCH 0x01 \r
+#define ERR_JUMPER_MISMATCH 0x01\r
\r
//! Both batteries disabled.\r
-#define ERR_NO_BATTERIES_ENABLED 0x02 \r
+#define ERR_NO_BATTERIES_ENABLED 0x02\r
\r
//! PWM output too much/little.\r
-#define ERR_PWM_CONTROL 0x04 \r
+#define ERR_PWM_CONTROL 0x04\r
\r
//! Battery temperature out of limits.\r
-#define ERR_BATTERY_TEMPERATURE 0x08 \r
+#define ERR_BATTERY_TEMPERATURE 0x08\r
\r
//! Battery couldn't be charged.\r
-#define ERR_BATTERY_EXHAUSTED 0x10 \r
+#define ERR_BATTERY_EXHAUSTED 0x10\r
\r
\r
//******************************************************************************\r
*/\r
struct Batteries_struct\r
{\r
+#if 0\r
+#warning "no bitfield, used for debugging - mthomas"\r
+ unsigned char Present ; //!< Battery found. (TRUE/FALSE)\r
+ unsigned char Charged ; //!< Battery fully charged. (TRUE/FALSE)\r
+ unsigned char Low ; //!< Battery low voltage. (TRUE/FALSE)\r
+ unsigned char Exhausted ; //!< Battery exhausted. (TRUE/FALSE)\r
+ unsigned char HasRID ; //!< Battery has resistor ID. (TRUE/FALSE)\r
+#else\r
unsigned char Present : 1; //!< Battery found. (TRUE/FALSE)\r
unsigned char Charged : 1; //!< Battery fully charged. (TRUE/FALSE)\r
unsigned char Low : 1; //!< Battery low voltage. (TRUE/FALSE)\r
unsigned char Exhausted : 1; //!< Battery exhausted. (TRUE/FALSE)\r
unsigned char HasRID : 1; //!< Battery has resistor ID. (TRUE/FALSE)\r
+#endif\r
unsigned char Circuit; //!< Battery safety circuit (family id).\r
signed char Temperature; //!< Battery temperature, in centigrade.\r
unsigned char ADCSteps; //!< ADC steps per half degree.\r
\r
#include <ioavr.h>\r
#include <inavr.h>\r
+#include <intrinsics.h>\r
\r
#include "structs.h"\r
\r
* This ISR stores the sampled values in the ADC status-struct, then\r
* updates the ADC MUX to the next channel in the scanning-sequence.\n\r
* Once the sequence is completed, ADCS.Flag is set and unless\r
- * ADCS.Halt has been set, the sequence starts over. Otherwise, the ADC \r
+ * ADCS.Halt has been set, the sequence starts over. Otherwise, the ADC\r
* is disabled.\n\r
* If the mains voltage is below minimum, ADCS.Mains gets set to FALSE.\r
*\r
static unsigned char avgIndex = 0;\r
unsigned char i, Next, Signed;\r
signed int temp = 0;\r
- \r
+\r
Signed = FALSE; // Presume next conversion is unipolar.\r
ADCSRA &= ~(1<<ADEN); // Stop conversion before handling. This makes all\r
// conversions take at least 25 ADCCLK. (It is restarted later)\r
- \r
+\r
// Handle the conversion, depending on what channel it is from, then\r
// switch to the next channel in the sequence.\r
switch (ADCS.MUX){\r
Next=0x02;\r
break;\r
\r
- \r
+\r
// MUX = 0b000010 => ADC2 (PA2) = RID\r
case 0x02:\r
ADCS.rawRID = ADC;\r
Next=0x03;\r
break;\r
\r
- \r
+\r
// MUX = 0b000011 => ADC3 (PA4) = VIN-\r
case 0x03:\r
// Supply voltage is always divided by 16.\r
ADCS.VIN = ScaleU(4, (unsigned int)ADC); // Cast because ADC is short.\r
- \r
+\r
// Is mains failing?\r
if (ADCS.VIN < VIN_MIN) {\r
ADCS.Mains = FALSE;\r
} else {\r
ADCS.Mains = TRUE;\r
}\r
- \r
+\r
Next=0x05;\r
break;\r
\r
- \r
+\r
// MUX = 0b000101 => ADC5 (PA6) = VBAT-\r
case 0x05:\r
ADCS.rawVBAT = ADC;\r
- \r
+\r
// Scale voltage according to jumper setting.\r
ADCS.VBAT = ScaleU(VBAT_RANGE, (unsigned int)ADC); // ADC is a short.\r
+ __no_operation();\r
Next=0x17;\r
// Signed = TRUE; // Next conversion is bipolar. Halves sensitivity!\r
break;\r
case 0x17: // MUX = 0b010111 => 20 x [ADC6(PA7) - ADC5(PA6)] = IBAT\r
// If bipolar, from -512 to 0, to 511:\r
// 0x200 ... 0x3ff, 0x000, 0x001 ... 0x1FF\r
- \r
+\r
// Scale sample according to jumper setting, handle negative numbers.\r
if (ADC > 511) {\r
ADCS.IBAT = -(signed int)ScaleI(VBAT_RANGE,\r
for (i = 0; i < 4 ; i++) {\r
temp += ADCS.discIBAT[i];\r
}\r
- \r
+\r
ADCS.avgIBAT = (temp / 4);\r
- \r
+\r
ADCS.Flag = TRUE;\r
Next=0x01;\r
Signed = FALSE; // This is the only bipolar conversion.\r
break;\r
\r
- \r
+\r
default: // Should not happen. (Invalid MUX-channel)\r
Next=0x01; // Start at the beginning of sequence.\r
break;\r
}\r
- \r
+\r
// Update MUX to next channel in sequence, set a bipolar conversion if\r
// this has been flagged.\r
- ADCS.MUX = Next; \r
- ADMUX = (1<<REFS0) + ADCS.MUX; \r
+ ADCS.MUX = Next;\r
+ ADMUX = (1<<REFS0) + ADCS.MUX;\r
\r
if (Signed) {\r
- ADCSRB |= (1<<BIN); \r
+ ADCSRB |= (1<<BIN);\r
} else {\r
- ADCSRB &= ~(1<<BIN); \r
+ ADCSRB &= ~(1<<BIN);\r
}\r
\r
// Re-enable the ADC unless a halt has been flagged and a conversion\r
// cycle has completed.\r
if (!((ADCS.Halt) && (ADCS.Flag))) {\r
- ADCSRA |= (1<<ADEN)|(1<<ADSC); \r
+ ADCSRA |= (1<<ADEN)|(1<<ADSC);\r
}\r
}\r
\r
// Jumper setting 4: mV/LSB = 39.06 ~= 39 + 1/16\r
scaled = 39 * data;\r
scaled += (data >> 4);\r
- \r
+\r
if (setting <3) {\r
// Jumper setting 0: mV/LSB = 4.883 = 39.06 / 8\r
// 1: mV/LSB = 9.766 = 39.06 / 4\r
{\r
// Temporary variable needed.\r
unsigned int scaled = 0;\r
- \r
+\r
// Jumper setting 3: mA/LSB = 20.931mA ~= 21 - 1/16 + 1/128\r
if (setting == 3) {\r
scaled = 21 * data;\r
scaled = 28 * data;\r
scaled -= (data >> 3);\r
scaled += (data >> 5);\r
- \r
+\r
if (setting <3) {\r
// Jumper setting 0: mA/LSB = 3.489mA = 27.909 / 8\r
// 1: mA/LSB = 6.978mA = 27.909 / 4\r
scaled = (scaled >> (3-setting));\r
}\r
}\r
- \r
+\r
return(scaled);\r
}\r
\r
*\r
* This function clears the cycle complete-flag, then waits for it to be set\r
* again. This is then repeated once before the function exits.\r
- * \r
+ *\r
*/\r
void ADC_Wait(void)\r
{\r
// Clear ADC flag and wait for cycle to complete.\r
- ADCS.Flag = FALSE; \r
+ ADCS.Flag = FALSE;\r
do {\r
- } while (ADCS.Flag == FALSE); \r
- \r
+ } while (ADCS.Flag == FALSE);\r
+\r
// Repeat, so we are sure the data beong to the same cycle.\r
- ADCS.Flag = FALSE; \r
+ ADCS.Flag = FALSE;\r
do {\r
- } while (ADCS.Flag == FALSE); \r
+ } while (ADCS.Flag == FALSE);\r
}\r
\r
\r
\r
// Set ADC3 as reference, and MUX to measure the same pin.\r
ADMUX = (1<<REFS0) | (1<<MUX0) | (1<<MUX1);\r
- \r
+\r
ADCSRB = 0;\r
\r
// Start conversion, no interrupt (disable ADC-ISR).\r
- ADCSRA = (1<<ADEN) | (1<<ADSC) | ADC_PRESCALER; \r
+ ADCSRA = (1<<ADEN) | (1<<ADSC) | ADC_PRESCALER;\r
\r
do { // Wait for conversion to finish.\r
} while (!(ADCSRA & (1<<ADIF)));\r
ADCS.ADC3_G20_OS = ADC; // Save the sampled offset.\r
\r
ADMUX = (1<<REFS0) | 0x16; // ADC5/ADC5 (external ref.), 20x\r
- \r
+\r
// Start conversion, no interrupt. ADC_PRESCALER is defined in ADC.h.\r
- ADCSRA = (1<<ADEN) | (1<<ADSC) | ADC_PRESCALER; \r
+ ADCSRA = (1<<ADEN) | (1<<ADSC) | ADC_PRESCALER;\r
\r
do { // Wait for conversion to finish.\r
} while (!(ADCSRA & (1<<ADIF)));\r
ADCS.ADC5_G20_OS = ADC; // Save the sampled offset.\r
\r
// Reset the ADC-cycle.\r
- ADCS.Flag = FALSE; \r
- ADCS.MUX = 0x01; \r
- ADMUX = (1<<REFS0) | ADCS.MUX; \r
+ ADCS.Flag = FALSE;\r
+ ADCS.MUX = 0x01;\r
+ ADMUX = (1<<REFS0) | ADCS.MUX;\r
\r
// Clear averaged battery current and the discrete readings.\r
ADCS.avgIBAT = 0;\r
- \r
+\r
for (i = 0; i < 4; i++) {\r
- ADCS.discIBAT[i] = 0; \r
+ ADCS.discIBAT[i] = 0;\r
}\r
- \r
+\r
// Re-enable the ADC and ISR.\r
ADCSRA=(1<<ADEN)|(1<<ADSC)|(1<<ADIE)|ADC_PRESCALER;\r
- \r
+\r
__enable_interrupt();\r
\r
// Get a complete cycle of data before returning.\r
#ifndef LIIONSPECS_H\r
#define LIIONSPECS_H\r
\r
+/*\r
+ Information on Varta EasyPack 66590 711 099 collected by M. Thomas:\r
+\r
+ Connections:\r
+ Pad 1 - marked with + : Battery +\r
+ Pad 2 - not marked : ID-Resistor (RID) to Pad 4, 3.9kOhm\r
+ Pad 3 - not marked : NTC to Pad 4, 10kOhm B=3435K\r
+ Pad 4 - marked with - : Battery -\r
+ -> 1Wire not available\r
+\r
+ Capacity: nom. 550mAh (min. 520 mAh) at 0.2C from 4.2V to 3.0V\r
+ Nominal Voltage: 3.7V, Range: 2.75V - 4.2V\r
+ Charging Method: Constant Current + Constant Voltage\r
+ Charge Voltage: 4.2V\r
+ Initial charge Current: std. 260mA, rapid 520mA\r
+ Charging cut of either:\r
+ (a) at time: std. 5h, rapid 3h\r
+ (b) by min current of 10mA\r
+ Temparature 0 to 45degC\r
+ Discharge max. Current: 1040mA\r
+ Protection:\r
+ overcharge : 4.35V (resume at 4.0V)\r
+ discharge : 2.2V\r
+ overcurrent: 3.0A\r
+\r
+ Additional from PoliFlex-Handbook:\r
+ - fast charging in termperatur-range 0 - 45degC\r
+ - max charge current 1C (=550mA here)\r
+ - max charge current has to be limited stricly to 4,2V +/- 50mV\r
+ - stop charge 3h after start of when current is <0.02C (=11mA here)\r
+*/\r
+\r
\r
//******************************************************************************\r
// Cell limits\r
//******************************************************************************\r
// This is for common NiMH batteries.\r
#define CELL_VOLTAGE_SAFETY 0 /*!< \brief Buffer for unmatched batteries.\r
- * \r
+ *\r
* If we are charging a multicell battery and the cells aren't matched, we\r
* may risk overcharging at least one. Therefore, we may subtract this constant\r
* per additional cell in battery to allow for a "buffer".\r
//! Charge voltage hysteresis, in mV.\r
#define BAT_VOLTAGE_HYST 10\r
\r
-//! Maximum battery voltage, in mV. \r
+//! Maximum battery voltage, in mV.\r
#define BAT_VOLTAGE_MAX (CELL_VOLTAGE_MAX * BAT_CELL_NUMBER) - \\r
((BAT_CELL_NUMBER - 1) * CELL_VOLTAGE_SAFETY)\r
\r
\r
*\r
* \par Documentation\r
- * For comprehensive code documentation, supported compilers, compiler \r
+ * For comprehensive code documentation, supported compilers, compiler\r
* settings and supported devices see readme.html\r
*\r
* \author\r
* Atmel Corporation: http://www.atmel.com \n\r
* Support email: avr@atmel.com\r
*\r
- * \r
+ *\r
* $Name$\r
* $Revision: 2299 $\r
* $RCSfile$\r
*\r
* Stores current capacity, then attempts to refresh battery status.\n\r
* If the refresh is successful, old capacity is compared with the new one.\r
- * \r
+ *\r
* \retval FALSE Battery is disconnected, or capacity has changed.\r
* \retval TRUE All OK.\r
*/\r
{\r
unsigned char success = TRUE;\r
unsigned int oldCapacity;\r
- \r
+\r
// Save to see if battery data has changed.\r
- oldCapacity = BattData.Capacity; \r
- \r
+ oldCapacity = BattData.Capacity;\r
+\r
if (!BatteryStatusRefresh()) {\r
success = FALSE; // Battery not present or RID was invalid.\r
}\r
- \r
+\r
if (oldCapacity != BattData.Capacity) {\r
success = FALSE; // Battery configuration has changed.\r
}\r
{\r
// Assume the worst..\r
unsigned char success = FALSE;\r
- \r
+\r
BattData.Present = FALSE;\r
BattData.Charged = FALSE;\r
BattData.Low = TRUE;\r
\r
// If we are not charging, yet VBAT is above safe limit, battery is present.\r
// If we are charging and there's a current flowing, the battery is present.\r
- \r
+\r
/*! \todo If ABORT_IF_PWM_MAX is defined this last check battery presence\r
* check is redundant since charging will be aborted due to low current at\r
* max duty cycle. That is preferrable since the charge current reading is\r
unsigned char offset;\r
unsigned char i, crc, family, temp, page;\r
unsigned char success;\r
- \r
+\r
// Look for EPROM and read 4 pages of 32 bytes each worth of data, if found.\r
for (page = 0; page < 4; page++) {\r
success = FALSE;\r
- \r
+\r
if (OWI_DetectPresence(OWIBUS) == OWIBUS) {\r
- \r
+\r
// Presence detected, check type and CRC.\r
OWI_SendByte(OWI_ROM_READ, OWIBUS);\r
family = OWI_ReceiveByte(OWIBUS);\r
// and writing it to EEPROM.\r
if (OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc) == 0) {\r
crc = 0;\r
- \r
+\r
// Fill page with data.\r
for (i=0; i<32; i++) {\r
temp = OWI_ReceiveByte(OWIBUS);\r
crc = OWI_ComputeCRC8(temp, crc);\r
BattEEPROM[page][i] = temp;\r
}\r
- \r
+\r
if (OWI_ComputeCRC8(OWI_ReceiveByte(OWIBUS),crc) == 0) {\r
success = TRUE; // Data read OK\r
}\r
}\r
} else { // Wrong device type.\r
}\r
- } else { // No device found. \r
+ } else { // No device found.\r
}\r
} else { // No presence detected on one-wire bus.\r
}\r
// Erase local EEPROM page if there were any errors during transfer.\r
if (!success) {\r
for (i=0; i<32; i++) {\r
- BattEEPROM[page][i] = 0;\r
+ // mthomas: avoid unneeded writes\r
+ if ( eeprom_read_byte( &BattEEPROM[page][i] ) != 0 ) {\r
+ BattEEPROM[page][i] = 0;\r
+ }\r
}\r
}\r
}\r
PORTB |= (1 << (PB4+bat));\r
\r
// Disconnect other battery.\r
- PORTB &= ~(1<<(PB5-bat)); \r
+ PORTB &= ~(1<<(PB5-bat));\r
\r
do { // Let port switch settle.\r
- } while (Time_Left(TIMER_GEN)); \r
+ } while (Time_Left(TIMER_GEN));\r
}\r
\r
\r
void DisableBatteries(void)\r
{\r
// Turn off LEDs and disconnect batteries.\r
- PORTB &= ~((1<<PB4)|(1<<PB5)); \r
+ PORTB &= ~((1<<PB4)|(1<<PB5));\r
}\r
\r
\r
unsigned char RIDLookUp (void)\r
{\r
unsigned char i, found = FALSE;\r
- \r
+\r
// Lookup in the RID-table. If measured RID is within the limits\r
// of an entry, those data are used, and TRUE is returned.\r
for (i = 0 ; i < RID_TABLE_SIZE; i++) {\r
BattData.MaxCurrent = RID[i].Icharge;\r
BattData.MaxTime = RID[i].tCutOff;\r
BattData.MinCurrent = RID[i].ICutOff;\r
- \r
+\r
found = TRUE;\r
}\r
}\r
}\r
- \r
+\r
// If no valid entry is found, use defaults and return FALSE.\r
if (!found) {\r
BattData.Capacity = DEF_BAT_CAPACITY;\r
BattData.MaxTime = DEF_BAT_TIME_MAX;\r
BattData.MinCurrent = DEF_BAT_CURRENT_MIN;\r
}\r
- \r
+\r
return(found);\r
}\r
\r
{\r
unsigned char i;\r
unsigned char found = FALSE;\r
- \r
+\r
// Lookup in the NTC-table. Use the first entry which is equal or below\r
// sampled NTC. Calculate temperature by using the index number, and the\r
// difference between the measured NTC value and the one in the entry.\r
for (i=0 ; (i < NTC_TABLE_SIZE) && (!found); i++) {\r
if (ADCS.rawNTC >= NTC[i].ADC) {\r
BattData.Temperature = (i<<2) ;\r
- BattData.ADCSteps = NTC[i].ADCsteps; \r
+ BattData.ADCSteps = NTC[i].ADCsteps;\r
BattData.Temperature -= ((ADCS.rawNTC - NTC[i].ADC)<<1) / BattData.ADCSteps;\r
- \r
+\r
found = TRUE; // Could be done with a break, but that violates MISRA.\r
}\r
}\r
- \r
- // For safety, is temperature is greater than the NTC \r
+\r
+ // For safety, is temperature is greater than the NTC\r
if (!found) {\r
BattData.Temperature = 80;\r
}\r
//******************************************************************************\r
// RID-less charging (for BatteryStatusRefresh())\r
//******************************************************************************\r
+#ifdef EASYPACK550\r
+\r
+#warning "using EasyPack 66590 711 099 (550mAh) settings - mthomas, no warranty!"\r
+// RID not connected\r
+#define ALLOW_NO_RID //!< Use default battery data if no matching entry found.\r
+#define DEF_BAT_CAPACITY 550 //!< Default battery capacity, in mAh.\r
+#define DEF_BAT_CURRENT_MAX 260 //!< Default maximum charge current, in mA.\r
+#define DEF_BAT_TIME_MAX (5*60) //!< Default maximum charge time, in minutes.\r
+//! Default minimum current to stop charge, in mA.\r
+#define DEF_BAT_CURRENT_MIN 10\r
+\r
+#else\r
+\r
//#define ALLOW_NO_RID //!< Use default battery data if no matching entry found.\r
\r
#define DEF_BAT_CAPACITY 0 //!< Default battery capacity, in mAh.\r
//! Default minimum current to stop charge, in mA.\r
#define DEF_BAT_CURRENT_MIN 0\r
\r
+#endif /* EASYPACK550 */\r
\r
\r
//******************************************************************************\r
Time_Init();\r
\r
// Attempt to get ADC-readings (also gets RID-data) from both batteries.\r
- for (i = 0; i < 2; i++) {\r
+ for (i = 0; i < BATCONN; i++) {\r
EnableBattery(i);\r
ADC_Wait();\r
BatteryStatusRefresh();\r
\r
// Get ADC-readings, try to read EPROM, and start prequalification\r
// of any uncharged battery.\r
- for (i = 0; i < 2; i++) {\r
+ for (i = 0; i < BATCONN; i++) {\r
if (BattControl[i].Enabled) {\r
EnableBattery(i);\r
ADC_Wait();\r
\r
// If any batteries need charging, go to ST_BATCON.\r
// Otherwise, keep sleeping.\r
- for (i = 0; i < 2; i++) {\r
+ for (i = 0; i < BATCONN; i++) {\r
EnableBattery(i);\r
ADC_Wait();\r
- if ((BatteryStatusRefresh()) && (!BattData.Charged)) {\r
- return(ST_BATCON);\r
+ if ( BatteryStatusRefresh() ) {\r
+ if ( !BattData.Charged ) {\r
+ return(ST_BATCON);\r
+ }\r
}\r
}\r
\r
__sleep(); // Go to sleep, wake up by WDT.\r
}\r
else {\r
+ // stay awake if PB6 is pulled low by master\r
do {\r
} while ( !(WatchdogFlag) );\r
}\r
* AVR458: Charging Li-Ion Batteries with BC100\r
*\r
* \par Documentation\r
- * For comprehensive code documentation, supported compilers, compiler \r
+ * For comprehensive code documentation, supported compilers, compiler\r
* settings and supported devices see readme.html\r
*\r
* \author\r
* Atmel Corporation: http://www.atmel.com \n\r
* Support email: avr@atmel.com\r
*\r
- * \r
+ *\r
* $Name$\r
* $Revision: 2261 $\r
* $RCSfile$\r
#ifndef STATEFUNC_H\r
#define STATEFUNC_H\r
\r
+//! number of connectors (1: just process A, 2 process A and B )\r
+#define BATCONN 1\r
+#if ( BATCONN < 1 ) || ( BATCONN > 2 )\r
+#error "Invalid BATCONN. Must be set to 1 or 2."\r
+#endif\r
\r
//******************************************************************************\r
// Wanted SPI-mode\r
#define SPIMODE 0\r
\r
//! Sample on leading _falling_ edge, setup on trailing _rising_ edge.\r
-//#define SPIMODE 1 \r
+//#define SPIMODE 1\r
\r
\r
//******************************************************************************\r
// Error-flag bit identifiers\r
//******************************************************************************\r
//! Wrong jumper settings.\r
-#define ERR_JUMPER_MISMATCH 0x01 \r
+#define ERR_JUMPER_MISMATCH 0x01\r
\r
//! Both batteries disabled.\r
-#define ERR_NO_BATTERIES_ENABLED 0x02 \r
+#define ERR_NO_BATTERIES_ENABLED 0x02\r
\r
//! PWM output too much/little.\r
-#define ERR_PWM_CONTROL 0x04 \r
+#define ERR_PWM_CONTROL 0x04\r
\r
//! Battery temperature out of limits.\r
-#define ERR_BATTERY_TEMPERATURE 0x08 \r
+#define ERR_BATTERY_TEMPERATURE 0x08\r
\r
//! Battery couldn't be charged.\r
-#define ERR_BATTERY_EXHAUSTED 0x10 \r
+#define ERR_BATTERY_EXHAUSTED 0x10\r
\r
\r
//******************************************************************************\r
*/\r
struct Batteries_struct\r
{\r
+#if 0\r
+#warning "no bitfield, used for debugging - mthomas"\r
+ unsigned char Present ; //!< Battery found. (TRUE/FALSE)\r
+ unsigned char Charged ; //!< Battery fully charged. (TRUE/FALSE)\r
+ unsigned char Low ; //!< Battery low voltage. (TRUE/FALSE)\r
+ unsigned char Exhausted ; //!< Battery exhausted. (TRUE/FALSE)\r
+ unsigned char HasRID ; //!< Battery has resistor ID. (TRUE/FALSE)\r
+#else\r
unsigned char Present : 1; //!< Battery found. (TRUE/FALSE)\r
unsigned char Charged : 1; //!< Battery fully charged. (TRUE/FALSE)\r
unsigned char Low : 1; //!< Battery low voltage. (TRUE/FALSE)\r
unsigned char Exhausted : 1; //!< Battery exhausted. (TRUE/FALSE)\r
unsigned char HasRID : 1; //!< Battery has resistor ID. (TRUE/FALSE)\r
+#endif\r
unsigned char Circuit; //!< Battery safety circuit (family id).\r
signed char Temperature; //!< Battery temperature, in centigrade.\r
unsigned char ADCSteps; //!< ADC steps per half degree.\r
{\r
//! Battery valid, enabling allowed. (TRUE/FALSE)\r
unsigned char Enabled : 1;\r
- \r
+\r
//! Disconnect allowed. (TRUE/FALSE)\r
unsigned char DisconnectAllowed : 1;\r
- \r
+\r
//! Inhibit charging. (TRUE/FALSE) \todo Changed by master?\r
unsigned char ChargeInhibit : 1;\r
};\r
-2008-04-21 Kevin Rosenberg <kevin@rosenberg.net>\r
- * BaseTinyFirmware/GCC/*/Makefile: Add GCC optimizations from\r
- Eric Weddington \r
-\r
-2008-04-07 Kevin Rosenberg <kevin@rosenberg.net>\r
- * BaseTinyFirmware/IAR: Port Martin's changes from 2008-04-03\r
- to IAR\r
- \r
-2008-04-03 Martin Thomas <mthomas@rhrk.uni-kl.de>\r
- * BaseMegaFirmware/GCC: Experimental Master Code for the ATmega644\r
- with basic "drivers" for\r
- - keys incl. power-off with debounceing\r
- - 74HC595 low-level "software-SPI"\r
- - LEDs though 74HC595\r
- - Power-off and Slave-Reset control though 74HC595\r
- - hardware SPI for comm. with slave\r
- - simple test-function for communication with slave\r
- * BaseTinyFirmware/GCC/statefunc.c: \r
- - prevent unneeded writes to eeprom if init fails\r
- - prevent slave from entering sleep-mode standby if\r
- "MASTER_INT" is low (so SPI communication with master is\r
- possible even during the "8-second watchdog delay")\r
-\r
-2008-03-30 Kevin Rosenberg <kevin@rosenberg.net>\r
- * BaseTinyFirmware/GCC Makefile's improved with more listing\r
- output as well as added -Wl,-gc-sections option which stops\r
- crashes using linker relaxation [thanks to Eric Weddington]\r
-\r
-2008-03-28 Kevin Rosenberg <kevin@rosenberg.net>\r
- * BaseTinyFirmware/GCC/avr463/Makefile: Added -Wl,-relax to linker\r
- flags. On my system this crashes avr-ld.exe, but others have\r
- reported a large reduction in firmware size with this option. I\r
- added this option for others to try. *\r
- BaseTinyFirmware/GCC/avr458/Makefile: Added missing file\r
- \r
-2008-03-14 Martin Thomas <mthomas@rhrk.uni-kl.de>\r
- Improvements to BaseTinyFirmware:\r
- * added "volatile" to structure object and array declarations for\r
- objects sed in main-thread and ISRs. I'm not sure about the\r
- current state of implicitly "guaranteed" accesses in (avr-)gcc but\r
- it should be a "better safe than sorry" extension.\r
- * enveloped access to timer-values in timer.c to make them\r
- "atomic" since they are unsigned long\r
- * "atomic" access to singned int and unsigned int members of ADCS\r
- * it maybe better to have one place to globally enable\r
- interrupts ("sei"). Done in "initialize" now and not several\r
- times in the driver init-functions.\r
- * changed some space to tab as in the original code\r
- * added header files to the AVR-Studio project workspace\r
- * added -lm to the linker-options in the AVR Studio gcc-plugin,\r
- not important for the basic application but might be good if\r
- someone uses the ode as a base for own developments\r
-\r
-2008-03-12 Kevin Rosenberg <kevin@rosenberg.net>\r
- * Initial GCC port performed and compiles without error\r
- * Warning: Not yet tested on BC100 hardware!\r
+2008-06-26 Kevin Rosenberg <kevin@rosenberg.net>
+ * BaseTinyFirmwave/IAR: Port Martin's changes from 2008-06-12 to IAR
+
+2008-06-12 Martin Thomas <mthomas@rhrk.uni-kl.de>
+ Modifications to test AVR458 (LiIon). Tests done with
+ Varta EasyPack #66590 711 099: the BC100 at least enters
+ the charging-state now. Charging itself not fully monitored
+ so far. No tests done with NiMH (AVR463).
+
+ * BaseTinyFirmware/GCC/battery.c
+ - NTCLookUp(): type of adcs_rawNTC_tmp to uint16_t
+ - BatteryDataRefresh() avoid unneeded EEPROM writes
+ * BaseTinyFirmware/GCC/statefunc.h
+ - added BATCONN to set number of connectors to scan
+ (1=Battery A only, 2=Battery A and B)
+ * BaseTinyFirmware/GCC/structs.h
+ - Batteries_struct: option do disable bitfield (default: use bitfield)
+ * BaseTinyFirmware/GCC/statefunc.c
+ - sleep(): split if ( ... && ... ) into two ifs for easier debugging
+ * BaseTinyFirmware/GCC/LIIONspecs.h
+ - added comment with technical information on used battery
+ from Varta PoliFlex handbook and battery's datasheet
+ * Project settings:
+ - added -DEASYPACK550 in custom options [all files]
+ - NOT added: settings mentioned in entry "2008-04-21"
+ since they cause wrong code with avr-gcc 4.1.2/avr-binutils 2.17
+ (interrupt-vector not linked)
+ * BaseTinyFirmware/GCC/battery.h
+ - added DEF_BAT_*-values for the test-battery which
+ are enabled if EASYPACK550 is defined, RID not used,
+ #warning to indicate fixed settings (= 6 warnings on rebuild)
+ - NO warranty for these settings but even if something
+ goes wrong in firmware or BC100-hardware the battery
+ protects itself with it's internal circuits.
+ * BaseMegaFirmware/GCC/bc100_slave.c
+ - bc100_slave_test(): added battery-data readout
+
+2008-04-21 Kevin Rosenberg <kevin@rosenberg.net>
+ * BaseTinyFirmware/GCC/*/Makefile: Add GCC optimizations from
+ Eric Weddington
+
+2008-04-07 Kevin Rosenberg <kevin@rosenberg.net>
+ * BaseTinyFirmware/IAR: Port Martin's changes from 2008-04-03
+ to IAR
+
+2008-04-03 Martin Thomas <mthomas@rhrk.uni-kl.de>
+ * BaseMegaFirmware/GCC: Experimental Master Code for the ATmega644
+ with basic "drivers" for
+ - keys incl. power-off with debounceing
+ - 74HC595 low-level "software-SPI"
+ - LEDs though 74HC595
+ - Power-off and Slave-Reset control though 74HC595
+ - hardware SPI for comm. with slave
+ - simple test-function for communication with slave
+ * BaseTinyFirmware/GCC/statefunc.c:
+ - prevent unneeded writes to eeprom if init fails
+ - prevent slave from entering sleep-mode standby if
+ "MASTER_INT" is low (so SPI communication with master is
+ possible even during the "8-second watchdog delay")
+
+2008-03-30 Kevin Rosenberg <kevin@rosenberg.net>
+ * BaseTinyFirmware/GCC Makefile's improved with more listing
+ output as well as added -Wl,-gc-sections option which stops
+ crashes using linker relaxation [thanks to Eric Weddington]
+
+2008-03-28 Kevin Rosenberg <kevin@rosenberg.net>
+ * BaseTinyFirmware/GCC/avr463/Makefile: Added -Wl,-relax to linker
+ flags. On my system this crashes avr-ld.exe, but others have
+ reported a large reduction in firmware size with this option. I
+ added this option for others to try. *
+ BaseTinyFirmware/GCC/avr458/Makefile: Added missing file
+
+2008-03-14 Martin Thomas <mthomas@rhrk.uni-kl.de>
+ Improvements to BaseTinyFirmware:
+ * added "volatile" to structure object and array declarations for
+ objects sed in main-thread and ISRs. I'm not sure about the
+ current state of implicitly "guaranteed" accesses in (avr-)gcc but
+ it should be a "better safe than sorry" extension.
+ * enveloped access to timer-values in timer.c to make them
+ "atomic" since they are unsigned long
+ * "atomic" access to signed int and unsigned int members of ADCS
+ * it maybe better to have one place to globally enable
+ interrupts ("sei"). Done in "initialize" now and not several
+ times in the driver init-functions.
+ * changed some space to tab as in the original code
+ * added header files to the AVR-Studio project workspace
+ * added -lm to the linker-options in the AVR Studio gcc-plugin,
+ not important for the basic application but might be good if
+ someone uses the code as a base for own developments
+
+2008-03-12 Kevin Rosenberg <kevin@rosenberg.net>
+ * Initial GCC port performed and compiles without error
+ * Warning: Not yet tested on BC100 hardware!