2020-07-30 17:11:48 +02:00
|
|
|
#include <avr/io.h>
|
|
|
|
#include "batmon.h"
|
2020-07-30 21:40:57 +02:00
|
|
|
#include "systick.h"
|
|
|
|
|
|
|
|
static uint8_t vbat = 0;
|
2020-07-30 17:11:48 +02:00
|
|
|
|
|
|
|
void batmon_init()
|
|
|
|
{
|
2020-07-30 21:40:57 +02:00
|
|
|
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.
|
2020-07-30 21:40:57 +02:00
|
|
|
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);
|
2020-07-30 21:40:57 +02:00
|
|
|
ADCSRA |= (1 << ADSC);
|
|
|
|
}
|
|
|
|
|
|
|
|
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)) {
|
2020-07-30 21:40:57 +02:00
|
|
|
vbat = sum >> 8;
|
|
|
|
sum = 0;
|
2020-07-31 18:22:52 +02:00
|
|
|
if (vbat < BAT_THRES_POWER_OFF)
|
|
|
|
return 1;
|
2020-07-30 21:40:57 +02:00
|
|
|
}
|
|
|
|
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()
|
|
|
|
{
|
2020-07-30 21:40:57 +02:00
|
|
|
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);
|
|
|
|
}
|