ChibiOS/HAL  6.1.0
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 #include "hal_adc_lld.h"
80 
81 /*===========================================================================*/
82 /* Driver macros. */
83 /*===========================================================================*/
84 
85 /**
86  * @name Low level driver helper macros
87  * @{
88  */
89 #if (ADC_USE_WAIT == TRUE) || defined(__DOXYGEN__)
90 /**
91  * @brief Resumes a thread waiting for a conversion completion.
92  *
93  * @param[in] adcp pointer to the @p ADCDriver object
94  *
95  * @notapi
96  */
97 #define _adc_reset_i(adcp) \
98  osalThreadResumeI(&(adcp)->thread, MSG_RESET)
99 
100 /**
101  * @brief Resumes a thread waiting for a conversion completion.
102  *
103  * @param[in] adcp pointer to the @p ADCDriver object
104  *
105  * @notapi
106  */
107 #define _adc_reset_s(adcp) \
108  osalThreadResumeS(&(adcp)->thread, MSG_RESET)
109 
110 /**
111  * @brief Wakes up the waiting thread.
112  *
113  * @param[in] adcp pointer to the @p ADCDriver object
114  *
115  * @notapi
116  */
117 #define _adc_wakeup_isr(adcp) { \
118  osalSysLockFromISR(); \
119  osalThreadResumeI(&(adcp)->thread, MSG_OK); \
120  osalSysUnlockFromISR(); \
121 }
122 
123 /**
124  * @brief Wakes up the waiting thread with a timeout message.
125  *
126  * @param[in] adcp pointer to the @p ADCDriver object
127  *
128  * @notapi
129  */
130 #define _adc_timeout_isr(adcp) { \
131  osalSysLockFromISR(); \
132  osalThreadResumeI(&(adcp)->thread, MSG_TIMEOUT); \
133  osalSysUnlockFromISR(); \
134 }
135 
136 #else /* !ADC_USE_WAIT */
137 #define _adc_reset_i(adcp)
138 #define _adc_reset_s(adcp)
139 #define _adc_wakeup_isr(adcp)
140 #define _adc_timeout_isr(adcp)
141 #endif /* !ADC_USE_WAIT */
142 
143 /**
144  * @brief Common ISR code, half buffer event.
145  * @details This code handles the portable part of the ISR code:
146  * - Callback invocation.
147  * .
148  * @note This macro is meant to be used in the low level drivers
149  * implementation only.
150  *
151  * @param[in] adcp pointer to the @p ADCDriver object
152  *
153  * @notapi
154  */
155 #define _adc_isr_half_code(adcp) { \
156  if ((adcp)->grpp->end_cb != NULL) { \
157  (adcp)->grpp->end_cb(adcp, (adcp)->samples, (adcp)->depth / 2); \
158  } \
159 }
160 
161 /**
162  * @brief Common ISR code, full buffer event.
163  * @details This code handles the portable part of the ISR code:
164  * - Callback invocation.
165  * - Waiting thread wakeup, if any.
166  * - Driver state transitions.
167  * .
168  * @note This macro is meant to be used in the low level drivers
169  * implementation only.
170  *
171  * @param[in] adcp pointer to the @p ADCDriver object
172  *
173  * @notapi
174  */
175 #define _adc_isr_full_code(adcp) { \
176  if ((adcp)->grpp->circular) { \
177  /* Callback handling.*/ \
178  if ((adcp)->grpp->end_cb != NULL) { \
179  if ((adcp)->depth > 1) { \
180  /* Invokes the callback passing the 2nd half of the buffer.*/ \
181  size_t half = (adcp)->depth / 2; \
182  size_t half_index = half * (adcp)->grpp->num_channels; \
183  (adcp)->grpp->end_cb(adcp, (adcp)->samples + half_index, half); \
184  } \
185  else { \
186  /* Invokes the callback passing the whole buffer.*/ \
187  (adcp)->grpp->end_cb(adcp, (adcp)->samples, (adcp)->depth); \
188  } \
189  } \
190  } \
191  else { \
192  /* End conversion.*/ \
193  adc_lld_stop_conversion(adcp); \
194  if ((adcp)->grpp->end_cb != NULL) { \
195  (adcp)->state = ADC_COMPLETE; \
196  /* Invoke the callback passing the whole buffer.*/ \
197  (adcp)->grpp->end_cb(adcp, (adcp)->samples, (adcp)->depth); \
198  if ((adcp)->state == ADC_COMPLETE) { \
199  (adcp)->state = ADC_READY; \
200  (adcp)->grpp = NULL; \
201  } \
202  } \
203  else { \
204  (adcp)->state = ADC_READY; \
205  (adcp)->grpp = NULL; \
206  } \
207  _adc_wakeup_isr(adcp); \
208  } \
209 }
210 
211 /**
212  * @brief Common ISR code, error event.
213  * @details This code handles the portable part of the ISR code:
214  * - Callback invocation.
215  * - Waiting thread timeout signaling, if any.
216  * - Driver state transitions.
217  * .
218  * @note This macro is meant to be used in the low level drivers
219  * implementation only.
220  *
221  * @param[in] adcp pointer to the @p ADCDriver object
222  * @param[in] err platform dependent error code
223  *
224  * @notapi
225  */
226 #define _adc_isr_error_code(adcp, err) { \
227  adc_lld_stop_conversion(adcp); \
228  if ((adcp)->grpp->error_cb != NULL) { \
229  (adcp)->state = ADC_ERROR; \
230  (adcp)->grpp->error_cb(adcp, err); \
231  if ((adcp)->state == ADC_ERROR) \
232  (adcp)->state = ADC_READY; \
233  (adcp)->grpp = NULL; \
234  } \
235  else { \
236  (adcp)->state = ADC_READY; \
237  (adcp)->grpp = NULL; \
238  } \
239  _adc_timeout_isr(adcp); \
240 }
241 /** @} */
242 
243 /*===========================================================================*/
244 /* External declarations. */
245 /*===========================================================================*/
246 
247 #ifdef __cplusplus
248 extern "C" {
249 #endif
250  void adcInit(void);
251  void adcObjectInit(ADCDriver *adcp);
252  void adcStart(ADCDriver *adcp, const ADCConfig *config);
253  void adcStop(ADCDriver *adcp);
254  void adcStartConversion(ADCDriver *adcp,
255  const ADCConversionGroup *grpp,
256  adcsample_t *samples,
257  size_t depth);
258  void adcStartConversionI(ADCDriver *adcp,
259  const ADCConversionGroup *grpp,
260  adcsample_t *samples,
261  size_t depth);
262  void adcStopConversion(ADCDriver *adcp);
263  void adcStopConversionI(ADCDriver *adcp);
264 #if ADC_USE_WAIT == TRUE
265  msg_t adcConvert(ADCDriver *adcp,
266  const ADCConversionGroup *grpp,
267  adcsample_t *samples,
268  size_t depth);
269 #endif
270 #if ADC_USE_MUTUAL_EXCLUSION == TRUE
271  void adcAcquireBus(ADCDriver *adcp);
272  void adcReleaseBus(ADCDriver *adcp);
273 #endif
274 #ifdef __cplusplus
275 }
276 #endif
277 
278 #endif /* HAL_USE_ADC == TRUE */
279 
280 #endif /* HAL_ADC_H */
281 
282 /** @} */
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
void adcAcquireBus(ADCDriver *adcp)
Gains exclusive access to the ADC peripheral.
Definition: hal_adc.c:299
PLATFORM ADC subsystem low level driver header.
void adcReleaseBus(ADCDriver *adcp)
Releases exclusive access to the ADC peripheral.
Definition: hal_adc.c:315
Conversion group configuration structure.
Definition: hal_adc_lld.h:113
int32_t msg_t
Type of a message.
Definition: osal.h:160
void adcStart(ADCDriver *adcp, const ADCConfig *config)
Configures and activates the ADC peripheral.
Definition: hal_adc.c:95
Structure representing an ADC driver.
Definition: hal_adc_lld.h:144
msg_t adcConvert(ADCDriver *adcp, const ADCConversionGroup *grpp, adcsample_t *samples, size_t depth)
Performs an ADC conversion.
Definition: hal_adc.c:272
void adcStopConversion(ADCDriver *adcp)
Stops an ongoing conversion.
Definition: hal_adc.c:205
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:231
Driver configuration structure.
Definition: hal_adc_lld.h:137
void adcInit(void)
ADC Driver initialization.
Definition: hal_adc.c:56