adc_stm32.c
Go to the documentation of this file.00001
00047 #include "adc_stm32.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
00055 #include <cfg/macros.h>
00056 #include <cfg/compiler.h>
00057 #include <cfg/debug.h>
00058
00059
00060 #define LOG_LEVEL ADC_LOG_LEVEL
00061 #define LOG_FORMAT ADC_LOG_FORMAT
00062 #include <cfg/log.h>
00063
00064 #include <drv/adc.h>
00065 #include <drv/clock_stm32.h>
00066 #include <drv/gpio_stm32.h>
00067
00068 #include <io/stm32.h>
00069
00070 struct stm32_adc *adc = (struct stm32_adc *)ADC1_BASE;
00071
00072 #if CONFIG_KERN
00073 #include <cfg/module.h>
00074
00075 #include <kern/proc.h>
00076 #include <kern/signal.h>
00077
00078 #include <drv/irq_cm3.h>
00079
00080
00081 #if !CONFIG_KERN_SIGNALS
00082 #error Signals must be active to use ADC with kernel
00083 #endif
00084
00085
00086 #define SIG_ADC_COMPLETE SIG_USER0
00087
00088
00089 static struct Process *adc_process;
00090
00095 static DECLARE_ISR(adc_conversion_end_irq)
00096 {
00097 sig_post(adc_process, SIG_ADC_COMPLETE);
00098
00099
00100 adc->SR &= ~BV(SR_EOC);
00101 }
00102
00103 static void adc_enable_irq(void)
00104 {
00105
00106 sysirq_setHandler(ADC_IRQHANDLER, adc_conversion_end_irq);
00107 adc->CR1 |= BV(CR1_EOCIE);
00108 }
00109
00110 #endif
00111
00119 void adc_hw_select_ch(uint8_t ch)
00120 {
00121
00122 adc->SQR1 |= BV(SQR1_SQ_LEN_SHIFT);
00123 adc->SQR3 = (ch & SQR3_SQ_MASK);
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->CR2 |= CR2_EXTTRIG_SWSTRT_SET;
00141
00142 #if CONFIG_KERN
00143
00144 IRQ_ASSERT_ENABLED();
00145 sig_wait(SIG_ADC_COMPLETE);
00146
00147
00148 uint16_t ret = adc->DR;
00149 MEMORY_BARRIER;
00150 adc_process = NULL;
00151 return ret;
00152 #else
00153
00154 while (!(adc->SR & BV(SR_EOC)));
00155
00156
00157 return (adc->DR);
00158 #endif
00159 }
00160
00164 void adc_hw_init(void)
00165 {
00166 RCC->APB2ENR |= (RCC_APB2_GPIOA | RCC_APB2_GPIOB | RCC_APB2_GPIOC);
00167 RCC->APB2ENR |= RCC_APB2_ADC1;
00168
00169
00170 adc->CR1 = 0;
00171 adc->CR2 = 0;
00172 adc->SQR1 = 0;
00173 adc->SQR2 = 0;
00174 adc->SQR3 = 0;
00175
00176
00177 adc->CR2 |= BV(CR2_RTSCAL);
00178 adc->CR2 |= BV(CR2_CAL);
00179
00180
00181 while (adc->CR2 & BV(CR2_CAL));
00182
00183
00184
00185
00186
00187
00188
00189 adc->CR2 |= (BV(CR2_ADON) | ADC_EXTERNALTRIGCONV_NONE | BV(CR2_TSVREFE));
00190
00191
00192 adc->SMPR1 |= ((ADC_SAMPLETIME_239CYCLES5 << SMPR1_CH17) |
00193 (ADC_SAMPLETIME_239CYCLES5 << SMPR1_CH16) |
00194 (ADC_SAMPLETIME_239CYCLES5 << SMPR1_CH15) |
00195 (ADC_SAMPLETIME_239CYCLES5 << SMPR1_CH14) |
00196 (ADC_SAMPLETIME_239CYCLES5 << SMPR1_CH13) |
00197 (ADC_SAMPLETIME_239CYCLES5 << SMPR1_CH12) |
00198 (ADC_SAMPLETIME_239CYCLES5 << SMPR1_CH11) |
00199 (ADC_SAMPLETIME_239CYCLES5 << SMPR1_CH10));
00200
00201 adc->SMPR2 |= ((ADC_SAMPLETIME_239CYCLES5 << SMPR2_CH9) |
00202 (ADC_SAMPLETIME_239CYCLES5 << SMPR2_CH8) |
00203 (ADC_SAMPLETIME_239CYCLES5 << SMPR2_CH7) |
00204 (ADC_SAMPLETIME_239CYCLES5 << SMPR2_CH6) |
00205 (ADC_SAMPLETIME_239CYCLES5 << SMPR2_CH5) |
00206 (ADC_SAMPLETIME_239CYCLES5 << SMPR2_CH4) |
00207 (ADC_SAMPLETIME_239CYCLES5 << SMPR2_CH3) |
00208 (ADC_SAMPLETIME_239CYCLES5 << SMPR2_CH2) |
00209 (ADC_SAMPLETIME_239CYCLES5 << SMPR2_CH1) |
00210 (ADC_SAMPLETIME_239CYCLES5 << SMPR2_CH0));
00211
00212 #if CONFIG_KERN
00213 adc_enable_irq();
00214 #endif
00215 }