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 ADMUX &= ~(BV(MUX4) | BV(MUX3) | BV(MUX2) | BV(MUX1) | BV(MUX0));
00106 #else
00107 #error Unknown CPU
00108 #endif
00109
00110
00111 ADMUX |= (ch & 0x07);
00112 }
00113
00114
00120 uint16_t adc_hw_read(void)
00121 {
00122
00123 ASSERT(!(ADCSRA & BV(ADSC)));
00124
00125
00126 ADCSRA |= BV(ADSC);
00127
00128 #if CONFIG_KERN
00129
00130 IRQ_ASSERT_ENABLED();
00131 adc_process = proc_current();
00132 sig_wait(SIG_ADC_COMPLETE);
00133 #else
00134
00135 while (ADCSRA & BV(ADSC)) ;
00136 #endif
00137
00138 return(ADC);
00139 }
00140
00144 void adc_hw_init(void)
00145 {
00146
00147
00148
00149
00150 ADMUX = 0;
00151
00152 #if CONFIG_ADC_AVR_REF == ADC_AVR_AREF
00153
00154
00155 #elif CONFIG_ADC_AVR_REF == ADC_AVR_AVCC
00156
00157 ADMUX |= BV(REFS0);
00158 #elif CONFIG_ADC_AVR_REF == ADC_AVR_INT256
00159
00160 ADMUX |= BV(REFS1) | BV(REFS0);
00161 #else
00162 #error Unsupported ADC ref value.
00163 #endif
00164
00165 #if defined(ADCSRB)
00166
00167 ADCSRB = 0;
00168 #endif
00169
00170
00171 ADCSRA = BV(ADEN);
00172
00173 #if CONFIG_KERN
00174 MOD_CHECK(proc);
00175 ADCSRA |= BV(ADIE);
00176 #endif
00177
00178
00179 #if CONFIG_ADC_AVR_DIVISOR == 2
00180 ADCSRA |= BV(ADPS0);
00181 #elif CONFIG_ADC_AVR_DIVISOR == 4
00182 ADCSRA |= BV(ADPS1);
00183 #elif CONFIG_ADC_AVR_DIVISOR == 8
00184 ADCSRA |= BV(ADPS1) | BV(ADPS0);
00185 #elif CONFIG_ADC_AVR_DIVISOR == 16
00186 ADCSRA |= BV(ADPS2);
00187 #elif CONFIG_ADC_AVR_DIVISOR == 32
00188 ADCSRA |= BV(ADPS2) | BV(ADPS0);
00189 #elif CONFIG_ADC_AVR_DIVISOR == 64
00190 ADCSRA |= BV(ADPS2) | BV(ADPS1);
00191 #elif CONFIG_ADC_AVR_DIVISOR == 128
00192 ADCSRA |= BV(ADPS2) | BV(ADPS1) | BV(ADPS0);
00193 #else
00194 #error Unsupported ADC prescaler value.
00195 #endif
00196
00197
00198 adc_hw_read();
00199 }