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