iLLD_TC27xC  1.0
IfxDsadc_Dsadc.c
Go to the documentation of this file.
1 /**
2  * \file IfxDsadc_Dsadc.c
3  * \brief DSADC DSADC details
4  *
5  * \version iLLD_0_1_0_10
6  * \copyright Copyright (c) 2013 Infineon Technologies AG. All rights reserved.
7  *
8  *
9  * IMPORTANT NOTICE
10  *
11  *
12  * Infineon Technologies AG (Infineon) is supplying this file for use
13  * exclusively with Infineon's microcontroller products. This file can be freely
14  * distributed within development tools that are supporting such microcontroller
15  * products.
16  *
17  * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
18  * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
20  * INFINEON SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL,
21  * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
22  *
23  */
24 
25 /******************************************************************************/
26 /*----------------------------------Includes----------------------------------*/
27 /******************************************************************************/
28 
29 #include "IfxDsadc_Dsadc.h"
30 #include "Scu/Std/IfxScuCcu.h"
31 #include "Scu/Std/IfxScuWdt.h"
32 
33 /******************************************************************************/
34 /*-----------------------Private Function Prototypes--------------------------*/
35 /******************************************************************************/
36 
37 /** \brief calculate division factor
38  * \param sourceFreq Source frequency
39  * \param targetFreq Target frequency
40  * \return division factor
41  */
42 static sint32 IfxDsadc_Dsadc_calcDIVx(float32 sourceFreq, float32 *targetFreq);
43 
44 /** \brief Initialises the auxilary filter
45  * \param channel Pointer to the DSADC channel handle
46  * \param config pointer to the DSADC fir auxilary filter configuration
47  * \return None
48  */
49 static void IfxDsadc_Dsadc_initAuxFilter(IfxDsadc_Dsadc_Channel *channel, const IfxDsadc_Dsadc_AuxFilterConfig *config);
50 
51 /** \brief Initialises the comb filter
52  * \param channel Pointer to the DSADC channel handle
53  * \param config pointer to the DSADC comb filter configuration
54  * \return None
55  */
56 static void IfxDsadc_Dsadc_initCombFilter(IfxDsadc_Dsadc_Channel *channel, const IfxDsadc_Dsadc_CombFilterConfig *config);
57 
58 /** \brief Initialises the demodulator
59  * \param channel Pointer to the DSADC channel handle
60  * \param config pointer to the DSADC demodulator configuration
61  * \return None
62  */
63 static void IfxDsadc_Dsadc_initDemodulator(IfxDsadc_Dsadc_Channel *channel, const IfxDsadc_Dsadc_DemodulatorConfig *config);
64 
65 /** \brief Initialises the fir filter
66  * \param channel Pointer to the DSADC channel handle
67  * \param config pointer to the DSADC fir filter configuration
68  * \return None
69  */
70 static void IfxDsadc_Dsadc_initFirFilter(IfxDsadc_Dsadc_Channel *channel, const IfxDsadc_Dsadc_FirFilterConfig *config);
71 
72 /** \brief Initialises the integrator
73  * \param channel Pointer to the DSADC channel handle
74  * \param config pointer to the DSADC fir integrator configuration
75  * \return None
76  */
77 static void IfxDsadc_Dsadc_initIntegrator(IfxDsadc_Dsadc_Channel *channel, const IfxDsadc_Dsadc_IntegratorConfig *config);
78 
79 /** \brief Initialises the modulator
80  * \param channel Pointer to the DSADC channel handle
81  * \param config pointer to the DSADC modulator configuration
82  * \return None
83  */
84 static void IfxDsadc_Dsadc_initModulator(IfxDsadc_Dsadc_Channel *channel, const IfxDsadc_Dsadc_ModulatorConfig *config);
85 
86 /** \brief Initialises the rectifier
87  * \param channel Pointer to the DSADC channel handle
88  * \param config pointer to the DSADC fir rectifier configuration
89  * \return None
90  */
91 static void IfxDsadc_Dsadc_initRectifier(IfxDsadc_Dsadc_Channel *channel, const IfxDsadc_Dsadc_RectifierConfig *config);
92 
93 /******************************************************************************/
94 /*-------------------------Function Implementations---------------------------*/
95 /******************************************************************************/
96 
97 static sint32 IfxDsadc_Dsadc_calcDIVx(float32 sourceFreq, float32 *targetFreq)
98 {
99  float32 bestError = 10e6;
100  sint32 bestDiv = 2, i;
101 
102  for (i = 2; i <= 32; i += 2)
103  {
104  float32 freq = sourceFreq / i;
105  float32 error = __absf(freq - *targetFreq);
106 
107  if (__leqf(error, bestError))
108  {
109  bestError = error;
110  bestDiv = i;
111 
112  if (!__neqf(error, 0))
113  {
114  break;
115  }
116  }
117  }
118 
119  *targetFreq = sourceFreq / bestDiv;
120 
121  return (bestDiv / 2) - 1;
122 }
123 
124 
126 {
127  return IfxDsadc_getAuxResult(channel->module, channel->channelId);
128 }
129 
130 
131 static void IfxDsadc_Dsadc_initAuxFilter(IfxDsadc_Dsadc_Channel *channel, const IfxDsadc_Dsadc_AuxFilterConfig *config)
132 {
133  Ifx_DSADC_CH_FCFGA fcfga;
134 
135  fcfga.U = 0;
136 
137  fcfga.B.CFADF = config->decimationFactor - 1;
138  fcfga.B.CFAC = config->combFilterType;
139 
140  fcfga.B.SRGA = config->serviceRequest;
141  fcfga.B.ESEL = config->eventSelect;
142  fcfga.B.EGT = config->eventGate;
143 
144  fcfga.B.AFSC = config->combFilterShift;
145 
146  (channel->channel)->FCFGA = fcfga;
147 }
148 
149 
151 {
152  Ifx_DSADC_CGCFG cgcfg;
153 
154  cgcfg.U = 0;
155 
157  float32 targetFreq = config->frequency;
158  cgcfg.B.DIVCG = IfxDsadc_Dsadc_calcDIVx(sourceFreq / (32 * 32), &targetFreq);
159  cgcfg.B.SIGPOL = (config->inverted == FALSE) ? 0 : 1;
160  cgcfg.B.BREV = (config->bitReversed == FALSE) ? 0 : 1;
161  cgcfg.B.CGMOD = config->carrierWaveformMode;
162 
163  dsadc->dsadc->CGCFG = cgcfg;
164 
165  const IfxDsadc_Cgpwm_Out *pinPos = config->pinPos;
166 
167  if (pinPos != NULL_PTR)
168  { /* Initialise positive carrier pin */
169  IfxDsadc_initCgPwmPin(pinPos, config->pinMode, config->pinDriver);
170  }
171 
172  const IfxDsadc_Cgpwm_Out *pinNeg = config->pinNeg;
173 
174  if (pinNeg != NULL_PTR)
175  { /* Initialise negative carrier pin */
176  IfxDsadc_initCgPwmPin(pinNeg, config->pinMode, config->pinDriver);
177  }
178 }
179 
180 
182 {
183  Ifx_DSADC *dsadc = config->module;
184 
185  channel->channelId = config->channelId;
186  channel->module = dsadc;
187  channel->channel = (Ifx_DSADC_CH *)&dsadc->CH[config->channelId];
188 
189  IfxDsadc_Dsadc_initModulator(channel, &config->modulator);
190  IfxDsadc_Dsadc_initDemodulator(channel, &config->demodulator);
191  IfxDsadc_Dsadc_initCombFilter(channel, &config->combFilter);
192  IfxDsadc_Dsadc_initFirFilter(channel, &config->firFilter);
193  IfxDsadc_Dsadc_initIntegrator(channel, &config->integrator);
194  IfxDsadc_Dsadc_initAuxFilter(channel, &config->auxFilter);
195  IfxDsadc_Dsadc_initRectifier(channel, &config->rectifier);
196 
197  const IfxDsadc_Dsadc_ChannelPins *pins = config->channelPins;
198 
199  if (pins != NULL_PTR)
200  {
201  const IfxDsadc_Dsn_In *dsn = pins->dsn;
202 
203  if (dsn != NULL_PTR)
204  {
205  IfxDsadc_initDsnPin(dsn, pins->dsnMode);
206  }
207 
208  const IfxDsadc_Dsp_In *dsp = pins->dsp;
209 
210  if (dsp != NULL_PTR)
211  {
212  IfxDsadc_initDspPin(dsp, pins->dspMode);
213  }
214 
215  const IfxDsadc_Cin_In *cin = pins->cin;
216 
217  if (cin != NULL_PTR)
218  {
219  IfxDsadc_initCinPin(cin, pins->cinMode);
220  }
221 
222  const IfxDsadc_Din_In *din = pins->din;
223 
224  if (din != NULL_PTR)
225  {
226  IfxDsadc_initDinPin(din, pins->dinMode);
227  }
228 
229  const IfxDsadc_Itr_In *itr = pins->itr;
230 
231  if (itr != NULL_PTR)
232  {
233  IfxDsadc_initItrPin(itr, pins->itrMode);
234  }
235  }
236 }
237 
238 
240 {
241  const IfxDsadc_Dsadc_ChannelConfig IfxDsadc_Dsadc_defaultChannelConfig = {
242  .modulator = {
244  .negativeInput = IfxDsadc_InputConfig_referenceGround,
245  .inputGain = IfxDsadc_InputGain_factor1,
246  .inputPin = IfxDsadc_InputPin_a,
247  .modulatorClockFreq = 10.0e6,
248  .commonModeVoltage = IfxDsadc_CommonModeVoltage_c,
249  },
250  .demodulator = {
252  .triggerInput = IfxDsadc_TriggerInput_a,
253  .integrationTrigger = IfxDsadc_IntegratorTrigger_bypassed,
254  .timestampTrigger = IfxDsadc_TimestampTrigger_noTrigger,
255  .sampleClockSource = IfxDsadc_SampleClockSource_internal,
257  },
258  .combFilter = {
259  .bypassed = FALSE,
260  .combFilterType = IfxDsadc_MainCombFilterType_comb3,
261  .combFilterShift = IfxDsadc_MainCombFilterShift_noShift,
263  .decimationFactor = 50,
264  .startValue = 0,
265  },
266  .firFilter = {
267  .fir0Enabled = FALSE,
268  .fir1Enabled = FALSE,
269  .offsetCompensation = FALSE,
270  .dataShift = IfxDsadc_FirDataShift_noShift,
271  .internalShift = IfxDsadc_FirInternalShift_noShift,
272  },
273  .integrator = {
275  .discardCount = 0,
276  .integrationCount = 20,
277  .integrationCycles = 1,
278  },
279  .auxFilter = {
280  .bypassed = TRUE,
281  .combFilterType = IfxDsadc_AuxCombFilterType_comb1,
282  .combFilterShift = IfxDsadc_AuxCombFilterShift_noShift,
283  .serviceRequest = IfxDsadc_AuxServiceRequest_never,
284  .eventSelect = IfxDsadc_AuxEvent_everyNewResult,
285  .eventGate = IfxDsadc_AuxGate_definedByESEL,
286  .decimationFactor = 4,
287  },
288  .channelPins = NULL_PTR
289  };
290 
291  *config = IfxDsadc_Dsadc_defaultChannelConfig;
292  config->module = dsadc->dsadc;
293 }
294 
295 
296 static void IfxDsadc_Dsadc_initCombFilter(IfxDsadc_Dsadc_Channel *channel, const IfxDsadc_Dsadc_CombFilterConfig *config)
297 {
298  Ifx_DSADC_CH_FCFGC fcfgc;
299 
300  fcfgc.U = 0;
301 
302  fcfgc.B.CFMDF = config->decimationFactor - 1;
303  fcfgc.B.CFMC = config->combFilterType;
304  fcfgc.B.CFEN = (config->bypassed == FALSE) ? 1 : 0;
305 
306  fcfgc.B.MFSC = config->combFilterShift;
307 
308  fcfgc.B.SRGM = config->serviceRequest;
309  fcfgc.B.CFMSV = config->startValue - 1;
310 
311  (channel->channel)->FCFGC = fcfgc;
312 }
313 
314 
315 static void IfxDsadc_Dsadc_initDemodulator(IfxDsadc_Dsadc_Channel *channel, const IfxDsadc_Dsadc_DemodulatorConfig *config)
316 {
317  Ifx_DSADC_CH_DICFG dicfg;
318 
319  dicfg.U = 0;
320 
321  dicfg.B.DSRC = config->inputDataSource;
322  dicfg.B.DSWC = 1; // enable write access for this bitfield
323 
324  dicfg.B.ITRMODE = config->integrationTrigger;
325  dicfg.B.TSTRMODE = config->timestampTrigger;
326  dicfg.B.TRSEL = config->triggerInput;
327  dicfg.B.TRWC = 1; // enable write access for these bitfields
328 
329  dicfg.B.CSRC = config->sampleClockSource;
330  dicfg.B.STROBE = config->sampleStrobe;
331  dicfg.B.SCWC = 1; // enable write access for these bitfields
332 
333  (channel->channel)->DICFG = dicfg;
334 }
335 
336 
337 static void IfxDsadc_Dsadc_initFirFilter(IfxDsadc_Dsadc_Channel *channel, const IfxDsadc_Dsadc_FirFilterConfig *config)
338 {
339  Ifx_DSADC_CH_FCFGM fcfgm;
340 
341  fcfgm.U = 0;
342 
343  fcfgm.B.FIR0EN = (config->fir0Enabled != FALSE) ? 1 : 0;
344  fcfgm.B.FIR1EN = (config->fir1Enabled != FALSE) ? 1 : 0;
345  fcfgm.B.OCEN = (config->offsetCompensation != FALSE) ? 1 : 0;
346  fcfgm.B.DSH = config->dataShift;
347  fcfgm.B.FSH = config->internalShift;
348 
349  (channel->channel)->FCFGM = fcfgm;
350 }
351 
352 
353 static void IfxDsadc_Dsadc_initIntegrator(IfxDsadc_Dsadc_Channel *channel, const IfxDsadc_Dsadc_IntegratorConfig *config)
354 {
355  Ifx_DSADC_CH_IWCTR iwctr;
356 
357  iwctr.U = 0;
358 
359  iwctr.B.REPVAL = config->integrationCycles - 1;
360  iwctr.B.NVALDIS = config->discardCount;
361  iwctr.B.IWS = config->windowSize;
362  iwctr.B.NVALINT = config->integrationCount - 1;
363 
364  (channel->channel)->IWCTR = iwctr;
365 }
366 
367 
368 static void IfxDsadc_Dsadc_initModulator(IfxDsadc_Dsadc_Channel *channel, const IfxDsadc_Dsadc_ModulatorConfig *config)
369 {
370  Ifx_DSADC_CH_MODCFG modcfg;
371 
372  modcfg.U = 0;
373 
374  modcfg.B.INCFGP = config->positiveInput;
375  modcfg.B.INCFGN = config->negativeInput;
376  modcfg.B.GAINSEL = config->inputGain;
377  modcfg.B.INSEL = config->inputPin;
378  modcfg.B.INCWC = 1; // enable write access for these bitfields
379 
380  float32 targetFreq = config->modulatorClockFreq;
381  float32 sourceFreq = IfxDsadc_getModulatorInputClockFreq(channel->module);
382  modcfg.B.DIVM = IfxDsadc_Dsadc_calcDIVx(sourceFreq, &targetFreq);
383  modcfg.B.DWC = 1; // enable write access for this bitfield
384 
385  modcfg.B.CMVS = config->commonModeVoltage;
386  modcfg.B.GCEN = 0; // normal operation (calibration mode disabled)
387  modcfg.B.MWC = 1; // enable write access for these bitfields
388 
389  (channel->channel)->MODCFG = modcfg;
390 }
391 
392 
394 {
395  Ifx_DSADC *dsadcSFR = config->dsadc;
396 
397  dsadc->dsadc = dsadcSFR;
398 
399  {
402  dsadcSFR->CLC.U = 0x00000000;
403 
404  if (dsadcSFR->CLC.U)
405  {} // sync access
406 
407  IfxScuWdt_setCpuEndinit(passwd);
408 
409  {
410  Ifx_DSADC_GLOBCFG globcfg;
411  globcfg.U = dsadcSFR->GLOBCFG.U;
412 
413  globcfg.B.MCSEL = config->modulatorClockSelect;
414  globcfg.B.LOSUP = config->lowPowerSupply;
415  globcfg.B.PSWC = 1;
416 
417  dsadcSFR->GLOBCFG.U = globcfg.U;
418  }
419  }
420 }
421 
422 
424 {
425  const IfxDsadc_Dsadc_Config IfxDsadc_Dsadc_defaultConfig = {
427  .lowPowerSupply = IfxDsadc_LowPowerSupply_5V
428  };
429 
430  *config = IfxDsadc_Dsadc_defaultConfig;
431  config->dsadc = dsadc;
432 }
433 
434 
435 static void IfxDsadc_Dsadc_initRectifier(IfxDsadc_Dsadc_Channel *channel, const IfxDsadc_Dsadc_RectifierConfig *config)
436 {
437  Ifx_DSADC_CH_RECTCFG rect;
438 
439  rect.U = 0;
440  rect.B.RFEN = config->enabled;
441  rect.B.SSRC = config->signSource;
442  (channel->channel)->RECTCFG = rect;
443  (channel->channel)->CGSYNC.B.SDPOS = config->signDelay;
444  (channel->channel)->CGSYNC.B.SDNEG = config->signDelay + (config->signPeriod / 2);
445 }