adc_avr.c
Go to the documentation of this file.00001
00015 #include "adc_avr.h"
00016
00017 #include <drv/adc.h>
00018 #include <appconfig.h>
00019
00020 #include <cfg/macros.h>
00021 #include <cfg/compiler.h>
00022
00023 #include <avr/io.h>
00024 #include <avr/interrupt.h>
00025
00026 #define ADC_AVR_AREF 0
00027 #define ADC_AVR_AVCC 1
00028 #define ADC_AVR_INT256 2
00029
00030 #if CONFIG_KERNEL
00031 #include <cfg/module.h>
00032 #include <config_kern.h>
00033 #include <kern/proc.h>
00034 #include <kern/signal.h>
00035
00036
00037 #if !CONFIG_KERN_SIGNALS
00038 #error Signals must be active to use ADC with kernel
00039 #endif
00040
00041
00042 #define SIG_ADC_COMPLETE SIG_SINGLE
00043
00044
00045 static struct Process *adc_process;
00046
00051 ISR(ADC_vect)
00052 {
00053 sig_signal(adc_process, SIG_ADC_COMPLETE);
00054 }
00055 #endif
00056
00061 INLINE void adc_hw_select_ch(uint8_t ch)
00062 {
00063
00064 ADMUX &= ~(BV(MUX3) | BV(MUX3) | BV(MUX2) | BV(MUX1) | BV(MUX0));
00065
00066
00067 ADMUX |= (ch & 0x07);
00068 }
00069
00070
00076 INLINE uint16_t adc_hw_read(void)
00077 {
00078
00079 ASSERT(!(ADCSRA & BV(ADSC)));
00080
00081
00082 ADCSRA |= BV(ADSC);
00083
00084 #if CONFIG_KERNEL
00085
00086 ASSERT(IRQ_ENABLED());
00087 adc_process = proc_current();
00088 sig_wait(SIG_ADC_COMPLETE);
00089 #else
00090
00091 while (ADCSRA & BV(ADSC)) ;
00092 #endif
00093
00094 return(ADC);
00095 }
00096
00100 INLINE void adc_hw_init(void)
00101 {
00102
00103
00104
00105
00106 ADMUX = 0;
00107
00108 #if CONFIG_ADC_AVR_REF == ADC_AVR_AREF
00109
00110
00111 #elif CONFIG_ADC_AVR_REF == ADC_AVR_AVCC
00112
00113 ADMUX |= BV(REFS0);
00114 #elif CONFIG_ADC_AVR_REF == ADC_AVR_INT256
00115
00116 ADMUX |= BV(REFS1) | BV(REFS0);
00117 #else
00118 #error Unsupported ADC ref value.
00119 #endif
00120
00121
00122 ADCSRB = 0;
00123
00124
00125 ADCSRA = BV(ADEN);
00126
00127 #if CONFIG_KERNEL
00128 MOD_CHECK(proc);
00129 ADCSRA |= BV(ADIE);
00130 #endif
00131
00132
00133 #if CONFIG_ADC_AVR_DIVISOR == 2
00134 ADCSRA |= BV(ADPS0);
00135 #elif CONFIG_ADC_AVR_DIVISOR == 4
00136 ADCSRA |= BV(ADPS1);
00137 #elif CONFIG_ADC_AVR_DIVISOR == 8
00138 ADCSRA |= BV(ADPS1) | BV(ADPS0);
00139 #elif CONFIG_ADC_AVR_DIVISOR == 16
00140 ADCSRA |= BV(ADPS2);
00141 #elif CONFIG_ADC_AVR_DIVISOR == 32
00142 ADCSRA |= BV(ADPS2) | BV(ADPS0);
00143 #elif CONFIG_ADC_AVR_DIVISOR == 64
00144 ADCSRA |= BV(ADPS2) | BV(ADPS1);
00145 #elif CONFIG_ADC_AVR_DIVISOR == 128
00146 ADCSRA |= BV(ADPS2) | BV(ADPS1) | BV(ADPS0);
00147 #else
00148 #error Unsupported ADC prescaler value.
00149 #endif
00150
00151
00152 adc_hw_read();
00153 }