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