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