fix ADC, update main
[gnuk/neug.git] / src / adc_stm32f103.c
1 /*
2  * adc_stm32f103.c - ADC driver for STM32F103
3  *
4  * Copyright (C) 2011, 2012, 2013 Free Software Initiative of Japan
5  * Author: NIIBE Yutaka <gniibe@fsij.org>
6  *
7  * This file is a part of NeuG, a True Random Number Generator
8  * implementation based on quantization error of ADC (for STM32F103).
9  *
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.
14  *
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.
19  *
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/>.
22  *
23  */
24
25 #include <stdint.h>
26 #include <stdlib.h>
27 #include <chopstx.h>
28
29 #include "neug.h"
30 #include "stm32f103.h"
31 #include "adc.h"
32
33 #define NEUG_CRC32_COUNTS 4
34
35 #define STM32_ADC_ADC1_DMA_PRIORITY         2
36
37 #define ADC_SMPR1_SMP_VREF(n)   ((n) << 21)
38 #define ADC_SMPR1_SMP_SENSOR(n) ((n) << 18)
39
40 #define ADC_SMPR1_SMP_AN10(n)   ((n) << 0)
41 #define ADC_SMPR1_SMP_AN11(n)   ((n) << 3)
42
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)
47
48 #define ADC_SQR1_NUM_CH(n)      (((n) - 1) << 20)
49
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)
54
55 #define ADC_SAMPLE_1P5          0
56
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
65
66 #define DELIBARATELY_DO_IT_WRONG_VREF_SAMPLE_TIME
67 #define DELIBARATELY_DO_IT_WRONG_START_STOP
68
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
72 #else
73 #define ADC_SAMPLE_VREF ADC_SAMPLE_239P5
74 #define ADC_SAMPLE_SENSOR ADC_SAMPLE_239P5
75 #endif
76
77 #define NEUG_DMA_CHANNEL STM32_DMA1_STREAM1
78 #define NEUG_DMA_MODE                                                   \
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                      \
82      | STM32_DMA_CR_TEIE  )
83
84 #define NEUG_ADC_SETTING1_SMPR1 ADC_SMPR1_SMP_VREF(ADC_SAMPLE_VREF)     \
85                               | ADC_SMPR1_SMP_SENSOR(ADC_SAMPLE_SENSOR)
86 #define NEUG_ADC_SETTING1_SMPR2 0
87 #define NEUG_ADC_SETTING1_SQR3  ADC_SQR3_SQ1_N(ADC_CHANNEL_VREFINT)     \
88                               | ADC_SQR3_SQ2_N(ADC_CHANNEL_SENSOR)      \
89                               | ADC_SQR3_SQ3_N(ADC_CHANNEL_SENSOR)      \
90                               | ADC_SQR3_SQ4_N(ADC_CHANNEL_VREFINT)     
91 #define NEUG_ADC_SETTING1_NUM_CHANNELS 4
92
93 #if !defined(NEUG_ADC_SETTING2_SMPR1)
94 #define NEUG_ADC_SETTING2_SMPR1 0
95 #define NEUG_ADC_SETTING2_SMPR2 ADC_SMPR2_SMP_AN0(ADC_SAMPLE_1P5)    \
96                               | ADC_SMPR2_SMP_AN1(ADC_SAMPLE_1P5)
97 #define NEUG_ADC_SETTING2_SQR3  ADC_SQR3_SQ1_N(ADC_CHANNEL_IN0)      \
98                               | ADC_SQR3_SQ2_N(ADC_CHANNEL_IN1)
99 #define NEUG_ADC_SETTING2_NUM_CHANNELS 2
100 #endif
101
102
103 /*
104  * Do calibration for both of ADCs.
105  */
106 void adc_init (void)
107 {
108   RCC->APB2ENR |= (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN);
109   RCC->APB2RSTR = (RCC_APB2RSTR_ADC1RST | RCC_APB2RSTR_ADC2RST);
110   RCC->APB2RSTR = 0;
111
112   ADC1->CR1 = 0;
113   ADC1->CR2 = ADC_CR2_ADON;
114   ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_RSTCAL;
115   while ((ADC1->CR2 & ADC_CR2_RSTCAL) != 0)
116     ;
117   ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_CAL;
118   while ((ADC1->CR2 & ADC_CR2_CAL) != 0)
119     ;
120   ADC1->CR2 = 0;
121
122   ADC2->CR1 = 0;
123   ADC2->CR2 = ADC_CR2_ADON;
124   ADC2->CR2 = ADC_CR2_ADON | ADC_CR2_RSTCAL;
125   while ((ADC2->CR2 & ADC_CR2_RSTCAL) != 0)
126     ;
127   ADC2->CR2 = ADC_CR2_ADON | ADC_CR2_CAL;
128   while ((ADC2->CR2 & ADC_CR2_CAL) != 0)
129     ;
130   ADC2->CR2 = 0;
131   RCC->APB2ENR &= ~(RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN);
132 }
133
134
135 void adc_start (void)
136 {
137   /* Use DMA channel 1.  */
138   RCC->AHBENR |= RCC_AHBENR_DMA1EN;
139   DMA1_Channel1->CCR = STM32_DMA_CCR_RESET_VALUE;
140   DMA1->IFCR = 0xffffffff;
141
142   RCC->APB2ENR |= (RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN);
143
144   ADC1->CR1 = (ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_1 | ADC_CR1_DUALMOD_0
145                | ADC_CR1_SCAN);
146   ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
147                | ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
148   ADC1->SMPR1 = NEUG_ADC_SETTING1_SMPR1;
149   ADC1->SMPR2 = NEUG_ADC_SETTING1_SMPR2;
150   ADC1->SQR1 = ADC_SQR1_NUM_CH(NEUG_ADC_SETTING1_NUM_CHANNELS);
151   ADC1->SQR2 = 0;
152   ADC1->SQR3 = NEUG_ADC_SETTING1_SQR3;
153
154   ADC2->CR1 = (ADC_CR1_DUALMOD_2 | ADC_CR1_DUALMOD_1 | ADC_CR1_DUALMOD_0
155                | ADC_CR1_SCAN);
156   ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
157   ADC2->SMPR1 = NEUG_ADC_SETTING2_SMPR1;
158   ADC2->SMPR2 = NEUG_ADC_SETTING2_SMPR2;
159   ADC2->SQR1 = ADC_SQR1_NUM_CH(NEUG_ADC_SETTING2_NUM_CHANNELS);
160   ADC2->SQR2 = 0;
161   ADC2->SQR3 = NEUG_ADC_SETTING2_SQR3;
162
163 #ifdef DELIBARATELY_DO_IT_WRONG_START_STOP
164   ADC2->CR2 = 0;
165   ADC1->CR2 = 0;
166 #endif
167 }
168
169 uint32_t adc_buf[64];
170
171 void adc_start_conversion (int offset, int count)
172 {
173   DMA1_Channel1->CPAR = (uint32_t)&ADC1->DR;        /* SetPeripheral */
174   DMA1_Channel1->CMAR = (uint32_t)&adc_buf[offset]; /* SetMemory0    */
175   DMA1_Channel1->CNDTR = count;                     /* Counter       */
176   DMA1_Channel1->CCR = NEUG_DMA_MODE | DMA_CCR1_EN; /* Mode   */
177
178 #ifdef DELIBARATELY_DO_IT_WRONG_START_STOP
179   /* Power on */
180   ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
181   ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
182                | ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
183   /* Start conversion.  tSTAB is 1uS, but we don't follow the spec.  */
184   ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
185   ADC1->CR2 = (ADC_CR2_TSVREFE | ADC_CR2_EXTTRIG | ADC_CR2_SWSTART
186                | ADC_CR2_EXTSEL | ADC_CR2_DMA | ADC_CR2_CONT | ADC_CR2_ADON);
187 #else
188   ADC2->CR2 = ADC_CR2_EXTTRIG | ADC_CR2_CONT | ADC_CR2_ADON;
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 #endif
192 }
193
194
195 static void adc_stop_conversion (void)
196 {
197   DMA1_Channel1->CCR &= ~DMA_CCR1_EN;
198
199 #ifdef DELIBARATELY_DO_IT_WRONG_START_STOP
200   ADC1->CR2 = 0;
201   ADC2->CR2 = 0;
202 #else
203   ADC2->CR2 &= ~ADC_CR2_CONT;
204   ADC1->CR2 &= ~ADC_CR2_CONT;
205 #endif
206 }
207
208 void adc_stop (void)
209 {
210   ADC1->CR1 = 0;
211   ADC1->CR2 = 0;
212
213   ADC2->CR1 = 0;
214   ADC2->CR2 = 0;
215
216   RCC->AHBENR &= ~RCC_AHBENR_DMA1EN;
217   RCC->APB2ENR &= ~(RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN);
218 }
219
220
221 static uint32_t adc_err;
222
223 /*
224  * Return 0 on success.
225  * Return 1 on error.
226  */
227 int adc_wait_completion (chopstx_intr_t *intr)
228 {
229   uint32_t flags;
230
231   while (1)
232     {
233       chopstx_intr_wait (intr);
234       flags = DMA1->ISR & STM32_DMA_ISR_MASK; /* Channel 1 interrupt cause.  */
235       DMA1->IFCR = flags; /* Clear interrupt of channel 1.  */
236
237       if ((flags & STM32_DMA_ISR_TEIF) != 0)  /* DMA errors  */
238         {
239           /* Should never happened.  If any, it's coding error. */
240           /* Access an unmapped address space or alignment violation.  */
241           adc_err++;
242           adc_stop_conversion ();
243           return 1;
244         }
245       else if ((flags & STM32_DMA_ISR_TCIF) != 0) /* Transfer complete */
246         {
247           adc_stop_conversion ();
248           return 0;
249         }
250
251       /*
252        * Even if STM32_DMA_CR_HTIE is unset, we come here with HTIF=1,
253        * with unknown reason.  Just ignore the interrupt by HTIF to
254        * continue more data.
255        */
256     }
257 }