1 /*
2  * Copyright (c) 2016, Freescale Semiconductor, Inc.
3  * Copyright 2016-2020 NXP
4  * All rights reserved.
5  *
6  * SPDX-License-Identifier: BSD-3-Clause
7  */
8 
9 #include "fsl_dac12.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.dac12"
17 #endif
18 
19 #if defined(DAC_RSTS)
20 #define DAC_RESETS_ARRAY DAC_RSTS
21 #endif
22 
23 /*******************************************************************************
24  * Prototypes
25  ******************************************************************************/
26 
27 /*!
28  * @brief Get instance number for DAC12 module.
29  *
30  * @param base DAC12 peripheral base address
31  */
32 static uint32_t DAC12_GetInstance(DAC_Type *base);
33 
34 /*******************************************************************************
35  * Variables
36  ******************************************************************************/
37 /*! @brief Pointers to DAC bases for each instance. */
38 static DAC_Type *const s_dac12Bases[] = DAC_BASE_PTRS;
39 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
40 /*! @brief Pointers to DAC clocks for each instance. */
41 static const clock_ip_name_t s_dac12Clocks[] = DAC_CLOCKS;
42 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
43 #if defined(DAC_RESETS_ARRAY)
44 /* Reset array */
45 static const reset_ip_name_t s_dac12Resets[] = DAC_RESETS_ARRAY;
46 #endif
47 
48 /*******************************************************************************
49  * Codes
50  ******************************************************************************/
DAC12_GetInstance(DAC_Type * base)51 static uint32_t DAC12_GetInstance(DAC_Type *base)
52 {
53     uint32_t instance;
54 
55     /* Find the instance index from base address mappings. */
56     for (instance = 0; instance < ARRAY_SIZE(s_dac12Bases); instance++)
57     {
58         if (s_dac12Bases[instance] == base)
59         {
60             break;
61         }
62     }
63 
64     assert(instance < ARRAY_SIZE(s_dac12Bases));
65 
66     return instance;
67 }
68 
69 /*!
70  * brief Get hardware information about this module.
71  *
72  * param base DAC12 peripheral base address.
73  * param info Pointer to info structure, see to #dac12_hardware_info_t.
74  */
DAC12_GetHardwareInfo(DAC_Type * base,dac12_hardware_info_t * info)75 void DAC12_GetHardwareInfo(DAC_Type *base, dac12_hardware_info_t *info)
76 {
77     assert(NULL != info);
78 
79     info->fifoSizeInfo =
80         (dac12_fifo_size_info_t)(uint32_t)((DAC_PARAM_FIFOSZ_MASK & base->PARAM) >> DAC_PARAM_FIFOSZ_SHIFT);
81 }
82 
83 /*!
84  * brief Initialize the DAC12 module.
85  *
86  * param base DAC12 peripheral base address.
87  * param config Pointer to configuration structure, see to #dac12_config_t.
88  */
DAC12_Init(DAC_Type * base,const dac12_config_t * config)89 void DAC12_Init(DAC_Type *base, const dac12_config_t *config)
90 {
91     assert(NULL != config);
92 
93     uint32_t tmp32;
94 
95 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
96     /* Enable the clock. */
97     CLOCK_EnableClock(s_dac12Clocks[DAC12_GetInstance(base)]);
98 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
99 
100 #if defined(DAC_RESETS_ARRAY)
101     RESET_ReleasePeripheralReset(s_dac12Resets[DAC12_GetInstance(base)]);
102 #endif
103 
104     tmp32 = DAC_CR_WML(config->fifoWatermarkLevel); /* FIFO watermark level. */
105     switch (config->fifoWorkMode)                   /* FIFO work mode. */
106     {
107         case kDAC12_FIFOWorkAsNormalMode:
108             tmp32 |= DAC_CR_FIFOEN_MASK;
109             break;
110         case kDAC12_FIFOWorkAsSwingMode:
111             tmp32 |= DAC_CR_FIFOEN_MASK | DAC_CR_SWMD_MASK;
112             break;
113         default: /* kDAC12_FIFODisabled. */
114             break;
115     }
116 
117     tmp32 |= DAC_CR_DACRFS(config->referenceVoltageSource) /* Reference voltage source. */
118              | DAC_CR_TRGSEL(config->fifoTriggerMode);     /* Trigger mode. */
119 
120     base->CR = tmp32;
121 
122     /* DACx_CR2. */
123     tmp32 = 0U;
124     /* Reference voltage current. */
125     switch (config->referenceCurrentSource)
126     {
127         case kDAC12_ReferenceCurrentSourceAlt0:
128             tmp32 |= DAC_CR2_IREF_MASK;
129             break;
130         case kDAC12_ReferenceCurrentSourceAlt1:
131             tmp32 |= DAC_CR2_IREF1_MASK;
132             break;
133         case kDAC12_ReferenceCurrentSourceAlt2:
134             tmp32 |= DAC_CR2_IREF2_MASK;
135             break;
136         default: /* kDAC12_ReferenceCurrentSourceDisabled */
137             break;
138     }
139 
140     /* Speed mode. */
141     switch (config->speedMode)
142     {
143         case kDAC12_SpeedMiddleMode:
144             tmp32 |= DAC_CR2_BFMS_MASK;
145             break;
146         case kDAC12_SpeedHighMode:
147             tmp32 |= DAC_CR2_BFHS_MASK;
148             break;
149         default: /* kDAC12_SpeedLowMode */
150             break;
151     }
152 
153     /* DAC buffered mode needs OPAMP enabled. DAC unbuffered mode needs OPAMP disabled. */
154     if (config->enableAnalogBuffer)
155     {
156         tmp32 |= DAC_CR2_BFEN_MASK; /* OPAMP is used as buffer. */
157     }
158     else
159     {
160         tmp32 |= DAC_CR2_OEN_MASK; /* Output buffer is bypassed. */
161     }
162     base->CR2 = tmp32;
163 
164 #if !(defined(FSL_FEATURE_DAC12_HAS_NO_ITRM_REGISTER) && FSL_FEATURE_DAC12_HAS_NO_ITRM_REGISTER)
165     base->ITRM = DAC_ITRM_TRIM(config->currentReferenceInternalTrimValue);
166 #endif /* FSL_FEATURE_DAC12_HAS_NO_ITRM_REGISTER */
167 }
168 
169 /*!
170  * brief De-initialize the DAC12 module.
171  *
172  * param base DAC12 peripheral base address.
173  */
DAC12_Deinit(DAC_Type * base)174 void DAC12_Deinit(DAC_Type *base)
175 {
176     DAC12_Enable(base, false);
177 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
178     CLOCK_DisableClock(s_dac12Clocks[DAC12_GetInstance(base)]);
179 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
180 }
181 
182 /*!
183  * brief Initializes the DAC12 user configuration structure.
184  *
185  * This function initializes the user configuration structure to a default value. The default values are:
186  * code
187  *   config->fifoWatermarkLevel = 0U;
188  *   config->fifoWorkMode = kDAC12_FIFODisabled;
189  *   config->referenceVoltageSource = kDAC12_ReferenceVoltageSourceAlt1;
190  *   config->fifoTriggerMode = kDAC12_FIFOTriggerByHardwareMode;
191  *   config->referenceCurrentSource = kDAC12_ReferenceCurrentSourceAlt0;
192  *   config->speedMode = kDAC12_SpeedLowMode;
193  *   config->speedMode = false;
194  *   config->currentReferenceInternalTrimValue = 0x4;
195  * endcode
196  * param config Pointer to the configuration structure. See "dac12_config_t".
197  */
DAC12_GetDefaultConfig(dac12_config_t * config)198 void DAC12_GetDefaultConfig(dac12_config_t *config)
199 {
200     assert(NULL != config);
201 
202     /* Initializes the configure structure to zero. */
203     (void)memset(config, 0, sizeof(*config));
204 
205     config->fifoWatermarkLevel     = 0U;
206     config->fifoWorkMode           = kDAC12_FIFODisabled;
207     config->referenceVoltageSource = kDAC12_ReferenceVoltageSourceAlt1;
208     config->fifoTriggerMode        = kDAC12_FIFOTriggerByHardwareMode;
209     config->referenceCurrentSource = kDAC12_ReferenceCurrentSourceAlt0;
210     config->speedMode              = kDAC12_SpeedLowMode;
211     config->enableAnalogBuffer     = false;
212 #if !(defined(FSL_FEATURE_DAC12_HAS_NO_ITRM_REGISTER) && FSL_FEATURE_DAC12_HAS_NO_ITRM_REGISTER)
213     config->currentReferenceInternalTrimValue = 0x4;
214 #endif /* FSL_FEATURE_DAC12_HAS_NO_ITRM_REGISTER */
215 }
216