2 * adc_stm32f103.c - ADC driver for STM32F103
4 * Copyright (C) 2011, 2012, 2013 Free Software Initiative of Japan
5 * Author: NIIBE Yutaka <gniibe@fsij.org>
7 * This file is a part of NeuG, a True 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 * NeuG 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 #include "stm32f103.h"
33 #define NEUG_CRC32_COUNTS 4
35 #define STM32_ADC_ADC1_DMA_PRIORITY 2
37 #define ADC_SMPR1_SMP_VREF(n) ((n) << 21)
38 #define ADC_SMPR1_SMP_SENSOR(n) ((n) << 18)
40 #define ADC_SMPR1_SMP_AN10(n) ((n) << 0)
41 #define ADC_SMPR1_SMP_AN11(n) ((n) << 3)
43 #define ADC_SMPR2_SMP_AN0(n) ((n) << 0)
44 #define ADC_SMPR2_SMP_AN1(n) ((n) << 3)
45 #define ADC_SMPR2_SMP_AN2(n) ((n) << 6)
46 #define ADC_SMPR2_SMP_AN9(n) ((n) << 27)
48 #define ADC_SQR1_NUM_CH(n) (((n) - 1) << 20)
50 #define ADC_SQR3_SQ1_N(n) ((n) << 0)
51 #define ADC_SQR3_SQ2_N(n) ((n) << 5)
52 #define ADC_SQR3_SQ3_N(n) ((n) << 10)
53 #define ADC_SQR3_SQ4_N(n) ((n) << 15)
55 #define ADC_SAMPLE_1P5 0
57 #define ADC_CHANNEL_IN0 0
58 #define ADC_CHANNEL_IN1 1
59 #define ADC_CHANNEL_IN2 2
60 #define ADC_CHANNEL_IN9 9
61 #define ADC_CHANNEL_IN10 10
62 #define ADC_CHANNEL_IN11 11
63 #define ADC_CHANNEL_SENSOR 16
64 #define ADC_CHANNEL_VREFINT 17
66 #define DELIBARATELY_DO_IT_WRONG_VREF_SAMPLE_TIME
67 #define DELIBARATELY_DO_IT_WRONG_START_STOP
69 #ifdef DELIBARATELY_DO_IT_WRONG_VREF_SAMPLE_TIME
70 #define ADC_SAMPLE_VREF ADC_SAMPLE_1P5
71 #define ADC_SAMPLE_SENSOR ADC_SAMPLE_1P5
73 #define ADC_SAMPLE_VREF ADC_SAMPLE_239P5
74 #define ADC_SAMPLE_SENSOR ADC_SAMPLE_239P5
77 #define NEUG_DMA_CHANNEL STM32_DMA1_STREAM1
78 #define NEUG_DMA_MODE_SAMPLE \
79 ( STM32_DMA_CR_PL (STM32_ADC_ADC1_DMA_PRIORITY) \
80 | STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_PSIZE_WORD \
81 | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE \
85 #define NEUG_DMA_MODE_CRC32 \
86 ( STM32_DMA_CR_PL (STM32_ADC_ADC1_DMA_PRIORITY) \
87 | STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_PSIZE_WORD \
88 | STM32_DMA_CR_TCIE | STM32_DMA_CR_TEIE)
90 #define NEUG_DMA_MODE_CRC32 \
91 ( STM32_DMA_CR_PL (STM32_ADC_ADC1_DMA_PRIORITY) \
92 | STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_PSIZE_WORD \
94 | STM32_DMA_CR_TCIE | STM32_DMA_CR_TEIE)
97 #define NEUG_ADC_SETTING1_SMPR1 ADC_SMPR1_SMP_VREF(ADC_SAMPLE_VREF) \
98 | ADC_SMPR1_SMP_SENSOR(ADC_SAMPLE_SENSOR)
99 #define NEUG_ADC_SETTING1_SMPR2 0
100 #define NEUG_ADC_SETTING1_SQR3 ADC_SQR3_SQ1_N(ADC_CHANNEL_VREFINT) \
101 | ADC_SQR3_SQ2_N(ADC_CHANNEL_SENSOR) \
102 | ADC_SQR3_SQ3_N(ADC_CHANNEL_SENSOR) \
103 | ADC_SQR3_SQ4_N(ADC_CHANNEL_VREFINT)
104 #define NEUG_ADC_SETTING1_NUM_CHANNELS 4
106 #if !defined(NEUG_ADC_SETTING2_SMPR1)
107 #define NEUG_ADC_SETTING2_SMPR1 0
108 #define NEUG_ADC_SETTING2_SMPR2 ADC_SMPR2_SMP_AN0(ADC_SAMPLE_1P5) \
109 | ADC_SMPR2_SMP_AN1(ADC_SAMPLE_1P5)
110 #define NEUG_ADC_SETTING2_SQR3 ADC_SQR3_SQ1_N(ADC_CHANNEL_IN0) \
111 | ADC_SQR3_SQ2_N(ADC_CHANNEL_IN1)
112 #define NEUG_ADC_SETTING2_NUM_CHANNELS 2
117 * Do calibration for both of ADCs.
121 RCC->APB2ENR |= (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN);
122 RCC->APB2RSTR = (RCC_APB2RSTR_ADC1RST | RCC_APB2RSTR_ADC2RST);
126 ADC1->CR2 = ADC_CR2_ADON;
127 ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_RSTCAL;
128 while ((ADC1->CR2 & ADC_CR2_RSTCAL) != 0)
130 ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_CAL;
131 while ((ADC1->CR2 & ADC_CR2_CAL) != 0)
136 ADC2->CR2 = ADC_CR2_ADON;
137 ADC2->CR2 = ADC_CR2_ADON | ADC_CR2_RSTCAL;
138 while ((ADC2->CR2 & ADC_CR2_RSTCAL) != 0)
140 ADC2->CR2 = ADC_CR2_ADON | ADC_CR2_CAL;
141 while ((ADC2->CR2 & ADC_CR2_CAL) != 0)
144 RCC->APB2ENR &= ~(RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN);
147 extern uint8_t __process4_stack_base__, __process4_stack_size__;
148 const uint32_t __stackaddr_adc = (uint32_t)&__process4_stack_base__;
149 const size_t __stacksize_adc = (size_t)&__process4_stack_size__;
152 static void adc_lld_serve_rx_interrupt (uint32_t flags);
154 #define INTR_REQ_DMA1_Channel1 11
156 adc_intr_thread (void *arg)
158 chopstx_intr_t interrupt;
161 chopstx_claim_irq (&interrupt, INTR_REQ_DMA1_Channel1);
167 chopstx_intr_wait (&interrupt);
168 flags = DMA1->ISR & STM32_DMA_ISR_MASK; /* Channel 1 interrupt cause. */
169 DMA1->IFCR = STM32_DMA_ISR_MASK; /* Clear interrupt of channel 1. */
170 adc_lld_serve_rx_interrupt (flags);
176 static chopstx_t adc_thd;
178 void adc_start (void)
180 /* Use DMA channel 1. */
181 RCC->AHBENR |= RCC_AHBENR_DMA1EN;
182 DMA1_Channel1->CCR = STM32_DMA_CCR_RESET_VALUE;
183 DMA1->IFCR = 0xffffffff;
185 RCC->APB2ENR |= (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN);
187 ADC1->CR1 = (ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_1 | ADC_CR1_DUALMOD_0
189 ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
190 | ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
191 ADC1->SMPR1 = NEUG_ADC_SETTING1_SMPR1;
192 ADC1->SMPR2 = NEUG_ADC_SETTING1_SMPR2;
193 ADC1->SQR1 = ADC_SQR1_NUM_CH(NEUG_ADC_SETTING1_NUM_CHANNELS);
195 ADC1->SQR3 = NEUG_ADC_SETTING1_SQR3;
197 ADC2->CR1 = (ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_1 | ADC_CR1_DUALMOD_0
199 ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
200 ADC2->SMPR1 = NEUG_ADC_SETTING2_SMPR1;
201 ADC2->SMPR2 = NEUG_ADC_SETTING2_SMPR2;
202 ADC2->SQR1 = ADC_SQR1_NUM_CH(NEUG_ADC_SETTING2_NUM_CHANNELS);
204 ADC2->SQR3 = NEUG_ADC_SETTING2_SQR3;
206 #ifdef DELIBARATELY_DO_IT_WRONG_START_STOP
211 adc_thd = chopstx_create (PRIO_ADC, __stackaddr_adc, __stacksize_adc,
212 adc_intr_thread, NULL);
216 static uint32_t *adc_ptr;
218 static uint32_t adc_buf[64];
220 static void adc_start_conversion_internal (void)
222 #ifdef DELIBARATELY_DO_IT_WRONG_START_STOP
224 ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
225 ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
226 | ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
227 /* Start conversion. tSTAB is 1uS, but we don't follow the spec. */
228 ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
229 ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
230 | ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
232 ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
233 ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
234 | ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
238 void adc_start_conversion (int mode, uint32_t *p, int size)
244 if (mode == ADC_SAMPLE_MODE)
246 DMA1_Channel1->CPAR = (uint32_t)&ADC1->DR; /* SetPeripheral */
247 DMA1_Channel1->CMAR = (uint32_t)p; /* SetMemory0 */
248 DMA1_Channel1->CNDTR = (uint32_t)size / 4; /* counter */
249 DMA1_Channel1->CCR = NEUG_DMA_MODE_SAMPLE; /*mode*/
250 DMA1_Channel1->CCR |= DMA_CCR1_EN; /* Enable */
254 DMA1_Channel1->CPAR = (uint32_t)&ADC1->DR; /* SetPeripheral */
255 DMA1_Channel1->CMAR = (uint32_t)adc_buf; /* SetMemory0 */
256 DMA1_Channel1->CNDTR = size; /* counter */
257 DMA1_Channel1->CCR = NEUG_DMA_MODE_CRC32; /*mode*/
258 DMA1_Channel1->CCR |= DMA_CCR1_EN; /* Enable */
261 adc_start_conversion_internal ();
265 static void adc_stop_conversion (void)
267 DMA1_Channel1->CCR &= ~DMA_CCR1_EN;
269 #ifdef DELIBARATELY_DO_IT_WRONG_START_STOP
273 ADC2->CR2 &= ~ADC_CR2_CONT;
274 ADC1->CR2 &= ~ADC_CR2_CONT;
286 /* XXX: here to disable the associated IRQ vector; stop intr thread. */
287 RCC->AHBENR &= ~RCC_AHBENR_DMA1EN;
288 RCC->APB2ENR &= ~(RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN);
290 chopstx_cancel (adc_thd);
291 chopstx_join (adc_thd, NULL);
295 static void adc_lld_serve_rx_interrupt (uint32_t flags)
297 if ((flags & STM32_DMA_ISR_TEIF) != 0) /* DMA errors */
299 /* Should never happened. If any, it's coding error. */
300 /* Access an unmapped address space or alignment violation. */
301 adc_stop_conversion ();
305 if ((flags & STM32_DMA_ISR_TCIF) != 0) /* Transfer complete */
307 adc_stop_conversion ();
309 if (adc_mode != ADC_SAMPLE_MODE)
313 for (i = 0; i < adc_size;)
315 CRC->DR = adc_buf[i++];
316 CRC->DR = adc_buf[i++];
317 CRC->DR = adc_buf[i++];
318 CRC->DR = adc_buf[i++];
319 *adc_ptr++ = CRC->DR;
323 chopstx_mutex_lock (&adc_mtx);
324 adc_data_available++;
326 chopstx_cond_signal (&adc_cond);
327 chopstx_mutex_unlock (&adc_mtx);