PWM_CCU4: PWM_CCU4.c Source File

PWM CCU4

PWM_CCU4.c
Go to the documentation of this file.
1 
65 /***********************************************************************************************************************
66  * HEADER FILES
67  **********************************************************************************************************************/
68 #include "pwm_ccu4.h"
69 
70 /***********************************************************************************************************************
71  * MACROS
72  **********************************************************************************************************************/
73 
74 /***********************************************************************************************************************
75  * LOCAL DATA
76  **********************************************************************************************************************/
77 
78 /***********************************************************************************************************************
79  * LOCAL ROUTINES
80  **********************************************************************************************************************/
81 
82 /* Initialize the App Interrupts */
83 static void PWM_CCU4_lInit_Interrupt(PWM_CCU4_t* handle_ptr);
84 
85 /* Initialize the App events and configurations */
86 static void PWM_CCU4_lConfigure_Events(PWM_CCU4_t* handle_ptr);
87 
88 /**********************************************************************************************************************
89  * API IMPLEMENTATION
90  **********************************************************************************************************************/
91 
92 /* API to retrieve App version info */
93 DAVE_APP_VERSION_t PWM_CCU4_GetAppVersion(void)
94 {
95  DAVE_APP_VERSION_t version;
96 
97  version.major = PWM_CCU4_MAJOR_VERSION;
98  version.minor = PWM_CCU4_MINOR_VERSION;
99  version.patch = PWM_CCU4_PATCH_VERSION;
100 
101  return version;
102 }
103 
104 /* This function initializes the app */
106 {
107  PWM_CCU4_STATUS_t status;
108  GLOBAL_CCU4_STATUS_t status_ccu4_global;
109  uint32_t frequency_module;
110  uint32_t prescalar;
111 
112  status = PWM_CCU4_STATUS_FAILURE;
113  status_ccu4_global = GLOBAL_CCU4_STATUS_FAILURE;
114  XMC_ASSERT("PWM_CCU4_Init:handle_ptr is NULL", (handle_ptr != NULL));
115 
116  if (PWM_CCU4_STATE_UNINITIALIZED == handle_ptr->state)
117  {
118  /* Initialize consumed Apps */
119  status_ccu4_global = GLOBAL_CCU4_Init(handle_ptr->config_ptr->global_ccu4_handle);
120 
121  /* Initialize CCU4x_CC4y slice */
122  if (GLOBAL_CCU4_STATUS_SUCCESS == status_ccu4_global)
123  {
124  XMC_DEBUG("PWM_CCU4_Init:Initilizing slice");
125 
126  /* Configure CCU4x_CC4y slice as timer */
127  XMC_CCU4_SLICE_CompareInit(handle_ptr->ccu4_slice_ptr, handle_ptr->config_ptr->ccu4_cc4_slice_timer_ptr);
128  /* Set period match value of the timer */
129  XMC_CCU4_SLICE_SetTimerPeriodMatch(handle_ptr->ccu4_slice_ptr, handle_ptr->config_ptr->period_value);
130 
131  /* Set timer compare match value for channel 1 */
132  XMC_CCU4_SLICE_SetTimerCompareMatch(handle_ptr->ccu4_slice_ptr, (uint16_t) handle_ptr->config_ptr->compare_value);
133 
134  if (1U == handle_ptr->config_ptr->ccu4_cc4_slice_timer_ptr->mcm_enable)
135  {
136  XMC_CCU4_SetMultiChannelShadowTransferMode(handle_ptr->ccu4_module_ptr,
137  (uint32_t) handle_ptr->config_ptr->mcm_shadow_txfr_mode);
138  }
139 
140 #if (UC_SERIES == XMC14) /*below feature available in XMC14xx devices */
141  XMC_CCU4_SLICE_SetShadowTransferMode(handle_ptr->ccu4_slice_ptr, handle_ptr->config_ptr->shadow_transfer_mode);
142  XMC_CCU4_SLICE_WriteImmediateAfterShadowTransfer(handle_ptr->ccu4_slice_ptr,
143  handle_ptr->config_ptr->immediate_write);
144  XMC_CCU4_SLICE_EnableAutomaticShadowTransferRequest(handle_ptr->ccu4_slice_ptr,
146  if((bool)true == handle_ptr->config_ptr->cascaded_shadow_txfr_enable)
147  {
148  XMC_CCU4_SLICE_EnableCascadedShadowTransfer(handle_ptr->ccu4_slice_ptr);
149  }
150 #endif
151 
152  /* Transfer value from shadow timer registers to actual timer registers */
153  XMC_CCU4_EnableShadowTransfer(handle_ptr->ccu4_module_ptr, handle_ptr->shadow_txfr_msk);
154  XMC_CCU4_EnableShadowTransfer(handle_ptr->ccu4_module_ptr, handle_ptr->dither_shadow_txfr_msk);
155 
156  /* Configure events */
157  PWM_CCU4_lConfigure_Events(handle_ptr);
158 
159  /* Enable the interrupts */
160  PWM_CCU4_lInit_Interrupt(handle_ptr);
161 
162  /*Initializes the GPIO*/
163  if ((bool) true == handle_ptr->config_ptr->gpio_ch_out_enable)
164  {
165  XMC_GPIO_Init(handle_ptr->config_ptr->gpio_ch_out_ptr, handle_ptr->config_ptr->gpio_ch_out_pin,
166  handle_ptr->config_ptr->gpio_ch_out_config_ptr);
167  }
168 
169  frequency_module = handle_ptr->config_ptr->global_ccu4_handle->module_frequency;
170  prescalar = (uint32_t) handle_ptr->config_ptr->ccu4_cc4_slice_timer_ptr->prescaler_initval;
171  frequency_module = frequency_module / ((uint32_t) 1 << prescalar);
172  handle_ptr->frequency_tclk = frequency_module;
173 
174  handle_ptr->state = PWM_CCU4_STATE_INITIALIZED;
175  status = PWM_CCU4_STATUS_SUCCESS;
176 
177  /* Start the PWM generation if start at initialization is enabled */
178  if ((bool) true == handle_ptr->config_ptr->start_control)
179  {
180  status = PWM_CCU4_Start(handle_ptr);
181  }
182  }
183  else
184  {
185  handle_ptr->state = PWM_CCU4_STATE_UNINITIALIZED;
186  }
187 
188  }
189  else
190  {
192  XMC_DEBUG("PWM_CCU4_Init:PWM_CCU4_STATUS_ALREADY_INITIALIZED");
193  }
194 
195  return (status);
196 } /* end of PWM_CCU4_Init() api */
197 
198 static void PWM_CCU4_lInit_Interrupt(PWM_CCU4_t* handle_ptr)
199 {
200 
201  /* Enable events. Bind event to corresponding service request node.Enable Interrupts. The user may choose to
202  disable the interrupts by LLD calls. */
203  if ((bool) true == handle_ptr->config_ptr->int_per_match)
204  {
205  XMC_DEBUG("PWM_CCU4_Init: Interrupt period match enable");
206  XMC_CCU4_SLICE_SetInterruptNode(handle_ptr->ccu4_slice_ptr, XMC_CCU4_SLICE_IRQ_ID_PERIOD_MATCH,
207  handle_ptr->config_ptr->sr_per_match);
208  XMC_CCU4_SLICE_EnableEvent(handle_ptr->ccu4_slice_ptr, XMC_CCU4_SLICE_IRQ_ID_PERIOD_MATCH);
209  }
210 
211  if ((bool) true == handle_ptr->config_ptr->int_cmp_match_up)
212  {
213  XMC_DEBUG("PWM_CCU4_Init: Interrupt compare match up enable");
214  XMC_CCU4_SLICE_SetInterruptNode(handle_ptr->ccu4_slice_ptr, XMC_CCU4_SLICE_IRQ_ID_COMPARE_MATCH_UP,
215  handle_ptr->config_ptr->sr_cmp_match_up);
216  XMC_CCU4_SLICE_EnableEvent(handle_ptr->ccu4_slice_ptr, XMC_CCU4_SLICE_IRQ_ID_COMPARE_MATCH_UP);
217  }
218 
219  if ((bool) true == handle_ptr->config_ptr->int_cmp_match_down)
220  {
221  XMC_DEBUG("PWM_CCU4_Init: Interrupt compare match down enable");
222  XMC_CCU4_SLICE_SetInterruptNode(handle_ptr->ccu4_slice_ptr, XMC_CCU4_SLICE_IRQ_ID_COMPARE_MATCH_DOWN,
223  handle_ptr->config_ptr->sr_cmp_match_down);
224  XMC_CCU4_SLICE_EnableEvent(handle_ptr->ccu4_slice_ptr, XMC_CCU4_SLICE_IRQ_ID_COMPARE_MATCH_DOWN);
225  }
226 
227  if ((bool) true == handle_ptr->config_ptr->int_one_match_down)
228  {
229  XMC_DEBUG("PWM_CCU4_Init: Interrupt one match enable");
230  XMC_CCU4_SLICE_SetInterruptNode(handle_ptr->ccu4_slice_ptr, XMC_CCU4_SLICE_IRQ_ID_ONE_MATCH,
231  handle_ptr->config_ptr->sr_one_match_down);
232  XMC_CCU4_SLICE_EnableEvent(handle_ptr->ccu4_slice_ptr, XMC_CCU4_SLICE_IRQ_ID_ONE_MATCH);
233  }
234 
235  if ((bool) true == handle_ptr->config_ptr->int_e0)
236  {
237  XMC_DEBUG("PWM_CCU4_Init: Interrupt event 0 enable");
238  XMC_CCU4_SLICE_SetInterruptNode(handle_ptr->ccu4_slice_ptr, XMC_CCU4_SLICE_IRQ_ID_EVENT0,
239  handle_ptr->config_ptr->sr_e0);
240  XMC_CCU4_SLICE_EnableEvent(handle_ptr->ccu4_slice_ptr, XMC_CCU4_SLICE_IRQ_ID_EVENT0);
241  }
242 
243  if ((bool) true == handle_ptr->config_ptr->int_e1)
244  {
245  XMC_DEBUG("PWM_CCU4_Init: Interrupt event 1 enable");
246  XMC_CCU4_SLICE_SetInterruptNode(handle_ptr->ccu4_slice_ptr, XMC_CCU4_SLICE_IRQ_ID_EVENT1,
247  handle_ptr->config_ptr->sr_e1);
248  XMC_CCU4_SLICE_EnableEvent(handle_ptr->ccu4_slice_ptr, XMC_CCU4_SLICE_IRQ_ID_EVENT1);
249  }
250 
251  if ((bool) true == handle_ptr->config_ptr->int_e2)
252  {
253  XMC_DEBUG("PWM_CCU4_Init: Interrupt event 2 enable");
254  XMC_CCU4_SLICE_SetInterruptNode(handle_ptr->ccu4_slice_ptr, XMC_CCU4_SLICE_IRQ_ID_EVENT2,
255  handle_ptr->config_ptr->sr_e2);
256  XMC_CCU4_SLICE_EnableEvent(handle_ptr->ccu4_slice_ptr, XMC_CCU4_SLICE_IRQ_ID_EVENT2);
257  }
258 }
259 
260 static void PWM_CCU4_lConfigure_Events(PWM_CCU4_t* handle_ptr)
261 {
262 
263  /* Configure slice to a external event 0 */
264  XMC_CCU4_SLICE_ConfigureEvent(handle_ptr->ccu4_slice_ptr, XMC_CCU4_SLICE_EVENT_0,
265  handle_ptr->config_ptr->event0_config_ptr);
266 
267  /* Configure slice to a external event 1 */
268  XMC_CCU4_SLICE_ConfigureEvent(handle_ptr->ccu4_slice_ptr, XMC_CCU4_SLICE_EVENT_1,
269  handle_ptr->config_ptr->event1_config_ptr);
270 
271  /* Configure slice to a external event 2 */
272  XMC_CCU4_SLICE_ConfigureEvent(handle_ptr->ccu4_slice_ptr, XMC_CCU4_SLICE_EVENT_2,
273  handle_ptr->config_ptr->event2_config_ptr);
274 
275  /* External signal controls start of the timer */
276  if (XMC_CCU4_SLICE_EVENT_NONE != handle_ptr->config_ptr->ext_start_event)
277  {
278  XMC_CCU4_SLICE_StartConfig(handle_ptr->ccu4_slice_ptr, handle_ptr->config_ptr->ext_start_event,
279  handle_ptr->config_ptr->ext_start_mode);
280  }
281 
282  /* External signal can stop the timer */
283  if (XMC_CCU4_SLICE_EVENT_NONE != handle_ptr->config_ptr->ext_stop_event)
284  {
285  XMC_CCU4_SLICE_StopConfig(handle_ptr->ccu4_slice_ptr, handle_ptr->config_ptr->ext_stop_event,
286  handle_ptr->config_ptr->ext_stop_mode);
287  }
288 
289  /* External signal can change the timer counting direction */
290  if (XMC_CCU4_SLICE_EVENT_NONE != handle_ptr->config_ptr->ext_count_dir_event)
291  {
292  XMC_CCU4_SLICE_DirectionConfig(handle_ptr->ccu4_slice_ptr, handle_ptr->config_ptr->ext_count_dir_event);
293  }
294  /* External signal can stop the timer and the timer value remains same */
295  if (XMC_CCU4_SLICE_EVENT_NONE != handle_ptr->config_ptr->ext_gate_event)
296  {
297  XMC_CCU4_SLICE_GateConfig(handle_ptr->ccu4_slice_ptr, handle_ptr->config_ptr->ext_gate_event);
298  }
299  /* Timer increments on external signal */
300  if (XMC_CCU4_SLICE_EVENT_NONE != handle_ptr->config_ptr->ext_count_event)
301  {
302  XMC_CCU4_SLICE_CountConfig(handle_ptr->ccu4_slice_ptr, handle_ptr->config_ptr->ext_count_event);
303  }
304  /* Timer gets loaded with compare register value or period register value on external signal */
305  if (XMC_CCU4_SLICE_EVENT_NONE != handle_ptr->config_ptr->ext_load_event)
306  {
307  XMC_CCU4_SLICE_LoadConfig(handle_ptr->ccu4_slice_ptr, handle_ptr->config_ptr->ext_load_event);
308  }
309  /* External signal PWM signal (ST bit) output gets modulated by external signal */
310  if (XMC_CCU4_SLICE_EVENT_NONE != handle_ptr->config_ptr->ext_mod_event)
311  {
312  XMC_CCU4_SLICE_ModulationConfig(handle_ptr->ccu4_slice_ptr, handle_ptr->config_ptr->ext_mod_event,
313  handle_ptr->config_ptr->ext_mod_mode, handle_ptr->config_ptr->ext_mod_sync);
314  }
315 
316  /* PWM signal (ST bit) output gets modulated by external signal */
317  if (XMC_CCU4_SLICE_EVENT_2 == handle_ptr->config_ptr->ext_trap_event)
318  {
319  XMC_CCU4_SLICE_TrapConfig(handle_ptr->ccu4_slice_ptr, handle_ptr->config_ptr->ext_trap_exit,
320  handle_ptr->config_ptr->ext_trap_sync);
321 
322  if ((bool) true == handle_ptr->config_ptr->ext_trap_enable)
323  {
324  XMC_CCU4_SLICE_EnableTrap(handle_ptr->ccu4_slice_ptr);
325  }
326  }
327  if ((XMC_CCU4_SLICE_EVENT_1 == handle_ptr->config_ptr->ext_override_edge_event) && (XMC_CCU4_SLICE_EVENT_2
328  == handle_ptr->config_ptr->ext_override_level_event))
329  {
330  XMC_CCU4_SLICE_ConfigureStatusBitOverrideEvent(handle_ptr->ccu4_slice_ptr,
331  handle_ptr->config_ptr->event1_config_ptr,
332  handle_ptr->config_ptr->event2_config_ptr);
333  XMC_CCU4_SLICE_StatusBitOverrideConfig(handle_ptr->ccu4_slice_ptr);
334  }
335 
336 }
337 /**********************************************************************************************************/
338 /*Starts the CCU4_CC4 slice. This needs to be called even if external start is configured.*/
340 {
341  PWM_CCU4_STATUS_t status;
342 
343  status = PWM_CCU4_STATUS_FAILURE;
344  XMC_ASSERT("PWM_CCU4_Start:handle_ptr NULL", (handle_ptr != NULL));
345  if ((PWM_CCU4_STATE_INITIALIZED == handle_ptr->state) || (PWM_CCU4_STATE_STOPPED == handle_ptr->state))
346  {
347  /* clear IDLE mode for the slice; Start timer */
348  XMC_CCU4_EnableClock(handle_ptr->ccu4_module_ptr, handle_ptr->slice_number);
349 
350  if (XMC_CCU4_SLICE_EVENT_NONE == handle_ptr->config_ptr->ext_start_event)
351  {
352  XMC_CCU4_SLICE_StartTimer(handle_ptr->ccu4_slice_ptr);
353  }
354 
355  handle_ptr->state = PWM_CCU4_STATE_RUNNING;
356  status = PWM_CCU4_STATUS_SUCCESS;
357  XMC_DEBUG("PWM_CCU4_Start:start PWM");
358  }
359  return (status);
360 } /* end of PWM_CCU4_Start() api */
361 /**********************************************************************************************************/
362 /*Stops the CCU4_CC4 slice. */
364 {
365  PWM_CCU4_STATUS_t status;
366 
367  status = PWM_CCU4_STATUS_FAILURE;
368  XMC_ASSERT("PWM_CCU4_Stop:handle_ptr NULL", (handle_ptr != NULL));
369  if (PWM_CCU4_STATE_UNINITIALIZED != handle_ptr->state)
370  {
371  XMC_CCU4_SLICE_StopTimer(handle_ptr->ccu4_slice_ptr);
372  XMC_CCU4_SLICE_ClearTimer(handle_ptr->ccu4_slice_ptr);
373 
374  handle_ptr->state = PWM_CCU4_STATE_STOPPED;
375  status = PWM_CCU4_STATUS_SUCCESS;
376  XMC_DEBUG("PWM_CCU4_Stop:stop PWM");
377  }
378  return (status);
379 
380 } /* end of PWM_CCU4_Stop() api */
381 /**********************************************************************************************************/
382 /*Gets the timer value of CCU4_CC4 slice. */
383 uint32_t PWM_CCU4_GetTimerValue(PWM_CCU4_t* handle_ptr)
384 {
385  uint32_t timer_value;
386  XMC_ASSERT("PWM_CCU4_GetTimerValue:handle_ptr NULL", (handle_ptr != NULL));
387  timer_value = (uint32_t) XMC_CCU4_SLICE_GetTimerValue(handle_ptr->ccu4_slice_ptr);
388  XMC_DEBUG("PWM_CCU4_GetTimerValue:timer value");
389  return (timer_value);
390 }/* end of PWM_CCU4_GetTimerValue() api */
391 /**********************************************************************************************************/
392 /*Gets the status of CCU4_CC4 slice. */
394 {
395  bool status_timer;
396  XMC_ASSERT("PWM_CCU4_GetTimerStatus:handle_ptr NULL", (handle_ptr != NULL));
397  status_timer = XMC_CCU4_SLICE_IsTimerRunning(handle_ptr->ccu4_slice_ptr);
398  return (status_timer);
399 
400 } /* end of PWM_CCU4_GetStatus() api */
401 
402 /**********************************************************************************************************/
403 
404 /*Sets the frequency for CCU4_CC4 slice. */
405 PWM_CCU4_STATUS_t PWM_CCU4_SetFreq(PWM_CCU4_t* handle_ptr, uint32_t pwm_freq_hz)
406 {
407  PWM_CCU4_STATUS_t status;
408  uint32_t frequency_tclk;
409  uint32_t period;
410  uint32_t duty;
411  uint16_t compare;
412 
413  status = PWM_CCU4_STATUS_FAILURE;
414  frequency_tclk = 0U;
415  XMC_ASSERT("PWM_CCU4_SetFreq:handle_ptr NULL", (handle_ptr != NULL));
416  if (PWM_CCU4_STATE_UNINITIALIZED != handle_ptr->state)
417  {
418  if (0U == pwm_freq_hz)
419  {
420  XMC_DEBUG("PWM_CCU4_SetFreq:cannot set frequency 0Hz");
421  }
422  else
423  {
424  frequency_tclk = handle_ptr->frequency_tclk;
425  period = frequency_tclk / pwm_freq_hz;
426 
427  if ((uint32_t) XMC_CCU4_SLICE_TIMER_COUNT_MODE_CA == handle_ptr->config_ptr->ccu4_cc4_slice_timer_ptr->timer_mode)
428  {
429  period = period >> 1U;/*divide by 2*/
430  }
431 
432  if ((period != 0U) && (period <= PWM_CCU4_MAX_TIMER_COUNT))
433  {
434  /*Calculate the current duty cycle in no-timer concatenation mode*/
435  duty = handle_ptr->sym_duty;
436 
437  duty = (PWM_CCU4_DUTY_FULL_SCALE - duty);
438  duty = duty * period;
439  duty = duty / PWM_CCU4_DUTY_FULL_SCALE;
440 
441  compare = (uint16_t) duty;
442 
443  XMC_CCU4_SLICE_SetTimerPeriodMatch(handle_ptr->ccu4_slice_ptr, (uint16_t)(period - 1U));
444  XMC_CCU4_SLICE_SetTimerCompareMatch(handle_ptr->ccu4_slice_ptr, compare);
445  XMC_CCU4_EnableShadowTransfer(handle_ptr->ccu4_module_ptr, handle_ptr->shadow_txfr_msk);
446  XMC_DEBUG("PWM_CCU4_SetFreq:frequency set");
447  status = PWM_CCU4_STATUS_SUCCESS;
448  }
449  }
450  }
451  return (status);
452 
453 } /* end of PWM_CCU4_SetFreqSymmetric() api */
454 
455 /**********************************************************************************************************/
456 
457 /*Sets the duty cycle (uint32_t) for CCU4_CC4 slice. */
458 PWM_CCU4_STATUS_t PWM_CCU4_SetDutyCycle(PWM_CCU4_t* handle_ptr, uint32_t duty_cycle)
459 {
460  PWM_CCU4_STATUS_t status;
461  uint32_t period;
462  uint32_t compare;
463 
464  status = PWM_CCU4_STATUS_FAILURE;
465  XMC_ASSERT("PWM_CCU4_SetDutyCycle:handle_ptr NULL", (handle_ptr != NULL));
466  if (PWM_CCU4_STATE_UNINITIALIZED != handle_ptr->state)
467  {
468  /* duty cycle has to be in between 0 and 100 */
469  if ((duty_cycle > PWM_CCU4_SYM_DUTY_MAX))
470  {
471  XMC_DEBUG("PWM_CCU4_SetDutyCycle:Cannot set duty cycle > 100%");
472  }
473  else
474  {
475  period = (uint32_t) XMC_CCU4_SLICE_GetTimerPeriodMatch(handle_ptr->ccu4_slice_ptr) + 1U;
476 
477  /* Duty Cycle(symmetric) = (PR-CR1)+1 / period */
478  compare = ((period * (PWM_CCU4_DUTY_FULL_SCALE - duty_cycle)) / PWM_CCU4_DUTY_FULL_SCALE);
479 
480  XMC_CCU4_SLICE_SetTimerCompareMatch(handle_ptr->ccu4_slice_ptr, (uint16_t) compare);
481  XMC_CCU4_EnableShadowTransfer(handle_ptr->ccu4_module_ptr, handle_ptr->shadow_txfr_msk);
482 
483  handle_ptr->sym_duty = duty_cycle;
484 
485  XMC_DEBUG("PWM_CCU4_SetDutyCycle:dutycycle set");
486  status = PWM_CCU4_STATUS_SUCCESS;
487  }
488  }
489  return (status);
490 } /* end of PWM_CCU4_SetDutyCycle() api */
491 
492 /**********************************************************************************************************/
493 
494 /*Sets the frequency and duty cycle for CCU4_CC4 slice Symmetric Mode. */
495 PWM_CCU4_STATUS_t PWM_CCU4_SetFreqAndDutyCycle(PWM_CCU4_t* handle_ptr, uint32_t pwm_freq_hz, uint32_t duty)
496 {
497 
498  PWM_CCU4_STATUS_t status;
499  uint32_t frequency_tclk;
500  uint32_t period;
501  uint32_t compare;
502 
503  status = PWM_CCU4_STATUS_FAILURE;
504  frequency_tclk = 0U;
505  XMC_ASSERT("PWM_CCU4_SetFreqAndDutyCycle:handle_ptr NULL", (handle_ptr != NULL));
506  if (PWM_CCU4_STATE_UNINITIALIZED != handle_ptr->state)
507  {
508  if (0U == pwm_freq_hz)
509  {
510  XMC_DEBUG("PWM_CCU4_SetFreqAndDutyCycleSymmetric:cannot set frequency 0Hz");
511  }
512  else if (duty > PWM_CCU4_SYM_DUTY_MAX)
513  {
514  XMC_DEBUG("PWM_CCU4_SetFreqAndDutyCycle:duty > 100%");
515  }
516  else
517  {
518  frequency_tclk = handle_ptr->frequency_tclk;
519  period = frequency_tclk / pwm_freq_hz;
520 
521  if ((uint32_t) XMC_CCU4_SLICE_TIMER_COUNT_MODE_CA == handle_ptr->config_ptr->ccu4_cc4_slice_timer_ptr->timer_mode)
522  {
523  period = period >> 1U;/*divide by 2*/
524  }
525 
526  if ((period != 0U) && (period <= PWM_CCU4_MAX_TIMER_COUNT))
527  {
528  /*Calculate the current duty cycle in no-timer concatenation mode*/
529  compare = ((period * (PWM_CCU4_DUTY_FULL_SCALE - duty)) / PWM_CCU4_DUTY_FULL_SCALE);
530 
531  XMC_CCU4_SLICE_SetTimerPeriodMatch(handle_ptr->ccu4_slice_ptr, (uint16_t)(period - 1U));
532  XMC_CCU4_SLICE_SetTimerCompareMatch(handle_ptr->ccu4_slice_ptr, (uint16_t) compare);
533 
534  XMC_CCU4_EnableShadowTransfer(handle_ptr->ccu4_module_ptr, handle_ptr->shadow_txfr_msk);
535 
536  handle_ptr->sym_duty = duty;
537 
538  XMC_DEBUG("PWM_CCU4_SetFreqAndDutyCycle:frequency set");
539  status = PWM_CCU4_STATUS_SUCCESS;
540  }
541  }
542  }
543  return (status);
544 
545 }/* end of PWM_CCU4_SetFreqAndDutyCycle() api */
546 
547 /**********************************************************************************************************/
548 
549 /*Sets the dither value, enables the dither. */
550 void PWM_CCU4_SetDither(PWM_CCU4_t* handle_ptr, bool dither_period, bool dither_comp, uint8_t dither_value)
551 {
552 
553  XMC_ASSERT("PWM_CCU4_SetDither:handle_ptr NULL", (handle_ptr != NULL));
554  XMC_CCU4_SLICE_EnableDithering(handle_ptr->ccu4_slice_ptr, dither_period, dither_comp, dither_value);
555  XMC_CCU4_EnableShadowTransfer(handle_ptr->ccu4_module_ptr, handle_ptr->dither_shadow_txfr_msk);
556  XMC_DEBUG("PWM_CCU4_SetDither:dither compare value set");
557 
558 }/* end of PWM_CCU4_SetDither() api */
559 
560 /**********************************************************************************************************/
561 
562 /*exits trap condition if trap signal is inactive */
564 {
565 
566  XMC_ASSERT("PWM_CCU4_ClearTrap:handle_ptr NULL", (handle_ptr != NULL));
567  XMC_CCU4_SLICE_ClearEvent(handle_ptr->ccu4_slice_ptr, XMC_CCU4_SLICE_IRQ_ID_EVENT2);
568  XMC_DEBUG("PWM_CCU4_ClearTrap:trap event cleared");
569 
570 }/* end of PWM_CCU4_ClearTrap() api */
571 
572 /**********************************************************************************************************/
573 
574 /*Gets the interrupt status of CCU4_CC4 slice. */
575 bool PWM_CCU4_GetInterruptStatus(PWM_CCU4_t* handle_ptr, XMC_CCU4_SLICE_IRQ_ID_t pwm_interrupt)
576 {
577  bool status = (bool) false;
578  XMC_ASSERT("PWM_CCU4_GetInterruptStatus:handle_ptr NULL", (handle_ptr != NULL));
579  status = XMC_CCU4_SLICE_GetEvent(handle_ptr->ccu4_slice_ptr, pwm_interrupt);
580  return (status);
581 } /* end of PWM_CCU4_GetInterruptStatus() api */
582 
583 /**********************************************************************************************************/
584 
585 /*Acknowledges the interrupt of CCU4_CC4 slice. */
586 void PWM_CCU4_ClearEvent(PWM_CCU4_t* handle_ptr, XMC_CCU4_SLICE_IRQ_ID_t pwm_interrupt)
587 {
588  XMC_ASSERT("PWM_CCU4_ClearEvent:handle_ptr NULL", (handle_ptr != NULL));
589  XMC_CCU4_SLICE_ClearEvent(handle_ptr->ccu4_slice_ptr, pwm_interrupt);
590  XMC_DEBUG("PWM_CCU4_ClearEvent:Acknowledge Interrupt");
591 } /* end of PWM_CCU4_ClearEvent() api */
592 
593 /* end of CCU4 function definitions */
594