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_kern.h" 00054 #include <cfg/macros.h> 00055 #include <cfg/compiler.h> 00056 00057 // Define log settings for cfg/log.h. 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 /* Signal adc convertion end */ 00077 #define SIG_ADC_COMPLETE SIG_USER0 00078 00079 /* ADC waiting process */ 00080 static struct Process *adc_process; 00081 00086 static void ISR_FUNC adc_conversion_end_irq(void) 00087 { 00088 sig_signal(adc_process, SIG_ADC_COMPLETE); 00089 00090 /* Inform hw that we have served the IRQ */ 00091 AIC_EOICR = 0; 00092 } 00093 00094 static void adc_enable_irq(void) 00095 { 00096 00097 // Disable all interrupt 00098 ADC_IDR = 0xFFFFFFFF; 00099 00100 //Register interrupt vector 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 //Enable data ready irq 00106 ADC_IER = BV(ADC_DRDY); 00107 } 00108 00109 #endif /* CONFIG_KERN */ 00110 00111 00116 INLINE void adc_hw_select_ch(uint8_t ch) 00117 { 00118 //Disable all channels 00119 ADC_CHDR = ADC_CH_MASK; 00120 //Enable select channel 00121 ADC_CHER = BV(ch); 00122 } 00123 00124 00130 INLINE uint16_t adc_hw_read(void) 00131 { 00132 ASSERT(!(ADC_SR & ADC_EOC_MASK)); 00133 00134 #if CONFIG_KERN 00135 adc_process = proc_current(); 00136 #endif 00137 00138 // Start convertion 00139 ADC_CR = BV(ADC_START); 00140 00141 #if CONFIG_KERN 00142 // Ensure IRQs enabled. 00143 IRQ_ASSERT_ENABLED(); 00144 sig_wait(SIG_ADC_COMPLETE); 00145 #else 00146 //Wait in polling until is done 00147 while (!(ADC_SR & BV(ADC_DRDY))); 00148 #endif 00149 00150 //Return the last converted data 00151 return(ADC_LCDR); 00152 } 00153 00157 INLINE void adc_hw_init(void) 00158 { 00159 //Init ADC pins. 00160 ADC_INIT_PINS(); 00161 00162 /* 00163 * Set adc mode register: 00164 * - Disable hardware trigger and enable software trigger. 00165 * - Select normal mode. 00166 * - Set ADC_BITS bit convertion resolution. 00167 * 00168 * \{ 00169 */ 00170 ADC_MR = 0; 00171 #if ADC_BITS == 10 00172 ADC_MR &= ~BV(ADC_LOWRES); 00173 #elif ADC_BITS == 8 00174 ADC_MR |= BV(ADC_LOWRES); 00175 #else 00176 #error No select bit resolution is supported to this CPU 00177 #endif 00178 /* \} */ 00179 00180 LOG_INFO("prescaler[%ld], stup[%ld], shtim[%ld]\n",ADC_COMPUTED_PRESCALER, ADC_COMPUTED_STARTUPTIME, ADC_COMPUTED_SHTIME); 00181 00182 00183 //Apply computed prescaler value 00184 ADC_MR &= ~ADC_PRESCALER_MASK; 00185 ADC_MR |= ((ADC_COMPUTED_PRESCALER << ADC_PRESCALER_SHIFT) & ADC_PRESCALER_MASK); 00186 LOG_INFO("prescaler[%ld]\n", (ADC_COMPUTED_PRESCALER << ADC_PRESCALER_SHIFT) & ADC_PRESCALER_MASK); 00187 00188 //Apply computed start up time 00189 ADC_MR &= ~ADC_STARTUP_MASK; 00190 ADC_MR |= ((ADC_COMPUTED_STARTUPTIME << ADC_STARTUP_SHIFT) & ADC_STARTUP_MASK); 00191 LOG_INFO("sttime[%ld]\n", (ADC_COMPUTED_STARTUPTIME << ADC_STARTUP_SHIFT) & ADC_STARTUP_MASK); 00192 00193 //Apply computed sample and hold time 00194 ADC_MR &= ~ADC_SHTIME_MASK; 00195 ADC_MR |= ((ADC_COMPUTED_SHTIME << ADC_SHTIME_SHIFT) & ADC_SHTIME_MASK); 00196 LOG_INFO("shtime[%ld]\n", (ADC_COMPUTED_SHTIME << ADC_SHTIME_SHIFT) & ADC_SHTIME_MASK); 00197 00198 #if CONFIG_KERN 00199 //Register and enable irq for adc. 00200 adc_enable_irq(); 00201 #endif 00202 00203 }
