43a2c72407f7fe0260263d70b9cbd1aec259fc53
[gnuk/neug.git] / src / adc_stm32f103.c
1 /*
2  * adc_stm32f103.c - ADC driver for STM32F103
3  *                   In this ADC driver, there are NeuG specific parts.
4  *                   You need to modify to use this as generic ADC driver.
5  *
6  * Copyright (C) 2011, 2012, 2013 Free Software Initiative of Japan
7  * Author: NIIBE Yutaka <gniibe@fsij.org>
8  *
9  * This file is a part of NeuG, a True Random Number Generator
10  * implementation based on quantization error of ADC (for STM32F103).
11  *
12  * NeuG is free software: you can redistribute it and/or modify it
13  * under the terms of the GNU General Public License as published by
14  * the Free Software Foundation, either version 3 of the License, or
15  * (at your option) any later version.
16  *
17  * NeuG is distributed in the hope that it will be useful, but WITHOUT
18  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
20  * License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24  *
25  */
26
27 #include <stdint.h>
28 #include <stdlib.h>
29 #include <chopstx.h>
30
31 #include "neug.h"
32 #include "stm32f103.h"
33 #include "adc.h"
34
35 #define NEUG_CRC32_COUNTS 4
36
37 #define STM32_ADC_ADC1_DMA_PRIORITY         2
38
39 #define ADC_SMPR1_SMP_VREF(n)   ((n) << 21)
40 #define ADC_SMPR1_SMP_SENSOR(n) ((n) << 18)
41
42 #define ADC_SMPR1_SMP_AN10(n)   ((n) << 0)
43 #define ADC_SMPR1_SMP_AN11(n)   ((n) << 3)
44
45 #define ADC_SMPR2_SMP_AN0(n)    ((n) << 0)
46 #define ADC_SMPR2_SMP_AN1(n)    ((n) << 3)
47 #define ADC_SMPR2_SMP_AN2(n)    ((n) << 6)
48 #define ADC_SMPR2_SMP_AN9(n)    ((n) << 27)
49
50 #define ADC_SQR1_NUM_CH(n)      (((n) - 1) << 20)
51
52 #define ADC_SQR3_SQ1_N(n)       ((n) << 0)
53 #define ADC_SQR3_SQ2_N(n)       ((n) << 5)
54 #define ADC_SQR3_SQ3_N(n)       ((n) << 10)
55 #define ADC_SQR3_SQ4_N(n)       ((n) << 15)
56
57 #define ADC_SAMPLE_1P5          0
58
59 #define ADC_CHANNEL_IN0         0
60 #define ADC_CHANNEL_IN1         1
61 #define ADC_CHANNEL_IN2         2
62 #define ADC_CHANNEL_IN9         9
63 #define ADC_CHANNEL_IN10        10
64 #define ADC_CHANNEL_IN11        11
65 #define ADC_CHANNEL_SENSOR      16
66 #define ADC_CHANNEL_VREFINT     17
67
68 #define DELIBARATELY_DO_IT_WRONG_VREF_SAMPLE_TIME
69 #define DELIBARATELY_DO_IT_WRONG_START_STOP
70
71 #ifdef DELIBARATELY_DO_IT_WRONG_VREF_SAMPLE_TIME
72 #define ADC_SAMPLE_VREF ADC_SAMPLE_1P5
73 #define ADC_SAMPLE_SENSOR ADC_SAMPLE_1P5
74 #else
75 #define ADC_SAMPLE_VREF ADC_SAMPLE_239P5
76 #define ADC_SAMPLE_SENSOR ADC_SAMPLE_239P5
77 #endif
78
79 #define NEUG_DMA_CHANNEL STM32_DMA1_STREAM1
80 #define NEUG_DMA_MODE                                                   \
81   (  STM32_DMA_CR_PL (STM32_ADC_ADC1_DMA_PRIORITY)                      \
82      | STM32_DMA_CR_MSIZE_WORD | STM32_DMA_CR_PSIZE_WORD                \
83      | STM32_DMA_CR_MINC       | STM32_DMA_CR_TCIE                      \
84      | STM32_DMA_CR_TEIE  )
85
86 #define NEUG_ADC_SETTING1_SMPR1 ADC_SMPR1_SMP_VREF(ADC_SAMPLE_VREF)     \
87                               | ADC_SMPR1_SMP_SENSOR(ADC_SAMPLE_SENSOR)
88 #define NEUG_ADC_SETTING1_SMPR2 0
89 #define NEUG_ADC_SETTING1_SQR3  ADC_SQR3_SQ1_N(ADC_CHANNEL_VREFINT)     \
90                               | ADC_SQR3_SQ2_N(ADC_CHANNEL_SENSOR)      \
91                               | ADC_SQR3_SQ3_N(ADC_CHANNEL_SENSOR)      \
92                               | ADC_SQR3_SQ4_N(ADC_CHANNEL_VREFINT)     
93 #define NEUG_ADC_SETTING1_NUM_CHANNELS 4
94
95 #if !defined(NEUG_ADC_SETTING2_SMPR1)
96 #define NEUG_ADC_SETTING2_SMPR1 0
97 #define NEUG_ADC_SETTING2_SMPR2 ADC_SMPR2_SMP_AN0(ADC_SAMPLE_1P5)    \
98                               | ADC_SMPR2_SMP_AN1(ADC_SAMPLE_1P5)
99 #define NEUG_ADC_SETTING2_SQR3  ADC_SQR3_SQ1_N(ADC_CHANNEL_IN0)      \
100                               | ADC_SQR3_SQ2_N(ADC_CHANNEL_IN1)
101 #define NEUG_ADC_SETTING2_NUM_CHANNELS 2
102 #endif
103
104
105 /*
106  * Do calibration for both of ADCs.
107  */
108 void adc_init (void)
109 {
110   RCC->APB2ENR |= (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN);
111   RCC->APB2RSTR = (RCC_APB2RSTR_ADC1RST | RCC_APB2RSTR_ADC2RST);
112   RCC->APB2RSTR = 0;
113
114   ADC1->CR1 = 0;
115   ADC1->CR2 = ADC_CR2_ADON;
116   ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_RSTCAL;
117   while ((ADC1->CR2 & ADC_CR2_RSTCAL) != 0)
118     ;
119   ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_CAL;
120   while ((ADC1->CR2 & ADC_CR2_CAL) != 0)
121     ;
122   ADC1->CR2 = 0;
123
124   ADC2->CR1 = 0;
125   ADC2->CR2 = ADC_CR2_ADON;
126   ADC2->CR2 = ADC_CR2_ADON | ADC_CR2_RSTCAL;
127   while ((ADC2->CR2 & ADC_CR2_RSTCAL) != 0)
128     ;
129   ADC2->CR2 = ADC_CR2_ADON | ADC_CR2_CAL;
130   while ((ADC2->CR2 & ADC_CR2_CAL) != 0)
131     ;
132   ADC2->CR2 = 0;
133   RCC->APB2ENR &= ~(RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN);
134 }
135
136
137 void adc_start (void)
138 {
139   /* Use DMA channel 1.  */
140   RCC->AHBENR |= RCC_AHBENR_DMA1EN;
141   DMA1_Channel1->CCR = STM32_DMA_CCR_RESET_VALUE;
142   DMA1->IFCR = 0xffffffff;
143
144   RCC->APB2ENR |= (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN);
145
146   ADC1->CR1 = (ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_1 | ADC_CR1_DUALMOD_0
147                | ADC_CR1_SCAN);
148   ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
149                | ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
150   ADC1->SMPR1 = NEUG_ADC_SETTING1_SMPR1;
151   ADC1->SMPR2 = NEUG_ADC_SETTING1_SMPR2;
152   ADC1->SQR1 = ADC_SQR1_NUM_CH(NEUG_ADC_SETTING1_NUM_CHANNELS);
153   ADC1->SQR2 = 0;
154   ADC1->SQR3 = NEUG_ADC_SETTING1_SQR3;
155
156   ADC2->CR1 = (ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_1 | ADC_CR1_DUALMOD_0
157                | ADC_CR1_SCAN);
158   ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
159   ADC2->SMPR1 = NEUG_ADC_SETTING2_SMPR1;
160   ADC2->SMPR2 = NEUG_ADC_SETTING2_SMPR2;
161   ADC2->SQR1 = ADC_SQR1_NUM_CH(NEUG_ADC_SETTING2_NUM_CHANNELS);
162   ADC2->SQR2 = 0;
163   ADC2->SQR3 = NEUG_ADC_SETTING2_SQR3;
164
165 #ifdef DELIBARATELY_DO_IT_WRONG_START_STOP
166   /*
167    * We could just let ADC run continuously always and only enable DMA
168    * to receive stable data from ADC.  But our purpose is not to get
169    * correct data but noise.  In fact, we can get more noise when we
170    * start/stop ADC each time.
171    */
172   ADC2->CR2 = 0;
173   ADC1->CR2 = 0;
174 #else
175   /* Start conversion.  */
176   ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
177   ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
178                | ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
179 #endif
180 }
181
182 uint32_t adc_buf[64];
183
184 void adc_start_conversion (int offset, int count)
185 {
186   DMA1_Channel1->CPAR = (uint32_t)&ADC1->DR;        /* SetPeripheral */
187   DMA1_Channel1->CMAR = (uint32_t)&adc_buf[offset]; /* SetMemory0    */
188   DMA1_Channel1->CNDTR = count;                     /* Counter       */
189   DMA1_Channel1->CCR = NEUG_DMA_MODE | DMA_CCR1_EN; /* Mode   */
190
191 #ifdef DELIBARATELY_DO_IT_WRONG_START_STOP
192   /* Power on */
193   ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
194   ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
195                | ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
196   /*
197    * Start conversion.  tSTAB is 1uS, but we don't follow the spec, to
198    * get more noise.
199    */
200   ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
201   ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
202                | ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
203 #endif
204 }
205
206
207 static void adc_stop_conversion (void)
208 {
209   DMA1_Channel1->CCR &= ~DMA_CCR1_EN;
210
211 #ifdef DELIBARATELY_DO_IT_WRONG_START_STOP
212   ADC2->CR2 = 0;
213   ADC1->CR2 = 0;
214 #endif
215 }
216
217 void adc_stop (void)
218 {
219   ADC1->CR1 = 0;
220   ADC1->CR2 = 0;
221
222   ADC2->CR1 = 0;
223   ADC2->CR2 = 0;
224
225   RCC->AHBENR &= ~RCC_AHBENR_DMA1EN;
226   RCC->APB2ENR &= ~(RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN);
227 }
228
229
230 static uint32_t adc_err;
231
232 /*
233  * Return 0 on success.
234  * Return 1 on error.
235  */
236 int adc_wait_completion (chopstx_intr_t *intr)
237 {
238   uint32_t flags;
239
240   while (1)
241     {
242       chopstx_intr_wait (intr);
243       flags = DMA1->ISR & STM32_DMA_ISR_MASK; /* Channel 1 interrupt cause.  */
244       /*
245        * Clear interrupt cause of channel 1.
246        *
247        * Note that CGIFx=0, as CGIFx=1 clears all of GIF, HTIF, TCIF
248        * and TEIF.
249        */
250       DMA1->IFCR = (flags & ~1);
251
252       if ((flags & STM32_DMA_ISR_TEIF) != 0)  /* DMA errors  */
253         {
254           /* Should never happened.  If any, it's coding error. */
255           /* Access an unmapped address space or alignment violation.  */
256           adc_err++;
257           adc_stop_conversion ();
258           return 1;
259         }
260       else if ((flags & STM32_DMA_ISR_TCIF) != 0) /* Transfer complete */
261         {
262           adc_stop_conversion ();
263           return 0;
264         }
265
266       /*
267        * Even if STM32_DMA_CR_HTIE is unset, we come here with HTIF=1,
268        * with unknown reason.  Just ignore the interrupt by HTIF to
269        * continue more data.
270        */
271     }
272 }