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