webradio/firmware/batmon.c

86 lines
1.6 KiB
C
Raw Normal View History

2020-07-30 17:11:48 +02:00
#include <avr/io.h>
#include "batmon.h"
#include "systick.h"
static uint8_t vbat = 0;
2020-07-30 17:11:48 +02:00
void batmon_init()
{
TCCR0A = 0;
TCCR0B = (1 << CS02);
TIMSK0 = (1 << TOIE0);
2020-07-30 17:11:48 +02:00
ADCSRA = (1 << ADPS2) | (1 << ADPS1); // 125 kHz ADC clock
ADMUX = ADC_CHANNEL | (1 << REFS0) | (1 << REFS1) | (1 << ADLAR); // Internal 1.2V bandgap, left adj.
ADCSRB = 0;
2020-07-30 17:11:48 +02:00
#if ADC_CHANNEL < 7
DIDR0 = (1 << ADC_CHANNEL); // Disconnect digital channel
#endif
// Enable voltage divider
PORT_ADCC(DDR) |= PIN_ADCC;
PORT_ADCC(PORT) &= ~PIN_ADCC;
// Enable ADC
ADCSRA |= (1 << ADEN);
ADCSRA |= (1 << ADSC);
2020-08-09 12:14:21 +02:00
// Configure charging indicator pin
PORT_CHI(DDR) &= ~(1 << PIN_CHI);
PORT_CHI(PORT) &= ~(1 << PIN_CHI);
}
uint8_t batmon_proc()
{
static uint16_t sum = 0;
static uint8_t cnt = 0;
if (ADCSRA & (1 << ADIF)) {
sum += ADCH;
2020-07-31 18:22:52 +02:00
if (!(++cnt)) {
vbat = sum >> 8;
sum = 0;
2020-07-31 18:22:52 +02:00
if (vbat < BAT_THRES_POWER_OFF)
return 1;
}
ADCSRA &= ~(1 << ADIF);
ADCSRA |= (1 << ADSC); // TODO: I want this to work off TIMER0
}
return 0;
2020-07-30 17:11:48 +02:00
}
inline uint8_t batmon_get_voltage()
{
return vbat;
2020-07-30 17:11:48 +02:00
}
2020-07-31 18:23:58 +02:00
static uint8_t batmon_get_voltage_sync()
{
uint16_t sum = 0;
uint8_t cnt = 255;
ADCSRA |= (1 << ADSC);
do {
if (ADCSRA & (1 << ADIF)) {
sum += ADCH;
ADCSRA &= ~(1 << ADIF);
ADCSRA |= (1 << ADSC);
cnt--;
}
} while (cnt);
return (sum >> 8);
}
// Note: Call batmon_init() after using this function before using batmon_proc() again
inline uint8_t batmon_ok_to_boot()
{
return (batmon_get_voltage_sync() > BAT_THRES_POWER_ON);
}
2020-08-09 12:14:21 +02:00
inline uint8_t batmon_is_charging()
{
return !(PORT_CHI(PIN) & PIN_CHI);
}