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