adc_avr.c
Go to the documentation of this file.00001
00042 #include "adc_avr.h"
00043
00044 #include <cpu/irq.h>
00045 #include "cfg/cfg_adc.h"
00046 #include "cfg/cfg_kern.h"
00047 #include <cfg/macros.h>
00048 #include <cfg/compiler.h>
00049
00050 #include <drv/adc.h>
00051
00052 #include <avr/io.h>
00053 #include <avr/interrupt.h>
00054
00055 #define ADC_AVR_AREF 0
00056 #define ADC_AVR_AVCC 1
00057 #define ADC_AVR_INT256 2
00058
00059 #if CONFIG_KERN
00060 #include <cfg/module.h>
00061 #include <kern/proc.h>
00062 #include <kern/signal.h>
00063
00064
00065 #if !CONFIG_KERN_SIGNALS
00066 #error Signals must be active to use ADC with kernel
00067 #endif
00068
00069
00070 #define SIG_ADC_COMPLETE SIG_SINGLE
00071
00072
00073 static struct Process *adc_process;
00074
00079 ISR(ADC_vect)
00080 {
00081 sig_signal(adc_process, SIG_ADC_COMPLETE);
00082 }
00083 #endif
00084
00089 INLINE void adc_hw_select_ch(uint8_t ch)
00090 {
00091
00092 ADMUX &= ~(BV(MUX3) | BV(MUX3) | BV(MUX2) | BV(MUX1) | BV(MUX0));
00093
00094
00095 ADMUX |= (ch & 0x07);
00096 }
00097
00098
00104 INLINE uint16_t adc_hw_read(void)
00105 {
00106
00107 ASSERT(!(ADCSRA & BV(ADSC)));
00108
00109
00110 ADCSRA |= BV(ADSC);
00111
00112 #if CONFIG_KERN
00113
00114 IRQ_ASSERT_ENABLED();
00115 adc_process = proc_current();
00116 sig_wait(SIG_ADC_COMPLETE);
00117 #else
00118
00119 while (ADCSRA & BV(ADSC)) ;
00120 #endif
00121
00122 return(ADC);
00123 }
00124
00128 INLINE void adc_hw_init(void)
00129 {
00130
00131
00132
00133
00134 ADMUX = 0;
00135
00136 #if CONFIG_ADC_AVR_REF == ADC_AVR_AREF
00137
00138
00139 #elif CONFIG_ADC_AVR_REF == ADC_AVR_AVCC
00140
00141 ADMUX |= BV(REFS0);
00142 #elif CONFIG_ADC_AVR_REF == ADC_AVR_INT256
00143
00144 ADMUX |= BV(REFS1) | BV(REFS0);
00145 #else
00146 #error Unsupported ADC ref value.
00147 #endif
00148
00149 #if defined(ADCSRB)
00150
00151 ADCSRB = 0;
00152 #endif
00153
00154
00155 ADCSRA = BV(ADEN);
00156
00157 #if CONFIG_KERN
00158 MOD_CHECK(proc);
00159 ADCSRA |= BV(ADIE);
00160 #endif
00161
00162
00163 #if CONFIG_ADC_AVR_DIVISOR == 2
00164 ADCSRA |= BV(ADPS0);
00165 #elif CONFIG_ADC_AVR_DIVISOR == 4
00166 ADCSRA |= BV(ADPS1);
00167 #elif CONFIG_ADC_AVR_DIVISOR == 8
00168 ADCSRA |= BV(ADPS1) | BV(ADPS0);
00169 #elif CONFIG_ADC_AVR_DIVISOR == 16
00170 ADCSRA |= BV(ADPS2);
00171 #elif CONFIG_ADC_AVR_DIVISOR == 32
00172 ADCSRA |= BV(ADPS2) | BV(ADPS0);
00173 #elif CONFIG_ADC_AVR_DIVISOR == 64
00174 ADCSRA |= BV(ADPS2) | BV(ADPS1);
00175 #elif CONFIG_ADC_AVR_DIVISOR == 128
00176 ADCSRA |= BV(ADPS2) | BV(ADPS1) | BV(ADPS0);
00177 #else
00178 #error Unsupported ADC prescaler value.
00179 #endif
00180
00181
00182 adc_hw_read();
00183 }