iLLD_TC29x  1.0
IfxCcu6.c
Go to the documentation of this file.
1 /**
2  * \file IfxCcu6.c
3  * \brief CCU6 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 /******************************************************************************/
27 /*----------------------------------Includes----------------------------------*/
28 /******************************************************************************/
29 
30 #include "IfxCcu6.h"
31 
32 /******************************************************************************/
33 /*-------------------------Function Implementations---------------------------*/
34 /******************************************************************************/
35 
36 void IfxCcu6_connectTrigger(Ifx_CCU6 *ccu6, IfxCcu6_TrigOut outputLine, IfxCcu6_TrigSel selectedTrigger)
37 {
38  unsigned mosel = ccu6->MOSEL.U;
39  uint16 shift = (uint16)outputLine;
40  uint16 data = 2 * selectedTrigger;
41 
42  if (ccu6 == &MODULE_CCU61)
43  {
44  data = data + 1;
45  }
46 
47  mosel = ccu6->MOSEL.U;
48  __ldmst_c(&mosel, (0x7U << shift), (data << shift));
49  ccu6->MOSEL.U = mosel;
50 }
51 
52 
54 {
55  uint32 shift, mask;
56 
57  if (timer != IfxCcu6_TimerId_t13)
58  {
59  if (channelOut != IfxCcu6_ChannelOut_cout3)
60  {
61  shift = channelOut;
62  mask = (1 << shift);
63  ccu6->MODCTR.U = ccu6->MODCTR.U & ~(mask);
64  }
65  else
66  {}
67  }
68  else
69  {
70  if (channelOut != IfxCcu6_ChannelOut_cout3)
71  {
72  shift = channelOut + 8;
73  mask = (1 << shift);
74  ccu6->MODCTR.U = ccu6->MODCTR.U & ~(mask);
75  }
76  else
77  {
78  ccu6->MODCTR.B.ECT13O = FALSE;
79  }
80  }
81 }
82 
83 
84 void IfxCcu6_enableModulationOutput(Ifx_CCU6 *ccu6, IfxCcu6_TimerId timer, IfxCcu6_ChannelOut channelOut)
85 {
86  uint32 shift, mask;
87 
88  if (timer != IfxCcu6_TimerId_t13)
89  {
90  if (channelOut != IfxCcu6_ChannelOut_cout3)
91  {
92  shift = channelOut;
93  mask = (1 << shift);
94  ccu6->MODCTR.U = ccu6->MODCTR.U | (mask);
95  }
96  else
97  {}
98  }
99  else
100  {
101  if (channelOut != IfxCcu6_ChannelOut_cout3)
102  {
103  shift = channelOut + 8;
104  mask = (1 << shift);
105  ccu6->MODCTR.U = ccu6->MODCTR.U | (mask);
106  }
107  else
108  {
109  ccu6->MODCTR.B.ECT13O = TRUE;
110  }
111  }
112 }
113 
114 
115 void IfxCcu6_enableModule(Ifx_CCU6 *ccu6)
116 {
119  ccu6->CLC.U = 0x00000000;
120  IfxScuWdt_setCpuEndinit(passwd);
121 
122  /* Wait until module is enabled */
123  while (IfxCcu6_isModuleEnabled(ccu6) == FALSE)
124  {}
125 }
126 
127 
129 {
130  uint32 value = 0;
131 
132  switch (channel)
133  {
134  case 0:
135  {
136  value = ccu6->CC60R.U;
137  break;
138  }
139  case 1:
140  {
141  value = ccu6->CC61R.U;
142  break;
143  }
144  case 2:
145  {
146  value = ccu6->CC62R.U;
147  break;
148  }
149  }
150 
151  return value;
152 }
153 
154 
156 {
157  uint32 value = 0;
158 
159  switch (channel)
160  {
161  case 0:
162  {
163  value = ccu6->CC60SR.U;
164  break;
165  }
166  case 1:
167  {
168  value = ccu6->CC61SR.U;
169  break;
170  }
171  case 2:
172  {
173  value = ccu6->CC62SR.U;
174  break;
175  }
176  }
177 
178  return value;
179 }
180 
181 
182 sint32 IfxCcu6_getIndex(Ifx_CCU6 *ccu6)
183 {
184  sint32 result = -1, index;
185 
186  for (index = 0; index < IFXCCU6_NUM_MODULES; index++)
187  {
188  if (IfxCcu6_indexMap[index].module == ccu6)
189  {
190  result = IfxCcu6_indexMap[index].index;
191  break;
192  }
193  }
194 
195  return result;
196 }
197 
198 
199 volatile Ifx_SRC_SRCR *IfxCcu6_getSrcAddress(Ifx_CCU6 *ccu6, IfxCcu6_ServiceRequest serviceRequest)
200 {
201  sint32 moduleIdx = IfxCcu6_getIndex(ccu6);
202  volatile Ifx_SRC_SRCR *srcr;
203  srcr = &(MODULE_SRC.CCU6.CCU6[moduleIdx].SR0);
204  return &(srcr[serviceRequest]);
205 }
206 
207 
209 {
210  uint32 result = 0;
211 
212  if (timer != IfxCcu6_TimerId_t13)
213  {
214  result = ccu6->T12.U;
215  }
216  else
217  {
218  result = ccu6->T13.U;
219  }
220 
221  return result;
222 }
223 
224 
225 void IfxCcu6_resetModule(Ifx_CCU6 *ccu6)
226 {
228 
230  ccu6->KRST0.B.RST = 1; /* Only if both Kernel reset bits are set a reset is executed */
231  ccu6->KRST1.B.RST = 1;
232  IfxScuWdt_setCpuEndinit(passwd);
233 
234  while (0 == ccu6->KRST0.B.RSTSTAT) /* Wait until reset is executed */
235 
236  {}
237 
239  ccu6->KRSTCLR.B.CLR = 1; /* Clear Kernel reset status bit */
240  IfxScuWdt_setCpuEndinit(passwd);
241 }
242 
243 
245 {
247  {
248  ccu6->INP.B.INPCC60 = serviceRequest;
249  }
251  {
252  ccu6->INP.B.INPCC61 = serviceRequest;
253  }
255  {
256  ccu6->INP.B.INPCC62 = serviceRequest;
257  }
258  else if ((source == IfxCcu6_InterruptSource_correctHallEvent))
259  {
260  ccu6->INP.B.INPCHE = serviceRequest;
261  }
262  else if ((source == IfxCcu6_InterruptSource_trap) || (source == IfxCcu6_InterruptSource_wrongHallEvent))
263  {
264  ccu6->INP.B.INPERR = serviceRequest;
265  }
267  {
268  ccu6->INP.B.INPT12 = serviceRequest;
269  }
271  {
272  ccu6->INP.B.INPT13 = serviceRequest;
273  }
274  else
275  {
276  __debug();
277  }
278 }
279 
280 
281 void IfxCcu6_setOutputPassiveLevel(Ifx_CCU6 *ccu6, IfxCcu6_ChannelOut channelOut, boolean state)
282 {
283  if (channelOut != IfxCcu6_ChannelOut_cout3)
284  {
285  uint32 shift = channelOut;
286  uint32 mask = (1 << shift);
287  ccu6->PSLR.U = (ccu6->PSLR.U & ~mask) | ((uint32)state << shift);
288  }
289  else
290  {
291  ccu6->PSLR.B.PSL63 = state;
292  }
293 }
294 
295 
297 {
298  uint32 mask = (0x0101U << channel);
299  uint32 mode;
300 
301  if (state == IfxCcu6_CaptureCompareState_set)
302  {
303  mode = 0x0001U;
304  ccu6->CMPMODIF.U = (ccu6->CMPMODIF.U & ~mask) | (mode << channel);
305  }
306 
308  {
309  mode = 0x0100U;
310  ccu6->CMPMODIF.U = (ccu6->CMPMODIF.U & ~mask) | (mode << channel);
311  }
312 
314  {
315  mode = 0x0101U;
316  ccu6->CMPMODIF.U = (ccu6->CMPMODIF.U & ~mask) | (mode << channel);
317  }
318 }
319 
320 
321 void IfxCcu6_setT12CompareValue(Ifx_CCU6 *ccu6, IfxCcu6_T12Channel channel, uint16 value)
322 {
323  switch (channel)
324  {
326  ccu6->CC60SR.B.CCS = value;
327  break;
329  ccu6->CC61SR.B.CCS = value;
330  break;
332  ccu6->CC62SR.B.CCS = value;
333  break;
334  }
335 }
336 
337 
338 float32 IfxCcu6_setT12Frequency(Ifx_CCU6 *ccu6, float32 frequency, Ifx_TimerValue resolution, IfxCcu6_T12CountMode countMode)
339 {
340  uint16 prescaler;
341  float32 freqT1x = 0, periodT1x;
343  Ifx_TimerValue period;
344 
345  for (prescaler = 0; prescaler < 16; prescaler++)
346  {
347  freqT1x = freqCC6 / (1U << prescaler);
348  periodT1x = freqT1x / frequency;
349 
350  if ((periodT1x <= 16386.0) && (periodT1x > resolution))
351  {
352  break;
353  }
354  }
355 
356  if (prescaler < 16)
357  {
358  uint16 periodVal;
359  boolean additionalPrescaler;
360  IfxCcu6_TimerInputClock clockInput;
361 
362  period = ((Ifx_TimerValue)(periodT1x / 2)) * 2;
363 
364  periodVal = (uint16)((countMode != IfxCcu6_T12CountMode_edgeAligned) ? ((period / 2) - 1) : (period - 1));
365  IfxCcu6_setT12PeriodValue(ccu6, periodVal);
367 
368  clockInput = (IfxCcu6_TimerInputClock)(prescaler & 0x7U);
370 
371  additionalPrescaler = ((prescaler & 0x8U) != 0);
372 
373  if (additionalPrescaler)
374  {
376  }
377 
378  IfxCcu6_setT12CountMode(ccu6, countMode);
379 
380  frequency = freqT1x / period;
381  }
382  else
383  {
384  frequency = 0;
385  }
386 
387  return frequency;
388 }
389 
390 
391 void IfxCcu6_setT12InputSignal(Ifx_CCU6 *ccu6, IfxCcu6_T12hr_In *extInput)
392 {
393  ccu6->PISEL2.B.T12EXT = extInput->select >= Ifx_RxSel_e;
394  ccu6->PISEL0.B.IST12HR = extInput->select;
395 
396  IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, extInput->module == ccu6);
397 }
398 
399 
401 {
402  uint32 shift = 6;
403  uint32 mask = (0x0101U << shift);
404  uint32 mode;
405 
406  if (state == IfxCcu6_CaptureCompareState_set)
407  {
408  mode = 0x0001U;
409  ccu6->CMPMODIF.U = (ccu6->CMPMODIF.U & ~mask) | (mode << shift);
410  }
411 
413  {
414  mode = 0x0100U;
415  ccu6->CMPMODIF.U = (ccu6->CMPMODIF.U & ~mask) | (mode << shift);
416  }
417 
419  {
420  mode = 0x0101U;
421  ccu6->CMPMODIF.U = (ccu6->CMPMODIF.U & ~mask) | (mode << shift);
422  }
423 }
424 
425 
426 float32 IfxCcu6_setT13Frequency(Ifx_CCU6 *ccu6, float32 frequency, Ifx_TimerValue resolution)
427 {
428  uint16 prescaler;
429  float32 freqT1x = 0, periodT1x;
431  Ifx_TimerValue period;
432 
433  for (prescaler = 0; prescaler < 16; prescaler++)
434  {
435  freqT1x = freqCC6 / (1U << prescaler);
436  periodT1x = freqT1x / frequency;
437 
438  if ((periodT1x <= 16386.0) && (periodT1x > resolution))
439  {
440  break;
441  }
442  }
443 
444  if (prescaler < 16)
445  {
446  uint16 periodVal;
447  boolean additionalPrescaler;
448  IfxCcu6_TimerInputClock clockInput;
449 
450  period = ((Ifx_TimerValue)(periodT1x / 2)) * 2;
451 
452  periodVal = (uint16)(period - 1);
453  IfxCcu6_setT13PeriodValue(ccu6, periodVal);
455 
456  clockInput = (IfxCcu6_TimerInputClock)(prescaler & 0x7U);
458 
459  additionalPrescaler = ((prescaler & 0x8U) != 0);
460 
461  if (additionalPrescaler)
462  {
464  }
465 
466  frequency = freqT1x / period;
467  }
468  else
469  {
470  /** \retval IfxCcu6_Stat_wrongPwmFreq if the T12 prescaler can't fulfill the
471  * required frequency */
472  frequency = 0;
473  }
474 
475  return frequency;
476 }
477 
478 
479 void IfxCcu6_setT13InputSignal(Ifx_CCU6 *ccu6, IfxCcu6_T13hr_In *extInput)
480 {
481  ccu6->PISEL2.B.T13EXT = extInput->select >= Ifx_RxSel_e;
482  ccu6->PISEL2.B.IST13HR = extInput->select;
483 
484  IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, extInput->module == ccu6);
485 }