1 /*
2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
3 * Copyright 2016-2017 NXP
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * o Redistributions of source code must retain the above copyright notice, this list
9 * of conditions and the following disclaimer.
10 *
11 * o Redistributions in binary form must reproduce the above copyright notice, this
12 * list of conditions and the following disclaimer in the documentation and/or
13 * other materials provided with the distribution.
14 *
15 * o Neither the name of the copyright holder nor the names of its
16 * contributors may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "fsl_dac.h"
32
33 /*******************************************************************************
34 * Prototypes
35 ******************************************************************************/
36 /*!
37 * @brief Get instance number for DAC module.
38 *
39 * @param base DAC peripheral base address
40 */
41 static uint32_t DAC_GetInstance(DAC_Type *base);
42
43 /*******************************************************************************
44 * Variables
45 ******************************************************************************/
46 /*! @brief Pointers to DAC bases for each instance. */
47 static DAC_Type *const s_dacBases[] = DAC_BASE_PTRS;
48 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
49 /*! @brief Pointers to DAC clocks for each instance. */
50 static const clock_ip_name_t s_dacClocks[] = DAC_CLOCKS;
51 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
52
53 /*******************************************************************************
54 * Codes
55 ******************************************************************************/
DAC_GetInstance(DAC_Type * base)56 static uint32_t DAC_GetInstance(DAC_Type *base)
57 {
58 uint32_t instance;
59
60 /* Find the instance index from base address mappings. */
61 for (instance = 0; instance < ARRAY_SIZE(s_dacBases); instance++)
62 {
63 if (s_dacBases[instance] == base)
64 {
65 break;
66 }
67 }
68
69 assert(instance < ARRAY_SIZE(s_dacBases));
70
71 return instance;
72 }
73
DAC_Init(DAC_Type * base,const dac_config_t * config)74 void DAC_Init(DAC_Type *base, const dac_config_t *config)
75 {
76 assert(NULL != config);
77
78 uint8_t tmp8;
79
80 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
81 /* Enable the clock. */
82 CLOCK_EnableClock(s_dacClocks[DAC_GetInstance(base)]);
83 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
84
85 /* Configure. */
86 /* DACx_C0. */
87 tmp8 = base->C0 & ~(DAC_C0_DACRFS_MASK | DAC_C0_LPEN_MASK);
88 if (kDAC_ReferenceVoltageSourceVref2 == config->referenceVoltageSource)
89 {
90 tmp8 |= DAC_C0_DACRFS_MASK;
91 }
92 if (config->enableLowPowerMode)
93 {
94 tmp8 |= DAC_C0_LPEN_MASK;
95 }
96 base->C0 = tmp8;
97
98 /* DAC_Enable(base, true); */
99 /* Tip: The DAC output can be enabled till then after user sets their own available data in application. */
100 }
101
DAC_Deinit(DAC_Type * base)102 void DAC_Deinit(DAC_Type *base)
103 {
104 DAC_Enable(base, false);
105
106 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
107 /* Disable the clock. */
108 CLOCK_DisableClock(s_dacClocks[DAC_GetInstance(base)]);
109 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
110 }
111
DAC_GetDefaultConfig(dac_config_t * config)112 void DAC_GetDefaultConfig(dac_config_t *config)
113 {
114 assert(NULL != config);
115
116 config->referenceVoltageSource = kDAC_ReferenceVoltageSourceVref2;
117 config->enableLowPowerMode = false;
118 }
119
DAC_SetBufferConfig(DAC_Type * base,const dac_buffer_config_t * config)120 void DAC_SetBufferConfig(DAC_Type *base, const dac_buffer_config_t *config)
121 {
122 assert(NULL != config);
123
124 uint8_t tmp8;
125
126 /* DACx_C0. */
127 tmp8 = base->C0 & ~(DAC_C0_DACTRGSEL_MASK);
128 if (kDAC_BufferTriggerBySoftwareMode == config->triggerMode)
129 {
130 tmp8 |= DAC_C0_DACTRGSEL_MASK;
131 }
132 base->C0 = tmp8;
133
134 /* DACx_C1. */
135 tmp8 = base->C1 &
136 ~(
137 #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION
138 DAC_C1_DACBFWM_MASK |
139 #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */
140 DAC_C1_DACBFMD_MASK);
141 #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION
142 tmp8 |= DAC_C1_DACBFWM(config->watermark);
143 #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */
144 tmp8 |= DAC_C1_DACBFMD(config->workMode);
145 base->C1 = tmp8;
146
147 /* DACx_C2. */
148 tmp8 = base->C2 & ~DAC_C2_DACBFUP_MASK;
149 tmp8 |= DAC_C2_DACBFUP(config->upperLimit);
150 base->C2 = tmp8;
151 }
152
DAC_GetDefaultBufferConfig(dac_buffer_config_t * config)153 void DAC_GetDefaultBufferConfig(dac_buffer_config_t *config)
154 {
155 assert(NULL != config);
156
157 config->triggerMode = kDAC_BufferTriggerBySoftwareMode;
158 #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION
159 config->watermark = kDAC_BufferWatermark1Word;
160 #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_SELECTION */
161 config->workMode = kDAC_BufferWorkAsNormalMode;
162 config->upperLimit = DAC_DATL_COUNT - 1U;
163 }
164
DAC_SetBufferValue(DAC_Type * base,uint8_t index,uint16_t value)165 void DAC_SetBufferValue(DAC_Type *base, uint8_t index, uint16_t value)
166 {
167 assert(index < DAC_DATL_COUNT);
168
169 base->DAT[index].DATL = (uint8_t)(0xFFU & value); /* Low 8-bit. */
170 base->DAT[index].DATH = (uint8_t)((0xF00U & value) >> 8); /* High 4-bit. */
171 }
172
DAC_SetBufferReadPointer(DAC_Type * base,uint8_t index)173 void DAC_SetBufferReadPointer(DAC_Type *base, uint8_t index)
174 {
175 assert(index < DAC_DATL_COUNT);
176
177 uint8_t tmp8 = base->C2 & ~DAC_C2_DACBFRP_MASK;
178
179 tmp8 |= DAC_C2_DACBFRP(index);
180 base->C2 = tmp8;
181 }
182
DAC_EnableBufferInterrupts(DAC_Type * base,uint32_t mask)183 void DAC_EnableBufferInterrupts(DAC_Type *base, uint32_t mask)
184 {
185 mask &= (
186 #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION
187 DAC_C0_DACBWIEN_MASK |
188 #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */
189 DAC_C0_DACBTIEN_MASK | DAC_C0_DACBBIEN_MASK);
190 base->C0 |= ((uint8_t)mask); /* Write 1 to enable. */
191 }
192
DAC_DisableBufferInterrupts(DAC_Type * base,uint32_t mask)193 void DAC_DisableBufferInterrupts(DAC_Type *base, uint32_t mask)
194 {
195 mask &= (
196 #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION
197 DAC_C0_DACBWIEN_MASK |
198 #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */
199 DAC_C0_DACBTIEN_MASK | DAC_C0_DACBBIEN_MASK);
200 base->C0 &= (uint8_t)(~((uint8_t)mask)); /* Write 0 to disable. */
201 }
202
DAC_GetBufferStatusFlags(DAC_Type * base)203 uint32_t DAC_GetBufferStatusFlags(DAC_Type *base)
204 {
205 return (uint32_t)(base->SR & (
206 #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION
207 DAC_SR_DACBFWMF_MASK |
208 #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */
209 DAC_SR_DACBFRPTF_MASK | DAC_SR_DACBFRPBF_MASK));
210 }
211
DAC_ClearBufferStatusFlags(DAC_Type * base,uint32_t mask)212 void DAC_ClearBufferStatusFlags(DAC_Type *base, uint32_t mask)
213 {
214 mask &= (
215 #if defined(FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION) && FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION
216 DAC_SR_DACBFWMF_MASK |
217 #endif /* FSL_FEATURE_DAC_HAS_WATERMARK_DETECTION */
218 DAC_SR_DACBFRPTF_MASK | DAC_SR_DACBFRPBF_MASK);
219 base->SR &= (uint8_t)(~((uint8_t)mask)); /* Write 0 to clear flags. */
220 }
221