ChibiOS 21.11.5
hal_adc.h
Go to the documentation of this file.
1/*
2 ChibiOS - Copyright (C) 2006-2026 Giovanni Di Sirio.
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/**
18 * @file hal_adc.h
19 * @brief ADC Driver macros and structures.
20 *
21 * @addtogroup ADC
22 * @{
23 */
24
25#ifndef HAL_ADC_H
26#define HAL_ADC_H
27
28#if (HAL_USE_ADC == TRUE) || defined(__DOXYGEN__)
29
30/*===========================================================================*/
31/* Driver constants. */
32/*===========================================================================*/
33
34/*===========================================================================*/
35/* Driver pre-compile time settings. */
36/*===========================================================================*/
37
38/**
39 * @name ADC configuration options
40 * @{
41 */
42/**
43 * @brief Enables synchronous APIs.
44 * @note Disabling this option saves both code and data space.
45 */
46#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__)
47#define ADC_USE_WAIT TRUE
48#endif
49
50/**
51 * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs.
52 * @note Disabling this option saves both code and data space.
53 */
54#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
55#define ADC_USE_MUTUAL_EXCLUSION TRUE
56#endif
57/** @} */
58
59/*===========================================================================*/
60/* Derived constants and error checks. */
61/*===========================================================================*/
62
63/*===========================================================================*/
64/* Driver data structures and types. */
65/*===========================================================================*/
66
67/**
68 * @brief Driver state machine possible states.
69 */
70typedef enum {
71 ADC_UNINIT = 0, /**< Not initialized. */
72 ADC_STOP = 1, /**< Stopped. */
73 ADC_READY = 2, /**< Ready. */
74 ADC_ACTIVE = 3, /**< Converting. */
75 ADC_COMPLETE = 4, /**< Conversion complete. */
76 ADC_ERROR = 5 /**< Conversion error. */
78
79/**
80 * @brief Type of a structure representing an ADC driver.
81 */
83
84/**
85 * @brief Type of a structure representing an ADC driver configuration.
86 */
88
89/**
90 * @brief Conversion group configuration structure.
91 * @details This implementation-dependent structure describes a conversion
92 * operation.
93 * @note The use of this configuration structure requires knowledge of
94 * STM32 ADC cell registers interface, please refer to the STM32
95 * reference manual for details.
96 */
98
99/* Including the low level driver header, it exports information required
100 for completing types.*/
101#include "hal_adc_lld.h"
102
103/**
104 * @brief Type of an ADC notification callback.
105 * @details The callback is invoked from ISR context.
106 *
107 * @param[in] adcp pointer to the @p ADCDriver object triggering the
108 * callback
109 */
110typedef void (*adccallback_t)(ADCDriver *adcp);
111
112/**
113 * @brief Type of an ADC error callback.
114 *
115 * @param[in] adcp pointer to the @p ADCDriver object triggering the
116 * callback
117 * @param[in] err ADC error code
118 */
119typedef void (*adcerrorcallback_t)(ADCDriver *adcp, adcerror_t err);
120
121/**
122 * @brief Conversion group configuration structure.
123 * @details This implementation-dependent structure describes a conversion
124 * operation.
125 * @note The use of this configuration structure requires knowledge of
126 * STM32 ADC cell registers interface, please refer to the STM32
127 * reference manual for details.
128 */
130 /**
131 * @brief Enables the circular buffer mode for the group.
132 */
134 /**
135 * @brief Number of the analog channels belonging to the conversion group.
136 */
138 /**
139 * @brief Callback function associated to the group or @p NULL.
140 * @details In linear mode the callback is invoked after the driver returns
141 * to the @p ADC_READY state, this allows chaining another
142 * conversion using I-Class APIs. In circular mode the callback is
143 * invoked in either @p ADC_ACTIVE state (half buffer) or
144 * @p ADC_COMPLETE state (full buffer).
145 * @note If a synchronous API is waiting for completion then starting a
146 * follow-on conversion from this callback is undefined.
147 */
149 /**
150 * @brief Error callback or @p NULL.
151 */
153 /* End of the mandatory fields.*/
155};
156
157/**
158 * @brief Driver configuration structure.
159 */
161 /* End of the mandatory fields.*/
163};
164
165/**
166 * @brief Structure representing an ADC driver.
167 */
169 /**
170 * @brief Driver state.
171 */
173 /**
174 * @brief Current configuration data.
175 */
177 /**
178 * @brief Current samples buffer pointer or @p NULL.
179 */
181 /**
182 * @brief Current samples buffer depth or @p 0.
183 */
184 size_t depth;
185 /**
186 * @brief Current conversion group pointer or @p NULL.
187 */
189#if (ADC_USE_WAIT == TRUE) || defined(__DOXYGEN__)
190 /**
191 * @brief Waiting thread.
192 */
194#endif /* ADC_USE_WAIT == TRUE */
195#if (ADC_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__)
196 /**
197 * @brief Mutex protecting the peripheral.
198 */
200#endif /* ADC_USE_MUTUAL_EXCLUSION == TRUE */
201#if defined(ADC_DRIVER_EXT_FIELDS)
202 ADC_DRIVER_EXT_FIELDS
203#endif
204 /* End of the mandatory fields.*/
206};
207
208/*===========================================================================*/
209/* Driver macros. */
210/*===========================================================================*/
211
212/**
213 * @name Macro Functions
214 * @{
215 */
216/**
217 * @brief Buffer state.
218 * @note This function is meant to be called from the ADC callback only.
219 * @note This state is only meaningful for circular conversions, where it
220 * is used to distinguish the full buffer callback from the half
221 * buffer callback.
222 *
223 * @param[in] adcp pointer to the @p ADCDriver object
224 * @return The buffer state.
225 * @retval false if the driver filled/sent the first half of the
226 * buffer.
227 * @retval true if the driver filled/sent the second half of the
228 * buffer.
229 *
230 * @special
231 */
232#define adcIsBufferComplete(adcp) ((bool)((adcp)->state == ADC_COMPLETE))
233/** @} */
234
235/**
236 * @name Low level driver helper macros
237 * @{
238 */
239#if (ADC_USE_WAIT == TRUE) || defined(__DOXYGEN__)
240/**
241 * @brief Resumes a thread waiting for a conversion completion.
242 *
243 * @param[in] adcp pointer to the @p ADCDriver object
244 *
245 * @notapi
246 */
247#define _adc_reset_i(adcp) \
248 osalThreadResumeI(&(adcp)->thread, MSG_RESET)
249
250/**
251 * @brief Resumes a thread waiting for a conversion completion.
252 *
253 * @param[in] adcp pointer to the @p ADCDriver object
254 *
255 * @notapi
256 */
257#define _adc_reset_s(adcp) \
258 osalThreadResumeS(&(adcp)->thread, MSG_RESET)
259
260/**
261 * @brief Wakes up the waiting thread.
262 *
263 * @param[in] adcp pointer to the @p ADCDriver object
264 *
265 * @notapi
266 */
267#define _adc_wakeup_isr(adcp) { \
268 osalSysLockFromISR(); \
269 osalThreadResumeI(&(adcp)->thread, MSG_OK); \
270 osalSysUnlockFromISR(); \
271}
272
273/**
274 * @brief Wakes up the waiting thread with a timeout message.
275 *
276 * @param[in] adcp pointer to the @p ADCDriver object
277 *
278 * @notapi
279 */
280#define _adc_timeout_isr(adcp) { \
281 osalSysLockFromISR(); \
282 osalThreadResumeI(&(adcp)->thread, MSG_TIMEOUT); \
283 osalSysUnlockFromISR(); \
284}
285
286#else /* !ADC_USE_WAIT */
287#define _adc_reset_i(adcp)
288#define _adc_reset_s(adcp)
289#define _adc_wakeup_isr(adcp)
290#define _adc_timeout_isr(adcp)
291#endif /* !ADC_USE_WAIT */
292
293/**
294 * @brief Common ISR code, half buffer event.
295 * @details This code handles the portable part of the ISR code:
296 * - Callback invocation.
297 * .
298 * @note This macro is meant to be used in the low level drivers
299 * implementation only.
300 *
301 * @param[in] adcp pointer to the @p ADCDriver object
302 *
303 * @notapi
304 */
305#define _adc_isr_half_code(adcp) { \
306 if ((adcp)->grpp->end_cb != NULL) { \
307 (adcp)->grpp->end_cb(adcp); \
308 } \
309}
310
311/**
312 * @brief Common ISR code, full buffer event.
313 * @details This code handles the portable part of the ISR code:
314 * - Callback invocation.
315 * - Waiting thread wakeup, if any.
316 * - Driver state transitions.
317 * .
318 * @note This macro is meant to be used in the low level drivers
319 * implementation only.
320 *
321 * @param[in] adcp pointer to the @p ADCDriver object
322 *
323 * @notapi
324 */
325#define _adc_isr_full_code(adcp) { \
326 if ((adcp)->grpp->circular) { \
327 /* Callback handling.*/ \
328 if ((adcp)->grpp->end_cb != NULL) { \
329 (adcp)->state = ADC_COMPLETE; \
330 (adcp)->grpp->end_cb(adcp); \
331 if ((adcp)->state == ADC_COMPLETE) { \
332 (adcp)->state = ADC_ACTIVE; \
333 } \
334 } \
335 } \
336 else { \
337 /* End conversion.*/ \
338 const ADCConversionGroup *grpp = (adcp)->grpp; \
339 adc_lld_stop_conversion(adcp); \
340 if ((adcp)->grpp->end_cb != NULL) { \
341 (adcp)->state = ADC_READY; \
342 (adcp)->grpp->end_cb(adcp); \
343 if (((adcp)->state == ADC_READY) && ((adcp)->grpp == grpp)) { \
344 (adcp)->grpp = NULL; \
345 } \
346 } \
347 else { \
348 (adcp)->state = ADC_READY; \
349 (adcp)->grpp = NULL; \
350 } \
351 _adc_wakeup_isr(adcp); \
352 } \
353}
354
355/**
356 * @brief Common ISR code, error event.
357 * @details This code handles the portable part of the ISR code:
358 * - Callback invocation.
359 * - Waiting thread timeout signaling, if any.
360 * - Driver state transitions.
361 * .
362 * @note This macro is meant to be used in the low level drivers
363 * implementation only.
364 *
365 * @param[in] adcp pointer to the @p ADCDriver object
366 * @param[in] err platform dependent error code
367 *
368 * @notapi
369 */
370#define _adc_isr_error_code(adcp, err) { \
371 adc_lld_stop_conversion(adcp); \
372 if ((adcp)->grpp->error_cb != NULL) { \
373 (adcp)->state = ADC_ERROR; \
374 (adcp)->grpp->error_cb(adcp, err); \
375 if ((adcp)->state == ADC_ERROR) { \
376 (adcp)->state = ADC_READY; \
377 (adcp)->grpp = NULL; \
378 } \
379 } \
380 else { \
381 (adcp)->state = ADC_READY; \
382 (adcp)->grpp = NULL; \
383 } \
384 _adc_timeout_isr(adcp); \
385}
386/** @} */
387
388/*===========================================================================*/
389/* External declarations. */
390/*===========================================================================*/
391
392#ifdef __cplusplus
393extern "C" {
394#endif
395 void adcInit(void);
396 void adcObjectInit(ADCDriver *adcp);
397 msg_t adcStart(ADCDriver *adcp, const ADCConfig *config);
398 void adcStop(ADCDriver *adcp);
399 void adcStartConversion(ADCDriver *adcp,
400 const ADCConversionGroup *grpp,
401 adcsample_t *samples,
402 size_t depth);
404 const ADCConversionGroup *grpp,
405 adcsample_t *samples,
406 size_t depth);
407 void adcStopConversion(ADCDriver *adcp);
408 void adcStopConversionI(ADCDriver *adcp);
409#if ADC_USE_WAIT == TRUE
411 const ADCConversionGroup *grpp,
412 adcsample_t *samples,
413 size_t depth);
414#endif
415#if ADC_USE_MUTUAL_EXCLUSION == TRUE
416 void adcAcquireBus(ADCDriver *adcp);
417 void adcReleaseBus(ADCDriver *adcp);
418#endif
419#ifdef __cplusplus
420}
421#endif
422
423#endif /* HAL_USE_ADC == TRUE */
424
425#endif /* HAL_ADC_H */
426
427/** @} */
uint32_t adcerror_t
Type of an ADC error mask.
Definition hal_adc_lld.h:82
void(* adccallback_t)(ADCDriver *adcp)
Type of an ADC notification callback.
Definition hal_adc.h:110
struct hal_adc_driver ADCDriver
Type of a structure representing an ADC driver.
Definition hal_adc.h:82
void adcStartConversionI(ADCDriver *adcp, const ADCConversionGroup *grpp, adcsample_t *samples, size_t depth)
Starts an ADC conversion.
Definition hal_adc.c:192
msg_t adcStart(ADCDriver *adcp, const ADCConfig *config)
Configures and activates the ADC peripheral.
Definition hal_adc.c:96
void adcStop(ADCDriver *adcp)
Deactivates the ADC peripheral.
Definition hal_adc.c:132
#define adc_lld_driver_fields
Low level fields of the ADC driver structure.
Definition hal_adc_lld.h:91
void(* adcerrorcallback_t)(ADCDriver *adcp, adcerror_t err)
Type of an ADC error callback.
Definition hal_adc.h:119
adcstate_t
Driver state machine possible states.
Definition hal_adc.h:70
void adcAcquireBus(ADCDriver *adcp)
Gains exclusive access to the ADC peripheral.
Definition hal_adc.c:317
struct hal_adc_configuration_group ADCConversionGroup
Conversion group configuration structure.
Definition hal_adc.h:97
uint16_t adc_channels_num_t
Channels number in a conversion group.
Definition hal_adc_lld.h:77
struct hal_adc_config ADCConfig
Type of a structure representing an ADC driver configuration.
Definition hal_adc.h:87
#define adc_lld_configuration_group_fields
Low level fields of the ADC configuration structure.
void adcStopConversionI(ADCDriver *adcp)
Stops an ongoing conversion.
Definition hal_adc.c:247
#define adc_lld_config_fields
Low level fields of the ADC configuration structure.
Definition hal_adc_lld.h:98
void adcStartConversion(ADCDriver *adcp, const ADCConversionGroup *grpp, adcsample_t *samples, size_t depth)
Starts an ADC conversion.
Definition hal_adc.c:164
void adcStopConversion(ADCDriver *adcp)
Stops an ongoing conversion.
Definition hal_adc.c:221
uint16_t adcsample_t
ADC sample data type.
Definition hal_adc_lld.h:72
void adcObjectInit(ADCDriver *adcp)
Initializes the standard part of a ADCDriver structure.
Definition hal_adc.c:68
void adcReleaseBus(ADCDriver *adcp)
Releases exclusive access to the ADC peripheral.
Definition hal_adc.c:333
msg_t adcConvert(ADCDriver *adcp, const ADCConversionGroup *grpp, adcsample_t *samples, size_t depth)
Performs an ADC conversion.
Definition hal_adc.c:290
void adcInit(void)
ADC Driver initialization.
Definition hal_adc.c:56
@ ADC_UNINIT
Definition hal_adc.h:71
@ ADC_STOP
Definition hal_adc.h:72
@ ADC_ERROR
Definition hal_adc.h:76
@ ADC_READY
Definition hal_adc.h:73
@ ADC_COMPLETE
Definition hal_adc.h:75
@ ADC_ACTIVE
Definition hal_adc.h:74
struct ch_mutex mutex_t
Type of a mutex structure.
Definition chmtx.h:51
int32_t msg_t
Definition chearly.h:87
thread_t * thread_reference_t
Type of a thread reference.
Definition chobjects.h:135
PLATFORM ADC subsystem low level driver header.
Driver configuration structure.
Definition hal_adc.h:160
Conversion group configuration structure.
Definition hal_adc.h:129
adcerrorcallback_t error_cb
Error callback or NULL.
Definition hal_adc.h:152
adc_channels_num_t num_channels
Number of the analog channels belonging to the conversion group.
Definition hal_adc.h:137
adccallback_t end_cb
Callback function associated to the group or NULL.
Definition hal_adc.h:148
bool circular
Enables the circular buffer mode for the group.
Definition hal_adc.h:133
Structure representing an ADC driver.
Definition hal_adc.h:168
adcsample_t * samples
Current samples buffer pointer or NULL.
Definition hal_adc.h:180
const ADCConversionGroup * grpp
Current conversion group pointer or NULL.
Definition hal_adc.h:188
adcstate_t state
Driver state.
Definition hal_adc.h:172
size_t depth
Current samples buffer depth or 0.
Definition hal_adc.h:184
const ADCConfig * config
Current configuration data.
Definition hal_adc.h:176
thread_reference_t thread
Waiting thread.
Definition hal_adc.h:193
mutex_t mutex
Mutex protecting the peripheral.
Definition hal_adc.h:199