1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2020, 2022 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #ifndef FSL_DAC_H_
10 #define FSL_DAC_H_
11 
12 #include "fsl_common.h"
13 
14 /*!
15  * @addtogroup dac
16  * @{
17  */
18 
19 /*! @file */
20 
21 /*******************************************************************************
22  * Definitions
23  ******************************************************************************/
24 
25 /*! @name Driver version */
26 /*! @{ */
27 /*! @brief DAC driver version 2.1.2. */
28 #define FSL_DAC_DRIVER_VERSION (MAKE_VERSION(2, 1, 2))
29 /*! @} */
30 
31 /*!
32  * @brief DAC reset control.
33  */
34 enum
35 {
36     kDAC_ResetFIFO  = LPDAC_RCR_FIFORST_MASK, /*!< Resets the FIFO pointers and flags. */
37     kDAC_ResetLogic = LPDAC_RCR_SWRST_MASK,   /*!< Resets all DAC registers and internal logic. */
38 };
39 
40 /*!
41  * @brief DAC interrupts.
42  */
43 enum
44 {
45     kDAC_FIFOFullInterruptEnable      = LPDAC_IER_FULL_IE_MASK,  /*!< FIFO full interrupt enable. */
46     kDAC_FIFOEmptyInterruptEnable     = LPDAC_IER_EMPTY_IE_MASK, /*!< FIFO empty interrupt enable. */
47     kDAC_FIFOWatermarkInterruptEnable = LPDAC_IER_WM_IE_MASK,    /*!< FIFO watermark interrupt enable. */
48     kDAC_SwingBackInterruptEnable     = LPDAC_IER_SWBK_IE_MASK,  /*!< Swing back one cycle complete interrupt enable. */
49     kDAC_FIFOOverflowInterruptEnable  = LPDAC_IER_OF_IE_MASK,    /*!< FIFO overflow interrupt enable. */
50     kDAC_FIFOUnderflowInterruptEnable = LPDAC_IER_UF_IE_MASK,    /*!< FIFO underflow interrupt enable. */
51 #if defined(FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE) && FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE
52     kDAC_PeriodTriggerCompleteInterruptEnable =
53         LPDAC_IER_PTGCOCO_IE_MASK, /*!< Period trigger mode conversion complete interrupt enable */
54 #endif                             /* FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE */
55 };
56 
57 /*!
58  * @brief DAC DMA switchers.
59  */
60 enum
61 {
62     kDAC_FIFOEmptyDMAEnable     = LPDAC_DER_EMPTY_DMAEN_MASK, /*!< FIFO empty DMA enable. */
63     kDAC_FIFOWatermarkDMAEnable = LPDAC_DER_WM_DMAEN_MASK,    /*!< FIFO watermark DMA enable. */
64 };
65 
66 /*!
67  * @brief DAC status flags.
68  */
69 enum
70 {
71     kDAC_FIFOUnderflowFlag = LPDAC_FSR_UF_MASK, /*!< This flag means that there is a new trigger after the buffer is
72 empty. The FIFO read pointer will not
73 increase in this case and the data sent to DAC analog conversion will not changed. This flag is cleared by writing a 1
74 to it. */
75 
76     kDAC_FIFOOverflowFlag =
77         LPDAC_FSR_OF_MASK, /*!< This flag indicates that data is intended to write into FIFO after the
78 buffer is full. The writer pointer will
79 not increase in this case. The extra data will not be written into the FIFO. This flag is cleared by writing a 1 to it.
80 */
81 
82     kDAC_FIFOSwingBackFlag = LPDAC_FSR_SWBK_MASK, /*!< This flag indicates that the DAC has completed one period of
83 conversion in swing back mode. It means
84 that the read pointer has increased to the top (write pointer) once and then decreased to zero once. For
85 example, after three data is written to FIFO, the writer pointer is now 3. Then, if continually triggered, the
86 read pointer will swing like: 0-1-2-1-0-1-2-, and so on. After the fourth trigger, the flag is set. This flag is
87 cleared by writing a 1 to it. */
88 
89     kDAC_FIFOWatermarkFlag = LPDAC_FSR_WM_MASK, /*!< This field is set if the remaining data in FIFO is less than or
90                      equal to the setting value of wartermark. By writing data into FIFO by DMA or CPU, this flag is
91                      cleared automatically when the data in FIFO is more than the setting value of watermark. */
92 
93     kDAC_FIFOEmptyFlag = LPDAC_FSR_EMPTY_MASK, /*!< FIFO empty flag. */
94     kDAC_FIFOFullFlag  = LPDAC_FSR_FULL_MASK,  /*!< FIFO full flag. */
95 #if defined(FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE) && FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE
96     kDAC_PeriodTriggerCompleteFlag = LPDAC_FSR_PTGCOCO_MASK, /*!< Period trigger mode conversion complete flag. */
97 #endif                                                       /* FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE */
98 };
99 
100 /*!
101  * @brief DAC FIFO trigger mode.
102  */
103 typedef enum _dac_fifo_trigger_mode
104 {
105     kDAC_FIFOTriggerByHardwareMode = 0U, /*!< Buffer would be triggered by hardware. */
106     kDAC_FIFOTriggerBySoftwareMode = 1U, /*!< Buffer would be triggered by software. */
107 } dac_fifo_trigger_mode_t;
108 
109 /*!
110  * @brief DAC FIFO work mode.
111  */
112 typedef enum _dac_fifo_work_mode
113 {
114     kDAC_FIFODisabled = 0U, /*!< FIFO mode is disabled and buffer mode is enabled. Any data written to DATA[DATA] goes
115                                  to buffer then goes to conversion. */
116     kDAC_FIFOWorkAsNormalMode = 1U, /*!< FIFO mode is enabled. Data will be first read from FIFO to buffer then goes to
117                                          conversion. */
118     kDAC_FIFOWorkAsSwingMode = 2U, /*!< In swing mode, the read pointer swings between the writer pointer and zero. That
119                                         is, the trigger increases the read pointer till reach the writer pointer and
120                                         decreases the read pointer till zero, and so on. The FIFO empty/full/watermark
121                                         flag will not update during swing back mode. */
122 #if defined(FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE) && FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE
123     kDAC_FIFOWorkAsPeriodTriggerMode =
124         3U, /*!< In periodic trigger mode, user only needs to send the first trigger. Then after every [PTG_PERIOD+1]
125                RCLK cycles, DAC will be automatically triggered by internal trigger. There will be [PTG_NUM] internal
126                triggers, thus in total [PTG_NUM+1] conversions including the first trigger sent by user. User can
127                terminate the current conversion queue by clearing the GCR[PTGEN] bit. Then, after the current conversion
128                is completed, the conversion is terminated and the PTGCOCO flag is set. If PCR[PTG_NUM] is set to zero,
129                there will be infinite triggers following the first hardware/software trigger, until the GCR[PTGEN] is
130                cleared by software. In any case, the conversion can be terminated by FIFORST/SWRST. */
131     kDAC_FIFOWorkAsPeriodTriggerAndSwingMode = 4U, /*!< Periodically trigger DAC and swing back. */
132 #endif                                             /* FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE */
133 } dac_fifo_work_mode_t;
134 
135 /*!
136  * @brief DAC reference voltage source.
137  */
138 typedef enum _dac_reference_voltage_source
139 {
140 #if defined(FSL_FEATURE_ANALOG_NUM_OF_VREF_SRC) && (FSL_FEATURE_ANALOG_NUM_OF_VREF_SRC == 3)
141     kDAC_ReferenceVoltageSourceAlt1 = 0U, /*!< The DAC selects VDD_ANA as the reference voltage. */
142     kDAC_ReferenceVoltageSourceAlt2 = 1U, /*!< The DAC selects VREF_OUT as the reference voltage. */
143     kDAC_ReferenceVoltageSourceAlt3 = 2U, /*!< THe DAC selects VREFH as the reference voltage. */
144 #else
145     kDAC_ReferenceVoltageSourceAlt1 = 0U, /*!< The DAC selects VREFH_INT as the reference voltage. */
146     kDAC_ReferenceVoltageSourceAlt2 = 1U, /*!< The DAC selects VREFH_EXT as the reference voltage. */
147 #endif /* FSL_FEATURE_ANALOG_NUM_OF_VREF_SRC  */
148 } dac_reference_voltage_source_t;
149 
150 #if defined(FSL_FEATURE_LPDAC_HAS_INTERNAL_REFERENCE_CURRENT) && FSL_FEATURE_LPDAC_HAS_INTERNAL_REFERENCE_CURRENT
151 /*
152  * @brief DAC internal reference current source
153  */
154 typedef enum _dac_reference_current_source
155 {
156     kDAC_ReferenceCurrentSourcePtat = LPDAC_GCR_IREF_PTAT_EXT_SEL_MASK, /* Internal PTAT Current Reference selected */
157     kDAC_ReferenceCurrentSourceZtc  = LPDAC_GCR_IREF_ZTC_EXT_SEL_MASK,  /* Internal ZTC Current Reference selected */
158 } dac_reference_current_source_t;
159 #endif /* FSL_FEATURE_LPDAC_HAS_INTERNAL_REFERENCE_CURRENT */
160 
161 /*!
162  * @brief DAC configuration structure.
163  */
164 typedef struct _dac_config
165 {
166     uint32_t fifoWatermarkLevel;             /*!< FIFO's watermark, the max value can be the hardware FIFO size. */
167     dac_fifo_trigger_mode_t fifoTriggerMode; /*!< Select the trigger mode for FIFO. */
168     dac_fifo_work_mode_t fifoWorkMode;       /*!< Select the work mode for FIFO. */
169 #if defined(FSL_FEATURE_LPDAC_HAS_GCR_BUF_EN) && FSL_FEATURE_LPDAC_HAS_GCR_BUF_EN
170     bool enableOpampBuffer; /*!< Opamp is used as buffer. */
171 #endif                      /* FSL_FEATURE_LPDAC_HAS_GCR_BUF_EN */
172 #if defined(FSL_FEATURE_LPDAC_HAS_GCR_RCV_TRG) && FSL_FEATURE_LPDAC_HAS_GCR_RCV_TRG
173     bool enableExternalTriggerSource; /* DAC uses another DAC's hardware/software trigger as its trigger source. */
174 #endif                                /* FSL_FEATURE_LPDAC_HAS_GCR_RCV_TRG */
175 #if defined(FSL_FEATURE_LPDAC_HAS_GCR_BUF_SPD_CTRL) && FSL_FEATURE_LPDAC_HAS_GCR_BUF_SPD_CTRL
176     bool enableLowerLowPowerMode; /*!< Enable the lower low power mode. */
177 #else
178     bool enableLowPowerMode;              /*!< Enable the low power mode. */
179 #endif /* FSL_FEATURE_LPDAC_HAS_GCR_BUF_SPD_CTRL */
180 #if defined(FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE) && FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE
181     uint32_t periodicTriggerNumber; /*!< There will be 'periodicTriggerNumber' internal triggers following the first
182                                       hardware/software trigger. So there will be 'periodicTriggerNumber + 1'
183                                       conversions in total. If set to zero, there will be infinite triggers following
184                                       the first hw/sw trigger, until the GCR[PTGEN] is cleared. */
185     uint32_t periodicTriggerWidth; /*!< Control the periodic trigger frequency. There will be 'periodicTriggerWidth + 1'
186                                       RCLK cycles between each periodic trigger. The periodic trigger frequency should
187                                       be configured to not larger than the analog conversion speed. */
188 #endif                             /* FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE */
189 #if defined(FSL_FEATURE_LPDAC_HAS_GCR_LATCH_CYC) && FSL_FEATURE_LPDAC_HAS_GCR_LATCH_CYC
190     uint32_t syncTime; /*!< RCLK cycles before data latch. accessible range is 0-15. It is used to configure the DAC
191                           sync cycles which is helpful to reduce glitch on the output. The sync time is (LATCH_CYC+1)
192                           RCLK cycles. User should configure this register according to the RCLK frequency. The
193                           recommended sync time is at least 40ns.*/
194 #endif                 /* FSL_FEATURE_LPDAC_HAS_GCR_LATCH_CYC */
195 #if defined(FSL_FEATURE_LPDAC_HAS_INTERNAL_REFERENCE_CURRENT) && FSL_FEATURE_LPDAC_HAS_INTERNAL_REFERENCE_CURRENT
196     dac_reference_current_source_t referenceCurrentSource; /*!< Select the internal reference current source. */
197 #endif                                                     /* FSL_FEATURE_LPDAC_HAS_INTERNAL_REFERENCE_CURRENT */
198     dac_reference_voltage_source_t referenceVoltageSource; /*!< Select the reference voltage source. */
199 } dac_config_t;
200 
201 /*******************************************************************************
202  * API
203  ******************************************************************************/
204 #if defined(__cplusplus)
205 extern "C" {
206 #endif
207 
208 /*!
209  * @name Initialization and de-initialization
210  * @{
211  */
212 
213 /*!
214  * @brief Initialize the DAC module with common configuartion.
215  *
216  * The clock will be enabled in this function.
217  *
218  * @param base DAC peripheral base address.
219  * @param config Pointer to configuration structure.
220  */
221 void DAC_Init(LPDAC_Type *base, const dac_config_t *config);
222 
223 /*!
224  * @brief Get the default settings for initialization's configuration.
225  *
226  * This function initializes the user configuration structure to a default value. The default values are:
227  * @code
228  *   config->fifoWatermarkLevel = 0U;
229  *   config->fifoTriggerMode = kDAC_FIFOTriggerByHardwareMode;
230  *   config->fifoWorkMode = kDAC_FIFODisabled;
231  *   config->enableLowPowerMode = false;
232  *   config->referenceVoltageSource = kDAC_ReferenceVoltageSourceAlt1;
233  * @endcode
234  *
235  * @param config Pointer to configuration structure.
236  */
237 void DAC_GetDefaultConfig(dac_config_t *config);
238 
239 /*!
240  * @brief De-initialize the DAC module.
241  *
242  * The clock will be disabled in this function.
243  *
244  * @param base DAC peripheral base address.
245  */
246 void DAC_Deinit(LPDAC_Type *base);
247 
248 /*!
249  * @brief Assert the reset control to part hardware.
250  *
251  * This function is to assert the reset control to part hardware. Responding part hardware would remain reset untill
252  * cleared by software.
253  *
254  * @param base DAC peripheral base address.
255  * @param mask The reset control mask, see to _dac_reset_control_t.
256  */
DAC_SetReset(LPDAC_Type * base,uint32_t mask)257 static inline void DAC_SetReset(LPDAC_Type *base, uint32_t mask)
258 {
259     base->RCR |= mask;
260 }
261 
262 /*!
263  * @brief Clear the reset control to part hardware.
264  *
265  * This function is to clear the reset control to part hardware. Responding part hardware would work after the reset
266  * control is cleared by software.
267  *
268  * @param base DAC peripheral base address.
269  * @param mask The reset control mask, see to _dac_reset_control_t.
270  */
DAC_ClearReset(LPDAC_Type * base,uint32_t mask)271 static inline void DAC_ClearReset(LPDAC_Type *base, uint32_t mask)
272 {
273     base->RCR &= ~mask;
274 }
275 
276 /*!
277  * @brief Enable the DAC hardware system or not.
278  *
279  * This function is to start the Programmable Reference Generator operation or not.
280  *
281  * @param base DAC peripheral base address.
282  * @param enable Assertion of indicated event.
283  */
DAC_Enable(LPDAC_Type * base,bool enable)284 static inline void DAC_Enable(LPDAC_Type *base, bool enable)
285 {
286     if (enable)
287     {
288         base->GCR |= LPDAC_GCR_DACEN_MASK;
289     }
290     else
291     {
292         base->GCR &= ~LPDAC_GCR_DACEN_MASK;
293     }
294 }
295 
296 /*! @} */
297 
298 /*!
299  * @name Interrupts
300  * @{
301  */
302 
303 /*!
304  * @brief Enable the interrupts.
305  *
306  * @param base DAC peripheral base address.
307  * @param mask Mask value of indicated interrupt events. See to _dac_interrupt_enable.
308  */
DAC_EnableInterrupts(LPDAC_Type * base,uint32_t mask)309 static inline void DAC_EnableInterrupts(LPDAC_Type *base, uint32_t mask)
310 {
311     base->IER |= mask;
312 }
313 
314 /*!
315  * @brief Disable the interrupts.
316  *
317  * @param base DAC peripheral base address.
318  * @param mask Mask value of indicated interrupt events. See to _dac_interrupt_enable.
319  */
DAC_DisableInterrupts(LPDAC_Type * base,uint32_t mask)320 static inline void DAC_DisableInterrupts(LPDAC_Type *base, uint32_t mask)
321 {
322     base->IER &= ~mask;
323 }
324 
325 /*! @} */
326 
327 /*!
328  * @name DMA control
329  * @{
330  */
331 
332 /*!
333  * @brief Enable the DMA switchers or not.
334  *
335  * @param base DAC peripheral base address.
336  * @param mask Mask value of indicated DMA requeset. See to _dac_dma_enable.
337  * @param enable Enable the DMA or not.
338  */
DAC_EnableDMA(LPDAC_Type * base,uint32_t mask,bool enable)339 static inline void DAC_EnableDMA(LPDAC_Type *base, uint32_t mask, bool enable)
340 {
341     if (enable)
342     {
343         base->DER |= mask;
344     }
345     else
346     {
347         base->DER &= ~mask;
348     }
349 }
350 
351 /*! @} */
352 
353 /*!
354  * @name Status flags
355  * @{
356  */
357 
358 /*!
359  * @brief Get status flags of DAC module.
360  *
361  * @param base DAC peripheral base address.
362  * @return Mask value of status flags. See to _dac_status_flags.
363  */
DAC_GetStatusFlags(LPDAC_Type * base)364 static inline uint32_t DAC_GetStatusFlags(LPDAC_Type *base)
365 {
366     return base->FSR;
367 }
368 
369 /*!
370  * @brief Clear status flags of DAC module.
371  *
372  * @param base DAC peripheral base address.
373  * @param flags Mask value of status flags to be cleared. See to _dac_status_flags.
374  */
DAC_ClearStatusFlags(LPDAC_Type * base,uint32_t flags)375 static inline void DAC_ClearStatusFlags(LPDAC_Type *base, uint32_t flags)
376 {
377     base->FSR = flags;
378 }
379 
380 /*! @} */
381 
382 /*!
383  * @name Functional feature
384  * @{
385  */
386 
387 /*!
388  * @brief Set data into the entry of FIFO buffer.
389  *
390  * @param base DAC peripheral base address.
391  * @param value Setting value into FIFO buffer.
392  */
DAC_SetData(LPDAC_Type * base,uint32_t value)393 static inline void DAC_SetData(LPDAC_Type *base, uint32_t value)
394 {
395     base->DATA = LPDAC_DATA_DATA(value);
396 }
397 
398 /*!
399  * @brief Get the value of the FIFO write pointer.
400  *
401  * @param base DAC peripheral base address.
402  * @return Current value of the FIFO write pointer.
403  */
404 
DAC_GetFIFOWritePointer(LPDAC_Type * base)405 static inline uint32_t DAC_GetFIFOWritePointer(LPDAC_Type *base)
406 {
407     return (LPDAC_FPR_FIFO_WPT_MASK & base->FPR) >> LPDAC_FPR_FIFO_WPT_SHIFT;
408 }
409 
410 /*!
411  * @brief  Get the value of the FIFO read pointer.
412  *
413  * @param base DAC peripheral base address.
414  * @return Current value of the FIFO read pointer.
415  */
416 
DAC_GetFIFOReadPointer(LPDAC_Type * base)417 static inline uint32_t DAC_GetFIFOReadPointer(LPDAC_Type *base)
418 {
419     return (LPDAC_FPR_FIFO_RPT_MASK & base->FPR) >> LPDAC_FPR_FIFO_RPT_SHIFT;
420 }
421 
422 /*!
423  * @brief Do software trigger to FIFO when in software mode.
424  *
425  * @param base DAC peripheral base address.
426  */
427 
DAC_DoSoftwareTriggerFIFO(LPDAC_Type * base)428 static inline void DAC_DoSoftwareTriggerFIFO(LPDAC_Type *base)
429 {
430     base->TCR = LPDAC_TCR_SWTRG_MASK;
431 }
432 
433 /*! @} */
434 
435 #if defined(__cplusplus)
436 }
437 #endif
438 
439 /*!
440  * @}
441  */
442 #endif /* FSL_DAC12_H_ */
443