adc_avr.c
Go to the documentation of this file.00001
00043 #include "adc_avr.h"
00044
00045 #include "cfg/cfg_adc.h"
00046 #include "cfg/cfg_proc.h"
00047 #include "cfg/cfg_signal.h"
00048 #include <cfg/macros.h>
00049 #include <cfg/compiler.h>
00050
00051 #include <cpu/irq.h>
00052
00053 #include <drv/adc.h>
00054
00055 #include <avr/io.h>
00056 #include <avr/interrupt.h>
00057
00064 #define ADC_AVR_AREF 0
00065 #define ADC_AVR_AVCC 1
00066 #define ADC_AVR_INT256 2
00067
00068
00069 #if CONFIG_KERN
00070 #include <cfg/module.h>
00071 #include <kern/proc.h>
00072 #include <kern/signal.h>
00073
00074
00075 #if !CONFIG_KERN_SIGNALS
00076 #error Signals must be active to use the ADC with kernel
00077 #endif
00078
00079
00080 #define SIG_ADC_COMPLETE SIG_SINGLE
00081
00082
00083 static struct Process *adc_process;
00084
00089 ISR(ADC_vect)
00090 {
00091 sig_post(adc_process, SIG_ADC_COMPLETE);
00092 }
00093 #endif
00094
00099 void adc_hw_select_ch(uint8_t ch)
00100 {
00101
00102 #if CPU_AVR_ATMEGA8 || CPU_AVR_ATMEGA328P || CPU_AVR_ATMEGA168
00103 ADMUX &= ~(BV(MUX3) | BV(MUX2) | BV(MUX1) | BV(MUX0));
00104 #elif CPU_AVR_ATMEGA32 || CPU_AVR_ATMEGA64 || CPU_AVR_ATMEGA128 || CPU_AVR_ATMEGA1281 \
00105 || CPU_AVR_ATMEGA1280 || CPU_AVR_ATMEGA2560
00106 ADMUX &= ~(BV(MUX4) | BV(MUX3) | BV(MUX2) | BV(MUX1) | BV(MUX0));
00107 #if CPU_AVR_ATMEGA1280 || CPU_AVR_ATMEGA2560
00108 ADCSRB &= ~(BV(MUX5));
00109 #endif
00110 #else
00111 #error Unknown CPU
00112 #endif
00113
00114
00115 ADMUX |= (ch & 0x07);
00116
00117 #if CPU_AVR_ATMEGA1280 || CPU_AVR_ATMEGA2560
00118
00119 if (ch > 0x07)
00120 ADCSRB |= BV(MUX5);
00121
00122 #endif
00123
00124 }
00125
00126
00132 uint16_t adc_hw_read(void)
00133 {
00134
00135 ASSERT(!(ADCSRA & BV(ADSC)));
00136
00137
00138 ADCSRA |= BV(ADSC);
00139
00140 #if CONFIG_KERN
00141
00142 IRQ_ASSERT_ENABLED();
00143 adc_process = proc_current();
00144 sig_wait(SIG_ADC_COMPLETE);
00145 #else
00146
00147 while (ADCSRA & BV(ADSC)) ;
00148 #endif
00149
00150 return(ADC);
00151 }
00152
00156 void adc_hw_init(void)
00157 {
00158
00159
00160
00161
00162 ADMUX = 0;
00163
00164 #if CONFIG_ADC_AVR_REF == ADC_AVR_AREF
00165
00166
00167 #elif CONFIG_ADC_AVR_REF == ADC_AVR_AVCC
00168
00169 ADMUX |= BV(REFS0);
00170 #elif CONFIG_ADC_AVR_REF == ADC_AVR_INT256
00171
00172 ADMUX |= BV(REFS1) | BV(REFS0);
00173 #else
00174 #error Unsupported ADC ref value.
00175 #endif
00176
00177 #if defined(ADCSRB)
00178
00179 ADCSRB = 0;
00180 #endif
00181
00182
00183 ADCSRA = BV(ADEN);
00184
00185 #if CONFIG_KERN
00186 MOD_CHECK(proc);
00187 ADCSRA |= BV(ADIE);
00188 #endif
00189
00190
00191 #if CONFIG_ADC_AVR_DIVISOR == 2
00192 ADCSRA |= BV(ADPS0);
00193 #elif CONFIG_ADC_AVR_DIVISOR == 4
00194 ADCSRA |= BV(ADPS1);
00195 #elif CONFIG_ADC_AVR_DIVISOR == 8
00196 ADCSRA |= BV(ADPS1) | BV(ADPS0);
00197 #elif CONFIG_ADC_AVR_DIVISOR == 16
00198 ADCSRA |= BV(ADPS2);
00199 #elif CONFIG_ADC_AVR_DIVISOR == 32
00200 ADCSRA |= BV(ADPS2) | BV(ADPS0);
00201 #elif CONFIG_ADC_AVR_DIVISOR == 64
00202 ADCSRA |= BV(ADPS2) | BV(ADPS1);
00203 #elif CONFIG_ADC_AVR_DIVISOR == 128
00204 ADCSRA |= BV(ADPS2) | BV(ADPS1) | BV(ADPS0);
00205 #else
00206 #error Unsupported ADC prescaler value.
00207 #endif
00208
00209
00210 adc_hw_read();
00211 }