libxr
Embedded C++ framework for bare-metal, RTOS and Linux
Loading...
Searching...
No Matches
stm32_adc.hpp
1#pragma once
2
3#include <initializer_list>
4
5#include "main.h"
6
7#ifdef HAL_ADC_MODULE_ENABLED
8
9#ifdef ADC
10#undef ADC
11#endif
12
13#include "adc.hpp"
14#include "libxr.hpp"
15#include "libxr_def.hpp"
16#include "stm32_adc_gpdma.hpp"
17
18namespace LibXR
19{
20
25{
26 template <typename, typename = void>
27 struct GetADCResolution
28 {
29 float Get(ADC_HandleTypeDef* hadc)
30 {
31 UNUSED(hadc);
32 return 4095.0f;
33 }
34 };
35
36 template <typename T>
37 struct GetADCResolution<T, std::void_t<decltype(std::declval<T>().Init.Resolution)>>
38 {
39 float Get(T* hadc)
40 {
41 switch (hadc->Init.Resolution)
42 {
43#ifdef ADC_RESOLUTION_16B
44 case ADC_RESOLUTION_16B:
45 return 65535.0f;
46#endif
47#ifdef ADC_RESOLUTION_12B
48 case ADC_RESOLUTION_12B:
49 return 4095.0f;
50#endif
51#ifdef ADC_RESOLUTION_10B
52 case ADC_RESOLUTION_10B:
53 return 1023.0f;
54#endif
55#ifdef ADC_RESOLUTION_8B
56 case ADC_RESOLUTION_8B:
57 return 255.0f;
58#endif
59#ifdef ADC_RESOLUTION_6B
60 case ADC_RESOLUTION_6B:
61 return 63.0f;
62#endif
63 default:
64 return 4095.0f;
65 }
66 }
67 };
68
69 template <typename T, typename = void>
70 struct HasContinuousConvMode : std::false_type
71 {
72 };
73
74 template <typename T>
75 struct HasContinuousConvMode<
76 T, std::void_t<decltype(std::declval<T>()->Init.ContinuousConvMode)>>
77 : std::true_type
78 {
79 };
80
81 template <typename T, typename = void>
82 struct HasDMAContinuousRequests : std::false_type
83 {
84 };
85
86 template <typename T>
87 struct HasDMAContinuousRequests<
88 T, std::void_t<decltype(std::declval<T>()->Init.DMAContinuousRequests)>>
89 : std::true_type
90 {
91 };
92
93 template <typename T, typename = void>
94 struct HasNbrOfConversion : std::false_type
95 {
96 };
97
98 template <typename T>
99 struct HasNbrOfConversion<
100 T, std::void_t<decltype(std::declval<T>()->Init.NbrOfConversion)>> : std::true_type
101 {
102 };
103
104 template <typename T, typename = void>
105 struct HasDMACircularMode : std::false_type
106 {
107 };
108
109 template <typename T>
110 struct HasDMACircularMode<
111 T, std::void_t<decltype(std::declval<T>()->DMA_Handle->Init.Mode)>> : std::true_type
112 {
113 };
114
115 template <typename T, typename = void>
116 struct HasConversionDataManagement : std::false_type
117 {
118 };
119
120 template <typename T>
121 struct HasConversionDataManagement<
122 T, std::void_t<decltype(std::declval<T>()->Init.ConversionDataManagement)>>
123 : std::true_type
124 {
125 };
126
127 template <typename T>
128 static typename std::enable_if<HasContinuousConvMode<T>::value>::type
129 AssertContinuousConvModeEnabled(T hadc)
130 {
131 ASSERT(hadc->Init.ContinuousConvMode == ENABLE);
132 }
133
134 template <typename T>
135 static typename std::enable_if<!HasContinuousConvMode<T>::value>::type
136 AssertContinuousConvModeEnabled(T)
137 {
138 }
139
140 template <typename T>
141 static typename std::enable_if<HasContinuousConvMode<T>::value>::type
142 AssertContinuousConvModeDisabled(T hadc)
143 {
144 ASSERT(hadc->Init.ContinuousConvMode == DISABLE);
145 }
146
147 template <typename T>
148 static typename std::enable_if<!HasContinuousConvMode<T>::value>::type
149 AssertContinuousConvModeDisabled(T)
150 {
151 }
152
153 // 有 ConversionDataManagement 的时候,只看 ConversionDataManagement ==
154 // ADC_CONVERSIONDATA_DMA_CIRCULAR
155 template <typename T>
156 static typename std::enable_if<HasConversionDataManagement<T>::value>::type
157 AssertDMAContReqEnabled(T hadc)
158 {
159#ifdef ADC_CONVERSIONDATA_DMA_CIRCULAR
160 ASSERT(hadc->Init.ConversionDataManagement == ADC_CONVERSIONDATA_DMA_CIRCULAR);
161#else
162 UNUSED(hadc);
163#endif
164 }
165
166 // 没有 ConversionDataManagement,但有 DMAContinuousRequests => 维持原有检查
167 template <typename T>
168 static typename std::enable_if<!HasConversionDataManagement<T>::value &&
169 HasDMAContinuousRequests<T>::value>::type
170 AssertDMAContReqEnabled(T hadc)
171 {
172 ASSERT(hadc->Init.DMAContinuousRequests == ENABLE);
173 }
174
175 template <typename T>
176 static typename std::enable_if<!HasConversionDataManagement<T>::value &&
177 !HasDMAContinuousRequests<T>::value>::type
178 AssertDMAContReqEnabled(T)
179 {
180 }
181
182 template <typename T>
183 static typename std::enable_if<HasNbrOfConversion<T>::value>::type AssertNbrOfConvEq(
184 T hadc, uint32_t n)
185 {
186 ASSERT(hadc->Init.NbrOfConversion == n);
187 }
188
189 template <typename T>
190 static typename std::enable_if<!HasNbrOfConversion<T>::value>::type AssertNbrOfConvEq(
191 T, uint32_t)
192 {
193 }
194
195 template <typename T>
196 static typename std::enable_if<HasDMACircularMode<T>::value>::type AssertDMACircular(
197 T hadc)
198 {
199 ASSERT(hadc->DMA_Handle != nullptr);
200#if defined(DMA_CIRCULAR)
201 ASSERT(hadc->DMA_Handle->Init.Mode == DMA_CIRCULAR);
202#else
203 static_assert(sizeof(T) == 0, "DMA_CIRCULAR is not defined by the HAL");
204#endif
205 }
206
207 template <typename T>
208 static typename std::enable_if<!HasDMACircularMode<T>::value>::type AssertDMACircular(T)
209 {
210 }
211
212 public:
216 class Channel : public ADC
217 {
218 public:
226 Channel(STM32ADC* adc, uint8_t index, uint32_t ch);
227
233 float Read() override;
234
235 private:
236 Channel();
237 STM32ADC* adc_;
238 uint8_t index_;
239 uint32_t ch_;
240
241 friend class STM32ADC;
242 };
243
255 STM32ADC(ADC_HandleTypeDef* hadc, RawData dma_buff,
256 std::initializer_list<uint32_t> channels, float vref);
257
261 ~STM32ADC();
262
269 Channel& GetChannel(uint8_t index);
270
277 float ReadChannel(uint8_t channel);
278
279 private:
280 alignas(LibXR::CONCURRENCY_ALIGNMENT) std::atomic<uint32_t> locked_ = 0U;
281 ADC_HandleTypeDef* hadc_;
282 const uint8_t NUM_CHANNELS;
283 uint8_t filter_size_;
284 bool use_dma_;
285 RawData dma_buffer_;
286 float resolution_;
287 Channel** channels_;
288 float vref_;
289#if defined(LIBXR_STM32_ADC_GPDMA)
290 STM32GpdmaAdcAdapter gpdma_adapter_;
291#endif
292
293 float ConvertToVoltage(float adc_value);
294};
295
296} // namespace LibXR
297
298#endif
模拟数字转换器(ADC)基类 Abstract base class for Analog-to-Digital Converter (ADC)
Definition adc.hpp:18
可写原始数据视图 / Mutable raw data view
ADC 通道对象 / ADC channel object.
float Read() override
读取 ADC 电压值 / Read ADC voltage
Definition stm32_adc.cpp:46
STM32 ADC 驱动实现 / STM32 ADC driver implementation.
Definition stm32_adc.hpp:25
STM32ADC(ADC_HandleTypeDef *hadc, RawData dma_buff, std::initializer_list< uint32_t > channels, float vref)
构造 ADC 驱动对象 / Construct ADC driver object
Definition stm32_adc.cpp:48
~STM32ADC()
析构函数 / Destructor
float ReadChannel(uint8_t channel)
读取指定通道电压 / Read channel voltage
Channel & GetChannel(uint8_t index)
获取 ADC 通道对象 / Get ADC channel object
STM32 ADC 循环采样的 GPDMA 适配器 / GPDMA adapter for circular STM32 ADC sampling.
LibXR 命名空间 / LibXR namespace.
Definition ch32_can.hpp:14
constexpr size_t CONCURRENCY_ALIGNMENT
并发结构对齐粒度(用于降低多核伪共享) / Alignment policy used by concurrency-oriented structures
Definition libxr_def.hpp:61