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