1 /***************************************************************************//**
2 * @file
3 * @brief Digital to Analog Converter (VDAC) peripheral API
4 *******************************************************************************
5 * # License
6 * <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
7 *******************************************************************************
8 *
9 * SPDX-License-Identifier: Zlib
10 *
11 * The licensor of this software is Silicon Laboratories Inc.
12 *
13 * This software is provided 'as-is', without any express or implied
14 * warranty. In no event will the authors be held liable for any damages
15 * arising from the use of this software.
16 *
17 * Permission is granted to anyone to use this software for any purpose,
18 * including commercial applications, and to alter it and redistribute it
19 * freely, subject to the following restrictions:
20 *
21 * 1. The origin of this software must not be misrepresented; you must not
22 * claim that you wrote the original software. If you use this software
23 * in a product, an acknowledgment in the product documentation would be
24 * appreciated but is not required.
25 * 2. Altered source versions must be plainly marked as such, and must not be
26 * misrepresented as being the original software.
27 * 3. This notice may not be removed or altered from any source distribution.
28 *
29 ******************************************************************************/
30
31 #ifndef EM_VDAC_H
32 #define EM_VDAC_H
33
34 #include "em_device.h"
35
36 #if defined(VDAC_COUNT) && (VDAC_COUNT > 0)
37
38 #include "em_assert.h"
39 #include <stdbool.h>
40
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44
45 /***************************************************************************//**
46 * @addtogroup vdac VDAC - Voltage DAC
47 * @brief Digital to Analog Voltage Converter (VDAC) Peripheral API
48 *
49 * @details
50 * This module contains functions to control the VDAC peripheral of Silicon
51 * Labs' 32-bit MCUs and SoCs. VDAC converts digital values to analog
52 * signals at up to 500 ksps with 12-bit accuracy. VDAC is designed for
53 * low energy consumption, but can also provide very good performance.
54 *
55 * The following steps are necessary for basic operation:
56 *
57 * Clock enable:
58 * @code
59 CMU_ClockEnable(cmuClock_VDAC0, true);@endcode
60 *
61 * Initialize the VDAC with default settings and modify selected fields:
62 * @code
63 VDAC_Init_TypeDef vdacInit = VDAC_INIT_DEFAULT;
64 VDAC_InitChannel_TypeDef vdacChInit = VDAC_INITCHANNEL_DEFAULT;
65
66 // Set prescaler to get 1 MHz VDAC clock frequency.
67 vdacInit.prescaler = VDAC_PrescaleCalc(1000000, true, 0);
68 VDAC_Init(VDAC0, &vdacInit);
69
70 vdacChInit.enable = true;
71 VDAC_InitChannel(VDAC0, &vdacChInit, 0);@endcode
72 *
73 * Perform a conversion:
74 * @code
75 VDAC_ChannelOutputSet(VDAC0, 0, 250);@endcode
76 *
77 * @note The output stage of a VDAC channel consists of an on-chip operational
78 * amplifier (OPAMP) in the OPAMP module. This OPAMP is highly configurable;
79 * and to exploit the VDAC functionality fully, configure the OPAMP using
80 * the OPAMP API. Using the OPAMP API also loads OPAMP calibration values.
81 * The default (reset) settings of OPAMP is sufficient for many applications.
82 * @{
83 ******************************************************************************/
84
85 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
86
87 /** Validation of VDAC register block pointer reference for assert statements.*/
88
89 #define VDAC_REF_VALID(ref) ((ref) == VDAC0)
90
91 /** @endcond */
92
93 /*******************************************************************************
94 ******************************** ENUMS ************************************
95 ******************************************************************************/
96
97 #if !defined(_SILICON_LABS_32B_SERIES_2)
98 /** Channel refresh period. */
99 typedef enum {
100 vdacRefresh8 = _VDAC_CTRL_REFRESHPERIOD_8CYCLES, /**< Refresh every 8 clock cycles. */
101 vdacRefresh16 = _VDAC_CTRL_REFRESHPERIOD_16CYCLES, /**< Refresh every 16 clock cycles. */
102 vdacRefresh32 = _VDAC_CTRL_REFRESHPERIOD_32CYCLES, /**< Refresh every 32 clock cycles. */
103 vdacRefresh64 = _VDAC_CTRL_REFRESHPERIOD_64CYCLES, /**< Refresh every 64 clock cycles. */
104 } VDAC_Refresh_TypeDef;
105
106 /** Reference voltage for VDAC. */
107 typedef enum {
108 vdacRef1V25Ln = _VDAC_CTRL_REFSEL_1V25LN, /**< Internal low noise 1.25 V band gap reference. */
109 vdacRef2V5Ln = _VDAC_CTRL_REFSEL_2V5LN, /**< Internal low noise 2.5 V band gap reference. */
110 vdacRef1V25 = _VDAC_CTRL_REFSEL_1V25, /**< Internal 1.25 V band gap reference. */
111 vdacRef2V5 = _VDAC_CTRL_REFSEL_2V5, /**< Internal 2.5 V band gap reference. */
112 vdacRefAvdd = _VDAC_CTRL_REFSEL_VDD, /**< AVDD reference. */
113 vdacRefExtPin = _VDAC_CTRL_REFSEL_EXT, /**< External pin reference. */
114 } VDAC_Ref_TypeDef;
115
116 /** Peripheral Reflex System signal used to trigger VDAC channel conversion. */
117 typedef enum {
118 vdacPrsSelCh0 = _VDAC_CH0CTRL_PRSSEL_PRSCH0, /**< PRS ch 0 triggers conversion. */
119 vdacPrsSelCh1 = _VDAC_CH0CTRL_PRSSEL_PRSCH1, /**< PRS ch 1 triggers conversion. */
120 vdacPrsSelCh2 = _VDAC_CH0CTRL_PRSSEL_PRSCH2, /**< PRS ch 2 triggers conversion. */
121 vdacPrsSelCh3 = _VDAC_CH0CTRL_PRSSEL_PRSCH3, /**< PRS ch 3 triggers conversion. */
122 vdacPrsSelCh4 = _VDAC_CH0CTRL_PRSSEL_PRSCH4, /**< PRS ch 4 triggers conversion. */
123 vdacPrsSelCh5 = _VDAC_CH0CTRL_PRSSEL_PRSCH5, /**< PRS ch 5 triggers conversion. */
124 vdacPrsSelCh6 = _VDAC_CH0CTRL_PRSSEL_PRSCH6, /**< PRS ch 6 triggers conversion. */
125 vdacPrsSelCh7 = _VDAC_CH0CTRL_PRSSEL_PRSCH7, /**< PRS ch 7 triggers conversion. */
126 #if defined(_VDAC_CH0CTRL_PRSSEL_PRSCH8)
127 vdacPrsSelCh8 = _VDAC_CH0CTRL_PRSSEL_PRSCH8, /**< PRS ch 8 triggers conversion. */
128 #endif
129 #if defined(_VDAC_CH0CTRL_PRSSEL_PRSCH9)
130 vdacPrsSelCh9 = _VDAC_CH0CTRL_PRSSEL_PRSCH9, /**< PRS ch 9 triggers conversion. */
131 #endif
132 #if defined(_VDAC_CH0CTRL_PRSSEL_PRSCH10)
133 vdacPrsSelCh10 = _VDAC_CH0CTRL_PRSSEL_PRSCH10, /**< PRS ch 10 triggers conversion. */
134 #endif
135 #if defined(_VDAC_CH0CTRL_PRSSEL_PRSCH11)
136 vdacPrsSelCh11 = _VDAC_CH0CTRL_PRSSEL_PRSCH11, /**< PRS ch 11 triggers conversion. */
137 #endif
138 } VDAC_PrsSel_TypeDef;
139
140 /** Channel conversion trigger mode. */
141 typedef enum {
142 vdacTrigModeSw = _VDAC_CH0CTRL_TRIGMODE_SW, /**< Channel is triggered by CHnDATA or COMBDATA write. */
143 vdacTrigModePrs = _VDAC_CH0CTRL_TRIGMODE_PRS, /**< Channel is triggered by PRS input. */
144 vdacTrigModeRefresh = _VDAC_CH0CTRL_TRIGMODE_REFRESH, /**< Channel is triggered by Refresh timer. */
145 vdacTrigModeSwPrs = _VDAC_CH0CTRL_TRIGMODE_SWPRS, /**< Channel is triggered by CHnDATA/COMBDATA write or PRS input. */
146 vdacTrigModeSwRefresh = _VDAC_CH0CTRL_TRIGMODE_SWREFRESH, /**< Channel is triggered by CHnDATA/COMBDATA write or Refresh timer. */
147 vdacTrigModeLesense = _VDAC_CH0CTRL_TRIGMODE_LESENSE, /**< Channel is triggered by LESENSE. */
148 } VDAC_TrigMode_TypeDef;
149
150 /*******************************************************************************
151 ******************************* STRUCTS ***********************************
152 ******************************************************************************/
153
154 /** VDAC initialization structure, common for both channels. */
155 typedef struct {
156 /** Selects between main and alternate output path calibration values. */
157 bool mainCalibration;
158
159 /** Selects clock from asynchronous or synchronous (with respect to
160 peripheral clock) source. */
161 bool asyncClockMode;
162
163 /** Warm-up mode, keep VDAC on (in idle) - or shutdown between conversions.*/
164 bool warmupKeepOn;
165
166 /** Channel refresh period. */
167 VDAC_Refresh_TypeDef refresh;
168
169 /** Prescaler for VDAC clock. Clock is source clock divided by prescaler+1. */
170 uint32_t prescaler;
171
172 /** Reference voltage to use. */
173 VDAC_Ref_TypeDef reference;
174
175 /** Enable/disable reset of prescaler on CH 0 start. */
176 bool ch0ResetPre;
177
178 /** Enable/disable output enable control by CH1 PRS signal. */
179 bool outEnablePRS;
180
181 /** Enable/disable sine mode. */
182 bool sineEnable;
183
184 /** Select if single ended or differential output mode. */
185 bool diff;
186 } VDAC_Init_TypeDef;
187
188 /** Default configuration for VDAC initialization structure. */
189 #define VDAC_INIT_DEFAULT \
190 { \
191 true, /* Use main output path calibration values. */ \
192 false, /* Use synchronous clock mode. */ \
193 false, /* Turn off between sample off conversions.*/ \
194 vdacRefresh8, /* Refresh every 8th cycle. */ \
195 0, /* No prescaling. */ \
196 vdacRef1V25Ln, /* 1.25 V internal low noise reference. */ \
197 false, /* Do not reset prescaler on CH 0 start. */ \
198 false, /* VDAC output enable always on. */ \
199 false, /* Disable sine mode. */ \
200 false /* Single ended mode. */ \
201 }
202
203 /** VDAC channel initialization structure. */
204 typedef struct {
205 /** Enable channel. */
206 bool enable;
207
208 /**
209 * Peripheral reflex system trigger selection. Only applicable if @p trigMode
210 * is set to @p vdacTrigModePrs or @p vdacTrigModeSwPrs. */
211 VDAC_PrsSel_TypeDef prsSel;
212
213 /** Treat the PRS signal asynchronously. */
214 bool prsAsync;
215
216 /** Channel conversion trigger mode. */
217 VDAC_TrigMode_TypeDef trigMode;
218
219 /** Set channel conversion mode to sample/shut-off mode. Default is
220 * continuous.*/
221 bool sampleOffMode;
222 } VDAC_InitChannel_TypeDef;
223
224 /** Default configuration for VDAC channel initialization structure. */
225 #define VDAC_INITCHANNEL_DEFAULT \
226 { \
227 false, /* Leave channel disabled when initialization is done. */ \
228 vdacPrsSelCh0, /* PRS CH 0 triggers conversion. */ \
229 false, /* Treat PRS channel as a synchronous signal. */ \
230 vdacTrigModeSw, /* Conversion trigged by CH0DATA or COMBDATA write. */ \
231 false, /* Channel conversion set to continuous. */ \
232 }
233 #else // defined(_SILICON_LABS_32B_SERIES_2)
234
235 /** Channel refresh period. */
236 typedef enum {
237 vdacRefresh2 = _VDAC_CFG_REFRESHPERIOD_CYCLES2, /**< Refresh every 2 clock cycles. */
238 vdacRefresh4 = _VDAC_CFG_REFRESHPERIOD_CYCLES4, /**< Refresh every 4 clock cycles. */
239 vdacRefresh8 = _VDAC_CFG_REFRESHPERIOD_CYCLES8, /**< Refresh every 8 clock cycles. */
240 vdacRefresh16 = _VDAC_CFG_REFRESHPERIOD_CYCLES16, /**< Refresh every 16 clock cycles. */
241 vdacRefresh32 = _VDAC_CFG_REFRESHPERIOD_CYCLES32, /**< Refresh every 32 clock cycles. */
242 vdacRefresh64 = _VDAC_CFG_REFRESHPERIOD_CYCLES64, /**< Refresh every 64 clock cycles. */
243 vdacRefresh128 = _VDAC_CFG_REFRESHPERIOD_CYCLES128, /**< Refresh every 128 clock cycles. */
244 vdacRefresh256 = _VDAC_CFG_REFRESHPERIOD_CYCLES256, /**< Refresh every 256 clock cycles. */
245 } VDAC_Refresh_TypeDef;
246
247 /** Timer overflow period. */
248 typedef enum {
249 vdacCycles2 = _VDAC_CFG_TIMEROVRFLOWPERIOD_CYCLES2, /**< Overflows every 2 clock cycles. */
250 vdacCycles4 = _VDAC_CFG_TIMEROVRFLOWPERIOD_CYCLES4, /**< Overflows every 4 clock cycles. */
251 vdacCycles8 = _VDAC_CFG_TIMEROVRFLOWPERIOD_CYCLES8, /**< Overflows every 8 clock cycles. */
252 vdacCycles16 = _VDAC_CFG_TIMEROVRFLOWPERIOD_CYCLES16, /**< Overflows every 16 clock cycles. */
253 vdacCycles32 = _VDAC_CFG_TIMEROVRFLOWPERIOD_CYCLES32, /**< Overflows every 32 clock cycles. */
254 vdacCycles64 = _VDAC_CFG_TIMEROVRFLOWPERIOD_CYCLES64 /**< Overflows every 64 clock cycles. */
255 } VDAC_TimerOverflow_TypeDef;
256
257 /** Reference voltage for VDAC. */
258 typedef enum {
259 vdacRef1V25 = _VDAC_CFG_REFRSEL_V125, /**< Internal 1.25 V band gap reference. */
260 vdacRef2V5 = _VDAC_CFG_REFRSEL_V25, /**< Internal 2.5 V band gap reference. */
261 vdacRefAvdd = _VDAC_CFG_REFRSEL_VDD, /**< AVDD reference. */
262 vdacRefExtPin = _VDAC_CFG_REFRSEL_EXT, /**< External pin reference. */
263 } VDAC_Ref_TypeDef;
264
265 typedef enum {
266 vdacRefreshSrcNone = _VDAC_CH0CFG_REFRESHSOURCE_NONE, /**< No refresh source. */
267 vdacRefreshSrcRefreshTimer = _VDAC_CH0CFG_REFRESHSOURCE_REFRESHTIMER,/**< Refresh triggered by refresh timer overflow. */
268 vdacRefreshSrcSyncPrs = _VDAC_CH0CFG_REFRESHSOURCE_SYNCPRS, /**< Refresh triggered by sync PRS. */
269 vdacRefreshSrcAsyncPrs = _VDAC_CH0CFG_REFRESHSOURCE_ASYNCPRS, /**< Refresh triggered by async PRS. */
270 } VDAC_RefreshSource_TypeDef;
271
272 /** Channel conversion trigger mode. */
273 typedef enum {
274 vdacTrigModeNone = _VDAC_CH0CFG_TRIGMODE_NONE, /**< No conversion trigger source selected. */
275 vdacTrigModeSw = _VDAC_CH0CFG_TRIGMODE_SW, /**< Channel is triggered by CHnDATA or COMBDATA write. */
276 vdacTrigModeSyncPrs = _VDAC_CH0CFG_TRIGMODE_SYNCPRS, /**< Channel is triggered by Sync PRS input. */
277 vdacTrigModeLesense = _VDAC_CH0CFG_TRIGMODE_LESENSE, /**< Channel is triggered by LESENSE. */
278 vdacTrigModeInternalTimer = _VDAC_CH0CFG_TRIGMODE_INTERNALTIMER, /**< Channel is triggered by Internal Timer. */
279 vdacTrigModeAsyncPrs = _VDAC_CH0CFG_TRIGMODE_ASYNCPRS /**< Channel is triggered by Async PRS input. */
280 } VDAC_TrigMode_TypeDef;
281
282 /** Channel power mode. */
283 typedef enum {
284 vdacPowerModeHighPower = _VDAC_CH0CFG_POWERMODE_HIGHPOWER, /**< High power buffer mode. */
285 vdacPowerModeLowPower = _VDAC_CH0CFG_POWERMODE_LOWPOWER /**< Low power buffer mode. */
286 } VDAC_PowerMode_TypeDef;
287
288 /** VDAC channel Abus port selection. */
289 typedef enum {
290 /** NoneSelected */
291 vdacChPortNone = _VDAC_OUTCTRL_ABUSPORTSELCH0_NONE,
292 vdacChPortA = _VDAC_OUTCTRL_ABUSPORTSELCH0_PORTA,
293 vdacChPortB = _VDAC_OUTCTRL_ABUSPORTSELCH0_PORTB,
294 vdacChPortC = _VDAC_OUTCTRL_ABUSPORTSELCH0_PORTC,
295 vdacChPortD = _VDAC_OUTCTRL_ABUSPORTSELCH0_PORTD,
296 } VDAC_ChPortSel_t;
297
298 /*******************************************************************************
299 ******************************* STRUCTS ***********************************
300 ******************************************************************************/
301
302 /** VDAC initialization structure, common for both channels. */
303 typedef struct {
304 /** Number of prescaled CLK_DAC + 1 for the vdac to warmup. */
305 uint32_t warmupTime;
306
307 /** Halt during debug. */
308 bool dbgHalt;
309
310 /** Always allow clk_dac. */
311 bool onDemandClk;
312
313 /** DMA Wakeup. */
314 bool dmaWakeUp;
315
316 /** Bias keep warm enable. */
317 bool biasKeepWarm;
318
319 /** Channel refresh period. */
320 VDAC_Refresh_TypeDef refresh;
321
322 /** Internal timer overflow period. */
323 VDAC_TimerOverflow_TypeDef timerOverflow;
324
325 /** Prescaler for VDAC clock. Clock is source clock divided by prescaler+1. */
326 uint32_t prescaler;
327
328 /** Reference voltage to use. */
329 VDAC_Ref_TypeDef reference;
330
331 /** Enable/disable reset of prescaler on CH 0 start. */
332 bool ch0ResetPre;
333
334 /** Sine reset mode. */
335 bool sineReset;
336
337 /** Enable/disable sine mode. */
338 bool sineEnable;
339
340 /** Select if single ended or differential output mode. */
341 bool diff;
342 } VDAC_Init_TypeDef;
343
344 /** Default configuration for VDAC initialization structure. */
345 #define VDAC_INIT_DEFAULT \
346 { \
347 _VDAC_CFG_WARMUPTIME_DEFAULT, /* Number of prescaled DAC_CLK for Vdac to warmup. */ \
348 false, /* Continue while debugging. */ \
349 true, /* On demand clock. */ \
350 false, /* DMA wake up. */ \
351 false, /* Bias keep warm. */ \
352 vdacRefresh8, /* Refresh every 8th cycle. */ \
353 vdacCycles2, /* Internal overflow every 8th cycle. */ \
354 0, /* No prescaling. */ \
355 vdacRef1V25, /* 1.25 V internal low noise reference. */ \
356 false, /* Do not reset prescaler on CH 0 start. */ \
357 false, /* Sine wave is stopped at the sample its currently outputting. */ \
358 false, /* Disable sine mode. */ \
359 false /* Differential mode. */ \
360 }
361
362 /** VDAC channel initialization structure. */
363 typedef struct {
364 /** Enable channel. */
365 bool enable;
366
367 /** Warm-up mode, keep VDAC on (in idle) - or shutdown between conversions.*/
368 bool warmupKeepOn;
369
370 /** Select high capacitance load mode in conjunction with high power. */
371 bool highCapLoadEnable;
372
373 /** Channel x FIFO Low threshold data valid level. */
374 uint32_t fifoLowDataThreshold;
375
376 /** Channel refresh source. */
377 VDAC_RefreshSource_TypeDef chRefreshSource;
378
379 /** Channel conversion trigger mode. */
380 VDAC_TrigMode_TypeDef trigMode;
381
382 /** Channel power mode. */
383 VDAC_PowerMode_TypeDef powerMode;
384
385 /** Set channel conversion mode to sample/shut-off mode. Default is
386 * continuous.*/
387 bool sampleOffMode;
388
389 /** Vdac channel output pin. */
390 uint32_t pin;
391
392 /** Vdac channel output port. */
393 VDAC_ChPortSel_t port;
394
395 /** Short High power and low power output. */
396 bool shortOutput;
397
398 /** Alternative output enable. */
399 bool auxOutEnable;
400
401 /** Main output enable. */
402 bool mainOutEnable;
403
404 /** Channel output hold time. */
405 uint32_t holdOutTime;
406 } VDAC_InitChannel_TypeDef;
407
408 /** Default configuration for VDAC channel initialization structure. */
409 #define VDAC_INITCHANNEL_DEFAULT \
410 { \
411 false, /* Leave channel disabled when initialization is done. */ \
412 false, /* Turn off between sample off conversions.*/ \
413 true, /* Enable High cap mode. */ \
414 0, /* Fifo data low watermark at 0. */ \
415 vdacRefreshSrcNone, /* Channel refresh source. */ \
416 vdacTrigModeSw, /* Conversion trigged by CH0DATA or COMBDATA write. */ \
417 vdacPowerModeHighPower, /* High power mode enabled. */ \
418 false, /* Continuous conversion mode. */ \
419 0, /* ABUS pin selected. */ \
420 vdacChPortNone, /* No Analog bus port selected. */ \
421 false, /* Output not shorted */ \
422 false, /* Alternative output disabled. */ \
423 true, /* Main output enabled. */ \
424 0 /* Hold out time. Previously called settle time */ \
425 }
426
427 #endif
428 /*******************************************************************************
429 ***************************** PROTOTYPES **********************************
430 ******************************************************************************/
431
432 void VDAC_ChannelOutputSet(VDAC_TypeDef *vdac,
433 unsigned int channel,
434 uint32_t value);
435 void VDAC_Enable(VDAC_TypeDef *vdac, unsigned int ch, bool enable);
436 void VDAC_Init(VDAC_TypeDef *vdac, const VDAC_Init_TypeDef *init);
437 void VDAC_InitChannel(VDAC_TypeDef *vdac,
438 const VDAC_InitChannel_TypeDef *init,
439 unsigned int ch);
440
441 #if defined(_SILICON_LABS_32B_SERIES_2)
442 /***************************************************************************//**
443 * @brief
444 * Sinemode start/stop
445 *
446 * @details
447 * This function send the sine mode start/stop signal to the DAC.
448 *
449 * @param[in] vdac
450 * Pointer to VDAC peripheral register block.
451 *
452 * @param[in] start
453 * True to start the Sine mode, false to stop it.
454 ******************************************************************************/
VDAC_SineModeStart(VDAC_TypeDef * vdac,bool start)455 __STATIC_INLINE void VDAC_SineModeStart(VDAC_TypeDef *vdac, bool start)
456 {
457 EFM_ASSERT(VDAC_REF_VALID(vdac));
458
459 while (vdac->STATUS & VDAC_STATUS_SYNCBUSY) ;
460
461 if (start) {
462 vdac->CMD = VDAC_CMD_SINEMODESTART;
463 while ((vdac->STATUS & VDAC_STATUS_SINEACTIVE) == 0) ;
464 } else {
465 vdac->CMD = VDAC_CMD_SINEMODESTOP;
466 while ((vdac->STATUS & VDAC_STATUS_SINEACTIVE) != 0) ;
467 }
468 }
469 #endif
470
471 /***************************************************************************//**
472 * @brief
473 * Set the output signal of VDAC channel 0 to a given value.
474 *
475 * @details
476 * This function sets the output signal of VDAC channel 0 by writing @p value
477 * to the CH0DATA register.
478 *
479 * @param[in] vdac
480 * Pointer to VDAC peripheral register block.
481 *
482 * @param[in] value
483 * Value to write to channel 0 output register CH0DATA.
484 ******************************************************************************/
VDAC_Channel0OutputSet(VDAC_TypeDef * vdac,uint32_t value)485 __STATIC_INLINE void VDAC_Channel0OutputSet(VDAC_TypeDef *vdac,
486 uint32_t value)
487 {
488 #if defined(_SILICON_LABS_32B_SERIES_0) || defined(_SILICON_LABS_32B_SERIES_1)
489 EFM_ASSERT(value <= _VDAC_CH0DATA_MASK);
490 vdac->CH0DATA = value;
491 #elif defined(_SILICON_LABS_32B_SERIES_2)
492 EFM_ASSERT(value <= _VDAC_CH0F_MASK);
493 vdac->CH0F = value;
494 #endif
495 }
496
497 /***************************************************************************//**
498 * @brief
499 * Set the output signal of VDAC channel 1 to a given value.
500 *
501 * @details
502 * This function sets the output signal of VDAC channel 1 by writing @p value
503 * to the CH1DATA register.
504 *
505 * @param[in] vdac
506 * Pointer to VDAC peripheral register block.
507 *
508 * @param[in] value
509 * Value to write to channel 1 output register CH1DATA.
510 ******************************************************************************/
VDAC_Channel1OutputSet(VDAC_TypeDef * vdac,uint32_t value)511 __STATIC_INLINE void VDAC_Channel1OutputSet(VDAC_TypeDef *vdac,
512 uint32_t value)
513 {
514 #if defined(_SILICON_LABS_32B_SERIES_0) || defined(_SILICON_LABS_32B_SERIES_1)
515 EFM_ASSERT(value <= _VDAC_CH1DATA_MASK);
516 vdac->CH1DATA = value;
517 #elif defined(_SILICON_LABS_32B_SERIES_2)
518 EFM_ASSERT(value <= _VDAC_CH1F_MASK);
519 vdac->CH1F = value;
520 #endif
521 }
522
523 /***************************************************************************//**
524 * @brief
525 * Clear one or more pending VDAC interrupts.
526 *
527 * @param[in] vdac
528 * Pointer to VDAC peripheral register block.
529 *
530 * @param[in] flags
531 * Pending VDAC interrupt source to clear. Use a bitwise logic OR combination
532 * of valid interrupt flags for the VDAC module (VDAC_IF_nnn).
533 ******************************************************************************/
VDAC_IntClear(VDAC_TypeDef * vdac,uint32_t flags)534 __STATIC_INLINE void VDAC_IntClear(VDAC_TypeDef *vdac, uint32_t flags)
535 {
536 #if defined(VDAC_HAS_SET_CLEAR)
537 vdac->IF_CLR = flags;
538 #else
539 vdac->IFC = flags;
540 #endif
541 }
542
543 /***************************************************************************//**
544 * @brief
545 * Disable one or more VDAC interrupts.
546 *
547 * @param[in] vdac
548 * Pointer to VDAC peripheral register block.
549 *
550 * @param[in] flags
551 * VDAC interrupt sources to disable. Use a bitwise logic OR combination of
552 * valid interrupt flags for the VDAC module (VDAC_IF_nnn).
553 ******************************************************************************/
VDAC_IntDisable(VDAC_TypeDef * vdac,uint32_t flags)554 __STATIC_INLINE void VDAC_IntDisable(VDAC_TypeDef *vdac, uint32_t flags)
555 {
556 #if defined(VDAC_HAS_SET_CLEAR)
557 vdac->IEN_CLR = flags;
558 #else
559 vdac->IEN &= ~flags;
560 #endif
561 }
562
563 /***************************************************************************//**
564 * @brief
565 * Enable one or more VDAC interrupts.
566 *
567 * @note
568 * Depending on the use, a pending interrupt may already be set prior to
569 * enabling the interrupt. To ignore a pending interrupt, consider using
570 * VDAC_IntClear() prior to enabling the interrupt.
571 *
572 * @param[in] vdac
573 * Pointer to VDAC peripheral register block.
574 *
575 * @param[in] flags
576 * VDAC interrupt sources to enable. Use a bitwise logic OR combination
577 * of valid interrupt flags for the VDAC module (VDAC_IF_nnn).
578 ******************************************************************************/
VDAC_IntEnable(VDAC_TypeDef * vdac,uint32_t flags)579 __STATIC_INLINE void VDAC_IntEnable(VDAC_TypeDef *vdac, uint32_t flags)
580 {
581 #if defined(VDAC_HAS_SET_CLEAR)
582 vdac->IEN_SET = flags;
583 #else
584 vdac->IEN |= flags;
585 #endif
586 }
587
588 /***************************************************************************//**
589 * @brief
590 * Get pending VDAC interrupt flags.
591 *
592 * @note
593 * The event bits are not cleared by the use of this function.
594 *
595 * @param[in] vdac
596 * Pointer to VDAC peripheral register block.
597 *
598 * @return
599 * VDAC interrupt sources pending. Use a bitwise logic OR combination
600 * of valid interrupt flags for the VDAC module (VDAC_IF_nnn).
601 ******************************************************************************/
VDAC_IntGet(VDAC_TypeDef * vdac)602 __STATIC_INLINE uint32_t VDAC_IntGet(VDAC_TypeDef *vdac)
603 {
604 return vdac->IF;
605 }
606
607 /***************************************************************************//**
608 * @brief
609 * Get enabled and pending VDAC interrupt flags.
610 * Useful for handling more interrupt sources in the same interrupt handler.
611 *
612 * @param[in] vdac
613 * Pointer to VDAC peripheral register block.
614 *
615 * @note
616 * Interrupt flags are not cleared by the use of this function.
617 *
618 * @return
619 * Pending and enabled VDAC interrupt sources.
620 * The return value is the bitwise AND combination of
621 * - the OR combination of enabled interrupt sources in VDACx_IEN_nnn
622 * register (VDACx_IEN_nnn) and
623 * - the OR combination of valid interrupt flags of the VDAC module
624 * (VDACx_IF_nnn).
625 ******************************************************************************/
VDAC_IntGetEnabled(VDAC_TypeDef * vdac)626 __STATIC_INLINE uint32_t VDAC_IntGetEnabled(VDAC_TypeDef *vdac)
627 {
628 uint32_t ien = vdac->IEN;
629
630 /* Bitwise AND of pending and enabled interrupts */
631 return vdac->IF & ien;
632 }
633
634 /***************************************************************************//**
635 * @brief
636 * Set one or more pending VDAC interrupts from SW.
637 *
638 * @param[in] vdac
639 * Pointer to VDAC peripheral register block.
640 *
641 * @param[in] flags
642 * VDAC interrupt sources to set to pending. Use a bitwise logic OR
643 * combination of valid interrupt flags for the VDAC module (VDAC_IF_nnn).
644 ******************************************************************************/
VDAC_IntSet(VDAC_TypeDef * vdac,uint32_t flags)645 __STATIC_INLINE void VDAC_IntSet(VDAC_TypeDef *vdac, uint32_t flags)
646 {
647 #if defined(VDAC_HAS_SET_CLEAR)
648 vdac->IF_SET = flags;
649 #else
650 vdac->IFS = flags;
651 #endif
652 }
653
654 #if defined(_SILICON_LABS_32B_SERIES_2)
655 /***************************************************************************//**
656 * @brief
657 * Get Vdac Status register.
658 *
659 * @return
660 * Current STATUS register value.
661 ******************************************************************************/
VDAC_GetStatus(VDAC_TypeDef * vdac)662 __STATIC_INLINE uint32_t VDAC_GetStatus(VDAC_TypeDef *vdac)
663 {
664 return vdac->STATUS;
665 }
666 #endif
667
668 #if defined(_SILICON_LABS_32B_SERIES_0) || defined(_SILICON_LABS_32B_SERIES_1)
669 uint32_t VDAC_PrescaleCalc(uint32_t vdacFreq, bool syncMode, uint32_t hfperFreq);
670 #else
671 uint32_t VDAC_PrescaleCalc(uint32_t vdacFreq);
672 #endif
673
674 void VDAC_Reset(VDAC_TypeDef *vdac);
675
676 /** @} (end addtogroup vdac) */
677
678 #ifdef __cplusplus
679 }
680 #endif
681
682 #endif /* defined(VDAC_COUNT) && (VDAC_COUNT > 0) */
683 #endif /* EM_VDAC_H */
684