X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?p=tinyboard.git;a=blobdiff_plain;f=projects%2Fstep-up%2Fbattery.c;fp=projects%2Fstep-up%2Fbattery.c;h=ceb53cb2c1133eecb104b607fd79d67f15cfbbee;hp=0000000000000000000000000000000000000000;hb=287f589eb6aee0d3aa9726106c6782c41c81ec6a;hpb=887aa3ba899b44aa07cfabfab4ce3495074f0788 diff --git a/projects/step-up/battery.c b/projects/step-up/battery.c new file mode 100644 index 0000000..ceb53cb --- /dev/null +++ b/projects/step-up/battery.c @@ -0,0 +1,89 @@ +#include + +#include "lights.h" + +#define BATTERY_ADC_SHIFT 2 +#define RESISTOR_HI 1500 // kOhm +#define RESISTOR_LO 100 // kOhm +/* + * The internal 1.1V reference has tolerance from 1.0 to 1.2V + * (datasheet, section 19.6). We have to measure the actual value + * of our part. + */ +#define AREF_1100MV 1060 // mV + +static volatile uint16_t battery_adcval; +static unsigned char initial_readings = 0; + +void init_battery() +{ + battery_adcval = 0; + initial_readings = 5; +} + +unsigned char battery_100mv() +{ + /* + * This is tricky: we need to maintain precision, so we first + * multiply adcval by as big number as possible to fit uint16_t, + * then divide to get the final value, + * and finally type-cast it to unsigned char. + * We don't do running average, as the required precision + * is coarse (0.1 V). + */ + return (unsigned char) + ((uint16_t)( + (battery_adcval >> BATTERY_ADC_SHIFT) + * (11 // 1.1V + * (RESISTOR_HI+RESISTOR_LO)/RESISTOR_LO // resistor ratio + / 4)) >> 8); // divide by 1024 +} + +void battery_adc(uint16_t adcval) +{ + if (initial_readings) { + initial_readings--; + battery_adcval = adcval << BATTERY_ADC_SHIFT; + } else if (battery_adcval == 0) { + battery_adcval = adcval << BATTERY_ADC_SHIFT; + } else { // running average + battery_adcval += (adcval + - (battery_adcval >> BATTERY_ADC_SHIFT)); + } +#if 0 + log_byte(battery_100mv()); + log_flush(); +#endif +} + +unsigned char battery_gauge() +{ + unsigned char b8 = battery_100mv(); + unsigned char rv; + + if (b8 < 70) { + rv = 1; + } else if (b8 < 75) { + rv = 2; + } else if (b8 < 80) { + rv = 3; + } else if (b8 < 85) { + rv = 4; + } else if (b8 < 90) { + rv = 5; + } else if (b8 < 95) { + rv = 6; + } else { + rv = 7; + } + + if (rv == 1 && !initial_readings) + set_error(ERR_BATTERY); + +#if 0 + log_byte(0xbb); + log_byte(rv); + log_flush(); +#endif + return rv; +}