iLLD_TC27xD  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 
112 void IfxVadc_enableGroupSync(Ifx_VADC *vadc, uint32 ccu6Num)
113 {
116 
117  // VADC Config: enable ADC group sync
118  {
119  Ifx_VADC_GLOBCFG vadcGlobCfg;
120  vadcGlobCfg.U = vadc->GLOBCFG.U;
121  vadcGlobCfg.B.DIVWC = 1;
122  vadcGlobCfg.B.DCMSB = 1;
123 
125  vadc->GLOBCFG.U = vadcGlobCfg.U;
127  }
128 
129  if (ccu6Num == 0)
130  {
131  // CCU60 Config
132  CCU60_CLC.U = 0;
133 
134  if (CCU60_CLC.U)
135  {}
136 
137  CCU60_T13PR.U = 4; // results in 4+1 clock periods (100MHz) = 20MHz
138  CCU60_CC63SR.U = 4; // configures duty cycle of 40ns low and 10ns high
139  CCU60_MODCTR.B.ECT13O = 1; // bit ECT130 = 1 serves to route CC63ST signals out to COUT63
140  CCU60_TCTR4.U = (1 << IFX_CCU6_TCTR4_T13STR_OFF) | (1 << IFX_CCU6_TCTR4_T13RS_OFF); // set bit T13STR & T13RS -> enable shadow transfer & start timer T13
141  CCU60_MOSEL.B.TRIG1SEL = 0; // CCU60_COUT63 routed to output signal CCU6061 TRIG1
142  }
143  else if (ccu6Num == 1)
144  {
145  // CCU60 + CCU61 Config
146  CCU60_CLC.U = 0;
147  CCU61_CLC.U = 0;
148 
149  if (CCU61_CLC.U)
150  {}
151 
152  CCU61_T13PR.U = 4; // results in 4+1 clock periods (100MHz) = 20MHz
153  CCU61_CC63SR.U = 4; // configures duty cycle of 40ns low and 10ns high
154  CCU61_MODCTR.B.ECT13O = 1; // bit ECT130 = 1 serves to route CC63ST signals out to COUT63
155  CCU61_TCTR4.U = (1 << IFX_CCU6_TCTR4_T13STR_OFF) | (1 << IFX_CCU6_TCTR4_T13RS_OFF); // set bit T13STR & T13RS -> enable shadow transfer & start timer T13
156  CCU60_MOSEL.B.TRIG1SEL = 1; // CCU61_COUT63 routed to output signal CCU6061 TRIG1
157  }
158 
159  IfxScuWdt_setCpuEndinit(passwd);
160 }
161 
162 
164 {
165  return IfxScuCcu_getSpbFrequency() / (1U + vadc->GLOBCFG.B.DIVA);
166 }
167 
168 
170 {
171  return IfxScuCcu_getSpbFrequency() / (1U + vadc->GLOBCFG.B.DIVD);
172 }
173 
174 
176 {
177  return IfxScuCcu_getSpbFrequency();
178 }
179 
180 
182 {
184  uint8 i;
185 
186  for (i = 0; i < IFXVADC_NUM_ADC_GROUPS; i++)
187  {
188  if (vadc->BRSPND[i].U)
189  {
191  }
192  else
193  {
194  continue;
195  }
196  }
197 
198  return status;
199 }
200 
201 
202 float32 IfxVadc_getChannelConversionTime(Ifx_VADC *vadc, IfxVadc_GroupId group, IfxVadc_InputClasses inputClass, float32 analogFrequency, float32 moduleFrequency, IfxVadc_ConversionType conversionMode)
203 {
204  float32 conversionTime = 0.0;
205  Ifx_VADC_G *vadcG = &vadc->G[group];
206  uint32 stc;
207  IfxVadc_ChannelResolution resolution;
208  uint32 n;
209 
210  uint32 inputClassNum;
211 
212  if (inputClass <= IfxVadc_InputClasses_group1)
213  {
214  inputClassNum = inputClass;
215  stc = vadcG->ICLASS[inputClassNum].B.STCS;
216  resolution = (IfxVadc_ChannelResolution)vadcG->ICLASS[inputClassNum].B.CMS;
217  }
218  else
219  {
220  inputClassNum = inputClass - IfxVadc_InputClasses_global0;
221  stc = vadc->GLOBICLASS[inputClassNum].B.STCS;
222  resolution = (IfxVadc_ChannelResolution)vadc->GLOBICLASS[inputClassNum].B.CMS;
223  }
224 
225  switch (resolution)
226  {
227  case IfxVadc_ChannelResolution_12bit: n = 12;
228  break;
229  case IfxVadc_ChannelResolution_10bit: n = 10;
230  break;
231  case IfxVadc_ChannelResolution_8bit: n = 8;
232  break;
234  break;
235  default: n = 0;
236  break;
237  }
238 
239  if (conversionMode == IfxVadc_ConversionType_Compatible)
240  {
241  if (resolution != IfxVadc_ChannelResolution_10bitFast)
242  {
243  /* Standard conversion */
244  uint32 pc = IfxVadc_isPostCalibration(vadc, group) ? 2 : 0;
245  conversionTime = (float32)(2 + stc + n + pc) / analogFrequency + 2.0 / moduleFrequency;
246  }
247  else
248  {
249  /* Fast compare mode */
250  conversionTime = (float32)(2 + stc + 2) / analogFrequency + 2.0 / moduleFrequency;
251  }
252  }
253  else
254  {
255  // do nothing
256  }
257 
258  return conversionTime;
259 }
260 
261 
263 {
265 
266  /* just fill level is checked */
267  if (0x7 == group->QSR0.B.FILL)
268  {
269  status = IfxVadc_Status_queueFull;
270  }
271  else
272  {
273  status = IfxVadc_Status_noError;
274  }
275 
276  return status;
277 }
278 
279 
280 Ifx_VADC_RES IfxVadc_getResultBasedOnRequestSource(Ifx_VADC *vadc, Ifx_VADC_G *group, IfxVadc_ChannelId channel, IfxVadc_RequestSource sourceType)
281 {
282  sint32 sourceResultRegister = -1;
283  Ifx_VADC_RES tmpResult;
284 
285  switch (sourceType)
286  {
288  sourceResultRegister = group->QCTRL0.B.SRCRESREG;
289  break;
290 
292  sourceResultRegister = group->ASCTRL.B.SRCRESREG;
293  break;
294 
296  sourceResultRegister = vadc->BRSCTRL.B.SRCRESREG;
297  break;
298  }
299 
300  if (sourceResultRegister > 0)
301  {
302  tmpResult.U = group->RES[sourceResultRegister].U;
303 
304  return tmpResult;
305  }
306  else
307  {
308  if ((sourceType == IfxVadc_RequestSource_background) && (group->CHCTR[channel].B.RESTBS == 1))
309  {
310  tmpResult.B.VF = vadc->GLOBRES.B.VF;
311  tmpResult.B.FCR = vadc->GLOBRES.B.FCR;
312  tmpResult.B.CRS = vadc->GLOBRES.B.CRS;
313  tmpResult.B.EMUX = vadc->GLOBRES.B.EMUX;
314  tmpResult.B.CHNR = vadc->GLOBRES.B.CHNR;
315  tmpResult.B.DRC = vadc->GLOBRES.B.GNR; //The bitfields are the same but interpretation is different. TODO- define a generic result register type.
316  tmpResult.B.RESULT = vadc->GLOBRES.B.RESULT;
317 
318  return tmpResult;
319  }
320  else
321  {
322  tmpResult.U = group->RES[group->CHCTR[channel].B.RESREG].U;
323 
324  return tmpResult;
325  }
326  }
327 }
328 
329 
331 {
333 
334  if (group->ASPND.U)
335  {
337  }
338  else
339  {
340  return status;
341  }
342 }
343 
344 
345 volatile Ifx_SRC_SRCR *IfxVadc_getSrcAddress(IfxVadc_GroupId group, IfxVadc_SrcNr index)
346 {
347  Ifx_SRC_SRCR *base;
348 
349  if (IfxVadc_SrcNr_shared0 <= index)
350  {
351  index -= 4;
352 
353  if ((group & 0x1) != 0)
354  {
355  group = IfxVadc_GroupId_global1; /* Shared interrupt common 1 is used */
356  }
357  else
358  {
359  group = IfxVadc_GroupId_global0; /* Shared interrupt common 0 is used */
360  }
361  }
362  else
363  {
364  /* do nothing */
365  }
366 
367  base = (Ifx_SRC_SRCR *)IfxVadc_cfg_srcAddresses[(group * 4) + index];
368 
369  return &(base[0]);
370 }
371 
372 
373 void IfxVadc_initialiseAdcArbiterClock(Ifx_VADC *vadc, uint32 arbiterClockDivider)
374 {
375  Ifx_VADC_GLOBCFG tempGLOBCFG;
376  tempGLOBCFG.U = vadc->GLOBCFG.U;
377  tempGLOBCFG.B.DIVD = arbiterClockDivider;
378  tempGLOBCFG.B.DIVWC = 1;
380  vadc->GLOBCFG.U = tempGLOBCFG.U;
382 }
383 
384 
385 void IfxVadc_initialiseAdcConverterClock(Ifx_VADC *vadc, uint32 converterClockDivider)
386 {
387  Ifx_VADC_GLOBCFG tempGLOBCFG;
388  tempGLOBCFG.U = vadc->GLOBCFG.U;
389  tempGLOBCFG.B.DIVA = converterClockDivider;
390  tempGLOBCFG.B.DIVWC = 1;
392  vadc->GLOBCFG.U = tempGLOBCFG.U;
394 }
395 
396 
397 uint32 IfxVadc_initializeFAdcD(Ifx_VADC *vadc, uint32 fAdcD)
398 {
399  uint32 divD;
400  uint32 result;
402 
403  divD = (fadc / fAdcD - 1);
404 
405  divD = __minu(divD, 0x3u);
406 
407  result = fadc / (divD + 1);
409  return result;
410 }
411 
412 
413 uint32 IfxVadc_initializeFAdcI(Ifx_VADC *vadc, uint32 fAdcI)
414 {
415  uint32 divA;
416  uint32 result;
418 
419  /* DivA = min(max(0, Fadc / FAdcI - 1), 0x3F); */
420  divA = (fadc << 2) / fAdcI;
421 
422  divA = (divA + 2) >> 2; /* Round to nearest integer */
423  divA = __minu(divA - 1, 0x1Fu);
424  result = fadc / (divA + 1);
425 
426  if (result > IFXVADC_ANALOG_FREQUENCY_MAX)
427  {
428  divA = __minu(divA + 1, 0x1Fu);
429 
430  result = fadc / (divA + 1);
431  }
432  else
433  {
434  /* do nothing */
435  }
436 
437  if (!((result >= IFXVADC_ANALOG_FREQUENCY_MIN) && (result <= IFXVADC_ANALOG_FREQUENCY_MAX)))
438  {
439  result = 0; /* Min / Max FAdcI frequency */
440  }
441  else
442  {
444  }
445 
446  return result;
447 }
448 
449 
450 boolean IfxVadc_isPostCalibration(Ifx_VADC *vadc, IfxVadc_GroupId group)
451 {
452  boolean pcEnabled;
453 
454  switch (group)
455  {
456  case IfxVadc_GroupId_0: pcEnabled = vadc->GLOBCFG.B.DPCAL0 == 0;
457  break;
458  case IfxVadc_GroupId_1: pcEnabled = vadc->GLOBCFG.B.DPCAL1 == 0;
459  break;
460  case IfxVadc_GroupId_2: pcEnabled = vadc->GLOBCFG.B.DPCAL2 == 0;
461  break;
462  case IfxVadc_GroupId_3: pcEnabled = vadc->GLOBCFG.B.DPCAL3 == 0;
463  break;
464  case IfxVadc_GroupId_4: pcEnabled = vadc->GLOBCFG.B.DPCAL4 == 0;
465  break;
466  case IfxVadc_GroupId_5: pcEnabled = vadc->GLOBCFG.B.DPCAL5 == 0;
467  break;
468  case IfxVadc_GroupId_6: pcEnabled = vadc->GLOBCFG.B.DPCAL6 == 0;
469  break;
470  case IfxVadc_GroupId_7: pcEnabled = vadc->GLOBCFG.B.DPCAL7 == 0;
471  break;
472  default: pcEnabled = FALSE;
473  break;
474  }
475 
476  return pcEnabled;
477 }
478 
479 
480 void IfxVadc_resetKernel(Ifx_VADC *vadc)
481 {
483 
486  vadc->KRST1.B.RST = 1; /* Only if both Kernel reset bits are set a reset is executed */
487  vadc->KRST0.B.RST = 1;
488  IfxScuWdt_setCpuEndinit(passwd);
489 
490  while (vadc->KRST0.B.RSTSTAT == 0) /* Wait until reset is executed */
491 
492  {}
493 
495  vadc->KRSTCLR.B.CLR = 1; /* Clear Kernel reset status bit */
497  IfxScuWdt_setCpuEndinit(passwd);
498 }
499 
500 
502 {
503  Ifx_VADC_GLOBCFG tempGLOBCFG;
504  tempGLOBCFG.U = vadc->GLOBCFG.U;
505  tempGLOBCFG.B.LOSUP = supplyVoltage;
506  tempGLOBCFG.B.DIVWC = 1;
508  vadc->GLOBCFG.U = tempGLOBCFG.U;
510 }
511 
512 
514 {
515  if (slotEnable != FALSE)
516  {
517  vadcG->ARBPR.U |= slotEnable << (IFX_VADC_G_ARBPR_ASEN0_OFF + slot); /* enable Slot */
518  vadcG->ARBPR.U &= ~(IFX_VADC_G_ARBPR_PRIO0_MSK << (slot * 4u)); /* clear Priority */
519  vadcG->ARBPR.U |= (prio << (slot * 4u)); /* Set Priority */
520 
522  {
523  vadcG->ARBPR.U |= 0x1u << (IFX_VADC_G_ARBPR_CSM0_OFF + (slot * 4u)); /* Set cancel inject mode */
524  }
525  else
526  {
527  vadcG->ARBPR.U &= ~(0x1u << (IFX_VADC_G_ARBPR_CSM0_OFF + (slot * 4u))); /* Set Wait for Start mode */
528  }
529  }
530  else
531  {
532  vadcG->ARBPR.U &= ~(IFX_VADC_G_ARBPR_ASEN0_MSK << (IFX_VADC_G_ARBPR_ASEN0_OFF + slot)); /* disable Slot */
533  }
534 }
535 
536 
537 void IfxVadc_setScan(Ifx_VADC_G *group, uint32 channels, uint32 mask)
538 {
539  /* select channels which should take part in the scan sequence */
540  /* the mask allows to specify the channels which should be enabled/disabled */
541  group->ASSEL.U = (group->ASSEL.U & ~mask) | (channels & mask);
542 }
543 
544 
545 void IfxVadc_startupCalibration(Ifx_VADC *vadc)
546 {
547  boolean calibrationRunning;
548  uint8 adcCalGroupNum;
549 
550  /* Start calibration */
552  /* Set SUCAL bit */
555 
556  /* Wait for hardware self-test and calibration to complete */
557  /* Wait until Calibration is done */
558  do
559  {
560  calibrationRunning = FALSE;
561 
562  for (adcCalGroupNum = 0; adcCalGroupNum < IFXVADC_NUM_ADC_CAL_GROUPS; adcCalGroupNum++)
563  {
564  if (IfxVadc_getAdcCalibrationActiveState(vadc, adcCalGroupNum) != 0) /* Check ADC Calibration Flag CAL */
565  {
566  calibrationRunning = TRUE;
567  }
568  else
569  {
570  /* do nothing */
571  }
572  }
573  } while (calibrationRunning == TRUE); /* wait until calibration of all calibrated kernels are done */
574 }