1 /**
2 * @file xmc_dac.c
3 * @date 2015-06-19
4 *
5 * @cond
6 **********************************************************************************
7 * XMClib v2.1.24 - XMC Peripheral Driver Library
8 *
9 * Copyright (c) 2015-2019, Infineon Technologies AG
10 * All rights reserved.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification,are permitted provided that the following conditions are met:
14 *
15 * Redistributions of source code must retain the above copyright notice,
16 * this list of conditions and the following disclaimer.
17 *
18 * Redistributions in binary form must reproduce the above copyright notice,
19 * this list of conditions and the following disclaimer in the documentation
20 * and/or other materials provided with the distribution.
21 *
22 * Neither the name of the copyright holders nor the names of its contributors
23 * may be used to endorse or promote products derived from this software without
24 * specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
27 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
30 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 *
38 * To improve the quality of the software, users are encouraged to share
39 * modifications, enhancements or bug fixes with Infineon Technologies AG
40 * dave@infineon.com).
41 **********************************************************************************
42 *
43 * Change History
44 * --------------
45 *
46 * 2015-02-18:
47 * - Initial version
48 *
49 * 2015-06-19:
50 * - Removed GetDriverVersion API
51 * @endcond
52 *
53 */
54
55 /*******************************************************************************
56 * HEADER FILES
57 *******************************************************************************/
58
59 #include <xmc_dac.h>
60 #include <xmc_scu.h>
61
62 /* DAC peripheral is not available on XMC1X devices. */
63 #if defined(DAC)
64
65 /*******************************************************************************
66 * MACROS
67 *******************************************************************************/
68
69 #define XMC_DAC_MIN_FREQ_DIVIDER (16U)
70 #define XMC_DAC_MAX_FREQ_DIVIDER (1048576U)
71 #define XMC_DAC_DAC0PATL_PAT_BITSIZE (5U)
72
73 /*******************************************************************************
74 * API IMPLEMENTATION
75 *******************************************************************************/
76
77 /* API to enable the DAC module */
XMC_DAC_Enable(XMC_DAC_t * const dac)78 void XMC_DAC_Enable(XMC_DAC_t *const dac)
79 {
80 XMC_UNUSED_ARG(dac);
81
82 #if defined(CLOCK_GATING_SUPPORTED)
83 XMC_SCU_CLOCK_UngatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_DAC);
84 #endif
85 XMC_SCU_RESET_DeassertPeripheralReset(XMC_SCU_PERIPHERAL_RESET_DAC);
86 }
87
88 /* API to disable the DAC module */
XMC_DAC_Disable(XMC_DAC_t * const dac)89 void XMC_DAC_Disable(XMC_DAC_t *const dac)
90 {
91 XMC_UNUSED_ARG(dac);
92
93 XMC_SCU_RESET_AssertPeripheralReset(XMC_SCU_PERIPHERAL_RESET_DAC);
94 #if defined(CLOCK_GATING_SUPPORTED)
95 XMC_SCU_CLOCK_GatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_DAC);
96 #endif
97 }
98
99 /* API to check whether DAC is enabled */
XMC_DAC_IsEnabled(const XMC_DAC_t * const dac)100 bool XMC_DAC_IsEnabled(const XMC_DAC_t *const dac)
101 {
102 bool status;
103
104 XMC_UNUSED_ARG(dac);
105
106 status = XMC_SCU_RESET_IsPeripheralResetAsserted(XMC_SCU_PERIPHERAL_RESET_DAC);
107 if(status == true)
108 {
109 status = false;
110 }
111 else
112 {
113 status = true;
114 }
115 return (status);
116 }
117
118 /* API to initialize DAC channel configuration */
XMC_DAC_CH_Init(XMC_DAC_t * const dac,const uint8_t channel,const XMC_DAC_CH_CONFIG_t * const config)119 void XMC_DAC_CH_Init(XMC_DAC_t *const dac, const uint8_t channel, const XMC_DAC_CH_CONFIG_t *const config)
120 {
121 XMC_DAC_Enable(dac);
122
123 dac->DACCFG[channel].low = config->cfg0;
124 dac->DACCFG[channel].high = config->cfg1;
125 if (channel < XMC_DAC_NO_CHANNELS)
126 {
127 XMC_DAC_CH_EnableOutput(dac, channel);
128 }
129 }
130
131 /* API to set the waveform frequency except in Ramp and Pattern generation mode. */
XMC_DAC_CH_SetFrequency(XMC_DAC_t * const dac,const uint8_t channel,const uint32_t frequency)132 XMC_DAC_CH_STATUS_t XMC_DAC_CH_SetFrequency(XMC_DAC_t *const dac,
133 const uint8_t channel,
134 const uint32_t frequency)
135 {
136 uint32_t divider;
137 XMC_DAC_CH_STATUS_t status;
138
139 XMC_ASSERT("XMC_DAC_CH_SetFrequency: frequency must be greater than zero", frequency > 0U);
140
141 divider = XMC_SCU_CLOCK_GetPeripheralClockFrequency() / frequency;
142
143 if (divider < XMC_DAC_MIN_FREQ_DIVIDER)
144 {
145 status = XMC_DAC_CH_STATUS_ERROR_FREQ2HIGH;
146 }
147 else if (divider >= XMC_DAC_MAX_FREQ_DIVIDER)
148 {
149 status = XMC_DAC_CH_STATUS_ERROR_FREQ2LOW;
150 }
151 else {
152 dac->DACCFG[channel].low = (dac->DACCFG[channel].low & (uint32_t)(~DAC_DAC0CFG0_FREQ_Msk)) |
153 (divider << DAC_DAC0CFG0_FREQ_Pos);
154 status = XMC_DAC_CH_STATUS_OK;
155 }
156
157 return status;
158 }
159
160 /* API to set the waveform frequency in Ramp Mode. */
XMC_DAC_CH_SetRampFrequency(XMC_DAC_t * const dac,const uint8_t channel,const uint32_t frequency)161 XMC_DAC_CH_STATUS_t XMC_DAC_CH_SetRampFrequency(XMC_DAC_t *const dac,
162 const uint8_t channel,
163 const uint32_t frequency)
164 {
165 uint32_t stop;
166 uint32_t start;
167
168 start = dac->DACDATA[channel];
169 stop = (dac->DAC01DATA >> (channel * DAC_DAC01DATA_DATA1_Pos)) & (uint32_t)DAC_DAC01DATA_DATA0_Msk;
170
171 return XMC_DAC_CH_SetFrequency(dac, channel, frequency * ((stop - start) + 1U));
172 }
173
174 /* API to start the operation in Single Value Mode. */
XMC_DAC_CH_StartSingleValueMode(XMC_DAC_t * const dac,const uint8_t channel)175 XMC_DAC_CH_STATUS_t XMC_DAC_CH_StartSingleValueMode(XMC_DAC_t *const dac, const uint8_t channel)
176 {
177 XMC_ASSERT("XMC_DAC_CH_StartSingleValueMode: dac parameter not valid\n", XMC_DAC_IS_DAC_VALID(dac));
178 XMC_ASSERT("XMC_DAC_CH_StartSingleValueMode: channel parameter not valid\n", XMC_DAC_IS_CHANNEL_VALID(channel));
179 XMC_ASSERT("XMC_DAC_CH_StartSingleValueMode: dac module not enabled\n", XMC_DAC_IsEnabled(dac));
180
181 XMC_DAC_CH_SetMode(dac, channel, XMC_DAC_CH_MODE_SINGLE);
182
183 return XMC_DAC_CH_STATUS_OK;
184 }
185
186 /* API to start the operation in Data Mode. */
XMC_DAC_CH_StartDataMode(XMC_DAC_t * const dac,const uint8_t channel,const XMC_DAC_CH_TRIGGER_t trigger,const uint32_t frequency)187 XMC_DAC_CH_STATUS_t XMC_DAC_CH_StartDataMode(XMC_DAC_t *const dac,
188 const uint8_t channel,
189 const XMC_DAC_CH_TRIGGER_t trigger,
190 const uint32_t frequency)
191 {
192 XMC_DAC_CH_STATUS_t status = XMC_DAC_CH_STATUS_OK;
193
194 XMC_ASSERT("XMC_DAC_CH_StartDataMode: dac parameter not valid\n", XMC_DAC_IS_DAC_VALID(dac));
195 XMC_ASSERT("XMC_DAC_CH_StartDataMode: channel parameter not valid\n", XMC_DAC_IS_CHANNEL_VALID(channel));
196 XMC_ASSERT("XMC_DAC_CH_StartDataMode: dac module not enabled\n", XMC_DAC_IsEnabled(dac));
197
198 XMC_DAC_CH_SetMode(dac, channel, XMC_DAC_CH_MODE_IDLE);
199
200 if (trigger == XMC_DAC_CH_TRIGGER_INTERNAL)
201 {
202 status = XMC_DAC_CH_SetFrequency(dac, channel, frequency);
203 }
204
205 if (status == XMC_DAC_CH_STATUS_OK)
206 {
207 XMC_DAC_CH_SetTrigger(dac, channel, trigger);
208 XMC_DAC_CH_SetMode(dac, channel, XMC_DAC_CH_MODE_DATA);
209 }
210
211 return status;
212 }
213
214 /* API to start the operation in Ramp Mode. */
XMC_DAC_CH_StartRampMode(XMC_DAC_t * const dac,const uint8_t channel,const uint16_t start,const uint16_t stop,const XMC_DAC_CH_TRIGGER_t trigger,const uint32_t frequency)215 XMC_DAC_CH_STATUS_t XMC_DAC_CH_StartRampMode(XMC_DAC_t *const dac,
216 const uint8_t channel,
217 const uint16_t start,
218 const uint16_t stop,
219 const XMC_DAC_CH_TRIGGER_t trigger,
220 const uint32_t frequency)
221 {
222 XMC_DAC_CH_STATUS_t status = XMC_DAC_CH_STATUS_OK;
223
224 XMC_ASSERT("XMC_DAC_CH_StartRampMode: dac parameter not valid\n", XMC_DAC_IS_DAC_VALID(dac));
225 XMC_ASSERT("XMC_DAC_CH_StartRampMode: channel parameter not valid\n", XMC_DAC_IS_CHANNEL_VALID(channel));
226 XMC_ASSERT("XMC_DAC_CH_StartRampMode: dac module not enabled\n", XMC_DAC_IsEnabled(dac));
227
228 XMC_DAC_CH_SetMode(dac, channel, XMC_DAC_CH_MODE_IDLE);
229
230 XMC_DAC_CH_SetRampStart(dac, channel, start);
231 XMC_DAC_CH_SetRampStop(dac, channel, stop);
232 XMC_DAC_CH_SetTrigger(dac, channel, trigger);
233
234 if (trigger == XMC_DAC_CH_TRIGGER_INTERNAL)
235 {
236 status = XMC_DAC_CH_SetRampFrequency(dac, channel, frequency);
237 }
238
239 if (status == XMC_DAC_CH_STATUS_OK)
240 {
241 XMC_DAC_CH_SetMode(dac, channel, XMC_DAC_CH_MODE_RAMP);
242 }
243
244 return status;
245 }
246
247 /* API to start the operation in Pattern Mode. */
XMC_DAC_CH_StartPatternMode(XMC_DAC_t * const dac,const uint8_t channel,const uint8_t * const pattern,const XMC_DAC_CH_PATTERN_SIGN_OUTPUT_t sign_output,const XMC_DAC_CH_TRIGGER_t trigger,const uint32_t frequency)248 XMC_DAC_CH_STATUS_t XMC_DAC_CH_StartPatternMode(XMC_DAC_t *const dac,
249 const uint8_t channel,
250 const uint8_t *const pattern,
251 const XMC_DAC_CH_PATTERN_SIGN_OUTPUT_t sign_output,
252 const XMC_DAC_CH_TRIGGER_t trigger,
253 const uint32_t frequency)
254 {
255 XMC_DAC_CH_STATUS_t status = XMC_DAC_CH_STATUS_OK;
256
257 XMC_ASSERT("XMC_DAC_CH_StartPatternMode: dac parameter not valid\n", XMC_DAC_IS_DAC_VALID(dac));
258 XMC_ASSERT("XMC_DAC_CH_StartPatternMode: channel parameter not valid\n", XMC_DAC_IS_CHANNEL_VALID(channel));
259 XMC_ASSERT("XMC_DAC_CH_StartPatternMode: dac module not enabled\n", XMC_DAC_IsEnabled(dac));
260
261 XMC_DAC_CH_SetMode(dac, channel, XMC_DAC_CH_MODE_IDLE);
262
263 if (trigger == XMC_DAC_CH_TRIGGER_INTERNAL)
264 {
265 status = XMC_DAC_CH_SetFrequency(dac, channel, frequency * XMC_DAC_SAMPLES_PER_PERIOD);
266 }
267
268 if (status == XMC_DAC_CH_STATUS_OK)
269 {
270 XMC_DAC_CH_SetPattern(dac, channel, pattern);
271 if (XMC_DAC_CH_PATTERN_SIGN_OUTPUT_ENABLED == sign_output)
272 {
273 XMC_DAC_CH_EnablePatternSignOutput(dac, channel);
274 }
275 else
276 {
277 XMC_DAC_CH_DisablePatternSignOutput(dac, channel);
278 }
279 XMC_DAC_CH_SetTrigger(dac, channel, trigger);
280 XMC_DAC_CH_SetMode(dac, channel, XMC_DAC_CH_MODE_PATTERN);
281 }
282
283 return status;
284 }
285
286 /* API to start the operation in Noise Mode. */
XMC_DAC_CH_StartNoiseMode(XMC_DAC_t * const dac,const uint8_t channel,const XMC_DAC_CH_TRIGGER_t trigger,const uint32_t frequency)287 XMC_DAC_CH_STATUS_t XMC_DAC_CH_StartNoiseMode(XMC_DAC_t *const dac,
288 const uint8_t channel,
289 const XMC_DAC_CH_TRIGGER_t trigger,
290 const uint32_t frequency)
291 {
292 XMC_DAC_CH_STATUS_t status = XMC_DAC_CH_STATUS_OK;
293
294 XMC_ASSERT("XMC_DAC_CH_StartNoiseMode: dac parameter not valid\n", XMC_DAC_IS_DAC_VALID(dac));
295 XMC_ASSERT("XMC_DAC_CH_StartNoiseMode: channel parameter not valid\n", XMC_DAC_IS_CHANNEL_VALID(channel));
296 XMC_ASSERT("XMC_DAC_CH_StartNoiseMode: dac module not enabled\n", XMC_DAC_IsEnabled(dac));
297
298 XMC_DAC_CH_SetMode(dac, channel, XMC_DAC_CH_MODE_IDLE);
299
300 if (trigger == XMC_DAC_CH_TRIGGER_INTERNAL)
301 {
302 status = XMC_DAC_CH_SetFrequency(dac, channel, frequency);
303 }
304
305 if (status == XMC_DAC_CH_STATUS_OK)
306 {
307 XMC_DAC_CH_SetTrigger(dac, channel, trigger);
308 XMC_DAC_CH_SetMode(dac, channel, XMC_DAC_CH_MODE_NOISE);
309 }
310
311 return status;
312 }
313
314 /* API to write the pattern data table. */
XMC_DAC_CH_SetPattern(XMC_DAC_t * const dac,uint8_t channel,const uint8_t * const data)315 void XMC_DAC_CH_SetPattern(XMC_DAC_t *const dac, uint8_t channel, const uint8_t *const data)
316 {
317 uint32_t index;
318 uint32_t temp;
319
320 XMC_ASSERT("XMC_DAC_CH_SetPattern: dac parameter not valid\n", XMC_DAC_IS_DAC_VALID(dac));
321 XMC_ASSERT("XMC_DAC_CH_SetPattern: channel parameter not valid\n", XMC_DAC_IS_CHANNEL_VALID(channel));
322 XMC_ASSERT("XMC_DAC_CH_SetPattern: dac module not enabled\n", XMC_DAC_IsEnabled(dac));
323
324 temp = data[0U];
325 for(index = 1U; index < 6U; ++index)
326 {
327 temp |= (uint32_t)data[index] << (index * XMC_DAC_DAC0PATL_PAT_BITSIZE);
328 }
329 dac->DACPAT[channel].low = temp;
330
331 temp = data[6U];
332 for(index = 1U; index < 6U; ++index)
333 {
334 temp |= (uint32_t)data[index + 6U] << (index * XMC_DAC_DAC0PATL_PAT_BITSIZE);
335 }
336 dac->DACPAT[channel].high = temp;
337 }
338
339 #endif /* defined(DAC) */
340