ChibiOS/HAL  7.0.3
hal_dac.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_dac.h
19  * @brief DAC Driver macros and structures.
20  *
21  * @addtogroup DAC
22  * @{
23  */
24 
25 #ifndef HAL_DAC_H
26 #define HAL_DAC_H
27 
28 #if (HAL_USE_DAC == TRUE) || defined(__DOXYGEN__)
29 
30 /*===========================================================================*/
31 /* Driver constants. */
32 /*===========================================================================*/
33 
34 /*===========================================================================*/
35 /* Driver pre-compile time settings. */
36 /*===========================================================================*/
37 
38 /**
39  * @name DAC 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(DAC_USE_WAIT) || defined(__DOXYGEN__)
47 #define DAC_USE_WAIT TRUE
48 #endif
49 
50 /**
51  * @brief Enables the @p dacAcquireBus() and @p dacReleaseBus() APIs.
52  * @note Disabling this option saves both code and data space.
53  */
54 #if !defined(DAC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__)
55 #define DAC_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  DAC_UNINIT = 0, /**< Not initialized. */
72  DAC_STOP = 1, /**< Stopped. */
73  DAC_READY = 2, /**< Ready. */
74  DAC_ACTIVE = 3, /**< Exchanging data. */
75  DAC_COMPLETE = 4, /**< Asynchronous operation complete. */
76  DAC_ERROR = 5 /**< Error. */
77 } dacstate_t;
78 
79 /**
80  * @brief Type of a structure representing an DAC driver.
81  */
82 typedef struct hal_dac_driver DACDriver;
83 
84 /**
85  * @brief Type of a structure representing an DAC driver configuration.
86  */
87 typedef struct hal_dac_config DACConfig;
88 
89 /**
90  * @brief Type of a DAC conversion group.
91  */
93 
94 /* Including the low level driver header, it exports information required
95  for completing types.*/
96 #include "hal_dac_lld.h"
97 
98 /**
99  * @brief DAC notification callback type.
100  *
101  * @param[in] dacp pointer to the @p DACDriver object triggering the
102  */
103 typedef void (*daccallback_t)(DACDriver *dacp);
104 
105 /**
106  * @brief DAC error callback type.
107  *
108  * @param[in] dacp pointer to the @p DACDriver object triggering the
109  * callback
110  * @param[in] err DAC error code
111  */
112 typedef void (*dacerrorcallback_t)(DACDriver *dacp, dacerror_t err);
113 
114 /**
115  * @brief DAC Conversion group structure.
116  */
118  /**
119  * @brief Number of DAC channels.
120  */
121  uint32_t num_channels;
122  /**
123  * @brief Operation complete callback or @p NULL.
124  */
126  /**
127  * @brief Error handling callback or @p NULL.
128  */
130  /* End of the mandatory fields.*/
131  dac_lld_conversion_group_fields;
132 };
133 
134 /**
135  * @brief Driver configuration structure.
136  */
138  /* End of the mandatory fields.*/
140 };
141 
142 /**
143  * @brief Structure representing a DAC driver.
144  */
146  /**
147  * @brief Driver state.
148  */
150  /**
151  * @brief Conversion group.
152  */
154  /**
155  * @brief Samples buffer pointer.
156  */
158  /**
159  * @brief Samples buffer size.
160  */
161  size_t depth;
162  /**
163  * @brief Current configuration data.
164  */
166 #if (DAC_USE_WAIT == TRUE) || defined(__DOXYGEN__)
167  /**
168  * @brief Waiting thread.
169  */
171 #endif /* DAC_USE_WAIT */
172 #if (DAC_USE_MUTUAL_EXCLUSION == TRUE) || defined(__DOXYGEN__)
173  /**
174  * @brief Mutex protecting the bus.
175  */
177 #endif /* DAC_USE_MUTUAL_EXCLUSION */
178 #if defined(DAC_DRIVER_EXT_FIELDS)
179  DAC_DRIVER_EXT_FIELDS
180 #endif
181  /* End of the mandatory fields.*/
183 };
184 
185 /*===========================================================================*/
186 /* Driver macros. */
187 /*===========================================================================*/
188 
189 /**
190  * @name Low level driver helper macros
191  * @{
192  */
193 /**
194  * @brief Buffer state.
195  * @note This function is meant to be called from the DAC callback only.
196  *
197  * @param[in] dacp pointer to the @p DACDriver object
198  * @return The buffer state.
199  * @retval false if the driver filled/sent the first half of the
200  * buffer.
201  * @retval true if the driver filled/sent the second half of the
202  * buffer.
203  *
204  * @special
205  */
206 #define dacIsBufferComplete(dacp) ((bool)((dacp)->state == DAC_COMPLETE))
207 
208 #if (DAC_USE_WAIT == TRUE) || defined(__DOXYGEN__)
209 /**
210  * @brief Waits for operation completion.
211  * @details This function waits for the driver to complete the current
212  * operation.
213  * @pre An operation must be running while the function is invoked.
214  * @note No more than one thread can wait on a DAC driver using
215  * this function.
216  *
217  * @param[in] dacp pointer to the @p DACDriver object
218  *
219  * @notapi
220  */
221 #define _dac_wait_s(dacp) osalThreadSuspendS(&(dacp)->thread)
222 
223 /**
224  * @brief Resumes a thread waiting for a conversion completion.
225  *
226  * @param[in] dacp pointer to the @p DACDriver object
227  *
228  * @notapi
229  */
230 #define _dac_reset_i(dacp) osalThreadResumeI(&(dacp)->thread, MSG_RESET)
231 
232 /**
233  * @brief Resumes a thread waiting for a conversion completion.
234  *
235  * @param[in] dacp pointer to the @p DACDriver object
236  *
237  * @notapi
238  */
239 #define _dac_reset_s(dacp) osalThreadResumeS(&(dacp)->thread, MSG_RESET)
240 
241 /**
242  * @brief Wakes up the waiting thread.
243  *
244  * @param[in] dacp pointer to the @p DACDriver object
245  *
246  * @notapi
247  */
248 #define _dac_wakeup_isr(dacp) { \
249  osalSysLockFromISR(); \
250  osalThreadResumeI(&(dacp)->thread, MSG_OK); \
251  osalSysUnlockFromISR(); \
252 }
253 
254 /**
255  * @brief Wakes up the waiting thread with a timeout message.
256  *
257  * @param[in] dacp pointer to the @p DACDriver object
258  *
259  * @notapi
260  */
261 #define _dac_timeout_isr(dacp) { \
262  osalSysLockFromISR(); \
263  osalThreadResumeI(&(dacp)->thread, MSG_TIMEOUT); \
264  osalSysUnlockFromISR(); \
265 }
266 
267 #else /* !DAC_USE_WAIT */
268 #define _dac_wait_s(dacp)
269 #define _dac_reset_i(dacp)
270 #define _dac_reset_s(dacp)
271 #define _dac_wakeup_isr(dacp)
272 #define _dac_timeout_isr(dacp)
273 #endif /* !DAC_USE_WAIT */
274 
275 /**
276  * @brief Common ISR code, half buffer event.
277  * @details This code handles the portable part of the ISR code:
278  * - Callback invocation.
279  * .
280  * @note This macro is meant to be used in the low level drivers
281  * implementation only.
282  *
283  * @param[in] dacp pointer to the @p DACDriver object
284  *
285  * @notapi
286  */
287 #define _dac_isr_half_code(dacp) { \
288  if ((dacp)->grpp->end_cb != NULL) { \
289  (dacp)->grpp->end_cb(dacp); \
290  } \
291 }
292 
293 /**
294  * @brief Common ISR code, full buffer event.
295  * @details This code handles the portable part of the ISR code:
296  * - Callback invocation.
297  * - Driver state transitions.
298  * .
299  * @note This macro is meant to be used in the low level drivers
300  * implementation only.
301  *
302  * @param[in] dacp pointer to the @p DACDriver object
303  *
304  * @notapi
305  */
306 #define _dac_isr_full_code(dacp) { \
307  if ((dacp)->grpp->end_cb) { \
308  (dacp)->state = DAC_COMPLETE; \
309  (dacp)->grpp->end_cb(dacp); \
310  if ((dacp)->state == DAC_COMPLETE) \
311  (dacp)->state = DAC_ACTIVE; \
312  } \
313 }
314 
315 /**
316  * @brief Common ISR code, error event.
317  * @details This code handles the portable part of the ISR code:
318  * - Callback invocation.
319  * - Waiting thread timeout signaling, if any.
320  * - Driver state transitions.
321  * .
322  * @note This macro is meant to be used in the low level drivers
323  * implementation only.
324  *
325  * @param[in] dacp pointer to the @p DACDriver object
326  * @param[in] err platform dependent error code
327  *
328  * @notapi
329  */
330 #define _dac_isr_error_code(dacp, err) { \
331  dac_lld_stop_conversion(dacp); \
332  if ((dacp)->grpp->error_cb != NULL) { \
333  (dacp)->state = DAC_ERROR; \
334  (dacp)->grpp->error_cb(dacp, err); \
335  if ((dacp)->state == DAC_ERROR) \
336  (dacp)->state = DAC_READY; \
337  } \
338  (dacp)->grpp = NULL; \
339  _dac_timeout_isr(dacp); \
340 }
341 /** @} */
342 
343 /*===========================================================================*/
344 /* External declarations. */
345 /*===========================================================================*/
346 
347 #ifdef __cplusplus
348 extern "C" {
349 #endif
350  void dacInit(void);
351  void dacObjectInit(DACDriver *dacp);
352  void dacStart(DACDriver *dacp, const DACConfig *config);
353  void dacStop(DACDriver *dacp);
354  void dacPutChannelX(DACDriver *dacp,
355  dacchannel_t channel,
356  dacsample_t sample);
357  void dacStartConversion(DACDriver *dacp, const DACConversionGroup *grpp,
358  dacsample_t *samples, size_t depth);
359  void dacStartConversionI(DACDriver *dacp, const DACConversionGroup *grpp,
360  dacsample_t *samples, size_t depth);
361  void dacStopConversion(DACDriver *dacp);
362  void dacStopConversionI(DACDriver *dacp);
363 #if DAC_USE_WAIT
364  msg_t dacConvert(DACDriver *dacp, const DACConversionGroup *grpp,
365  dacsample_t *samples, size_t depth);
366 #endif
367 #if DAC_USE_MUTUAL_EXCLUSION
368  void dacAcquireBus(DACDriver *dacp);
369  void dacReleaseBus(DACDriver *dacp);
370 #endif
371 #ifdef __cplusplus
372 }
373 #endif
374 
375 #endif /* HAL_USE_DAC == TRUE */
376 
377 #endif /* HAL_DAC_H */
378 
379 /** @} */
void dacStartConversion(DACDriver *dacp, const DACConversionGroup *grpp, dacsample_t *samples, size_t depth)
Starts a DAC conversion.
Definition: hal_dac.c:167
size_t depth
Samples buffer size.
Definition: hal_dac.h:161
#define dac_lld_config_fields
Low level fields of the DAC configuration structure.
Definition: hal_dac_lld.h:99
dacstate_t state
Driver state.
Definition: hal_dac.h:149
msg_t dacConvert(DACDriver *dacp, const DACConversionGroup *grpp, dacsample_t *samples, size_t depth)
Performs a DAC conversion.
Definition: hal_dac.c:296
void dacInit(void)
DAC Driver initialization.
Definition: hal_dac.c:56
uint32_t dacchannel_t
Type of a DAC channel index.
Definition: hal_dac_lld.h:68
dacstate_t
Driver state machine possible states.
Definition: hal_dac.h:70
Driver configuration structure.
Definition: hal_dac.h:137
void dacObjectInit(DACDriver *dacp)
Initializes the standard part of a DACDriver structure.
Definition: hal_dac.c:68
void dacStartConversionI(DACDriver *dacp, const DACConversionGroup *grpp, dacsample_t *samples, size_t depth)
Starts a DAC conversion.
Definition: hal_dac.c:195
mutex_t mutex
Mutex protecting the bus.
Definition: hal_dac.h:176
DAC Conversion group structure.
Definition: hal_dac.h:117
dacerrorcallback_t error_cb
Error handling callback or NULL.
Definition: hal_dac.h:129
int32_t msg_t
Type of a message.
Definition: osal.h:160
Structure representing a DAC driver.
Definition: hal_dac.h:145
void dacAcquireBus(DACDriver *dacp)
Gains exclusive access to the DAC bus.
Definition: hal_dac.c:324
void dacReleaseBus(DACDriver *dacp)
Releases exclusive access to the DAC bus.
Definition: hal_dac.c:340
const DACConversionGroup * grpp
Conversion group.
Definition: hal_dac.h:153
void(* dacerrorcallback_t)(DACDriver *dacp, dacerror_t err)
DAC error callback type.
Definition: hal_dac.h:112
void * thread_reference_t
Type of a thread reference.
Definition: osal.h:180
uint32_t num_channels
Number of DAC channels.
Definition: hal_dac.h:121
void dacStop(DACDriver *dacp)
Deactivates the DAC peripheral.
Definition: hal_dac.c:118
daccallback_t end_cb
Operation complete callback or NULL.
Definition: hal_dac.h:125
const DACConfig * config
Current configuration data.
Definition: hal_dac.h:165
dacerror_t
Possible DAC failure causes.
Definition: hal_dac_lld.h:80
dacsample_t * samples
Samples buffer pointer.
Definition: hal_dac.h:157
void dacPutChannelX(DACDriver *dacp, dacchannel_t channel, dacsample_t sample)
Outputs a value directly on a DAC channel.
Definition: hal_dac.c:143
void dacStopConversion(DACDriver *dacp)
Stops an ongoing conversion.
Definition: hal_dac.c:225
uint32_t mutex_t
Type of a mutex.
Definition: osal.h:223
void dacStopConversionI(DACDriver *dacp)
Stops an ongoing conversion.
Definition: hal_dac.c:255
void(* daccallback_t)(DACDriver *dacp)
DAC notification callback type.
Definition: hal_dac.h:103
void dacStart(DACDriver *dacp, const DACConfig *config)
Configures and activates the DAC peripheral.
Definition: hal_dac.c:93
thread_reference_t thread
Waiting thread.
Definition: hal_dac.h:170
uint16_t dacsample_t
Type representing a DAC sample.
Definition: hal_dac_lld.h:73
#define dac_lld_driver_fields
Low level fields of the DAC driver structure.
Definition: hal_dac_lld.h:92
PLATFORM DAC subsystem low level driver header.