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