#ifndef ADC_H #define ADC_H #include #include "lib/mystd.h" typedef enum e_adc_ref { ADC_AREF = 0, ADC_AVCC = BV(REFS0), ADC_INT = BV(REFS0) | BV(REFS1), _ADC_REF_MASK = BV(REFS0) | BV(REFS1), } e_adc_ref; typedef enum e_adc_size { ADC_10BIT = 0, ADC_8BIT = BV(ADLAR), _ADC_SIZE_MASK = BV(ADLAR), } e_adc_size; typedef enum e_adc_prescaler { ADC_PRESCALER_2 = BV(ADPS0), ADC_PRESCALER_4 = BV(ADPS1), ADC_PRESCALER_8 = BV(ADPS1) | BV(ADPS0), ADC_PRESCALER_16 = BV(ADPS2), ADC_PRESCALER_32 = BV(ADPS2) | BV(ADPS0), ADC_PRESCALER_64 = BV(ADPS2) | BV(ADPS1), ADC_PRESCALER_128 = BV(ADPS2) | BV(ADPS1) | BV(ADPS0), _ADC_PRESCALER_MASK = BV(ADPS2) | BV(ADPS1) | BV(ADPS0), } e_adc_prescaler; typedef enum e_adc_input { ADC_ADC0 = 0, ADC_ADC1 = BV(MUX0), ADC_ADC2 = BV(MUX1), ADC_ADC3 = BV(MUX0) | BV(MUX1), ADC_ADC4 = BV(MUX2), ADC_ADC5 = BV(MUX2) | BV(MUX0), ADC_ADC6 = BV(MUX2) | BV(MUX1), ADC_ADC7 = BV(MUX2) | BV(MUX1) | BV(MUX0), ADC_TEMP = BV(MUX3), ADC_11V = BV(MUX3) | BV(MUX2) | BV(MUX1), ADC_0V = BV(MUX3) | BV(MUX2) | BV(MUX1) | BV(MUX0), _ADC_INPUT_MASK = BV(MUX0) | BV(MUX1) | BV(MUX2) | BV(MUX3), } e_adc_input; static inline uint8_t adc_read_pin(e_adc_input input) { ADMUX = (ADMUX & ~(_ADC_INPUT_MASK | _ADC_SIZE_MASK)) | input | BV(ADLAR); ADCSRA |= BV(ADSC); while (ADCSRA & BV(ADSC)) ; return ADCH; } static inline uint16_t adc_read_pin_10bit(e_adc_input input) { ADMUX = (ADMUX & ~(_ADC_SIZE_MASK | _ADC_INPUT_MASK)) | (input & _ADC_INPUT_MASK); ADCSRA |= BV(ADSC); while (ADCSRA & BV(ADSC)) ; return ADC; } static inline void adc_init(e_adc_ref v_ref, e_adc_prescaler prescaler) { ADMUX = (ADMUX & ~(_ADC_REF_MASK)) | v_ref; ADCSRA = BV(ADEN) | (prescaler & _ADC_PRESCALER_MASK); (void)adc_read_pin(0); } #endif /* ADC_H */