1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016-2019 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_dac.h"
10 
11 /* Component ID definition, used by tools. */
12 #ifndef FSL_COMPONENT_ID
13 #define FSL_COMPONENT_ID "platform.drivers.dac"
14 #endif
15 
16 /*******************************************************************************
17  * Prototypes
18  ******************************************************************************/
19 /*!
20  * @brief Get instance number for DAC module.
21  *
22  * @param base DAC peripheral base address
23  */
24 static uint32_t DAC_GetInstance(DAC_Type *base);
25 
26 /*******************************************************************************
27  * Variables
28  ******************************************************************************/
29 /*! @brief Pointers to DAC bases for each instance. */
30 static DAC_Type *const s_dacBases[] = DAC_BASE_PTRS;
31 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
32 /*! @brief Pointers to DAC clocks for each instance. */
33 static const clock_ip_name_t s_dacClocks[] = DAC_CLOCKS;
34 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
35 
36 /*******************************************************************************
37  * Codes
38  ******************************************************************************/
DAC_GetInstance(DAC_Type * base)39 static uint32_t DAC_GetInstance(DAC_Type *base)
40 {
41     uint32_t instance;
42 
43     /* Find the instance index from base address mappings. */
44     for (instance = 0; instance < ARRAY_SIZE(s_dacBases); instance++)
45     {
46         if (s_dacBases[instance] == base)
47         {
48             break;
49         }
50     }
51 
52     assert(instance < ARRAY_SIZE(s_dacBases));
53 
54     return instance;
55 }
56 
57 /*!
58  * brief Initializes the DAC module.
59  *
60  * This function initializes the DAC module including the following operations.
61  *  - Enabling the clock for DAC module.
62  *  - Configuring the DAC converter with a user configuration.
63  *  - Enabling the DAC module.
64  *
65  * param base DAC peripheral base address.
66  * param config Pointer to the configuration structure. See "dac_config_t".
67  */
DAC_Init(DAC_Type * base,const dac_config_t * config)68 void DAC_Init(DAC_Type *base, const dac_config_t *config)
69 {
70     assert(NULL != config);
71 
72     uint8_t tmp8;
73 
74 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
75     /* Enable the clock. */
76     CLOCK_EnableClock(s_dacClocks[DAC_GetInstance(base)]);
77 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
78 
79     /* Configure. */
80     /* DACx_C0. */
81     tmp8 = base->C0 & (uint8_t)(~(DAC_C0_DACRFS_MASK | DAC_C0_LPEN_MASK));
82     if (kDAC_ReferenceVoltageSourceVref2 == config->referenceVoltageSource)
83     {
84         tmp8 |= DAC_C0_DACRFS_MASK;
85     }
86     if (config->enableLowPowerMode)
87     {
88         tmp8 |= DAC_C0_LPEN_MASK;
89     }
90     base->C0 = tmp8;
91 
92     /* DAC_Enable(base, true); */
93     /* Tip: The DAC output can be enabled till then after user sets their own available data in application. */
94 }
95 
96 /*!
97  * brief De-initializes the DAC module.
98  *
99  * This function de-initializes the DAC module including the following operations.
100  *  - Disabling the DAC module.
101  *  - Disabling the clock for the DAC module.
102  *
103  * param base DAC peripheral base address.
104  */
DAC_Deinit(DAC_Type * base)105 void DAC_Deinit(DAC_Type *base)
106 {
107     DAC_Enable(base, false);
108 
109 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
110     /* Disable the clock. */
111     CLOCK_DisableClock(s_dacClocks[DAC_GetInstance(base)]);
112 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
113 }
114 
115 /*!
116  * brief Initializes the DAC user configuration structure.
117  *
118  * This function initializes the user configuration structure to a default value. The default values are as follows.
119  * code
120  *   config->referenceVoltageSource = kDAC_ReferenceVoltageSourceVref2;
121  *   config->enableLowPowerMode = false;
122  * endcode
123  * param config Pointer to the configuration structure. See "dac_config_t".
124  */
DAC_GetDefaultConfig(dac_config_t * config)125 void DAC_GetDefaultConfig(dac_config_t *config)
126 {
127     assert(NULL != config);
128 
129     /* Initializes the configure structure to zero. */
130     (void)memset(config, 0, sizeof(*config));
131 
132     config->referenceVoltageSource = kDAC_ReferenceVoltageSourceVref2;
133     config->enableLowPowerMode     = false;
134 }
135 
136 /*!
137  * brief Configures the CMP buffer.
138  *
139  * param base   DAC peripheral base address.
140  * param config Pointer to the configuration structure. See "dac_buffer_config_t".
141  */
DAC_SetBufferConfig(DAC_Type * base,const dac_buffer_config_t * config)142 void DAC_SetBufferConfig(DAC_Type *base, const dac_buffer_config_t *config)
143 {
144     assert(NULL != config);
145 
146     uint8_t tmp8;
147 
148     /* DACx_C0. */
149     tmp8 = base->C0 & (uint8_t)(~DAC_C0_DACTRGSEL_MASK);
150     if (kDAC_BufferTriggerBySoftwareMode == config->triggerMode)
151     {
152         tmp8 |= DAC_C0_DACTRGSEL_MASK;
153     }
154     base->C0 = tmp8;
155 
156     /* DACx_C1. */
157     tmp8 = base->C1 & (uint8_t)(~(
158 #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION
159                           DAC_C1_DACBFWM_MASK |
160 #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */
161                           DAC_C1_DACBFMD_MASK));
162 #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION
163     tmp8 |= DAC_C1_DACBFWM(config->watermark);
164 #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */
165     tmp8 |= DAC_C1_DACBFMD(config->workMode);
166     base->C1 = tmp8;
167 
168     /* DACx_C2. */
169     tmp8 = base->C2 & (uint8_t)(~DAC_C2_DACBFUP_MASK);
170     tmp8 |= DAC_C2_DACBFUP(config->upperLimit);
171     base->C2 = tmp8;
172 }
173 
174 /*!
175  * brief Initializes the DAC buffer configuration structure.
176  *
177  * This function initializes the DAC buffer configuration structure to default values. The default values are as
178  * follows.
179  * code
180  *   config->triggerMode = kDAC_BufferTriggerBySoftwareMode;
181  *   config->watermark   = kDAC_BufferWatermark1Word;
182  *   config->workMode    = kDAC_BufferWorkAsNormalMode;
183  *   config->upperLimit  = DAC_DATL_COUNT - 1U;
184  * endcode
185  * param config Pointer to the configuration structure. See "dac_buffer_config_t".
186  */
DAC_GetDefaultBufferConfig(dac_buffer_config_t * config)187 void DAC_GetDefaultBufferConfig(dac_buffer_config_t *config)
188 {
189     assert(NULL != config);
190 
191     /* Initializes the configure structure to zero. */
192     (void)memset(config, 0, sizeof(*config));
193 
194     config->triggerMode = kDAC_BufferTriggerBySoftwareMode;
195 #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION
196     config->watermark = kDAC_BufferWatermark1Word;
197 #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */
198     config->workMode   = kDAC_BufferWorkAsNormalMode;
199     config->upperLimit = DAC_DATL_COUNT - 1U;
200 }
201 
202 /*!
203  * brief Sets the value for  items in the buffer.
204  *
205  * param base  DAC peripheral base address.
206  * param index Setting the index for items in the buffer. The available index should not exceed the size of the DAC
207  * buffer.
208  * param value Setting the value for items in the buffer. 12-bits are available.
209  */
DAC_SetBufferValue(DAC_Type * base,uint8_t index,uint16_t value)210 void DAC_SetBufferValue(DAC_Type *base, uint8_t index, uint16_t value)
211 {
212     assert(index < DAC_DATL_COUNT);
213 
214     base->DAT[index].DATL = (uint8_t)(0xFFU & value);         /* Low 8-bit. */
215     base->DAT[index].DATH = (uint8_t)((0xF00U & value) >> 8); /* High 4-bit. */
216 }
217 
218 /*!
219  * brief Sets the current read pointer of the DAC buffer.
220  *
221  * This function sets the current read pointer of the DAC buffer.
222  * The current output value depends on the item indexed by the read pointer. It is updated either by a
223  * software trigger or a hardware trigger. After the read pointer changes, the DAC output value also changes.
224  *
225  * param base  DAC peripheral base address.
226  * param index Setting an index value for the pointer.
227  */
DAC_SetBufferReadPointer(DAC_Type * base,uint8_t index)228 void DAC_SetBufferReadPointer(DAC_Type *base, uint8_t index)
229 {
230     assert(index < DAC_DATL_COUNT);
231 
232     uint8_t tmp8 = base->C2 & (uint8_t)(~DAC_C2_DACBFRP_MASK);
233 
234     tmp8 |= DAC_C2_DACBFRP(index);
235     base->C2 = tmp8;
236 }
237 
238 /*!
239  * brief Enables interrupts for the DAC buffer.
240  *
241  * param base DAC peripheral base address.
242  * param mask Mask value for interrupts. See "_dac_buffer_interrupt_enable".
243  */
DAC_EnableBufferInterrupts(DAC_Type * base,uint32_t mask)244 void DAC_EnableBufferInterrupts(DAC_Type *base, uint32_t mask)
245 {
246     mask &= (
247 #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION
248         DAC_C0_DACBWIEN_MASK |
249 #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */
250         DAC_C0_DACBTIEN_MASK | DAC_C0_DACBBIEN_MASK);
251     base->C0 |= ((uint8_t)mask); /* Write 1 to enable. */
252 }
253 
254 /*!
255  * brief Disables interrupts for the DAC buffer.
256  *
257  * param base DAC peripheral base address.
258  * param mask Mask value for interrupts. See  "_dac_buffer_interrupt_enable".
259  */
DAC_DisableBufferInterrupts(DAC_Type * base,uint32_t mask)260 void DAC_DisableBufferInterrupts(DAC_Type *base, uint32_t mask)
261 {
262     mask &= (
263 #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION
264         DAC_C0_DACBWIEN_MASK |
265 #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */
266         DAC_C0_DACBTIEN_MASK | DAC_C0_DACBBIEN_MASK);
267     base->C0 &= (uint8_t)(~((uint8_t)mask)); /* Write 0 to disable. */
268 }
269 
270 /*!
271  * brief Gets the flags of events for the DAC buffer.
272  *
273  * param  base DAC peripheral base address.
274  *
275  * return      Mask value for the asserted flags. See  "_dac_buffer_status_flags".
276  */
DAC_GetBufferStatusFlags(DAC_Type * base)277 uint8_t DAC_GetBufferStatusFlags(DAC_Type *base)
278 {
279     return base->SR & (
280 #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION
281                           DAC_SR_DACBFWMF_MASK |
282 #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */
283                           DAC_SR_DACBFRPTF_MASK | DAC_SR_DACBFRPBF_MASK);
284 }
285 
286 /*!
287  * brief Clears the flags of events for the DAC buffer.
288  *
289  * param base DAC peripheral base address.
290  * param mask Mask value for flags. See "_dac_buffer_status_flags_t".
291  */
DAC_ClearBufferStatusFlags(DAC_Type * base,uint32_t mask)292 void DAC_ClearBufferStatusFlags(DAC_Type *base, uint32_t mask)
293 {
294     mask &= (
295 #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION
296         DAC_SR_DACBFWMF_MASK |
297 #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */
298         DAC_SR_DACBFRPTF_MASK | DAC_SR_DACBFRPBF_MASK);
299     base->SR &= (uint8_t)(~((uint8_t)mask)); /* Write 0 to clear flags. */
300 }
301