adc_at91.c
Go to the documentation of this file.00001 00049 #include "adc_at91.h" 00050 00051 #include <drv/adc.h> 00052 00053 #include <cfg/macros.h> 00054 #include <cfg/compiler.h> 00055 00056 #include <io/arm.h> 00057 00058 #include "appconfig.h" 00059 00060 #if CONFIG_KERNEL 00061 #include <cfg/module.h> 00062 #include <config_kern.h> 00063 #include <kern/proc.h> 00064 #include <kern/signal.h> 00065 00066 00067 #if !CONFIG_KERN_SIGNALS 00068 #error Signals must be active to use ADC with kernel 00069 #endif 00070 00071 /* Signal adc convertion end */ 00072 #define SIG_ADC_COMPLETE SIG_USER0 00073 00074 /* ADC waiting process */ 00075 static struct Process *adc_process; 00076 00081 static void ISR_FUNC adc_conversion_end_irq(void) 00082 { 00083 sig_signal(adc_process, SIG_ADC_COMPLETE); 00084 00085 /* Inform hw that we have served the IRQ */ 00086 AIC_EOICR = 0; 00087 } 00088 00089 static void adc_enable_irq(void) 00090 { 00091 00092 // Disable all interrupt 00093 ADC_IDR = 0xFFFFFFFF; 00094 00095 //Register interrupt vector 00096 AIC_SVR(ADC_ID) = adc_conversion_end_irq; 00097 AIC_SMR(ADC_ID) = AIC_SRCTYPE_INT_EDGE_TRIGGERED; 00098 AIC_IECR = BV(ADC_ID); 00099 00100 //Enable data ready irq 00101 ADC_IER = BV(ADC_DRDY); 00102 } 00103 00104 #endif /* CONFIG_KERNEL */ 00105 00106 00111 INLINE void adc_hw_select_ch(uint8_t ch) 00112 { 00113 //Disable all channels 00114 ADC_CHDR = ADC_CH_MASK; 00115 //Enable select channel 00116 ADC_CHER = BV(ch); 00117 } 00118 00119 00125 INLINE uint16_t adc_hw_read(void) 00126 { 00127 ASSERT(!(ADC_SR & ADC_EOC_MASK)); 00128 00129 #if CONFIG_KERNEL 00130 adc_process = proc_current(); 00131 #endif 00132 00133 // Start convertion 00134 ADC_CR = BV(ADC_START); 00135 00136 #if CONFIG_KERNEL 00137 // Ensure IRQs enabled. 00138 ASSERT(IRQ_ENABLED()); 00139 sig_wait(SIG_ADC_COMPLETE); 00140 #else 00141 //Wait in polling until is done 00142 while (!(ADC_SR & BV(ADC_DRDY))); 00143 #endif 00144 00145 //Return the last converted data 00146 return(ADC_LCDR); 00147 } 00148 00152 INLINE void adc_hw_init(void) 00153 { 00154 //Init ADC pins. 00155 ADC_INIT_PINS(); 00156 00157 /* 00158 * Set adc mode register: 00159 * - Disable hardware trigger and enable software trigger. 00160 * - Select normal mode. 00161 * - Set ADC_BITS bit convertion resolution. 00162 * 00163 * \{ 00164 */ 00165 ADC_MR = 0; 00166 #if ADC_BITS == 10 00167 ADC_MR &= ~BV(ADC_LOWRES); 00168 #elif ADC_BITS == 8 00169 ADC_MR |= BV(ADC_LOWRES); 00170 #else 00171 #error No select bit resolution is supported to this CPU 00172 #endif 00173 /* \} */ 00174 00175 TRACEMSG("prescaler[%ld], stup[%ld], shtim[%ld]\n",ADC_COMPUTED_PRESCALER,ADC_COMPUTED_STARTUPTIME,ADC_COMPUTED_SHTIME); 00176 00177 00178 //Apply computed prescaler value 00179 ADC_MR &= ~ADC_PRESCALER_MASK; 00180 ADC_MR |= ((ADC_COMPUTED_PRESCALER << ADC_PRESCALER_SHIFT) & ADC_PRESCALER_MASK); 00181 TRACEMSG("prescaler[%ld]\n", (ADC_COMPUTED_PRESCALER << ADC_PRESCALER_SHIFT) & ADC_PRESCALER_MASK); 00182 00183 //Apply computed start up time 00184 ADC_MR &= ~ADC_STARTUP_MASK; 00185 ADC_MR |= ((ADC_COMPUTED_STARTUPTIME << ADC_STARTUP_SHIFT) & ADC_STARTUP_MASK); 00186 TRACEMSG("sttime[%ld]\n", (ADC_COMPUTED_STARTUPTIME << ADC_STARTUP_SHIFT) & ADC_STARTUP_MASK); 00187 00188 //Apply computed sample and hold time 00189 ADC_MR &= ~ADC_SHTIME_MASK; 00190 ADC_MR |= ((ADC_COMPUTED_SHTIME << ADC_SHTIME_SHIFT) & ADC_SHTIME_MASK); 00191 TRACEMSG("shtime[%ld]\n", (ADC_COMPUTED_SHTIME << ADC_SHTIME_SHIFT) & ADC_SHTIME_MASK); 00192 00193 #if CONFIG_KERNEL 00194 //Register and enable irq for adc. 00195 adc_enable_irq(); 00196 #endif 00197 00198 }
