1 /**
2 * @file xmc_dsd.c
3 * @date 2019-05-07
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-03-30:
47 * - Initial version
48 *
49 * 2015-06-19:
50 * - Removed GetDriverVersion API <BR>
51 *
52 * 2015-09-18:
53 * - Support added for XMC4800 microcontroller family <BR>
54 *
55 * 2019-05-07:
56 * - Fixed compilation warnings
57 *
58 * @endcond
59 *
60 */
61
62 /*********************************************************************************************************************
63 * HEADER FILES
64 ********************************************************************************************************************/
65 #include "xmc_dsd.h"
66
67 #if defined(DSD)
68
69 /*********************************************************************************************************************
70 * MACROS
71 ********************************************************************************************************************/
72
73 #define XMC_DSD_MIN_FILTER_START (4U)
74 #define XMC_DSD_MIN_DECIMATION_FACTOR (4U)
75 #define XMC_DSD_MAX_DECIMATION_FACTOR (256U)
76 #define XMC_DSD_MAX_DECIMATION_FACTOR_AUX (32U)
77
78 /*********************************************************************************************************************
79 * API IMPLEMENTATION
80 ********************************************************************************************************************/
81
82 /*Enable the DSD Module*/
XMC_DSD_Enable(XMC_DSD_t * const dsd)83 void XMC_DSD_Enable(XMC_DSD_t *const dsd)
84 {
85 XMC_ASSERT("XMC_DSD_Enable:Invalid module pointer", XMC_DSD_CHECK_MODULE_PTR(dsd));
86 XMC_UNUSED_ARG(dsd);
87
88 #if defined(CLOCK_GATING_SUPPORTED)
89 XMC_SCU_CLOCK_UngatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_DSD);
90 #endif
91 XMC_SCU_RESET_DeassertPeripheralReset(XMC_SCU_PERIPHERAL_RESET_DSD);
92 }
93
94 /*Disable the DSD Module*/
XMC_DSD_Disable(XMC_DSD_t * const dsd)95 void XMC_DSD_Disable(XMC_DSD_t *const dsd)
96 {
97 XMC_ASSERT("XMC_DSD_Disable:Invalid module pointer", XMC_DSD_CHECK_MODULE_PTR(dsd));
98 XMC_UNUSED_ARG(dsd);
99
100 XMC_SCU_RESET_AssertPeripheralReset(XMC_SCU_PERIPHERAL_RESET_DSD);
101 #if defined(CLOCK_GATING_SUPPORTED)
102 XMC_SCU_CLOCK_GatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_DSD);
103 #endif
104 }
105
106 /* Enable the module clock*/
XMC_DSD_EnableClock(XMC_DSD_t * const dsd)107 void XMC_DSD_EnableClock(XMC_DSD_t *const dsd)
108 {
109 XMC_ASSERT("XMC_DSD_EnableClock:Invalid module pointer", XMC_DSD_CHECK_MODULE_PTR(dsd));
110 /* Enable the module clock */
111 dsd->CLC &= ~(uint32_t)DSD_CLC_DISR_Msk;
112 /* enable internal module clock */
113 dsd ->GLOBCFG |= (uint32_t)0x01;
114 }
115
XMC_DSD_DisableClock(XMC_DSD_t * const dsd)116 void XMC_DSD_DisableClock(XMC_DSD_t *const dsd)
117 {
118 XMC_ASSERT("XMC_DSD_DisableClock:Invalid module pointer", XMC_DSD_CHECK_MODULE_PTR(dsd));
119
120 /* disable internal module clock */
121 dsd->GLOBCFG &= ~(uint32_t)DSD_GLOBCFG_MCSEL_Msk;
122
123 /* stop the module clock */
124 dsd->CLC |= (uint32_t)DSD_CLC_DISR_Msk;
125
126 }
127
128 /* Enable the DSD module and clock */
XMC_DSD_Init(XMC_DSD_t * const dsd)129 void XMC_DSD_Init(XMC_DSD_t *const dsd)
130 {
131 XMC_ASSERT("XMC_DSD_Init:Invalid module pointer", XMC_DSD_CHECK_MODULE_PTR(dsd));
132 XMC_DSD_Enable(dsd);
133 XMC_DSD_EnableClock(dsd);
134 }
135
XMC_DSD_IsEnabled(XMC_DSD_t * const dsd)136 bool XMC_DSD_IsEnabled(XMC_DSD_t *const dsd)
137 {
138 bool status;
139 XMC_ASSERT("XMC_DSD_Disable:Invalid module pointer", XMC_DSD_CHECK_MODULE_PTR(dsd));
140 XMC_UNUSED_ARG(dsd);
141
142 #if ((UC_SERIES == XMC44) || (UC_SERIES == XMC48)||(UC_SERIES == XMC47))
143 if(XMC_SCU_RESET_IsPeripheralResetAsserted(XMC_SCU_PERIPHERAL_RESET_DSD) == false)
144 {
145 if(XMC_SCU_CLOCK_IsPeripheralClockGated(XMC_SCU_PERIPHERAL_CLOCK_DSD) == false)
146 {
147 status = true;
148 }
149 else
150 {
151 status = false;
152 }
153 }
154 else
155 {
156 status = false;
157 }
158 #else
159 if(XMC_SCU_RESET_IsPeripheralResetAsserted(XMC_SCU_PERIPHERAL_RESET_DSD) == false)
160 {
161 status = true;
162 }
163 else
164 {
165 status = false;
166 }
167 #endif
168
169 return (status);
170 }
171
172 /*Initializes the Waveform Generator*/
XMC_DSD_Generator_Init(XMC_DSD_t * const dsd,const XMC_DSD_GENERATOR_CONFIG_t * const config)173 void XMC_DSD_Generator_Init(XMC_DSD_t *const dsd, const XMC_DSD_GENERATOR_CONFIG_t *const config)
174 {
175 XMC_ASSERT("XMC_DSD_GENERATOR_Init:Invalid module pointer", XMC_DSD_CHECK_MODULE_PTR(dsd));
176 XMC_ASSERT("XMC_DSD_GENERATOR_Init:NULL Pointer", (config != (XMC_DSD_GENERATOR_CONFIG_t *)NULL) );
177 /* Reset Generator */
178 dsd ->CGCFG &= ~((uint32_t)DSD_CGCFG_CGMOD_Msk | (uint32_t)DSD_CGCFG_BREV_Msk | (uint32_t)DSD_CGCFG_SIGPOL_Msk | (uint32_t)DSD_CGCFG_DIVCG_Msk);
179
180 /* Generator configuration */
181 dsd ->CGCFG = config->generator_conf;
182 }
183
184 /* Initialize main filter,auxiliary filter,integrator, rectifier and timestamp of DSD*/
XMC_DSD_CH_Init(XMC_DSD_CH_t * const channel,const XMC_DSD_CH_CONFIG_t * const config)185 XMC_DSD_STATUS_t XMC_DSD_CH_Init( XMC_DSD_CH_t *const channel, const XMC_DSD_CH_CONFIG_t *const config)
186 {
187 XMC_DSD_STATUS_t status;
188
189 XMC_ASSERT("XMC_DSD_CH_Init:Invalid module pointer", XMC_DSD_CHECK_CHANNEL_PTR(channel));
190 XMC_ASSERT("XMC_DSD_CH_Init:NULL Pointer", (config != (XMC_DSD_CH_CONFIG_t *)NULL) );
191
192 if (config->filter != (XMC_DSD_CH_FILTER_CONFIG_t*)NULL)
193 {
194 XMC_DSD_CH_MainFilter_Init(channel, config->filter);
195
196 if (config->aux != (XMC_DSD_CH_AUX_FILTER_CONFIG_t*)NULL)
197 {
198 XMC_DSD_CH_AuxFilter_Init(channel, config->aux);
199 }
200 if (config->integrator != (XMC_DSD_CH_INTEGRATOR_CONFIG_t*)NULL)
201 {
202 XMC_DSD_CH_Integrator_Init(channel, config->integrator);
203 }
204 if (config->rectify != (XMC_DSD_CH_RECTIFY_CONFIG_t*)NULL)
205 {
206 XMC_DSD_CH_Rectify_Init(channel, config->rectify);
207 }
208 if (config->timestamp != (XMC_DSD_CH_TIMESTAMP_CONFIG_t*)NULL)
209 {
210 XMC_DSD_CH_Timestamp_Init(channel, config->timestamp);
211 }
212 status = XMC_DSD_STATUS_OK;
213 }
214 else
215 {
216 status = XMC_DSD_STATUS_ERROR;
217 }
218 return (status);
219
220 }
221
222 /* Initialize main filter of DSD */
XMC_DSD_CH_MainFilter_Init(XMC_DSD_CH_t * const channel,const XMC_DSD_CH_FILTER_CONFIG_t * const config)223 void XMC_DSD_CH_MainFilter_Init(XMC_DSD_CH_t *const channel, const XMC_DSD_CH_FILTER_CONFIG_t *const config)
224 {
225 uint32_t decimation_factor_temp;
226 uint32_t filter_start_value_temp;
227
228 XMC_ASSERT("XMC_DSD_MAIN_FILTER_Init:Invalid module pointer", XMC_DSD_CHECK_CHANNEL_PTR(channel));
229 XMC_ASSERT("XMC_DSD_MAIN_FILTER_Init:NULL Pointer", (config != (XMC_DSD_CH_FILTER_CONFIG_t *)NULL) );
230 XMC_ASSERT("XMC_DSD_MAIN_FILTER_Init:Invalid Filter Start Value", (config->filter_start_value >= XMC_DSD_MIN_FILTER_START));
231 XMC_ASSERT("XMC_DSD_MAIN_FILTER_Init:Invalid Filter Start Value", (config->filter_start_value <= config->decimation_factor));
232 XMC_ASSERT("XMC_DSD_MAIN_FILTER_Init:Invalid Decimation Factor",
233 ((config->decimation_factor >= XMC_DSD_MIN_DECIMATION_FACTOR) && (config->decimation_factor <= XMC_DSD_MAX_DECIMATION_FACTOR)));
234
235 /*Set Channel frequency*/
236 channel->MODCFG = ((uint32_t)config->clock_divider << DSD_CH_MODCFG_DIVM_Pos) | (uint32_t)DSD_CH_MODCFG_DWC_Msk;
237
238 /* Input Data/Clk */
239 channel->DICFG = config->demodulator_conf | (uint32_t)DSD_CH_DICFG_DSWC_Msk | (uint32_t)DSD_CH_DICFG_SCWC_Msk;
240
241 /*The decimation factor of the Main CIC filter is CFMDF + 1.*/
242 decimation_factor_temp = config->decimation_factor-1U;
243 filter_start_value_temp = config->filter_start_value-1U;
244
245 /* Filter setup*/
246 channel->FCFGC = (decimation_factor_temp |
247 (filter_start_value_temp << (uint32_t)DSD_CH_FCFGC_CFMSV_Pos)|
248 config->main_filter_conf|
249 (uint32_t)DSD_CH_FCFGC_CFEN_Msk);
250
251 /* Offset */
252 channel->OFFM = (uint16_t)config->offset;
253 }
254
255 /* Initialize timestamp mode of DSD */
XMC_DSD_CH_Timestamp_Init(XMC_DSD_CH_t * const channel,const XMC_DSD_CH_TIMESTAMP_CONFIG_t * const config)256 void XMC_DSD_CH_Timestamp_Init(XMC_DSD_CH_t *const channel, const XMC_DSD_CH_TIMESTAMP_CONFIG_t *const config)
257 {
258 uint32_t temp;
259 XMC_ASSERT("XMC_DSD_MAIN_FILTER_Init:Invalid module pointer", XMC_DSD_CHECK_CHANNEL_PTR(channel));
260 XMC_ASSERT("XMC_DSD_MAIN_FILTER_Init:NULL Pointer", (config != (XMC_DSD_CH_TIMESTAMP_CONFIG_t *)NULL) );
261
262 temp = (channel->DICFG | (uint32_t)DSD_CH_DICFG_TRWC_Msk);
263 temp &= ~((uint32_t)DSD_CH_DICFG_TSTRMODE_Msk|(uint32_t)DSD_CH_DICFG_TRSEL_Msk);
264 temp |= config->timestamp_conf;
265 channel->DICFG = temp;
266 }
267
268 /* Initialize auxiliary filter of DSD */
XMC_DSD_CH_AuxFilter_Init(XMC_DSD_CH_t * const channel,const XMC_DSD_CH_AUX_FILTER_CONFIG_t * const config)269 void XMC_DSD_CH_AuxFilter_Init(XMC_DSD_CH_t *const channel, const XMC_DSD_CH_AUX_FILTER_CONFIG_t *const config)
270 {
271 uint32_t decimation_factor_temp;
272
273 XMC_ASSERT("XMC_DSD_AUX_FILTER_Init:Invalid module pointer", XMC_DSD_CHECK_CHANNEL_PTR(channel));
274 XMC_ASSERT("XMC_DSD_AUX_FILTER_Init:NULL Pointer", (config != (XMC_DSD_CH_AUX_FILTER_CONFIG_t *)NULL) );
275 XMC_ASSERT("XMC_DSD_AUX_FILTER_Init:Invalid Decimation Factor",
276 ((config->decimation_factor >= XMC_DSD_MIN_DECIMATION_FACTOR) && (config->decimation_factor <= XMC_DSD_MAX_DECIMATION_FACTOR_AUX)));
277
278 channel->BOUNDSEL = config->boundary_conf;
279 /*The decimation factor of the Aux CIC filter is CFMDF + 1.*/
280 decimation_factor_temp = config->decimation_factor-1U;
281 channel->FCFGA = (decimation_factor_temp | config->aux_filter_conf);
282 }
283
284 /* Integrator initialization of DSD */
XMC_DSD_CH_Integrator_Init(XMC_DSD_CH_t * const channel,const XMC_DSD_CH_INTEGRATOR_CONFIG_t * const config)285 void XMC_DSD_CH_Integrator_Init(XMC_DSD_CH_t *const channel, const XMC_DSD_CH_INTEGRATOR_CONFIG_t *const config)
286 {
287 uint32_t temp;
288 XMC_ASSERT("XMC_DSD_INTEGRATOR_Init:Invalid module pointer", XMC_DSD_CHECK_CHANNEL_PTR(channel));
289 XMC_ASSERT("XMC_DSD_INTEGRATOR_Init:NULL Pointer", (config != (XMC_DSD_CH_INTEGRATOR_CONFIG_t *)NULL) );
290 XMC_ASSERT("XMC_DSD_INTEGRATOR_Init:Invalid integration_loop", (config->integration_loop > 0U ));
291 XMC_ASSERT("XMC_DSD_INTEGRATOR_Init:Invalid counted_values", (config->counted_values > 0U ));
292
293 channel->IWCTR = ((config->integration_loop - 1U) << DSD_CH_IWCTR_REPVAL_Pos)
294 | (config->discarded_values << DSD_CH_IWCTR_NVALDIS_Pos)
295 | (config->stop_condition << DSD_CH_IWCTR_IWS_Pos)
296 | ((config->counted_values - 1U) << DSD_CH_IWCTR_NVALINT_Pos);
297
298 /*To ensure proper operation, ensure that bit field ITRMODE is zero before selecting any other trigger mode.*/
299 temp = (channel->DICFG & ~((uint32_t)DSD_CH_DICFG_ITRMODE_Msk|(uint32_t)DSD_CH_DICFG_TRSEL_Msk)) | (uint32_t)DSD_CH_DICFG_TRWC_Msk;
300
301 channel->DICFG = temp;
302
303 temp |= config->integrator_trigger;
304 channel->DICFG = temp;
305 }
306
307 /* Rectifier initialization of DSD */
XMC_DSD_CH_Rectify_Init(XMC_DSD_CH_t * const channel,const XMC_DSD_CH_RECTIFY_CONFIG_t * const config)308 void XMC_DSD_CH_Rectify_Init(XMC_DSD_CH_t *const channel, const XMC_DSD_CH_RECTIFY_CONFIG_t *const config)
309 {
310 XMC_ASSERT("XMC_DSD_RECTIFY_Init:Invalid module pointer", XMC_DSD_CHECK_CHANNEL_PTR(channel));
311 XMC_ASSERT("XMC_DSD_RECTIFY_Init:NULL Pointer", (config != (XMC_DSD_CH_RECTIFY_CONFIG_t *)NULL));
312 XMC_ASSERT("XMC_DSD_RECTIFY_Init:NULL Pointer", (((uint16_t)config->delay + (uint16_t)config->half_cycle) <= 0xFF));
313
314 channel->RECTCFG = config->rectify_config | (uint32_t)DSD_CH_RECTCFG_RFEN_Msk;
315 channel->CGSYNC = (((uint32_t) config->delay << (uint32_t)DSD_CH_CGSYNC_SDPOS_Pos)
316 | (((uint32_t)config->delay + (uint32_t)config->half_cycle) << (uint32_t)DSD_CH_CGSYNC_SDNEG_Pos));
317 }
318
319 /* API to get the result of the last conversion */
XMC_DSD_CH_GetResult_TS(XMC_DSD_CH_t * const channel,int16_t * dsd_result,uint8_t * dsd_filter_count,uint8_t * dsd_integration_count)320 void XMC_DSD_CH_GetResult_TS(XMC_DSD_CH_t* const channel,
321 int16_t* dsd_result,
322 uint8_t* dsd_filter_count,
323 uint8_t* dsd_integration_count)
324 {
325 uint32_t timestamp;
326 uint16_t result;
327
328 timestamp = channel->TSTMP;
329 result = (uint16_t)((uint32_t)timestamp & DSD_CH_TSTMP_RESULT_Msk);
330 *dsd_result = (int16_t)(result);
331 *dsd_filter_count = (uint8_t) ((timestamp & (uint32_t)DSD_CH_TSTMP_CFMDCNT_Msk)>>(uint32_t)DSD_CH_TSTMP_CFMDCNT_Pos);
332 *dsd_integration_count = (uint8_t) ((timestamp & (uint32_t)DSD_CH_TSTMP_NVALCNT_Msk)>>(uint32_t)DSD_CH_TSTMP_NVALCNT_Pos);
333 }
334
335 /* API to get the result of the last conversion with the time */
XMC_DSD_CH_GetResult_TS_Time(XMC_DSD_CH_t * const channel,int16_t * dsd_Result,uint32_t * time)336 void XMC_DSD_CH_GetResult_TS_Time(XMC_DSD_CH_t* const channel, int16_t* dsd_Result, uint32_t* time)
337 {
338 uint32_t timestamp;
339 uint16_t filter_count;
340 uint16_t integrator_count;
341 uint16_t decimation;
342 uint16_t result;
343
344 timestamp = channel->TSTMP;
345 decimation = (uint16_t)(channel->FCFGC & DSD_CH_FCFGC_CFMDF_Msk);
346 filter_count = (uint16_t)((timestamp & DSD_CH_TSTMP_CFMDCNT_Msk)>>DSD_CH_TSTMP_CFMDCNT_Pos);
347
348 /* Integration enabled? */
349 if ((channel->IWCTR & DSD_CH_IWCTR_INTEN_Msk))
350 {
351 integrator_count = (uint16_t) ((timestamp & DSD_CH_TSTMP_NVALCNT_Msk)>>DSD_CH_TSTMP_NVALCNT_Pos);
352
353 /*See Errata number: xxyy */
354 if (filter_count == decimation)
355 {
356 integrator_count++;
357 }
358 *time = (uint32_t)(((uint32_t) integrator_count * ((uint32_t) decimation + 1U)) + (uint32_t) ((uint32_t)decimation - filter_count));
359 }
360 else
361 {
362 *time = (uint32_t) ((uint32_t)decimation - filter_count);
363 }
364 result = (uint16_t)((uint32_t)timestamp & DSD_CH_TSTMP_RESULT_Msk);
365 *dsd_Result = (int16_t)(result);
366 }
367
368
369
370 #endif /*DSD*/
371
372
373