1  | #include <Arduino.h>
  | 
2  | 
  | 
3  | #include "analog2.h"
  | 
4  | 
  | 
5  | // /home/christoph/.arduino15/packages/STMicroelectronics/hardware/stm32/2.3.0/libraries/SrcWrapper/src/stm32
  | 
6  | //  analog.cpp
  | 
7  | // /home/christoph/.arduino15/packages/STMicroelectronics/hardware/stm32/2.3.0/system/Drivers
  | 
8  | 
  | 
9  | #ifdef __cplusplus
  | 
10  | extern "C" {
 | 
11  | #endif
  | 
12  | uint16_t adc_read_value2(PinName pin, uint32_t resolution);
  | 
13  | #ifdef __cplusplus
  | 
14  | }
  | 
15  | #endif
  | 
16  | 
  | 
17  | #define CHANNEL 5 // PA0 -> A0
  | 
18  | //#define CHANNEL 6 // PA1 -> A1
  | 
19  | //#define CHANNEL 8 // PA3 -> A2
  | 
20  | 
  | 
21  | // Initialize the ADC1 for single conversion mode
  | 
22  | void init_analog()
  | 
23  | {
 | 
24  |   // something is missing in the following initialization
  | 
25  |   // thererfore we need to call the HALL funktions
  | 
26  |   // tbd: find the missing register 
  | 
27  |   // hint: the error might be in a missing clock initialization of the ADC
  | 
28  |   adc_read_value2(PA_0, 12); 
  | 
29  |   // Enable clock for ADC
  | 
30  |   //SET_BIT(RCC->AHBENR, RCC_AHBENR_ADC12EN);
  | 
31  |   SET_BIT(RCC->AHB2ENR, RCC_AHB2ENR_ADCEN);
  | 
32  | 
  | 
33  |   // Disable the ADC
  | 
34  |   if (READ_BIT(ADC1->ISR, ADC_ISR_ADRDY))
  | 
35  |   {
 | 
36  |     SET_BIT(ADC1->ISR, ADC_ISR_ADRDY);
  | 
37  |   }
  | 
38  |   if (READ_BIT(ADC1->CR, ADC_CR_ADEN))
  | 
39  |   {
 | 
40  |     SET_BIT(ADC1->CR, ADC_CR_ADDIS);
  | 
41  |   }
  | 
42  | 
  | 
43  |   // Wait until ADC is disabled
  | 
44  |   while (READ_BIT(ADC1->CR, ADC_CR_ADEN));
  | 
45  | 
  | 
46  |   // Enable ADC voltage regulator
  | 
47  |   MODIFY_REG(ADC1->CR, ADC_CR_ADVREGEN, 0);
  | 
48  |   //MODIFY_REG(ADC1->CR, ADC_CR_ADVREGEN, ADC_CR_ADVREGEN_0);
  | 
49  |   MODIFY_REG(ADC1->CR, ADC_CR_ADVREGEN, ADC_CR_ADVREGEN);
  | 
50  |   // Delay 1-2 ms
  | 
51  |   //delay_ms(2);
  | 
52  |   delay(2);
  | 
53  | 
  | 
54  |   // ADC Clock = HCLK/4
  | 
55  |   //MODIFY_REG(ADC12_COMMON->CCR, ADC12_CCR_CKMODE, ADC12_CCR_CKMODE_0 + ADC12_CCR_CKMODE_1);
  | 
56  |   MODIFY_REG(ADC1_COMMON->CCR, ADC_CCR_CKMODE, ADC_CCR_CKMODE_0 + ADC_CCR_CKMODE_1);
  | 
57  | 
  | 
58  |   // Single ended mode for all channels
  | 
59  |   WRITE_REG(ADC1->DIFSEL, 0);
  | 
60  | 
  | 
61  |   // Start calibration for single ended mode
  | 
62  |   CLEAR_BIT(ADC1->CR, ADC_CR_ADCALDIF);
  | 
63  |   SET_BIT(ADC1->CR, ADC_CR_ADCAL);
  | 
64  | 
  | 
65  |   // Wait until the calibration is finished
  | 
66  |   while (READ_BIT(ADC1->CR, ADC_CR_ADCAL));
  | 
67  | 
  | 
68  |   // Clear the ready flag
  | 
69  |   SET_BIT(ADC1->ISR, ADC_ISR_ADRDY);
  | 
70  | 
  | 
71  |   // Enable the ADC repeatedly until success (workaround from errata)
  | 
72  |   do
  | 
73  |   {
 | 
74  |     SET_BIT(ADC1->CR, ADC_CR_ADEN);
  | 
75  |   }
  | 
76  |   while (!READ_BIT(ADC1->ISR, ADC_ISR_ADRDY));
  | 
77  | 
  | 
78  |   // Select software start trigger
  | 
79  |   MODIFY_REG(ADC1->CFGR, ADC_CFGR_EXTEN, 0);
  | 
80  | 
  | 
81  |   // Select single conversion mode
  | 
82  |   CLEAR_BIT(ADC1->CFGR, ADC_CFGR_CONT);
  | 
83  | 
  | 
84  |   // Set sample time to 32 cycles
  | 
85  |   MODIFY_REG(ADC1->SMPR1, ADC_SMPR1_SMP1, ADC_SMPR1_SMP1_2);
  | 
86  | }
  | 
87  | 
  | 
88  | // Read from an analog input of ADC1
  | 
89  | uint32_t read_analog(uint32_t channel)
  | 
90  | {
 | 
91  |   // Number of channels to convert: 1
  | 
92  |   MODIFY_REG(ADC1->SQR1, ADC_SQR1_L, 0);
  | 
93  |   // Select the channel
  | 
94  |   MODIFY_REG(ADC1->SQR1, ADC_SQR1_SQ1, channel << ADC_SQR1_SQ1_Pos);
  | 
95  |   // Clear the finish flag
  | 
96  |   CLEAR_BIT(ADC1->ISR, ADC_ISR_EOC);
  | 
97  |   // Start a conversion
  | 
98  |   SET_BIT(ADC1->CR, ADC_CR_ADSTART);
  | 
99  |   // Wait until the conversion is finished
  | 
100  |   while (!READ_BIT(ADC1->ISR, ADC_ISR_EOC));
  | 
101  |   while (READ_BIT(ADC1->CR, ADC_CR_ADSTART));
  | 
102  |   // Return the lower 12 bits of the result
  | 
103  |   return ADC1->DR & 0b111111111111;
  | 
104  | }
  | 
105  | 
  | 
106  | void speedTest()
  | 
107  | {
 | 
108  |   uint32_t n;
  | 
109  |   float value;
  | 
110  | 
  | 
111  |   Serial.print("channel: ");
 | 
112  |   Serial.print((int)CHANNEL);
  | 
113  |   Serial.println("");
 | 
114  | 
  | 
115  |   int32_t startTime = micros();
  | 
116  | 
  | 
117  |   for (n = 0; n < 1000; n++)
  | 
118  |   {
 | 
119  |     read_analog(CHANNEL);
  | 
120  |   }
  | 
121  | 
  | 
122  |   int32_t duration1000samples_us = micros() - startTime;
  | 
123  | 
  | 
124  |   Serial.print("1000 samples duration: ");
 | 
125  |   Serial.print(duration1000samples_us); Serial.println("us");
 | 
126  |   Serial.print("samples per second: ");
 | 
127  |   Serial.println((int)(1000 / ((float)duration1000samples_us / 1e6)));
  | 
128  | 
  | 
129  |   delay(5000);
  | 
130  | }
  | 
131  | 
  | 
132  | void setup()
  | 
133  | {
 | 
134  |   Serial.begin(115200);
  | 
135  | 
  | 
136  |   init_analog();
  | 
137  |   speedTest();
  | 
138  | }
  | 
139  | 
  | 
140  | void loop()
  | 
141  | {
 | 
142  |   uint16_t v;
  | 
143  |   // uint16_t adc_read_value2(PinName pin, uint32_t resolution);
  | 
144  |   //v=adc_read_value2(PA_0, 12);
  | 
145  |   v = read_analog(CHANNEL);
  | 
146  |   Serial.println(v);
  | 
147  |   delay(1);
  | 
148  | 
  | 
149  | }
  |