iLLD_TC27xD  1.0
IfxCcu6_PwmBc.c
Go to the documentation of this file.
1 /**
2  * \file IfxCcu6_PwmBc.c
3  * \brief CCU6 PWMBC 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 /******************************************************************************/
27 /*----------------------------------Includes----------------------------------*/
28 /******************************************************************************/
29 
30 #include "IfxCcu6_PwmBc.h"
31 
32 /******************************************************************************/
33 /*-------------------------Function Implementations---------------------------*/
34 /******************************************************************************/
35 
37 {
38  uint32 currentTime, previousTime;
39  float32 speed;
40 
43 
44  // TODO -- FIX IT --
45  speed = (currentTime - previousTime) * (6 / (pwmBc->base.t13Frequency));
46  speed = speed * 60 * 100000; //convertion to RPM (minutes),
47  return speed;
48 }
49 
50 
52 {
53  Ifx_CCU6 *ccu6SFR = config->ccu6; // pointer to CCU6 registers
54  pwmBc->ccu6 = ccu6SFR; // adding register pointer to module handler
55 
56  /* -- hardware module initialisation -- */
57 
58  // enable module if it hasn't been enabled by any other interface //
59  if (IfxCcu6_isModuleEnabled(ccu6SFR) == FALSE)
60  {
61  IfxCcu6_enableModule(ccu6SFR);
62  }
63 
64  /* -- Timer13 initialisation -- */
65 
66  // enable Timer13 if it hasn't been enabled by any other interface //
68  {
70  }
71 
72  // clock initialisation //
73  pwmBc->base.t13Frequency = IfxCcu6_setT13Frequency(ccu6SFR, config->base.t13Frequency, config->base.t13Period);
74 
75  // duty cycle initialisation //
76 
78 
80 
81  // if Timer 13 start is in sync with Timer 12 //
82 
83  if (config->trigger.t13InSyncWithT12)
84  {
87  }
88 
89  /* -- Timer12 initialisation -- */
90 
91  // enable Timer12 if it hasn't been enabled by any other interface //
93  {
95  }
96 
97  // clock initialisation //
98 
99  IfxCcu6_setT12Frequency(ccu6SFR, config->base.t12Frequency, config->base.t12Period, config->timer12.countMode);
100 
101  // duty cycle initialisation //
102 
104 
105  // hall effect noise filter initialisation
106  if (config->base.noiseFilter)
107  {
108  IfxCcu6_setDeadTimeValue(ccu6SFR, (uint8)config->base.noiseFilter);
111  }
112 
113  // channel initialisation for hall sensor mode ( for Brush Less DC motor)
117 
118  // phase delay initialisation
120 
121  // multichannel control / output pattern control initialisation
124 
125  /* -- output path initialisation -- */
126 
127  //enable Timer13 modulation output path for all T12 channel outs//
128 
132 
133  if (config->pins->cout63 != NULL_PTR)
134  {
136  }
137 
138  // output passive logic configuration //
139  //TODO check correct polarity:
140 
144 
145  if (config->pins->cout63 != NULL_PTR)
146 
147  {
149  }
150 
151  /* -- Pin mapping -- */
152 
153  const IfxCcu6_PwmBc_Pins *pins = config->pins;
154 
155  if (pins != NULL_PTR)
156  {
157  // modulation output pins
158 
159  IfxCcu6_Cc60_Out *cc60Out = pins->cc60Out;
160 
161  if (cc60Out != NULL_PTR)
162  {
163  IfxCcu6_initCc60OutPin(cc60Out, pins->outputMode, pins->pinDriver);
164  }
165 
166  IfxCcu6_Cc61_Out *cc61Out = pins->cc61Out;
167 
168  if (cc61Out != NULL_PTR)
169  {
170  IfxCcu6_initCc61OutPin(cc61Out, pins->outputMode, pins->pinDriver);
171  }
172 
173  IfxCcu6_Cc62_Out *cc62Out = pins->cc62Out;
174 
175  if (cc62Out != NULL_PTR)
176  {
177  IfxCcu6_initCc62OutPin(cc62Out, pins->outputMode, pins->pinDriver);
178  }
179 
180  IfxCcu6_Cout60_Out *cout60 = pins->cout60;
181 
182  if (cout60 != NULL_PTR)
183  {
184  IfxCcu6_initCout60Pin(cout60, pins->outputMode, pins->pinDriver);
185  }
186 
187  IfxCcu6_Cout61_Out *cout61 = pins->cout61;
188 
189  if (cout61 != NULL_PTR)
190  {
191  IfxCcu6_initCout61Pin(cout61, pins->outputMode, pins->pinDriver);
192  }
193 
194  IfxCcu6_Cout62_Out *cout62 = pins->cout62;
195 
196  if (cout62 != NULL_PTR)
197  {
198  IfxCcu6_initCout62Pin(cout62, pins->outputMode, pins->pinDriver);
199  }
200 
201  IfxCcu6_Cout63_Out *cout63 = pins->cout63;
202 
203  if (cout63 != NULL_PTR)
204  {
205  IfxCcu6_initCout63Pin(cout63, pins->outputMode, pins->pinDriver);
206  }
207 
208  // hall sensor input pins
209 
210  IfxCcu6_Ccpos0_In *ccpos0 = pins->ccpos0;
211 
212  if (ccpos0 != NULL_PTR)
213  {
214  IfxCcu6_initCcpos0Pin(ccpos0, pins->inputMode);
215  }
216 
217  IfxCcu6_Ccpos1_In *ccpos1 = pins->ccpos1;
218 
219  if (ccpos1 != NULL_PTR)
220  {
221  IfxCcu6_initCcpos1Pin(ccpos1, pins->inputMode);
222  }
223 
224  IfxCcu6_Ccpos2_In *ccpos2 = pins->ccpos2;
225 
226  if (ccpos2 != NULL_PTR)
227  {
228  IfxCcu6_initCcpos2Pin(ccpos2, pins->inputMode);
229  }
230 
231  IfxCcu6_T12hr_In *t12hr = pins->t12hr;
232 
233  if (t12hr != NULL_PTR)
234  {
235  IfxCcu6_initT12hrPin(t12hr, pins->t1xhrInputMode);
236  }
237 
238  IfxCcu6_T13hr_In *t13hr = pins->t13hr;
239 
240  if (t13hr != NULL_PTR)
241  {
242  IfxCcu6_initT13hrPin(t13hr, pins->t1xhrInputMode);
243  }
244  }
245 
246  /* -- hall pattern configuration (when to start the hall pattern evaluation) -- */
247 
249 
250  /* -- interrupt initialisation -- */
251 
252  if (config->interrupt1.priority > 0)
253  {
254  IfxCcu6_enableInterrupt(config->ccu6, config->interrupt1.source);
256 
257  volatile Ifx_SRC_SRCR *src;
258  src = IfxCcu6_getSrcAddress(config->ccu6, config->interrupt1.serviceRequest);
259  IfxSrc_init(src, config->interrupt1.typeOfService, config->interrupt1.priority);
260  IfxSrc_enable(src);
261  }
262 
263  if (config->interrupt2.priority > 0)
264  {
265  IfxCcu6_enableInterrupt(config->ccu6, config->interrupt2.source);
267 
268  volatile Ifx_SRC_SRCR *src;
269  src = IfxCcu6_getSrcAddress(config->ccu6, config->interrupt2.serviceRequest);
270  IfxSrc_init(src, config->interrupt2.typeOfService, config->interrupt2.priority);
271  IfxSrc_enable(src);
272  }
273 
274  if (config->interrupt3.priority > 0)
275  {
276  IfxCcu6_enableInterrupt(config->ccu6, config->interrupt3.source);
278 
279  volatile Ifx_SRC_SRCR *src;
280  src = IfxCcu6_getSrcAddress(config->ccu6, config->interrupt3.serviceRequest);
281  IfxSrc_init(src, config->interrupt3.typeOfService, config->interrupt3.priority);
282  IfxSrc_enable(src);
283  }
284 
285  if (config->interrupt4.priority > 0)
286  {
287  IfxCcu6_enableInterrupt(config->ccu6, config->interrupt4.source);
289 
290  volatile Ifx_SRC_SRCR *src;
291  src = IfxCcu6_getSrcAddress(config->ccu6, config->interrupt4.serviceRequest);
292  IfxSrc_init(src, config->interrupt4.typeOfService, config->interrupt4.priority);
293  IfxSrc_enable(src);
294  }
295 
296  /* -- output trigger initialisation --*/
297 
298  if (config->trigger.outputTriggerEnabled)
299  {
301  }
302 
303  pwmBc->trigger = config->trigger;
304  pwmBc->hallPatternIndex = 0;
305 
306 #if IFX_CFG_USE_STANDARD_INTERFACE
307  IFX_ASSERT(IFX_VERBOSE_LEVEL_ERROR, (uint32)pwmBc == ((uint32)&pwmBc->base));
308  pwmBc->base.functions.start = (PwmBc_Start) & IfxCcu6_PwmBc_start;
309  pwmBc->base.functions.stop = (PwmBc_Stop) & IfxCcu6_PwmBc_stop;
310  pwmBc->base.functions.updateHallPattern = (PwmBc_UpdateHallPattern) & IfxCcu6_PwmBc_updateHallPattern;
311  pwmBc->base.functions.getMotorSpeed = (PwmBc_GetMotorSpeed) & IfxCcu6_PwmBc_getMotorSpeed;
312 #endif
313 }
314 
315 
317 {
318  const IfxCcu6_PwmBc_Config defaultConfig = {
319  .ccu6 = NULL_PTR, // will be initialized below
320 
321  .base.t12Frequency = 400000,
322  .base.t13Frequency = 400000,
323  .base.t12Period = 100,
324  .base.t13Period = 100,
325  .base.phaseDelay = 20,
326  .base.noiseFilter = 10,
327  .base.activeState = Ifx_ActiveState_high,
328 
329  .timer12 = {
331  .counterValue = 0,
332  },
333 
334  .timer13 = {
335  .counterValue = 0,
336  .compareValue = 0,
337  .t12SyncEvent = IfxCcu6_T13TriggerEvent_noAction,
338  .t12SyncDirection = IfxCcu6_T13TriggerDirection_noAction,
339  },
340 
341  .hallSyncEvent = IfxCcu6_HallSensorTriggerMode_t13PM,
342 
343  .hallPatternIndex = 0,
344 
345  .multiChannelControl = {
348  },
349 
350  .pins = NULL_PTR,
351 
352  .interrupt1 = {
354  .serviceRequest = IfxCcu6_ServiceRequest_0,
355  .priority = 0, // interrupt priority 0
356  .typeOfService = IfxSrc_Tos_cpu0, // type of service CPU0
357  },
358 
359  .interrupt2 = {
361  .serviceRequest = IfxCcu6_ServiceRequest_1,
362  .priority = 0, // interrupt priority 0
363  .typeOfService = IfxSrc_Tos_cpu0, // type of service CPU0
364  },
365 
366  .interrupt3 = {
368  .serviceRequest = IfxCcu6_ServiceRequest_2,
369  .priority = 0, // interrupt priority 0
370  .typeOfService = IfxSrc_Tos_cpu0, // type of service CPU0
371  },
372 
373  .interrupt4 = {
375  .serviceRequest = IfxCcu6_ServiceRequest_3,
376  .priority = 0, // interrupt priority 0
377  .typeOfService = IfxSrc_Tos_cpu0, // type of service CPU0
378  },
379 
380  .trigger = {
381  .t12ExtInputTrigger = NULL_PTR,
382  .t12ExtInputTriggerMode = IfxCcu6_ExternalTriggerMode_risingEdge,
383  .t13ExtInputTrigger = NULL_PTR,
384  .t13ExtInputTriggerMode = IfxCcu6_ExternalTriggerMode_risingEdge,
385  .t13InSyncWithT12 = FALSE,
386 
387  .outputTriggerEnabled = TRUE,
388  .outputLine = IfxCcu6_TrigOut_0,
389  .outputTrigger = IfxCcu6_TrigSel_cout63,
390  },
391  };
392 
393  /* Default Configuration */
394  *config = defaultConfig;
395 
396  /* take over module pointer */
397  config->ccu6 = ccu6;
398 }
399 
400 
402 {
403  // enable shadow transfers
405 
406  // internal start
407  if ((pwmBc->trigger.t13ExtInputTrigger == NULL_PTR) && (pwmBc->trigger.t12ExtInputTrigger == NULL_PTR))
408  {
409  // if T13 start is in sync with T12 start the T12
410  if (pwmBc->trigger.t13InSyncWithT12)
411  {
412  IfxCcu6_startTimer(pwmBc->ccu6, TRUE, FALSE);
413  }
414  else // start both timers
415  {
416  IfxCcu6_startTimer(pwmBc->ccu6, TRUE, TRUE);
417  }
418  }
419 
420  // external start
421  else
422  {
423  // if T13 start is not in sync with T12
424  if (!(pwmBc->trigger.t13InSyncWithT12))
425  {
426  // T13 external start if selected
427  if (pwmBc->trigger.t13ExtInputTrigger != NULL_PTR)
428  {
431  }
432  else // internal start of T13 alone
433  {
434  IfxCcu6_startTimer(pwmBc->ccu6, FALSE, TRUE);
435  }
436  }
437  else
438  {}
439 
440  // T12 external start if selected
441  if (pwmBc->trigger.t12ExtInputTrigger != NULL_PTR)
442  {
445  }
446  else // internal start of T12 alone
447  {
448  IfxCcu6_startTimer(pwmBc->ccu6, TRUE, FALSE);
449  }
450  }
451 }
452 
453 
455 {
457 
458  // if T13 start is in sync with T12, remove sync trigger
459  if (pwmBc->trigger.t13InSyncWithT12)
460  {
463  }
464 
465  // remove external triggers if any
466  if ((pwmBc->trigger.t13ExtInputTrigger != NULL_PTR) || (pwmBc->trigger.t12ExtInputTrigger != NULL_PTR))
467  {
468  if (pwmBc->trigger.t13ExtInputTrigger != NULL_PTR)
469  {
471  }
472  else
473  {
475  }
476  }
477  else
478  {}
479 
480  // stop both timers
481  IfxCcu6_stopTimer(pwmBc->ccu6, TRUE, TRUE);
482 
483  //disable Timer13 modulation output path for all T12 channel outs//
484 
489 }
490 
491 
492 void IfxCcu6_PwmBc_updateHallPattern(IfxCcu6_PwmBc *pwmBc, uint8 controlTable[6][3])
493 {
494  uint8 index = pwmBc->hallPatternIndex;
495 
496  IfxCcu6_updateHallPattern(pwmBc->ccu6, controlTable[index][0], controlTable[index][1], controlTable[index][2]);
497 
498  index++;
499 
500  if (index >= 6)
501  {
502  index = 0;
503  }
504 
505  pwmBc->hallPatternIndex = index;
506 }