avr-fw-modules/core/src/adc_cpu.c

99 lines
1.7 KiB
C

#include <sys/adc.h>
#include <hwo/bits.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#if !defined (__SIMPLE_ADC__)
uint8_t _adc_bank;
union bits32 adc_bits;
#endif
uint8_t _adc_ch;
struct adc adc;
uint8_t _adc_wdog;
uint8_t _adc_wdog_flag;
union bits32 adc_bits;
void adc_init(uint8_t bank)
{
#if !defined (__SIMPLE_ADC__)
uint8_t n;
if (eeprom_load( bank, &adc.eeprom )) {
for (n=0;n<ADC_CHANNELS;n++) {
adc.params[n].min = 0;
adc.params[n].max = -1;
};
};
_adc_bank = bank;
#endif
ADCSRA = 0;
ADMUX = _BV(REFS0) | _BV(ADLAR);
#ifdef ADCSRB
ADCSRB = 0;
#endif
ADCSRA = _BV(ADEN) | _BV(ADIE) | _BV(ADPS0) | _BV(ADPS1) | _BV(ADPS2);
ADCSRA |= _BV(ADSC);
_adc_wdog = 5;
_adc_wdog_flag = 0x01;
};
void adc_reinit(void){
ADCSRA = 0;
ADMUX = _BV(REFS0) | _BV(ADLAR);
#ifdef ADCSRB
ADCSRB = 0;
#endif
ADCSRA = _BV(ADEN) | _BV(ADIE) | _BV(ADPS0) | _BV(ADPS1) | _BV(ADPS2);
ADCSRA |= _BV(ADSC);
_adc_wdog = 5;
_adc_wdog_flag ++;
};
VECT(ADC_vect)
{
#if !defined (__SIMPLE_ADC__)
adc_bits.ui16[0] = 0;
adc_bits.ui16[1] = adc.channels[_adc_ch].raw = ADC;
if (adc.channels[_adc_ch].raw <= adc.params[_adc_ch].min) {
adc.channels[_adc_ch].value = 0;
} else if (adc.channels[_adc_ch].raw >= adc.params[_adc_ch].max) {
adc.channels[_adc_ch].value = -1;
} else if (adc.params[_adc_ch].min | (adc.params[_adc_ch].max != -1)) {
adc_bits.ui16[1] -= adc.params[_adc_ch].min;
adc.channels[_adc_ch].value = (adc_bits.ui32) / (adc.params[_adc_ch].max - adc.params[_adc_ch].min);
} else {
adc.channels[_adc_ch].value = adc_bits.ui16[1];
};
#else
adc.channels[_adc_ch].raw = ADC;
#endif
_adc_ch++;
if (_adc_ch >= ADC_CHANNELS)
_adc_ch = 0x00;
ADMUX = (ADMUX & 0xE0) | _adc_ch;
ADCSRA |= _BV(ADSC);
_adc_wdog = 5;
};