2 * adc_stm32f103.c - ADC driver for STM32F103
4 * Copyright (C) 2011, 2012 Free Software Initiative of Japan
5 * Author: NIIBE Yutaka <gniibe@fsij.org>
7 * This file is a part of NeuG, a Random Number Generator
8 * implementation based on quantization error of ADC (for STM32F103).
10 * NeuG is free software: you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
15 * Gnuk is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
18 * License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
30 #define NEUG_CRC32_COUNTS 4
32 #define STM32_ADC_ADC1_DMA_PRIORITY 2
33 #define STM32_ADC_ADC1_IRQ_PRIORITY 5
35 #define ADC_SMPR1_SMP_VREF(n) ((n) << 21)
36 #define ADC_SMPR1_SMP_SENSOR(n) ((n) << 18)
38 #define ADC_SMPR2_SMP_AN0(n) ((n) << 0)
39 #define ADC_SMPR2_SMP_AN1(n) ((n) << 3)
41 #define ADC_SQR1_NUM_CH(n) (((n) - 1) << 20)
43 #define ADC_SQR3_SQ1_N(n) ((n) << 0)
44 #define ADC_SQR3_SQ2_N(n) ((n) << 5)
45 #define ADC_SQR3_SQ3_N(n) ((n) << 10)
46 #define ADC_SQR3_SQ4_N(n) ((n) << 15)
48 #define ADC_SAMPLE_1P5 0
50 #define ADC_CHANNEL_IN0 0
51 #define ADC_CHANNEL_IN1 1
52 #define ADC_CHANNEL_SENSOR 16
53 #define ADC_CHANNEL_VREFINT 17
55 #define DELIBARATELY_DO_IT_WRONG_VREF_SAMPLE_TIME
56 #define DELIBARATELY_DO_IT_WRONG_START_STOP
58 #ifdef DELIBARATELY_DO_IT_WRONG_VREF_SAMPLE_TIME
59 #define ADC_SAMPLE_VREF ADC_SAMPLE_1P5
60 #define ADC_SAMPLE_SENSOR ADC_SAMPLE_1P5
62 #define ADC_SAMPLE_VREF ADC_SAMPLE_239P5
63 #define ADC_SAMPLE_SENSOR ADC_SAMPLE_239P5
66 #define NEUG_DMA_CHANNEL STM32_DMA1_STREAM1
67 #define NEUG_DMA_MODE_SAMPLE \
68 ( STM32_DMA_CR_PL (STM32_ADC_ADC1_DMA_PRIORITY) \
69 | STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_PSIZE_WORD \
70 | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE \
73 #define NEUG_DMA_MODE_CRC32 \
74 ( STM32_DMA_CR_PL (STM32_ADC_ADC1_DMA_PRIORITY) \
75 | STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_PSIZE_WORD \
76 | STM32_DMA_CR_TCIE | STM32_DMA_CR_TEIE)
78 #define NEUG_ADC_SETTING1_SMPR1 ADC_SMPR1_SMP_VREF(ADC_SAMPLE_VREF) \
79 | ADC_SMPR1_SMP_SENSOR(ADC_SAMPLE_SENSOR)
80 #define NEUG_ADC_SETTING1_SMPR2 0
81 #define NEUG_ADC_SETTING1_SQR3 ADC_SQR3_SQ1_N(ADC_CHANNEL_VREFINT) \
82 | ADC_SQR3_SQ2_N(ADC_CHANNEL_SENSOR) \
83 | ADC_SQR3_SQ3_N(ADC_CHANNEL_SENSOR) \
84 | ADC_SQR3_SQ4_N(ADC_CHANNEL_VREFINT)
85 #define NEUG_ADC_SETTING1_NUM_CHANNELS 4
87 #if !defined(NEUG_ADC_SETTING2_SMPR1)
88 #define NEUG_ADC_SETTING2_SMPR1 0
89 #define NEUG_ADC_SETTING2_SMPR2 ADC_SMPR2_SMP_AN0(ADC_SAMPLE_1P5) \
90 | ADC_SMPR2_SMP_AN1(ADC_SAMPLE_1P5)
91 #define NEUG_ADC_SETTING2_SQR3 ADC_SQR3_SQ1_N(ADC_CHANNEL_IN0) \
92 | ADC_SQR3_SQ2_N(ADC_CHANNEL_IN1)
93 #define NEUG_ADC_SETTING2_NUM_CHANNELS 2
98 * Do calibration for both of ADCs.
103 rccEnableAPB2 (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN, FALSE);
105 ADC1->CR2 = ADC_CR2_ADON;
106 ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_RSTCAL;
107 while ((ADC1->CR2 & ADC_CR2_RSTCAL) != 0)
109 ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_CAL;
110 while ((ADC1->CR2 & ADC_CR2_CAL) != 0)
115 ADC2->CR2 = ADC_CR2_ADON;
116 ADC2->CR2 = ADC_CR2_ADON | ADC_CR2_RSTCAL;
117 while ((ADC2->CR2 & ADC_CR2_RSTCAL) != 0)
119 ADC2->CR2 = ADC_CR2_ADON | ADC_CR2_CAL;
120 while ((ADC2->CR2 & ADC_CR2_CAL) != 0)
123 rccDisableAPB2 (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN, FALSE);
127 static void adc_lld_serve_rx_interrupt (void *arg, uint32_t flags);
129 void adc_start (void)
131 dmaStreamAllocate (NEUG_DMA_CHANNEL, STM32_ADC_ADC1_IRQ_PRIORITY,
132 adc_lld_serve_rx_interrupt, NULL);
133 dmaStreamSetPeripheral (NEUG_DMA_CHANNEL, &ADC1->DR);
137 rccEnableAPB2 (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN, FALSE);
139 ADC1->CR1 = (ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_1 | ADC_CR1_DUALMOD_0
141 ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
142 | ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
143 ADC1->SMPR1 = NEUG_ADC_SETTING1_SMPR1;
144 ADC1->SMPR2 = NEUG_ADC_SETTING1_SMPR2;
145 ADC1->SQR1 = ADC_SQR1_NUM_CH(NEUG_ADC_SETTING1_NUM_CHANNELS);
147 ADC1->SQR3 = NEUG_ADC_SETTING1_SQR3;
149 ADC2->CR1 = (ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_1 | ADC_CR1_DUALMOD_0
151 ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
152 ADC2->SMPR1 = NEUG_ADC_SETTING2_SMPR1;
153 ADC2->SMPR2 = NEUG_ADC_SETTING2_SMPR2;
154 ADC2->SQR1 = ADC_SQR1_NUM_CH(NEUG_ADC_SETTING2_NUM_CHANNELS);
156 ADC2->SQR3 = NEUG_ADC_SETTING2_SQR3;
158 #ifdef DELIBARATELY_DO_IT_WRONG_START_STOP
167 static uint32_t *adc_ptr;
170 static void adc_start_conversion_internal (void)
172 #ifdef DELIBARATELY_DO_IT_WRONG_START_STOP
174 ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
175 ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
176 | ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
177 /* Start conversion. tSTAB is 1uS, but we don't follow the spec. */
178 ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
179 ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
180 | ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
182 ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
183 ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
184 | ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
188 void adc_start_conversion (int mode, uint32_t *p, int size)
194 if (mode == ADC_SAMPLE_MODE)
196 dmaStreamSetMemory0 (NEUG_DMA_CHANNEL, p);
197 dmaStreamSetTransactionSize (NEUG_DMA_CHANNEL, size / 4);
198 dmaStreamSetMode (NEUG_DMA_CHANNEL, NEUG_DMA_MODE_SAMPLE);
199 dmaStreamEnable (NEUG_DMA_CHANNEL);
203 dmaStreamSetMemory0 (NEUG_DMA_CHANNEL, &CRC->DR);
204 dmaStreamSetTransactionSize (NEUG_DMA_CHANNEL, NEUG_CRC32_COUNTS);
205 dmaStreamSetMode (NEUG_DMA_CHANNEL, NEUG_DMA_MODE_CRC32);
206 dmaStreamEnable (NEUG_DMA_CHANNEL);
209 adc_start_conversion_internal ();
213 static void adc_stop_conversion (void)
215 dmaStreamDisable (NEUG_DMA_CHANNEL);
216 #ifdef DELIBARATELY_DO_IT_WRONG_START_STOP
220 ADC2->CR2 &= ~ADC_CR2_CONT;
221 ADC1->CR2 &= ~ADC_CR2_CONT;
233 dmaStreamRelease (NEUG_DMA_CHANNEL);
234 rccDisableAPB2 (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN, FALSE);
238 static void adc_lld_serve_rx_interrupt (void *arg, uint32_t flags)
242 if ((flags & STM32_DMA_ISR_TEIF) != 0) /* DMA errors */
244 /* Should never happened. If any, it's coding error. */
245 /* Access an unmapped address space or alignment violation. */
246 adc_stop_conversion ();
250 if ((flags & STM32_DMA_ISR_TCIF) != 0) /* Transfer complete */
252 adc_stop_conversion ();
254 if (adc_mode != ADC_SAMPLE_MODE)
257 *adc_ptr++ = CRC->DR;
261 dmaStreamSetMemory0 (NEUG_DMA_CHANNEL, &CRC->DR);
262 dmaStreamSetTransactionSize (NEUG_DMA_CHANNEL, NEUG_CRC32_COUNTS);
263 dmaStreamSetMode (NEUG_DMA_CHANNEL, NEUG_DMA_MODE_CRC32);
264 dmaStreamEnable (NEUG_DMA_CHANNEL);
266 adc_start_conversion_internal ();
270 if (adc_mode == ADC_SAMPLE_MODE || adc_size <= 0)
274 chEvtSignalFlagsI (rng_thread, ADC_DATA_AVAILABLE);
275 chSysUnlockFromIsr();