adc_at91.c
Go to the documentation of this file.00001
00048 #include "adc_at91.h"
00049
00050 #include <cpu/irq.h>
00051
00052 #include "cfg/cfg_adc.h"
00053 #include "cfg/cfg_proc.h"
00054 #include "cfg/cfg_signal.h"
00055 #include <cfg/macros.h>
00056 #include <cfg/compiler.h>
00057
00058
00059 #define LOG_LEVEL ADC_LOG_LEVEL
00060 #define LOG_FORMAT ADC_LOG_FORMAT
00061 #include <cfg/log.h>
00062
00063 #include <drv/adc.h>
00064
00065 #include <io/arm.h>
00066
00067 #if CONFIG_KERN
00068 #include <cfg/module.h>
00069 #include <kern/proc.h>
00070 #include <kern/signal.h>
00071
00072
00073 #if !CONFIG_KERN_SIGNALS
00074 #error Signals must be active to use ADC with kernel
00075 #endif
00076
00077
00078 #define SIG_ADC_COMPLETE SIG_USER0
00079
00080
00081 static struct Process *adc_process;
00082
00087 static DECLARE_ISR(adc_conversion_end_irq)
00088 {
00089 sig_post(adc_process, SIG_ADC_COMPLETE);
00090
00091
00092 AIC_EOICR = 0;
00093 }
00094
00095 static void adc_enable_irq(void)
00096 {
00097
00098
00099 ADC_IDR = 0xFFFFFFFF;
00100
00101
00102 AIC_SVR(ADC_ID) = adc_conversion_end_irq;
00103 AIC_SMR(ADC_ID) = AIC_SRCTYPE_INT_EDGE_TRIGGERED;
00104 AIC_IECR = BV(ADC_ID);
00105
00106
00107 ADC_IER = BV(ADC_DRDY);
00108 }
00109
00110 #endif
00111
00112
00117 void adc_hw_select_ch(uint8_t ch)
00118 {
00119
00120 ADC_CHDR = ADC_CH_MASK;
00121
00122 ADC_CHER = BV(ch);
00123 }
00124
00125
00131 uint16_t adc_hw_read(void)
00132 {
00133 #if CONFIG_KERN
00134
00135 ASSERT(adc_process == NULL);
00136 adc_process = proc_current();
00137 #endif
00138
00139
00140 ADC_CR = BV(ADC_START);
00141
00142 #if CONFIG_KERN
00143
00144 IRQ_ASSERT_ENABLED();
00145 sig_wait(SIG_ADC_COMPLETE);
00146
00147
00148 uint16_t ret = ADC_LCDR;
00149 MEMORY_BARRIER;
00150 adc_process = NULL;
00151 return ret;
00152 #else
00153
00154 while (!(ADC_SR & BV(ADC_DRDY)));
00155
00156
00157 return(ADC_LCDR);
00158 #endif
00159 }
00160
00164 void adc_hw_init(void)
00165 {
00166
00167 ADC_INIT_PINS();
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 ADC_MR = 0;
00178 #if ADC_BITS == 10
00179 ADC_MR &= ~BV(ADC_LOWRES);
00180 #elif ADC_BITS == 8
00181 ADC_MR |= BV(ADC_LOWRES);
00182 #else
00183 #error No select bit resolution is supported to this CPU
00184 #endif
00185
00186
00187 LOG_INFO("Computed ADC_CLOCK %ld\n", ADC_COMPUTED_CLOCK);
00188 LOG_INFO("prescaler[%ld], stup[%ld], shtim[%ld]\n",ADC_COMPUTED_PRESCALER, ADC_COMPUTED_STARTUPTIME, ADC_COMPUTED_SHTIME);
00189
00190
00191
00192 ADC_MR &= ~ADC_PRESCALER_MASK;
00193 ADC_MR |= ((ADC_COMPUTED_PRESCALER << ADC_PRESCALER_SHIFT) & ADC_PRESCALER_MASK);
00194 LOG_INFO("prescaler[%ld]\n", (ADC_COMPUTED_PRESCALER << ADC_PRESCALER_SHIFT) & ADC_PRESCALER_MASK);
00195
00196
00197 ADC_MR &= ~ADC_STARTUP_MASK;
00198 ADC_MR |= ((ADC_COMPUTED_STARTUPTIME << ADC_STARTUP_SHIFT) & ADC_STARTUP_MASK);
00199 LOG_INFO("sttime[%ld]\n", (ADC_COMPUTED_STARTUPTIME << ADC_STARTUP_SHIFT) & ADC_STARTUP_MASK);
00200
00201
00202 ADC_MR &= ~ADC_SHTIME_MASK;
00203 ADC_MR |= ((ADC_COMPUTED_SHTIME << ADC_SHTIME_SHIFT) & ADC_SHTIME_MASK);
00204 LOG_INFO("shtime[%ld]\n", (ADC_COMPUTED_SHTIME << ADC_SHTIME_SHIFT) & ADC_SHTIME_MASK);
00205
00206 #if CONFIG_KERN
00207
00208 adc_enable_irq();
00209 #endif
00210
00211 }