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