1 /******************************************************************************
2 * Filename: aux_dac.c
3 *
4 * Description: Driver for the AUX Digital-to-Analog Converter interface.
5 *
6 * Copyright (c) 2015 - 2022, Texas Instruments Incorporated
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 * 1) Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 *
15 * 2) Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 *
19 * 3) Neither the name of the ORGANIZATION nor the names of its contributors may
20 * be used to endorse or promote products derived from this software without
21 * specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 *
35 ******************************************************************************/
36 #include "aux_dac.h"
37
38
39 //*****************************************************************************
40 //
41 // Sets the DAC's voltage reference
42 //
43 //*****************************************************************************
44 void
AUXDACSetVref(uint8_t refSource)45 AUXDACSetVref(uint8_t refSource)
46 {
47 HWREGB(AUX_ADI4_BASE + ADI_4_AUX_O_MUX2) = refSource;
48
49 if(refSource == AUXDAC_VREF_SEL_ADCREF)
50 {
51 // Enable the ADC reference module.
52 HWREGB(AUX_ADI4_BASE + ADI_4_AUX_O_ADCREF0) |= ADI_4_AUX_ADCREF0_REF_ON_IDLE | ADI_4_AUX_ADCREF0_EN;
53 }
54 }
55
56 //*****************************************************************************
57 //
58 // Enables precharge
59 //
60 //*****************************************************************************
61 void
AUXDACEnablePreCharge(void)62 AUXDACEnablePreCharge(void)
63 {
64 HWREG(AUX_ANAIF_BASE + AUX_ANAIF_O_DACCTL) |= AUX_ANAIF_DACCTL_DAC_PRECHARGE_EN;
65 }
66
67 //*****************************************************************************
68 //
69 // Disables precharge
70 //
71 //*****************************************************************************
72 void
AUXDACDisablePreCharge(void)73 AUXDACDisablePreCharge(void)
74 {
75 HWREG(AUX_ANAIF_BASE + AUX_ANAIF_O_DACCTL) &= ~(0x1 << AUX_ANAIF_DACCTL_DAC_PRECHARGE_EN_S);
76 }
77
78 //*****************************************************************************
79 //
80 // Returns maximum DAC voltage in uV
81 //
82 //*****************************************************************************
83 uint32_t
AUXDACCalcMax(void)84 AUXDACCalcMax(void)
85 {
86 uint32_t prechargeStatus;
87 uint32_t refSource;
88 uint32_t dacMax;
89
90 // Depending on the selected DAC voltage reference, obtain calibration value C2 in millivolts.
91 refSource = ((HWREGB(AUX_ADI4_BASE + ADI_4_AUX_O_MUX2) & ADI_4_AUX_MUX2_DAC_VREF_SEL_M) >> ADI_4_AUX_MUX2_DAC_VREF_SEL_S);
92
93 switch (refSource)
94 {
95 // Nothing connected. Input is floating.
96 case AUXDAC_VREF_SEL_NC:
97
98 dacMax = 0;
99 break;
100
101 // Core Voltage Decoupling pin as the DAC's voltage reference source.
102 case AUXDAC_VREF_SEL_DCOUPL:
103
104 prechargeStatus = ((HWREG( AUX_ANAIF_BASE + AUX_ANAIF_O_DACCTL) & AUX_ANAIF_DACCTL_DAC_PRECHARGE_EN_M) >> AUX_ANAIF_DACCTL_DAC_PRECHARGE_EN_S);
105 dacMax = (prechargeStatus == 0) ? ((HWREG(FCFG1_BASE + FCFG1_O_DAC_CAL0) & FCFG1_DAC_CAL0_SOC_DAC_VOUT_CAL_DECOUPLE_C2_M) >> FCFG1_DAC_CAL0_SOC_DAC_VOUT_CAL_DECOUPLE_C2_S) \
106 : ((HWREG(FCFG1_BASE + FCFG1_O_DAC_CAL1) & FCFG1_DAC_CAL1_SOC_DAC_VOUT_CAL_PRECH_C2_M) >> FCFG1_DAC_CAL1_SOC_DAC_VOUT_CAL_PRECH_C2_S);
107 break;
108
109 // ADC reference voltage as the DAC's voltage reference source.
110 case AUXDAC_VREF_SEL_ADCREF:
111
112 dacMax = ((HWREG(FCFG1_BASE + FCFG1_O_DAC_CAL2) & FCFG1_DAC_CAL2_SOC_DAC_VOUT_CAL_ADCREF_C2_M) >> FCFG1_DAC_CAL2_SOC_DAC_VOUT_CAL_ADCREF_C2_S);
113 break;
114
115 // Main supply voltage VDDS as the DAC's voltage reference source.
116 case AUXDAC_VREF_SEL_VDDS:
117
118 // Note: The calibration value is measured at a VDDS of 3.0V. If VDDS is selected as reference,
119 // measure VDDS and scale the calibration value.
120 dacMax = ((HWREG(FCFG1_BASE + FCFG1_O_DAC_CAL3) & FCFG1_DAC_CAL3_SOC_DAC_VOUT_CAL_VDDS_C2_M) >> FCFG1_DAC_CAL3_SOC_DAC_VOUT_CAL_VDDS_C2_S);
121 break;
122
123 // Nothing connected. Input is floating.
124 default:
125
126 dacMax = 0;
127 }
128
129 return dacMax;
130 }
131
132 //*****************************************************************************
133 //
134 // Returns minimum DAC voltage in uV
135 //
136 //*****************************************************************************
137 uint32_t
AUXDACCalcMin(void)138 AUXDACCalcMin(void)
139 {
140 uint32_t refSource;
141 uint32_t prechargeStatus;
142 uint32_t dacMin;
143
144 // Depending on the selected DAC voltage reference, obtain calibration value C1 in millivolts.
145 refSource = ((HWREGB(AUX_ADI4_BASE + ADI_4_AUX_O_MUX2) & ADI_4_AUX_MUX2_DAC_VREF_SEL_M) >> ADI_4_AUX_MUX2_DAC_VREF_SEL_S);
146
147 switch (refSource)
148 {
149 // Nothing connected. Input is floating.
150 case AUXDAC_VREF_SEL_NC:
151 dacMin = 0;
152 break;
153
154 // Core Voltage Decoupling pin as the DAC's voltage reference source.
155 case AUXDAC_VREF_SEL_DCOUPL:
156
157 prechargeStatus = ((HWREG(AUX_ANAIF_BASE + AUX_ANAIF_O_DACCTL) & AUX_ANAIF_DACCTL_DAC_PRECHARGE_EN_M) >> AUX_ANAIF_DACCTL_DAC_PRECHARGE_EN_S);
158 dacMin = (prechargeStatus == 0) ? ((HWREG(FCFG1_BASE + FCFG1_O_DAC_CAL0) & FCFG1_DAC_CAL0_SOC_DAC_VOUT_CAL_DECOUPLE_C1_M) >> FCFG1_DAC_CAL0_SOC_DAC_VOUT_CAL_DECOUPLE_C1_S) \
159 : ((HWREG(FCFG1_BASE + FCFG1_O_DAC_CAL1) & FCFG1_DAC_CAL1_SOC_DAC_VOUT_CAL_PRECH_C1_M) >> FCFG1_DAC_CAL1_SOC_DAC_VOUT_CAL_PRECH_C1_S);
160 break;
161
162 // ADC reference voltage as the DAC's voltage reference source.
163 case AUXDAC_VREF_SEL_ADCREF:
164 dacMin = ((HWREG( FCFG1_BASE + FCFG1_O_DAC_CAL2) & FCFG1_DAC_CAL2_SOC_DAC_VOUT_CAL_ADCREF_C1_M) >> FCFG1_DAC_CAL2_SOC_DAC_VOUT_CAL_ADCREF_C1_S);
165 break;
166
167 // Main supply voltage VDDS as the DAC's voltage reference source.
168 case AUXDAC_VREF_SEL_VDDS:
169 dacMin = ((HWREG( FCFG1_BASE + FCFG1_O_DAC_CAL3) & FCFG1_DAC_CAL3_SOC_DAC_VOUT_CAL_VDDS_C1_M) >> FCFG1_DAC_CAL3_SOC_DAC_VOUT_CAL_VDDS_C1_S);
170 break;
171
172 // Nothing connected. Input is floating.
173 default:
174
175 dacMin = 0;
176 }
177
178 return dacMin;
179 }
180
181 //*****************************************************************************
182 //
183 // Returns 8-bit DAC code from requested voltage in (uV)
184 //
185 //*****************************************************************************
186 uint32_t
AUXDACCalcCode(uint32_t uVoltOut,uint32_t uVoltOutMin,uint32_t uVoltOutMax)187 AUXDACCalcCode(uint32_t uVoltOut, uint32_t uVoltOutMin, uint32_t uVoltOutMax)
188 {
189 uint32_t dacCode = 0;
190
191 if(uVoltOut != 0)
192 {
193 // Rounding (by adding 0.5 before truncating)
194 dacCode = (((254 * (uVoltOut - uVoltOutMin) * 2) / (uVoltOutMax - uVoltOutMin) + 1) / 2) + 1;
195 }
196 return (uint32_t)dacCode;
197 }
198
199 //*****************************************************************************
200 //
201 // Sets the DAC sample clock
202 //
203 //*****************************************************************************
204 void
AUXDACSetSampleClock(uint8_t dacClkDiv)205 AUXDACSetSampleClock(uint8_t dacClkDiv)
206 {
207
208 // Set the peripheral operational rate to the AUX bus rate of 24 MHz.
209 HWREGB(AUX_SYSIF_BASE + AUX_SYSIF_O_PEROPRATE) |= AUX_SYSIF_PEROPRATE_ANAIF_DAC_OP_RATE_BUS_RATE;
210
211 // Set sample clock frequency considering a clock base frequency of 24 MHz and the given clock divider.
212 HWREGB(AUX_ANAIF_BASE + AUX_ANAIF_O_DACSMPLCFG0) = dacClkDiv;
213 }
214
215 //*****************************************************************************
216 //
217 // Sets the DAC's code
218 //
219 //*****************************************************************************
220 void
AUXDACSetCode(uint8_t dacCode)221 AUXDACSetCode(uint8_t dacCode)
222 {
223 // Update the DAC's output value.
224 HWREGB(AUX_ANAIF_BASE + AUX_ANAIF_O_DACVALUE) = dacCode;
225 }
226
227 //*****************************************************************************
228 //
229 // Enables the DAC
230 //
231 //*****************************************************************************
232 void
AUXDACEnable(uint8_t dacPinId)233 AUXDACEnable(uint8_t dacPinId)
234 {
235 // Set the operational mode to active
236 HWREG(AUX_SYSIF_BASE + AUX_SYSIF_O_OPMODEREQ) = AUX_SYSIF_OPMODEREQ_REQ_A;
237
238 // Disable the low power bias control
239 HWREGB(AUX_ANAIF_BASE + AUX_ANAIF_O_LPMBIASCTL) = 0x0;
240
241 // Enable the DAC sample clock
242 HWREGB(AUX_ANAIF_BASE + AUX_ANAIF_O_DACSMPLCTL) = AUX_ANAIF_DACSMPLCTL_EN;
243
244 // Enable DAC and buffer and set COMPA_IN
245 HWREGB(AUX_ANAIF_BASE + AUX_ANAIF_O_DACCTL) |= AUX_ANAIF_DACCTL_DAC_EN | AUX_ANAIF_DACCTL_DAC_BUFFER_EN | AUX_ANAIF_DACCTL_DAC_VOUT_SEL_COMPA_IN;
246
247 // Select COMPA output (0 will disconnect from DIOs)
248 HWREGB(AUX_ADI4_BASE + ADI_4_AUX_O_MUX1) = dacPinId;
249 }
250
251 //*****************************************************************************
252 //
253 // Disables the DAC
254 //
255 //*****************************************************************************
256 void
AUXDACDisable(void)257 AUXDACDisable(void)
258 {
259 // Disable the DAC sample clock
260 HWREGB(AUX_ANAIF_BASE + AUX_ANAIF_O_DACSMPLCTL) = 0x0;
261
262 // Disable DAC, the DAC's buffer, and disconnect internally.
263 HWREGB(AUX_ANAIF_BASE + AUX_ANAIF_O_DACCTL) &= ~(0x1 << AUX_ANAIF_DACCTL_DAC_EN_S) & \
264 ~(0x1 << AUX_ANAIF_DACCTL_DAC_BUFFER_EN_S) & \
265 ~(AUX_ANAIF_DACCTL_DAC_VOUT_SEL_M << AUX_ANAIF_DACCTL_DAC_VOUT_SEL_S);
266
267 // Disconnect COMPA_IN from DIOs
268 HWREGB(AUX_ADI4_BASE + ADI_4_AUX_O_MUX1) = 0x0;
269
270 // Set operational mode to Power-Down
271 HWREG(AUX_SYSIF_BASE + AUX_SYSIF_O_OPMODEREQ) = AUX_SYSIF_OPMODEREQ_REQ_PDA;
272
273 // Set the peripheral operational rate to the SCE rate
274 HWREGB(AUX_SYSIF_BASE + AUX_SYSIF_O_PEROPRATE) = AUX_SYSIF_PEROPRATE_ANAIF_DAC_OP_RATE_SCE_RATE;
275 }
276