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