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 | }
|