ChibiOS  19.1.4
hal_adc.h
Go to the documentation of this file.
1 /*
2  ChibiOS - Copyright (C) 2006..2018 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  */
70 typedef 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. */
77 } adcstate_t;
78 
79 /**
80  * @brief Type of a structure representing an ADC driver.
81  */
82 typedef struct hal_adc_driver ADCDriver;
83 
84 /**
85  * @brief Type of a structure representing an ADC driver configuration.
86  */
87 typedef struct hal_adc_config ADCConfig;
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  *
106  * @param[in] adcp pointer to the @p ADCDriver object triggering the
107  * callback
108  */
109 typedef void (*adccallback_t)(ADCDriver *adcp);
110 
111 /**
112  * @brief Type of an ADC error callback.
113  *
114  * @param[in] adcp pointer to the @p ADCDriver object triggering the
115  * callback
116  * @param[in] err ADC error code
117  */
118 typedef void (*adcerrorcallback_t)(ADCDriver *adcp, adcerror_t err);
119 
120 /**
121  * @brief Conversion group configuration structure.
122  * @details This implementation-dependent structure describes a conversion
123  * operation.
124  * @note The use of this configuration structure requires knowledge of
125  * STM32 ADC cell registers interface, please refer to the STM32
126  * reference manual for details.
127  */
129  /**
130  * @brief Enables the circular buffer mode for the group.
131  */
132  bool circular;
133  /**
134  * @brief Number of the analog channels belonging to the conversion group.
135  */
137  /**
138  * @brief Callback function associated to the group or @p NULL.
139  */
141  /**
142  * @brief Error callback or @p NULL.
143  */
145  /* End of the mandatory fields.*/
146  adc_lld_configuration_group_fields;
147 };
148 
149 /**
150  * @brief Driver configuration structure.
151  */
153  /* End of the mandatory fields.*/
155 };
156 
157 /**
158  * @brief Structure representing an ADC driver.
159  */
161  /**
162  * @brief Driver state.
163  */
165  /**
166  * @brief Current configuration data.
167  */
169  /**
170  * @brief Current samples buffer pointer or @p NULL.
171  */
173  /**
174  * @brief Current samples buffer depth or @p 0.
175  */
176  size_t depth;
177  /**
178  * @brief Current conversion group pointer or @p NULL.
179  */
181 #if (ADC_USE_WAIT == TRUE) || defined(__DOXYGEN__)
182  /**
183  * @brief Waiting thread.
184  */
186 #endif /* ADC_USE_WAIT == TRUE */
187 #if (ADC_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__)
188  /**
189  * @brief Mutex protecting the peripheral.
190  */
192 #endif /* ADC_USE_MUTUAL_EXCLUSION == TRUE */
193 #if defined(ADC_DRIVER_EXT_FIELDS)
194  ADC_DRIVER_EXT_FIELDS
195 #endif
196  /* End of the mandatory fields.*/
198 };
199 
200 /*===========================================================================*/
201 /* Driver macros. */
202 /*===========================================================================*/
203 
204 /**
205  * @name Macro Functions
206  * @{
207  */
208 /**
209  * @brief Buffer state.
210  * @note This function is meant to be called from the ADC callback only.
211  *
212  * @param[in] adcp pointer to the @p ADCDriver object
213  * @return The buffer state.
214  * @retval false if the driver filled/sent the first half of the
215  * buffer.
216  * @retval true if the driver filled/sent the second half of the
217  * buffer.
218  *
219  * @special
220  */
221 #define adcIsBufferComplete(adcp) ((bool)((adcp)->state == ADC_COMPLETE))
222 /** @} */
223 
224 /**
225  * @name Low level driver helper macros
226  * @{
227  */
228 #if (ADC_USE_WAIT == TRUE) || defined(__DOXYGEN__)
229 /**
230  * @brief Resumes a thread waiting for a conversion completion.
231  *
232  * @param[in] adcp pointer to the @p ADCDriver object
233  *
234  * @notapi
235  */
236 #define _adc_reset_i(adcp) \
237  osalThreadResumeI(&(adcp)->thread, MSG_RESET)
238 
239 /**
240  * @brief Resumes a thread waiting for a conversion completion.
241  *
242  * @param[in] adcp pointer to the @p ADCDriver object
243  *
244  * @notapi
245  */
246 #define _adc_reset_s(adcp) \
247  osalThreadResumeS(&(adcp)->thread, MSG_RESET)
248 
249 /**
250  * @brief Wakes up the waiting thread.
251  *
252  * @param[in] adcp pointer to the @p ADCDriver object
253  *
254  * @notapi
255  */
256 #define _adc_wakeup_isr(adcp) { \
257  osalSysLockFromISR(); \
258  osalThreadResumeI(&(adcp)->thread, MSG_OK); \
259  osalSysUnlockFromISR(); \
260 }
261 
262 /**
263  * @brief Wakes up the waiting thread with a timeout message.
264  *
265  * @param[in] adcp pointer to the @p ADCDriver object
266  *
267  * @notapi
268  */
269 #define _adc_timeout_isr(adcp) { \
270  osalSysLockFromISR(); \
271  osalThreadResumeI(&(adcp)->thread, MSG_TIMEOUT); \
272  osalSysUnlockFromISR(); \
273 }
274 
275 #else /* !ADC_USE_WAIT */
276 #define _adc_reset_i(adcp)
277 #define _adc_reset_s(adcp)
278 #define _adc_wakeup_isr(adcp)
279 #define _adc_timeout_isr(adcp)
280 #endif /* !ADC_USE_WAIT */
281 
282 /**
283  * @brief Common ISR code, half buffer event.
284  * @details This code handles the portable part of the ISR code:
285  * - Callback invocation.
286  * .
287  * @note This macro is meant to be used in the low level drivers
288  * implementation only.
289  *
290  * @param[in] adcp pointer to the @p ADCDriver object
291  *
292  * @notapi
293  */
294 #define _adc_isr_half_code(adcp) { \
295  if ((adcp)->grpp->end_cb != NULL) { \
296  (adcp)->grpp->end_cb(adcp); \
297  } \
298 }
299 
300 /**
301  * @brief Common ISR code, full buffer event.
302  * @details This code handles the portable part of the ISR code:
303  * - Callback invocation.
304  * - Waiting thread wakeup, if any.
305  * - Driver state transitions.
306  * .
307  * @note This macro is meant to be used in the low level drivers
308  * implementation only.
309  *
310  * @param[in] adcp pointer to the @p ADCDriver object
311  *
312  * @notapi
313  */
314 #define _adc_isr_full_code(adcp) { \
315  if ((adcp)->grpp->circular) { \
316  /* Callback handling.*/ \
317  if ((adcp)->grpp->end_cb != NULL) { \
318  (adcp)->state = ADC_COMPLETE; \
319  (adcp)->grpp->end_cb(adcp); \
320  if ((adcp)->state == ADC_COMPLETE) { \
321  (adcp)->state = ADC_ACTIVE; \
322  } \
323  } \
324  } \
325  else { \
326  /* End conversion.*/ \
327  adc_lld_stop_conversion(adcp); \
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_READY; \
333  (adcp)->grpp = NULL; \
334  } \
335  } \
336  else { \
337  (adcp)->state = ADC_READY; \
338  (adcp)->grpp = NULL; \
339  } \
340  _adc_wakeup_isr(adcp); \
341  } \
342 }
343 
344 /**
345  * @brief Common ISR code, error event.
346  * @details This code handles the portable part of the ISR code:
347  * - Callback invocation.
348  * - Waiting thread timeout signaling, if any.
349  * - Driver state transitions.
350  * .
351  * @note This macro is meant to be used in the low level drivers
352  * implementation only.
353  *
354  * @param[in] adcp pointer to the @p ADCDriver object
355  * @param[in] err platform dependent error code
356  *
357  * @notapi
358  */
359 #define _adc_isr_error_code(adcp, err) { \
360  adc_lld_stop_conversion(adcp); \
361  if ((adcp)->grpp->error_cb != NULL) { \
362  (adcp)->state = ADC_ERROR; \
363  (adcp)->grpp->error_cb(adcp, err); \
364  if ((adcp)->state == ADC_ERROR) { \
365  (adcp)->state = ADC_READY; \
366  (adcp)->grpp = NULL; \
367  } \
368  } \
369  else { \
370  (adcp)->state = ADC_READY; \
371  (adcp)->grpp = NULL; \
372  } \
373  _adc_timeout_isr(adcp); \
374 }
375 /** @} */
376 
377 /*===========================================================================*/
378 /* External declarations. */
379 /*===========================================================================*/
380 
381 #ifdef __cplusplus
382 extern "C" {
383 #endif
384  void adcInit(void);
385  void adcObjectInit(ADCDriver *adcp);
386  void adcStart(ADCDriver *adcp, const ADCConfig *config);
387  void adcStop(ADCDriver *adcp);
388  void adcStartConversion(ADCDriver *adcp,
389  const ADCConversionGroup *grpp,
390  adcsample_t *samples,
391  size_t depth);
392  void adcStartConversionI(ADCDriver *adcp,
393  const ADCConversionGroup *grpp,
394  adcsample_t *samples,
395  size_t depth);
396  void adcStopConversion(ADCDriver *adcp);
397  void adcStopConversionI(ADCDriver *adcp);
398 #if ADC_USE_WAIT == TRUE
399  msg_t adcConvert(ADCDriver *adcp,
400  const ADCConversionGroup *grpp,
401  adcsample_t *samples,
402  size_t depth);
403 #endif
404 #if ADC_USE_MUTUAL_EXCLUSION == TRUE
405  void adcAcquireBus(ADCDriver *adcp);
406  void adcReleaseBus(ADCDriver *adcp);
407 #endif
408 #ifdef __cplusplus
409 }
410 #endif
411 
412 #endif /* HAL_USE_ADC == TRUE */
413 
414 #endif /* HAL_ADC_H */
415 
416 /** @} */
bool circular
Enables the circular buffer mode for the group.
Definition: hal_adc.h:132
adcstate_t
Driver state machine possible states.
Definition: hal_adc.h:70
void adcObjectInit(ADCDriver *adcp)
Initializes the standard part of a ADCDriver structure.
Definition: hal_adc.c:68
void adcStartConversion(ADCDriver *adcp, const ADCConversionGroup *grpp, adcsample_t *samples, size_t depth)
Starts an ADC conversion.
Definition: hal_adc.c:147
void adcStop(ADCDriver *adcp)
Deactivates the ADC peripheral.
Definition: hal_adc.c:115
Driver configuration structure.
Definition: hal_adc.h:152
void adcAcquireBus(ADCDriver *adcp)
Gains exclusive access to the ADC peripheral.
Definition: hal_adc.c:298
mutex_t mutex
Mutex protecting the peripheral.
Definition: hal_adc.h:191
adcerror_t
Possible ADC failure causes.
Definition: hal_adc_lld.h:75
size_t depth
Current samples buffer depth or 0.
Definition: hal_adc.h:176
PLATFORM ADC subsystem low level driver header.
thread_reference_t thread
Waiting thread.
Definition: hal_adc.h:185
void adcReleaseBus(ADCDriver *adcp)
Releases exclusive access to the ADC peripheral.
Definition: hal_adc.c:314
Mutex structure.
Definition: chmtx.h:57
adcsample_t * samples
Current samples buffer pointer or NULL.
Definition: hal_adc.h:172
uint16_t adc_channels_num_t
Channels number in a conversion group.
Definition: hal_adc_lld.h:68
#define adc_lld_driver_fields
Low level fields of the ADC driver structure.
Definition: hal_adc_lld.h:88
void adcStart(ADCDriver *adcp, const ADCConfig *config)
Configures and activates the ADC peripheral.
Definition: hal_adc.c:95
Conversion group configuration structure.
Definition: hal_adc.h:128
adccallback_t end_cb
Callback function associated to the group or NULL.
Definition: hal_adc.h:140
void(* adccallback_t)(ADCDriver *adcp)
Type of an ADC notification callback.
Definition: hal_adc.h:109
adc_channels_num_t num_channels
Number of the analog channels belonging to the conversion group.
Definition: hal_adc.h:136
adcerrorcallback_t error_cb
Error callback or NULL.
Definition: hal_adc.h:144
msg_t adcConvert(ADCDriver *adcp, const ADCConversionGroup *grpp, adcsample_t *samples, size_t depth)
Performs an ADC conversion.
Definition: hal_adc.c:271
Structure representing an ADC driver.
Definition: hal_adc.h:160
void(* adcerrorcallback_t)(ADCDriver *adcp, adcerror_t err)
Type of an ADC error callback.
Definition: hal_adc.h:118
void adcStopConversion(ADCDriver *adcp)
Stops an ongoing conversion.
Definition: hal_adc.c:204
void adcStartConversionI(ADCDriver *adcp, const ADCConversionGroup *grpp, adcsample_t *samples, size_t depth)
Starts an ADC conversion.
Definition: hal_adc.c:175
uint16_t adcsample_t
ADC sample data type.
Definition: hal_adc_lld.h:63
void adcStopConversionI(ADCDriver *adcp)
Stops an ongoing conversion.
Definition: hal_adc.c:230
#define adc_lld_config_fields
Low level fields of the ADC configuration structure.
Definition: hal_adc_lld.h:95
const ADCConversionGroup * grpp
Current conversion group pointer or NULL.
Definition: hal_adc.h:180
const ADCConfig * config
Current configuration data.
Definition: hal_adc.h:168
int32_t msg_t
Definition: chtypes.h:51
void adcInit(void)
ADC Driver initialization.
Definition: hal_adc.c:56
adcstate_t state
Driver state.
Definition: hal_adc.h:164
Structure representing a thread.
Definition: chschd.h:153