1 /*
2 * Copyright (c) 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016-2019, 2022 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "fsl_dac.h"
10
11 /*******************************************************************************
12 * Definitions
13 ******************************************************************************/
14 /* Component ID definition, used by tools. */
15 #ifndef FSL_COMPONENT_ID
16 #define FSL_COMPONENT_ID "platform.drivers.dac_1"
17 #endif
18
19 #if defined(DAC_RSTS)
20 #define DAC_RESETS_ARRAY DAC_RSTS
21 #elif defined(DAC_RSTS_N)
22 #define DAC_RESETS_ARRAY DAC_RSTS_N
23 #endif
24
25 /*******************************************************************************
26 * Prototypes
27 ******************************************************************************/
28 /*!
29 * @brief Get instance number for DAC module.
30 *
31 * @param base DAC peripheral base address
32 */
33 static uint32_t DAC_GetInstance(LPDAC_Type *base);
34
35 /*******************************************************************************
36 * Variables
37 ******************************************************************************/
38 /*! @brief Pointers to DAC bases for each instance. */
39 static LPDAC_Type *const s_dacBases[] = LPDAC_BASE_PTRS;
40
41 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
42 /*! @brief Pointers to DAC clocks for each instance. */
43 static const clock_ip_name_t s_dacClocks[] = LPDAC_CLOCKS;
44 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
45
46 #if defined(DAC_RESETS_ARRAY)
47 /* Reset array */
48 static const reset_ip_name_t s_dacResets[] = DAC_RESETS_ARRAY;
49 #endif
50
51 /*******************************************************************************
52 * Code
53 ******************************************************************************/
DAC_GetInstance(LPDAC_Type * base)54 static uint32_t DAC_GetInstance(LPDAC_Type *base)
55 {
56 uint32_t instance;
57
58 /* Find the instance index from base address mappings. */
59 for (instance = 0; instance < ARRAY_SIZE(s_dacBases); instance++)
60 {
61 if (s_dacBases[instance] == base)
62 {
63 break;
64 }
65 }
66
67 assert(instance < ARRAY_SIZE(s_dacBases));
68
69 return instance;
70 }
71
72 /*!
73 * brief Initialize the DAC module with common configuartion.
74 *
75 * The clock will be enabled in this function.
76 *
77 * param base DAC peripheral base address.
78 * param config Pointer to configuration structure.
79 */
DAC_Init(LPDAC_Type * base,const dac_config_t * config)80 void DAC_Init(LPDAC_Type *base, const dac_config_t *config)
81 {
82 assert(NULL != config);
83
84 uint32_t tmp32 = 0U;
85
86 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
87 /* Enable the clock. */
88 CLOCK_EnableClock(s_dacClocks[DAC_GetInstance(base)]);
89 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
90
91 #if defined(DAC_RESETS_ARRAY)
92 RESET_ReleasePeripheralReset(s_dacResets[DAC_GetInstance(base)]);
93 #endif
94
95 /* Reset the logic. */
96 DAC_SetReset(base, kDAC_ResetLogic);
97 DAC_ClearReset(base, kDAC_ResetLogic);
98
99 /* Reset the FIFO. */
100 DAC_SetReset(base, kDAC_ResetFIFO);
101 DAC_ClearReset(base, kDAC_ResetFIFO);
102
103 /* Configuration. */
104 if (kDAC_FIFOTriggerBySoftwareMode == config->fifoTriggerMode)
105 {
106 tmp32 |= LPDAC_GCR_TRGSEL_MASK; /* Software trigger. */
107 }
108 switch (config->fifoWorkMode)
109 {
110 case kDAC_FIFOWorkAsNormalMode: /* Normal FIFO. */
111 tmp32 |= LPDAC_GCR_FIFOEN_MASK;
112 break;
113 case kDAC_FIFOWorkAsSwingMode:
114 tmp32 |= LPDAC_GCR_FIFOEN_MASK | LPDAC_GCR_SWMD_MASK; /* Enable swing mode. */
115 break;
116 #if defined(FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE) && FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE
117 case kDAC_FIFOWorkAsPeriodTriggerMode:
118 tmp32 |= LPDAC_GCR_FIFOEN_MASK | LPDAC_GCR_PTGEN_MASK; /* Enable period trigger mode. */
119 /* Set trigger number and width. */
120 base->PCR =
121 LPDAC_PCR_PTG_NUM(config->periodicTriggerNumber) | LPDAC_PCR_PTG_PERIOD(config->periodicTriggerWidth);
122 break;
123 case kDAC_FIFOWorkAsPeriodTriggerAndSwingMode:
124 tmp32 |= LPDAC_GCR_FIFOEN_MASK | LPDAC_GCR_PTGEN_MASK | LPDAC_GCR_SWMD_MASK;
125 /* Set trigger number and width. */
126 base->PCR =
127 LPDAC_PCR_PTG_NUM(config->periodicTriggerNumber) | LPDAC_PCR_PTG_PERIOD(config->periodicTriggerWidth);
128 break;
129 #endif /* FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE */
130 default: /* kDAC_FIFODisabled. */
131 break;
132 }
133
134 #if defined(FSL_FEATURE_LPDAC_HAS_GCR_RCV_TRG) && FSL_FEATURE_LPDAC_HAS_GCR_RCV_TRG
135 if (config->enableExternalTriggerSource)
136 {
137 tmp32 |= LPDAC_GCR_RCV_TRG_MASK; /* Use trigger source from another DAC. */
138 }
139 #endif /* FSL_FEATURE_LPDAC_HAS_GCR_RCV_TRG */
140 #if defined(FSL_FEATURE_LPDAC_HAS_GCR_BUF_SPD_CTRL) && FSL_FEATURE_LPDAC_HAS_GCR_BUF_SPD_CTRL
141 if (false == config->enableLowerLowPowerMode)
142 {
143 tmp32 |= LPDAC_GCR_BUF_SPD_CTRL_MASK; /* Enable low power. */
144 }
145 #else
146 if (config->enableLowPowerMode)
147 {
148 tmp32 |= LPDAC_GCR_LPEN_MASK; /* Enable low power. */
149 }
150 #endif /* LPDAC_GCR_BUF_SPD_CTRL_MASK */
151
152 #if defined(FSL_FEATURE_LPDAC_HAS_GCR_BUF_EN) && FSL_FEATURE_LPDAC_HAS_GCR_BUF_EN
153 tmp32 |= LPDAC_GCR_BUF_EN_MASK; /* Opamp is used as buffer. */
154 #endif /* FSL_FEATURE_LPDAC_HAS_GCR_BUF_EN */
155 #if defined(FSL_FEATURE_LPDAC_HAS_GCR_LATCH_CYC) && FSL_FEATURE_LPDAC_HAS_GCR_LATCH_CYC
156 /* Configure DAC sync cycles. */
157 tmp32 |= LPDAC_GCR_LATCH_CYC(config->syncTime);
158 #endif /* FSL_FEATURE_LPDAC_HAS_GCR_LATCH_CYC */
159 #if defined(FSL_FEATURE_LPDAC_HAS_INTERNAL_REFERENCE_CURRENT) && FSL_FEATURE_LPDAC_HAS_INTERNAL_REFERENCE_CURRENT
160 tmp32 |= (uint32_t)config->referenceCurrentSource;
161 #endif /* FSL_FEATURE_LPDAC_HAS_INTERNAL_REFERENCE_CURRENT */
162 /* Set reference voltage source. */
163 tmp32 |= LPDAC_GCR_DACRFS(config->referenceVoltageSource);
164
165 base->GCR = tmp32;
166 base->FCR = LPDAC_FCR_WML(config->fifoWatermarkLevel);
167
168 /* Now, the DAC is disabled. It needs to be enabled in application. */
169 }
170
171 /*!
172 * brief Get the default settings for initialization's configuration.
173 *
174 * This function initializes the user configuration structure to a default value. The default values are:
175 * code
176 * config->fifoWatermarkLevel = 0U;
177 * config->fifoTriggerMode = kDAC_FIFOTriggerByHardwareMode;
178 * config->fifoWorkMode = kDAC_FIFODisabled;
179 * config->enableLowPowerMode = false;
180 * config->referenceVoltageSource = kDAC_ReferenceVoltageSourceAlt1;
181 * endcode
182 *
183 * param config Pointer to configuration structure.
184 * param
185 */
DAC_GetDefaultConfig(dac_config_t * config)186 void DAC_GetDefaultConfig(dac_config_t *config)
187 {
188 assert(config != NULL);
189
190 /* Initializes the configure structure to zero. */
191 (void)memset(config, 0, sizeof(*config));
192
193 config->fifoWatermarkLevel = 0U;
194 config->fifoTriggerMode = kDAC_FIFOTriggerByHardwareMode;
195 config->fifoWorkMode = kDAC_FIFODisabled;
196
197 #if defined(FSL_FEATURE_LPDAC_HAS_GCR_RCV_TRG) && FSL_FEATURE_LPDAC_HAS_GCR_RCV_TRG
198 config->enableExternalTriggerSource = false;
199 #endif /* FSL_FEATURE_LPDAC_HAS_GCR_RCV_TRG */
200 #if defined(FSL_FEATURE_LPDAC_HAS_GCR_BUF_SPD_CTRL) && FSL_FEATURE_LPDAC_HAS_GCR_BUF_SPD_CTRL
201 config->enableLowerLowPowerMode = true;
202 #else
203 config->enableLowPowerMode = false;
204 #endif /* FSL_FEATURE_LPDAC_HAS_GCR_BUF_SPD_CTRL */
205 #if defined(FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE) && FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE
206 config->periodicTriggerNumber = 0UL;
207 config->periodicTriggerWidth = 0UL;
208 #endif /* FSL_FEATURE_LPDAC_HAS_PERIODIC_TRIGGER_MODE */
209 #if defined(FSL_FEATURE_LPDAC_HAS_GCR_LATCH_CYC) && FSL_FEATURE_LPDAC_HAS_GCR_LATCH_CYC
210 /* Configure DAC sync cycles. */
211 config->syncTime = 1U;
212 #endif /* FSL_FEATURE_LPDAC_HAS_GCR_LATCH_CYC */
213 #if defined(FSL_FEATURE_LPDAC_HAS_INTERNAL_REFERENCE_CURRENT) && FSL_FEATURE_LPDAC_HAS_INTERNAL_REFERENCE_CURRENT
214 config->referenceCurrentSource = kDAC_ReferenceCurrentSourcePtat;
215 #endif /* FSL_FEATURE_LPDAC_HAS_INTERNAL_REFERENCE_CURRENT */
216 config->referenceVoltageSource = kDAC_ReferenceVoltageSourceAlt1;
217 }
218
219 /*!
220 * brief De-initialize the DAC module.
221 *
222 * The clock will be disabled in this function.
223 *
224 * param base DAC peripheral base address.
225 * param
226 */
DAC_Deinit(LPDAC_Type * base)227 void DAC_Deinit(LPDAC_Type *base)
228 {
229 /* Disable the module. */
230 DAC_Enable(base, false);
231
232 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
233 /* Disable the clock. */
234 CLOCK_DisableClock(s_dacClocks[DAC_GetInstance(base)]);
235 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
236 }
237