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