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