Teacup_Firmware/battery_charger/adc.c

57 lines
1.1 KiB
C

#include "adc.h"
void adc_init(uint8_t vsel)
{
PRR &= ~_BV(PRADC);
ADMUX = (ADMUX & ~(_BV(REFS1) | _BV(REFS0))) | vsel;
ADCSRA = _BV(ADEN);
#if F_CPU >= (ADC_MAX_FREQ * 128)
#error F_CPU is too high for ADC prescaler!
#elif F_CPU >= (ADC_MAX_FREQ * 64)
ADCSRA |= _BV(ADPS2) | _BV(ADPS1) | _BV(ADPS0);
#elif F_CPU >= (ADC_MAX_FREQ * 32)
ADCSRA |= _BV(ADPS2) | _BV(ADPS1);
#elif F_CPU >= (ADC_MAX_FREQ * 16)
ADCSRA |= _BV(ADPS2) | _BV(ADPS0);
#elif F_CPU >= (ADC_MAX_FREQ * 8)
ADCSRA |= _BV(ADPS2);
#elif F_CPU >= (ADC_MAX_FREQ * 4)
ADCSRA |= _BV(ADPS1) | _BV(ADPS0);
#elif F_CPU >= (ADC_MAX_FREQ * 2)
ADCSRA |= _BV(ADPS1);
#elif F_CPU >= (ADC_MAX_FREQ >> 1)
ADSRA |= _BV(ADPS0);
#else
#error F_CPU is too slow for ADC to run well!
#endif
}
uint16_t adc_read(uint8_t pin)
{
adc_start(pin);
adc_wait();
return adc_result();
}
void adc_start(uint8_t pin)
{
ADMUX = (ADMUX & 0xF0) | pin;
ADCSRA |= _BV(ADSC);
}
uint16_t adc_result()
{
return ADC;
}
uint8_t adc_finished()
{
return (ADCSRA & _BV(ADSC))?0xFF:0;
}
void adc_wait()
{
for (;adc_finished() == 0;);
}