iLLD_TC29x  1.0
IfxVadc.c
Go to the documentation of this file.
1 /**
2  * \file IfxVadc.c
3  * \brief VADC basic functionality
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 "IfxVadc.h"
30 
31 /******************************************************************************/
32 /*-------------------------Function Implementations---------------------------*/
33 /******************************************************************************/
34 
35 void IfxVadc_configExternalMultiplexerMode(Ifx_VADC *vadc, Ifx_VADC_G *vadcG, IfxVadc_ExternalMultiplexerMode mode, uint8 channels, IfxVadc_EmuxSelectValue startChannel, IfxVadc_EmuxCodingScheme code, IfxVadc_EmuxSampleTimeControl sampleTimeControl, IfxVadc_ChannelSelectionStyle channelSelectionStyle)
36 {
37  Ifx_VADC_G_EMUXCTR emuxctr;
38 
39  emuxctr.B.EMXWC = 1;
40  emuxctr.B.EMUXMODE = mode;
41  emuxctr.B.EMXCSS = channelSelectionStyle;
42  emuxctr.B.EMUXCH = channels;
43  emuxctr.B.EMUXSET = startChannel;
44  emuxctr.B.EMXCOD = code;
45  emuxctr.B.EMXST = sampleTimeControl;
47  vadcG->EMUXCTR.U = emuxctr.U;
48  emuxctr.B.EMXWC = 0;
49  vadcG->EMUXCTR.U = emuxctr.U;
51 }
52 
53 
54 void IfxVadc_disableAccess(Ifx_VADC *vadc, IfxVadc_Protection protectionSet)
55 {
58 
60  {
61  vadc->ACCPROT0.U |= (0x00000001 << protectionSet);
62  }
63  else
64  {
65  vadc->ACCPROT1.U |= (0x00000001 << (protectionSet & 0x1F));
66  }
67 
69 }
70 
71 
72 void IfxVadc_disablePostCalibration(Ifx_VADC *vadc, IfxVadc_GroupId group, boolean disable)
73 {
74  if (group < IFXVADC_NUM_ADC_CAL_GROUPS)
75  {
77 
78  uint32 mask = 1 << (IFX_VADC_GLOBCFG_DPCAL0_OFF + group);
79 
80  if (disable == TRUE)
81  {
82  vadc->GLOBCFG.U |= mask;
83  }
84  else
85  {
86  vadc->GLOBCFG.U &= ~mask;
87  }
88 
90  }
91 }
92 
93 
94 void IfxVadc_enableAccess(Ifx_VADC *vadc, IfxVadc_Protection protectionSet)
95 {
98 
100  {
101  vadc->ACCPROT0.U &= ~(0x00000001 << protectionSet);
102  }
103  else
104  {
105  vadc->ACCPROT1.U &= ~(0x00000001 << (protectionSet & 0x1F));
106  }
107 
109 }
110 
111 
113 {
114  return IfxScuCcu_getSpbFrequency() / (1U + vadc->GLOBCFG.B.DIVA);
115 }
116 
117 
119 {
120  return IfxScuCcu_getSpbFrequency() / (1U + vadc->GLOBCFG.B.DIVD);
121 }
122 
123 
125 {
126  return IfxScuCcu_getSpbFrequency();
127 }
128 
129 
131 {
133  uint8 i;
134 
135  for (i = 0; i < IFXVADC_NUM_ADC_GROUPS; i++)
136  {
137  if (vadc->BRSPND[i].U)
138  {
140  }
141  else
142  {
143  continue;
144  }
145  }
146 
147  return status;
148 }
149 
150 
151 float32 IfxVadc_getChannelConversionTime(Ifx_VADC *vadc, IfxVadc_GroupId group, IfxVadc_InputClasses inputClass, float32 analogFrequency, float32 moduleFrequency, IfxVadc_ConversionType conversionMode)
152 {
153  float32 conversionTime = 0.0;
154  Ifx_VADC_G *vadcG = &vadc->G[group];
155  uint32 stc;
156  IfxVadc_ChannelResolution resolution;
157  uint32 n;
158 
159  uint32 inputClassNum;
160 
161  if (inputClass <= IfxVadc_InputClasses_group1)
162  {
163  inputClassNum = inputClass;
164  stc = vadcG->ICLASS[inputClassNum].B.STCS;
165  resolution = (IfxVadc_ChannelResolution)vadcG->ICLASS[inputClassNum].B.CMS;
166  }
167  else
168  {
169  inputClassNum = inputClass - IfxVadc_InputClasses_global0;
170  stc = vadc->GLOBICLASS[inputClassNum].B.STCS;
171  resolution = (IfxVadc_ChannelResolution)vadc->GLOBICLASS[inputClassNum].B.CMS;
172  }
173 
174  switch (resolution)
175  {
176  case IfxVadc_ChannelResolution_12bit: n = 12;
177  break;
178  case IfxVadc_ChannelResolution_10bit: n = 10;
179  break;
180  case IfxVadc_ChannelResolution_8bit: n = 8;
181  break;
183  break;
184  default: n = 0;
185  break;
186  }
187 
188  if (conversionMode == IfxVadc_ConversionType_Compatible)
189  {
190  if (resolution != IfxVadc_ChannelResolution_10bitFast)
191  {
192  /* Standard conversion */
193  uint32 pc = IfxVadc_isPostCalibration(vadc, group) ? 2 : 0;
194  conversionTime = (float32)(2 + stc + n + pc) / analogFrequency + 2.0 / moduleFrequency;
195  }
196  else
197  {
198  /* Fast compare mode */
199  conversionTime = (float32)(2 + stc + 2) / analogFrequency + 2.0 / moduleFrequency;
200  }
201  }
202  else
203  {
204  // do nothing
205  }
206 
207  return conversionTime;
208 }
209 
210 
212 {
214 
215  /* just fill level is checked */
216  if (0x7 == group->QSR0.B.FILL)
217  {
218  status = IfxVadc_Status_queueFull;
219  }
220  else
221  {
222  status = IfxVadc_Status_noError;
223  }
224 
225  return status;
226 }
227 
228 
229 Ifx_VADC_RES IfxVadc_getResultBasedOnRequestSource(Ifx_VADC *vadc, Ifx_VADC_G *group, IfxVadc_ChannelId channel, IfxVadc_RequestSource sourceType)
230 {
231  sint32 sourceResultRegister = -1;
232  Ifx_VADC_RES tmpResult;
233 
234  switch (sourceType)
235  {
237  sourceResultRegister = group->QCTRL0.B.SRCRESREG;
238  break;
239 
241  sourceResultRegister = group->ASCTRL.B.SRCRESREG;
242  break;
243 
245  sourceResultRegister = vadc->BRSCTRL.B.SRCRESREG;
246  break;
247  }
248 
249  if (sourceResultRegister > 0)
250  {
251  tmpResult.U = group->RES[sourceResultRegister].U;
252 
253  return tmpResult;
254  }
255  else
256  {
257  if ((sourceType == IfxVadc_RequestSource_background) && (group->CHCTR[channel].B.RESTBS == 1))
258  {
259  tmpResult.B.VF = vadc->GLOBRES.B.VF;
260  tmpResult.B.FCR = vadc->GLOBRES.B.FCR;
261  tmpResult.B.CRS = vadc->GLOBRES.B.CRS;
262  tmpResult.B.EMUX = vadc->GLOBRES.B.EMUX;
263  tmpResult.B.CHNR = vadc->GLOBRES.B.CHNR;
264  tmpResult.B.DRC = vadc->GLOBRES.B.GNR; //The bitfields are the same but interpretation is different. TODO- define a generic result register type.
265  tmpResult.B.RESULT = vadc->GLOBRES.B.RESULT;
266 
267  return tmpResult;
268  }
269  else
270  {
271  tmpResult.U = group->RES[group->CHCTR[channel].B.RESREG].U;
272 
273  return tmpResult;
274  }
275  }
276 }
277 
278 
280 {
282 
283  if (group->ASPND.U)
284  {
286  }
287  else
288  {
289  return status;
290  }
291 }
292 
293 
294 volatile Ifx_SRC_SRCR *IfxVadc_getSrcAddress(IfxVadc_GroupId group, IfxVadc_SrcNr index)
295 {
296  Ifx_SRC_SRCR *base;
297 
298  if (IfxVadc_SrcNr_shared0 <= index)
299  {
300  index -= 4;
301 
302  if ((group & 0x1) != 0)
303  {
304  group = IfxVadc_GroupId_global1; /* Shared interrupt common 1 is used */
305  }
306  else
307  {
308  group = IfxVadc_GroupId_global0; /* Shared interrupt common 0 is used */
309  }
310  }
311  else
312  {
313  /* do nothing */
314  }
315 
316  base = (Ifx_SRC_SRCR *)IfxVadc_cfg_srcAddresses[(group * 4) + index];
317 
318  return &(base[0]);
319 }
320 
321 
322 void IfxVadc_initialiseAdcArbiterClock(Ifx_VADC *vadc, uint32 arbiterClockDivider)
323 {
324  Ifx_VADC_GLOBCFG tempGLOBCFG;
325  tempGLOBCFG.U = vadc->GLOBCFG.U;
326  tempGLOBCFG.B.DIVD = arbiterClockDivider;
327  tempGLOBCFG.B.DIVWC = 1;
329  vadc->GLOBCFG.U = tempGLOBCFG.U;
331 }
332 
333 
334 void IfxVadc_initialiseAdcConverterClock(Ifx_VADC *vadc, uint32 converterClockDivider)
335 {
336  Ifx_VADC_GLOBCFG tempGLOBCFG;
337  tempGLOBCFG.U = vadc->GLOBCFG.U;
338  tempGLOBCFG.B.DIVA = converterClockDivider;
339  tempGLOBCFG.B.DIVWC = 1;
341  vadc->GLOBCFG.U = tempGLOBCFG.U;
343 }
344 
345 
346 uint32 IfxVadc_initializeFAdcD(Ifx_VADC *vadc, uint32 fAdcD)
347 {
348  uint32 divD;
349  uint32 result;
351 
352  divD = (fadc / fAdcD - 1);
353 
354  divD = __minu(divD, 0x3u);
355 
356  result = fadc / (divD + 1);
358  return result;
359 }
360 
361 
362 uint32 IfxVadc_initializeFAdcI(Ifx_VADC *vadc, uint32 fAdcI)
363 {
364  uint32 divA;
365  uint32 result;
367 
368  /* DivA = min(max(0, Fadc / FAdcI - 1), 0x3F); */
369  divA = (fadc << 2) / fAdcI;
370 
371  divA = (divA + 2) >> 2; /* Round to nearest integer */
372  divA = __minu(divA - 1, 0x1Fu);
373  result = fadc / (divA + 1);
374 
375  if (result > IFXVADC_ANALOG_FREQUENCY_MAX)
376  {
377  divA = __minu(divA + 1, 0x1Fu);
378 
379  result = fadc / (divA + 1);
380  }
381  else
382  {
383  /* do nothing */
384  }
385 
386  if (!((result >= IFXVADC_ANALOG_FREQUENCY_MIN) && (result <= IFXVADC_ANALOG_FREQUENCY_MAX)))
387  {
388  result = 0; /* Min / Max FAdcI frequency */
389  }
390  else
391  {
393  }
394 
395  return result;
396 }
397 
398 
399 boolean IfxVadc_isPostCalibration(Ifx_VADC *vadc, IfxVadc_GroupId group)
400 {
401  boolean pcEnabled;
402 
403  switch (group)
404  {
405  case IfxVadc_GroupId_0: pcEnabled = vadc->GLOBCFG.B.DPCAL0 == 0;
406  break;
407  case IfxVadc_GroupId_1: pcEnabled = vadc->GLOBCFG.B.DPCAL1 == 0;
408  break;
409  case IfxVadc_GroupId_2: pcEnabled = vadc->GLOBCFG.B.DPCAL2 == 0;
410  break;
411  case IfxVadc_GroupId_3: pcEnabled = vadc->GLOBCFG.B.DPCAL3 == 0;
412  break;
413  case IfxVadc_GroupId_4: pcEnabled = vadc->GLOBCFG.B.DPCAL4 == 0;
414  break;
415  case IfxVadc_GroupId_5: pcEnabled = vadc->GLOBCFG.B.DPCAL5 == 0;
416  break;
417  case IfxVadc_GroupId_6: pcEnabled = vadc->GLOBCFG.B.DPCAL6 == 0;
418  break;
419  case IfxVadc_GroupId_7: pcEnabled = vadc->GLOBCFG.B.DPCAL7 == 0;
420  break;
421  case IfxVadc_GroupId_8: pcEnabled = vadc->GLOBCFG.B.DPCAL8 == 0;
422  break;
423  case IfxVadc_GroupId_9: pcEnabled = vadc->GLOBCFG.B.DPCAL9 == 0;
424  break;
425  case IfxVadc_GroupId_10: pcEnabled = vadc->GLOBCFG.B.DPCAL10 == 0;
426  break;
427  default: pcEnabled = FALSE;
428  break;
429  }
430 
431  return pcEnabled;
432 }
433 
434 
435 void IfxVadc_resetKernel(Ifx_VADC *vadc)
436 {
438 
441  vadc->KRST1.B.RST = 1; /* Only if both Kernel reset bits are set a reset is executed */
442  vadc->KRST0.B.RST = 1;
443  IfxScuWdt_setCpuEndinit(passwd);
444 
445  while (vadc->KRST0.B.RSTSTAT == 0) /* Wait until reset is executed */
446 
447  {}
448 
450  vadc->KRSTCLR.B.CLR = 1; /* Clear Kernel reset status bit */
452  IfxScuWdt_setCpuEndinit(passwd);
453 }
454 
455 
457 {
458  if (slotEnable != FALSE)
459  {
460  vadcG->ARBPR.U |= slotEnable << (IFX_VADC_G_ARBPR_ASEN0_OFF + slot); /* enable Slot */
461  vadcG->ARBPR.U &= ~(IFX_VADC_G_ARBPR_PRIO0_MSK << (slot * 4u)); /* clear Priority */
462  vadcG->ARBPR.U |= (prio << (slot * 4u)); /* Set Priority */
463 
465  {
466  vadcG->ARBPR.U |= 0x1u << (IFX_VADC_G_ARBPR_CSM0_OFF + (slot * 4u)); /* Set cancel inject mode */
467  }
468  else
469  {
470  vadcG->ARBPR.U &= ~(0x1u << (IFX_VADC_G_ARBPR_CSM0_OFF + (slot * 4u))); /* Set Wait for Start mode */
471  }
472  }
473  else
474  {
475  vadcG->ARBPR.U &= ~(IFX_VADC_G_ARBPR_ASEN0_MSK << (IFX_VADC_G_ARBPR_ASEN0_OFF + slot)); /* disable Slot */
476  }
477 }
478 
479 
480 void IfxVadc_setScan(Ifx_VADC_G *group, uint32 channels, uint32 mask)
481 {
482  /* select channels which should take part in the scan sequence */
483  /* the mask allows to specify the channels which should be enabled/disabled */
484  group->ASSEL.U = (group->ASSEL.U & ~mask) | (channels & mask);
485 }
486 
487 
488 void IfxVadc_startupCalibration(Ifx_VADC *vadc)
489 {
490  boolean calibrationRunning;
491  uint8 adcCalGroupNum;
492 
493  /* Start calibration */
495  /* Set SUCAL bit */
498 
499  /* Wait for hardware self-test and calibration to complete */
500  /* Wait until Calibration is done */
501  do
502  {
503  calibrationRunning = FALSE;
504 
505  for (adcCalGroupNum = 0; adcCalGroupNum < IFXVADC_NUM_ADC_CAL_GROUPS; adcCalGroupNum++)
506  {
507  if (IfxVadc_getAdcCalibrationActiveState(vadc, adcCalGroupNum) != 0) /* Check ADC Calibration Flag CAL */
508  {
509  calibrationRunning = TRUE;
510  }
511  else
512  {
513  /* do nothing */
514  }
515  }
516  } while (calibrationRunning == TRUE); /* wait until calibration of all calibrated kernels are done */
517 }