1 /**
2  * @file xmc_ccu4.c
3  * @date 2017-04-27
4  *
5  * @cond
6  *********************************************************************************************************************
7  * XMClib v2.1.24 - XMC Peripheral Driver Library
8  *
9  * Copyright (c) 2015-2019, Infineon Technologies AG
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without modification,are permitted provided that the
13  * following conditions are met:
14  *
15  * Redistributions of source code must retain the above copyright notice, this list of conditions and the following
16  * disclaimer.
17  *
18  * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
19  * disclaimer in the documentation and/or other materials provided with the distribution.
20  *
21  * Neither the name of the copyright holders nor the names of its contributors may be used to endorse or promote
22  * products derived from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
25  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE  FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29  * WHETHER IN CONTRACT, STRICT LIABILITY,OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  * To improve the quality of the software, users are encouraged to share modifications, enhancements or bug fixes with
33  * Infineon Technologies AG dave@infineon.com).
34  *********************************************************************************************************************
35  *
36  * Change History
37  * --------------
38  *
39  * 2015-02-20:
40  *     - Initial <br>
41  *
42  * 2015-06-20:
43  *     - Removed definition of GetDriverVersion API <br>
44  *
45  * 2015-07-01:
46  *     - In XMC_CCU4_SLICE_StartConfig(), Options in XMC_ASSERT check for start mode is corrected. <br>
47  *
48  * 2015-07-24:
49  *     - XMC_CCU4_SLICE_ConfigureStatusBitOverrideEvent() is updated to support XMC14 device. <br>
50  *
51  * 2015-08-17:
52  *     - Start of prescaler XMC_CCU4_StartPrescaler() is invoked in XMC_CCU4_Init() API. <br>
53  *     - Bug fix XMC_CCU4_SLICE_ConfigureEvent() during the level setting for XMC14 devices. <br>
54  *     - XMC_CCU4_EnableShadowTransfer() definition is removed, since the API is made as inline. <br>
55  *
56  * 2015-10-07:
57  *     - XMC_CCU4_SLICE_GetEvent() is made as inline.
58  *     - DOC updates for the newly added APIs.
59  *
60  * 2017-02-25:
61  *     - XMC_CCU4_lAssertReset(), XMC_CCU4_lDeassertReset(), XMC_CCU4_lGateClock() and XMC_CCU4_lUngateClock() fix compilation warnings.
62  *
63  * 2017-04-27:
64  *     - XMC_CCU4_SLICE_SetPrescaler() changed div_val parameter to type XMC_CCU4_SLICE_PRESCALER_t
65  *
66  * @endcond
67  */
68 
69 /*********************************************************************************************************************
70  * HEADER FILES
71  ********************************************************************************************************************/
72 #include "xmc_ccu4.h"
73 
74 #if defined(CCU40)
75 #include "xmc_scu.h"
76 /*********************************************************************************************************************
77  * MACROS
78  ********************************************************************************************************************/
79 #define XMC_CCU4_NUM_SLICES_PER_MODULE          (4U)
80 #define XMC_CCU4_SLICE_DITHER_PERIOD_MASK       (1U)
81 #define XMC_CCU4_SLICE_DITHER_DUTYCYCLE_MASK    (2U)
82 #define XMC_CCU4_SLICE_EVENT_EDGE_CONFIG_MASK   (3U)
83 #define XMC_CCU4_SLICE_EVENT_LEVEL_CONFIG_MASK  (1U)
84 #define XMC_CCU4_SLICE_EVENT_FILTER_CONFIG_MASK (3U)
85 #if defined(CCU4V3) /* Defined for XMC1400 devices only */
86 #define XMC_CCU4_SLICE_EVENT_INPUT_CONFIG_MASK  CCU4_CC4_INS1_EV0IS_Msk
87 #else
88 #define XMC_CCU4_SLICE_EVENT_INPUT_CONFIG_MASK  CCU4_CC4_INS_EV0IS_Msk
89 #endif
90 #define XMC_CCU4_GIDLC_CLOCK_MASK               (15U)
91 #define XMC_CCU4_GCSS_SLICE0_MASK               (1U)
92 #define XMC_CCU4_GCSS_SLICE1_MASK               (16U)
93 #define XMC_CCU4_GCSS_SLICE2_MASK               (256U)
94 #define XMC_CCU4_GCSS_SLICE3_MASK               (4096U)
95 
96 /** Macro to check if the clock selected enum passed is valid */
97 #define XMC_CCU4_SLICE_CHECK_CLOCK(clock) \
98     ((clock == XMC_CCU4_CLOCK_SCU)        || \
99      (clock == XMC_CCU4_CLOCK_EXTERNAL_A) || \
100      (clock == XMC_CCU4_CLOCK_EXTERNAL_B) || \
101      (clock == XMC_CCU4_CLOCK_EXTERNAL_C))
102 
103 /** Macro used to check if the event ID is valid*/
104 #define XMC_CCU4_SLICE_CHECK_EVENT_ID(event_id) \
105     ((event_id == XMC_CCU4_SLICE_EVENT_NONE)|| \
106      (event_id == XMC_CCU4_SLICE_EVENT_0)   || \
107      (event_id == XMC_CCU4_SLICE_EVENT_1)   || \
108      (event_id == XMC_CCU4_SLICE_EVENT_2))
109 
110 /** Macro used to check if the edge sensitivity is valid*/
111 #define XMC_CCU4_SLICE_CHECK_EDGE_SENSITIVITY(edge) \
112     ((edge == XMC_CCU4_SLICE_EVENT_EDGE_SENSITIVITY_NONE)        || \
113      (edge == XMC_CCU4_SLICE_EVENT_EDGE_SENSITIVITY_RISING_EDGE) || \
114      (edge == XMC_CCU4_SLICE_EVENT_EDGE_SENSITIVITY_FALLING_EDGE)|| \
115      (edge == XMC_CCU4_SLICE_EVENT_EDGE_SENSITIVITY_DUAL_EDGE))
116 
117 /** Macro used to check if the filter clock cycles are valid */
118 #define XMC_CCU4_SLICE_CHECK_EVENT_FILTER(cycles) \
119     ((cycles == XMC_CCU4_SLICE_EVENT_FILTER_DISABLED) || \
120      (cycles == XMC_CCU4_SLICE_EVENT_FILTER_3_CYCLES) || \
121      (cycles == XMC_CCU4_SLICE_EVENT_FILTER_5_CYCLES) || \
122      (cycles == XMC_CCU4_SLICE_EVENT_FILTER_7_CYCLES))
123 
124 /** Macro used to check if the Multi-channel input related action is valid*/
125 #define XMC_CCU4_SLICE_CHECK_MCS_ACTION(mcs_action) \
126     ((mcs_action == XMC_CCU4_SLICE_MCMS_ACTION_TRANSFER_PR_CR)      || \
127      (mcs_action == XMC_CCU4_SLICE_MCMS_ACTION_TRANSFER_PR_CR_PCMP) || \
128      (mcs_action == XMC_CCU4_SLICE_MCMS_ACTION_TRANSFER_PR_CR_PCMP_DIT))
129 
130 /** Macro used to check if the SR line is valid*/
131 #define XMC_CCU4_SLICE_CHECK_SR_ID(id) \
132     ((id == XMC_CCU4_SLICE_SR_ID_0) || \
133      (id == XMC_CCU4_SLICE_SR_ID_1) || \
134      (id == XMC_CCU4_SLICE_SR_ID_2) || \
135      (id == XMC_CCU4_SLICE_SR_ID_3))
136 
137 /** Macro to check if the end mode enum passed is valid */
138 #define XMC_CCU4_CHECK_END_MODE(end_mode) \
139     ((end_mode == XMC_CCU4_SLICE_END_MODE_TIMER_STOP) || \
140      (end_mode == XMC_CCU4_SLICE_END_MODE_TIMER_CLEAR) || \
141      (end_mode == XMC_CCU4_SLICE_END_MODE_TIMER_STOP_CLEAR))
142 
143 /*********************************************************************************************************************
144  * LOCAL ROUTINES
145  ********************************************************************************************************************/
146 #if defined(PERIPHERAL_RESET_SUPPORTED)
XMC_CCU4_lAssertReset(const XMC_CCU4_MODULE_t * const module)147 __STATIC_INLINE void XMC_CCU4_lAssertReset(const XMC_CCU4_MODULE_t *const module)
148 {
149   if (module == CCU40)
150   {
151     XMC_SCU_RESET_AssertPeripheralReset(XMC_SCU_PERIPHERAL_RESET_CCU40);
152   }
153 #if defined(CCU41)
154   else if (module == CCU41)
155   {
156     XMC_SCU_RESET_AssertPeripheralReset(XMC_SCU_PERIPHERAL_RESET_CCU41);
157   }
158 #endif
159 #if defined(CCU42)
160   else if (module == CCU42)
161   {
162     XMC_SCU_RESET_AssertPeripheralReset(XMC_SCU_PERIPHERAL_RESET_CCU42);
163   }
164 #endif
165 #if defined(CCU43)
166   else if (module == CCU43)
167   {
168     XMC_SCU_RESET_AssertPeripheralReset(XMC_SCU_PERIPHERAL_RESET_CCU43);
169   }
170 #endif
171   else
172   {
173     XMC_ASSERT("XMC_CCU4_lAssertReset:Invalid Module Pointer", 0);
174   }
175 }
176 
XMC_CCU4_lDeassertReset(const XMC_CCU4_MODULE_t * const module)177 __STATIC_INLINE void XMC_CCU4_lDeassertReset(const XMC_CCU4_MODULE_t *const module)
178 {
179   if (module == CCU40)
180   {
181     XMC_SCU_RESET_DeassertPeripheralReset(XMC_SCU_PERIPHERAL_RESET_CCU40);
182   }
183 #if defined(CCU41)
184   else if (module == CCU41)
185   {
186     XMC_SCU_RESET_DeassertPeripheralReset(XMC_SCU_PERIPHERAL_RESET_CCU41);
187   }
188 #endif
189 #if defined(CCU42)
190   else if (module == CCU42)
191   {
192     XMC_SCU_RESET_DeassertPeripheralReset(XMC_SCU_PERIPHERAL_RESET_CCU42);
193   }
194 #endif
195 #if defined(CCU43)
196   else if (module == CCU43)
197   {
198     XMC_SCU_RESET_DeassertPeripheralReset(XMC_SCU_PERIPHERAL_RESET_CCU43);
199   }
200 #endif
201   else
202   {
203     XMC_ASSERT("XMC_CCU4_lDeassertReset:Invalid Module Pointer", 0);
204   }
205 }
206 #endif
207 
208 #if defined(CLOCK_GATING_SUPPORTED)
XMC_CCU4_lGateClock(const XMC_CCU4_MODULE_t * const module)209 __STATIC_INLINE void XMC_CCU4_lGateClock(const XMC_CCU4_MODULE_t *const module)
210 {
211 
212   if (module == CCU40)
213   {
214     XMC_SCU_CLOCK_GatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_CCU40);
215   }
216 #if defined(CCU41)
217   else if (module == CCU41)
218   {
219     XMC_SCU_CLOCK_GatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_CCU41);
220   }
221 #endif
222 #if defined(CCU42)
223   else if (module == CCU42)
224   {
225     XMC_SCU_CLOCK_GatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_CCU42);
226   }
227 #endif
228 #if defined(CCU43)
229   else if (module == CCU43)
230   {
231     XMC_SCU_CLOCK_GatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_CCU43);
232   }
233 #endif
234   else
235   {
236     XMC_ASSERT("XMC_CCU4_lGateClock:Invalid Module Pointer", 0);
237   }
238 }
239 
XMC_CCU4_lUngateClock(const XMC_CCU4_MODULE_t * const module)240 __STATIC_INLINE void XMC_CCU4_lUngateClock(const XMC_CCU4_MODULE_t *const module)
241 {
242   if (module == CCU40)
243   {
244     XMC_SCU_CLOCK_UngatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_CCU40);
245   }
246 #if defined(CCU41)
247   else if (module == CCU41)
248   {
249     XMC_SCU_CLOCK_UngatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_CCU41);
250   }
251 #endif
252 #if defined(CCU42)
253   else if (module == CCU42)
254   {
255     XMC_SCU_CLOCK_UngatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_CCU42);
256   }
257 #endif
258 #if defined(CCU43)
259   else if (module == CCU43)
260   {
261     XMC_SCU_CLOCK_UngatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_CCU43);
262   }
263 #endif
264   else
265   {
266     XMC_ASSERT("XMC_CCU4_lUngateClock:Invalid Module Pointer", 0);
267   }
268 }
269 #endif
270 
271 #if defined (XMC_ASSERT_ENABLE)
XMC_CCU4_SLICE_IsInputvalid(XMC_CCU4_SLICE_INPUT_t input)272 __STATIC_INLINE bool XMC_CCU4_SLICE_IsInputvalid(XMC_CCU4_SLICE_INPUT_t input)
273 {
274 #if (UC_SERIES == XMC14)
275   return (input < 48U);
276 #else
277   return (input < 16U);
278 #endif
279 }
280 #endif
281 /*********************************************************************************************************************
282  * API IMPLEMENTATION
283  ********************************************************************************************************************/
284 
XMC_CCU4_EnableModule(XMC_CCU4_MODULE_t * const module)285 void XMC_CCU4_EnableModule(XMC_CCU4_MODULE_t *const module)
286 {
287   XMC_ASSERT("XMC_CCU4_EnableModule:Invalid Module Pointer", XMC_CCU4_IsValidModule(module));
288 
289 #if UC_FAMILY == XMC4
290   /* Enable CCU4 module clock */
291   XMC_SCU_CLOCK_EnableClock(XMC_SCU_CLOCK_CCU);
292 #endif
293 
294 #if defined(CLOCK_GATING_SUPPORTED)
295   XMC_CCU4_lUngateClock(module);
296 #endif
297 
298 #if defined(PERIPHERAL_RESET_SUPPORTED)
299   XMC_CCU4_lDeassertReset(module);
300 #endif
301 }
302 
XMC_CCU4_DisableModule(XMC_CCU4_MODULE_t * const module)303 void XMC_CCU4_DisableModule(XMC_CCU4_MODULE_t *const module)
304 {
305   XMC_ASSERT("XMC_CCU4_DisableModule:Invalid Module Pointer", XMC_CCU4_IsValidModule(module));
306 
307 #if defined(PERIPHERAL_RESET_SUPPORTED)
308   XMC_CCU4_lAssertReset(module);
309 #endif
310 
311 #if defined(CLOCK_GATING_SUPPORTED)
312   XMC_CCU4_lGateClock(module);
313 #endif
314 }
315 
316 /* API to initialize CCU4 global resources  */
XMC_CCU4_Init(XMC_CCU4_MODULE_t * const module,const XMC_CCU4_SLICE_MCMS_ACTION_t mcs_action)317 void XMC_CCU4_Init(XMC_CCU4_MODULE_t *const module, const XMC_CCU4_SLICE_MCMS_ACTION_t mcs_action)
318 {
319   uint32_t gctrl;
320 
321   XMC_ASSERT("XMC_CCU4_Init:Invalid module pointer", XMC_CCU4_IsValidModule(module));
322   XMC_ASSERT("XMC_CCU4_Init:Invalid mcs action", XMC_CCU4_SLICE_CHECK_MCS_ACTION(mcs_action));
323 
324   /* Enable CCU4 module */
325   XMC_CCU4_EnableModule(module);
326   /* Start the prescaler */
327   XMC_CCU4_StartPrescaler(module);
328 
329   gctrl = module->GCTRL;
330   gctrl &= ~((uint32_t) CCU4_GCTRL_MSDE_Msk);
331   gctrl |= ((uint32_t) mcs_action) << CCU4_GCTRL_MSDE_Pos;
332 
333   module->GCTRL = gctrl;
334 }
335 
336 /* API to select CCU4 module clock */
XMC_CCU4_SetModuleClock(XMC_CCU4_MODULE_t * const module,const XMC_CCU4_CLOCK_t clock)337 void XMC_CCU4_SetModuleClock(XMC_CCU4_MODULE_t *const module, const XMC_CCU4_CLOCK_t clock)
338 {
339   uint32_t gctrl;
340 
341   XMC_ASSERT("XMC_CCU4_SetModuleClock:Invalid Module Pointer", XMC_CCU4_IsValidModule(module));
342   XMC_ASSERT("XMC_CCU4_SetModuleClock:Invalid Module Clock", XMC_CCU4_SLICE_CHECK_CLOCK(clock));
343 
344   gctrl = module->GCTRL;
345   gctrl &= ~((uint32_t) CCU4_GCTRL_PCIS_Msk);
346   gctrl |= ((uint32_t) clock) << CCU4_GCTRL_PCIS_Pos;
347 
348   module->GCTRL = gctrl;
349 }
350 
351 /* API to configure the multichannel shadow transfer request via SW and via the CCU4x.MCSS input. */
XMC_CCU4_SetMultiChannelShadowTransferMode(XMC_CCU4_MODULE_t * const module,const uint32_t slice_mode_msk)352 void XMC_CCU4_SetMultiChannelShadowTransferMode(XMC_CCU4_MODULE_t *const module, const uint32_t slice_mode_msk)
353 {
354   uint32_t gctrl;
355 
356   XMC_ASSERT("XMC_CCU4_SetMultiChannelShadowTransferMode:Invalid module Pointer", XMC_CCU4_IsValidModule(module));
357 
358   gctrl = module->GCTRL;
359   gctrl &= ~((uint32_t)slice_mode_msk >> 16U);
360   gctrl |= ((uint32_t)slice_mode_msk & 0xFFFFU);
361   module->GCTRL = gctrl;
362 }
363 
364 /* API to configure CC4 Slice as Timer */
XMC_CCU4_SLICE_CompareInit(XMC_CCU4_SLICE_t * const slice,const XMC_CCU4_SLICE_COMPARE_CONFIG_t * const compare_init)365 void XMC_CCU4_SLICE_CompareInit(XMC_CCU4_SLICE_t *const slice,
366                                 const XMC_CCU4_SLICE_COMPARE_CONFIG_t *const compare_init)
367 {
368   XMC_ASSERT("XMC_CCU4_SLICE_CompareInit:Invalid Slice Pointer", XMC_CCU4_IsValidSlice(slice));
369   XMC_ASSERT("XMC_CCU4_SLICE_CompareInit:Compare Init Pointer is NULL",
370              (XMC_CCU4_SLICE_COMPARE_CONFIG_t *) NULL != compare_init);
371 
372   /* Program the timer mode */
373   slice->TC = compare_init->tc;
374   /* Enable the timer concatenation */
375   slice->CMC = ((uint32_t) compare_init->timer_concatenation << CCU4_CC4_CMC_TCE_Pos);
376   /* Program initial prescaler divider value */
377   slice->PSC = (uint32_t) compare_init->prescaler_initval;
378   /* Program the dither compare value */
379   slice->DITS = (uint32_t) compare_init->dither_limit;
380   /* Program timer output passive level */
381   slice->PSL = (uint32_t) compare_init->passive_level;
382   /* Program floating prescaler compare value */
383   slice->FPCS = (uint32_t) compare_init->float_limit;
384 }
385 
386 /* API to configure CC4 Slice for Capture */
XMC_CCU4_SLICE_CaptureInit(XMC_CCU4_SLICE_t * const slice,const XMC_CCU4_SLICE_CAPTURE_CONFIG_t * const capture_init)387 void XMC_CCU4_SLICE_CaptureInit(XMC_CCU4_SLICE_t *const slice,
388                             const XMC_CCU4_SLICE_CAPTURE_CONFIG_t *const capture_init)
389 {
390   XMC_ASSERT("XMC_CCU4_SLICE_CaptureInit:Invalid Slice Pointer", XMC_CCU4_IsValidSlice(slice));
391   XMC_ASSERT("XMC_CCU4_SLICE_CaptureInit:Capture Init Pointer is NULL",
392              (XMC_CCU4_SLICE_CAPTURE_CONFIG_t *) NULL != capture_init);
393 
394   /* Program the capture mode */
395   slice->TC = capture_init->tc;
396   /* Enable the timer concatenation */
397   slice->CMC = ((uint32_t)capture_init->timer_concatenation << CCU4_CC4_CMC_TCE_Pos);
398   /* Program initial prescaler divider value */
399   slice->PSC = (uint32_t) capture_init->prescaler_initval;
400   /* Program initial floating prescaler compare value */
401   slice->FPCS = (uint32_t) capture_init->float_limit;
402 }
403 
404 
405 /* API to configure the Start trigger function of a slice */
XMC_CCU4_SLICE_StartConfig(XMC_CCU4_SLICE_t * const slice,const XMC_CCU4_SLICE_EVENT_t event,const XMC_CCU4_SLICE_START_MODE_t start_mode)406 void XMC_CCU4_SLICE_StartConfig(XMC_CCU4_SLICE_t *const slice,
407                             const XMC_CCU4_SLICE_EVENT_t event,
408                                 const XMC_CCU4_SLICE_START_MODE_t start_mode)
409 {
410   uint32_t cmc;
411   uint32_t tc;
412 
413   XMC_ASSERT("XMC_CCU4_SLICE_StartConfig:Invalid Slice Pointer", XMC_CCU4_IsValidSlice(slice));
414   XMC_ASSERT("XMC_CCU4_SLICE_StartConfig:Invalid Event ID", XMC_CCU4_SLICE_CHECK_EVENT_ID(event));
415   XMC_ASSERT("XMC_CCU4_SLICE_StartConfig:Invalid Start Mode",
416              ((start_mode == XMC_CCU4_SLICE_START_MODE_TIMER_START_CLEAR) ||\
417               (start_mode == XMC_CCU4_SLICE_START_MODE_TIMER_START)));
418   /* First, Bind the event with the stop function */
419   cmc = slice->CMC;
420   cmc &= ~((uint32_t) CCU4_CC4_CMC_STRTS_Msk);
421   cmc |= ((uint32_t) event) << CCU4_CC4_CMC_STRTS_Pos;
422 
423   slice->CMC = cmc;
424 
425   tc  = slice->TC;
426   /* Next, Configure the start mode */
427   if (start_mode == XMC_CCU4_SLICE_START_MODE_TIMER_START_CLEAR)
428   {
429     tc |= (uint32_t)CCU4_CC4_TC_STRM_Msk;
430   }
431   else
432   {
433     tc &= ~((uint32_t)CCU4_CC4_TC_STRM_Msk);
434   }
435 
436   slice->TC = tc;
437 }
438 
439 /* API to configure the Stop trigger function of a slice */
XMC_CCU4_SLICE_StopConfig(XMC_CCU4_SLICE_t * const slice,const XMC_CCU4_SLICE_EVENT_t event,const XMC_CCU4_SLICE_END_MODE_t end_mode)440 void XMC_CCU4_SLICE_StopConfig(XMC_CCU4_SLICE_t *const slice,
441                            const XMC_CCU4_SLICE_EVENT_t event,
442                                const XMC_CCU4_SLICE_END_MODE_t end_mode)
443 {
444   uint32_t cmc;
445   uint32_t tc;
446 
447   XMC_ASSERT("XMC_CCU4_SLICE_StopConfig:Invalid Slice Pointer", XMC_CCU4_IsValidSlice(slice));
448   XMC_ASSERT("XMC_CCU4_SLICE_StopConfig:Invalid Event ID", XMC_CCU4_SLICE_CHECK_EVENT_ID(event));
449   XMC_ASSERT("XMC_CCU4_SLICE_StopConfig:Invalid Start Mode", XMC_CCU4_CHECK_END_MODE(end_mode));
450 
451   /* First, Bind the event with the stop function */
452   cmc = slice->CMC;
453   cmc &= ~((uint32_t) CCU4_CC4_CMC_ENDS_Msk);
454   cmc |= ((uint32_t) event) << CCU4_CC4_CMC_ENDS_Pos;
455 
456   slice->CMC = cmc;
457 
458   /* Next, Configure the stop mode */
459   tc = slice->TC;
460   tc &= ~((uint32_t) CCU4_CC4_TC_ENDM_Msk);
461   tc |= ((uint32_t) end_mode) << CCU4_CC4_TC_ENDM_Pos;
462 
463   slice->TC = tc;
464 }
465 
466 /* API to configure the Load trigger function of a slice */
XMC_CCU4_SLICE_LoadConfig(XMC_CCU4_SLICE_t * const slice,const XMC_CCU4_SLICE_EVENT_t event)467 void XMC_CCU4_SLICE_LoadConfig(XMC_CCU4_SLICE_t *const slice, const XMC_CCU4_SLICE_EVENT_t event)
468 {
469   uint32_t cmc;
470 
471   XMC_ASSERT("XMC_CCU4_SLICE_LoadConfig:Invalid Slice Pointer", XMC_CCU4_IsValidSlice(slice));
472   XMC_ASSERT("XMC_CCU4_SLICE_LoadConfig:Invalid Event ID", XMC_CCU4_SLICE_CHECK_EVENT_ID(event));
473 
474   /* Bind the event with the load function */
475   cmc = slice->CMC;
476   cmc &= ~((uint32_t) CCU4_CC4_CMC_LDS_Msk);
477   cmc |= ((uint32_t) event) << CCU4_CC4_CMC_LDS_Pos;
478 
479   slice->CMC = cmc;
480 }
481 
482 /* API to configure the slice modulation function */
XMC_CCU4_SLICE_ModulationConfig(XMC_CCU4_SLICE_t * const slice,const XMC_CCU4_SLICE_EVENT_t event,const XMC_CCU4_SLICE_MODULATION_MODE_t mod_mode,const bool synch_with_pwm)483 void XMC_CCU4_SLICE_ModulationConfig(XMC_CCU4_SLICE_t *const slice,
484                                      const XMC_CCU4_SLICE_EVENT_t event,
485                                      const XMC_CCU4_SLICE_MODULATION_MODE_t mod_mode,
486                                      const bool synch_with_pwm)
487 {
488   uint32_t cmc;
489   uint32_t tc;
490 
491   XMC_ASSERT("XMC_CCU4_SLICE_ModulationConfig:Invalid Slice Pointer", XMC_CCU4_IsValidSlice(slice));
492   XMC_ASSERT("XMC_CCU4_SLICE_ModulationConfig:Invalid Event ID", XMC_CCU4_SLICE_CHECK_EVENT_ID(event));
493   XMC_ASSERT("XMC_CCU4_SLICE_ModulationConfig:Invalid Modulation Mode",
494              ((mod_mode == XMC_CCU4_SLICE_MODULATION_MODE_CLEAR_OUT) ||\
495               (mod_mode == XMC_CCU4_SLICE_MODULATION_MODE_CLEAR_ST_OUT)));
496 
497   tc  = slice->TC;
498   cmc = slice->CMC;
499 
500   /* First, Bind the event with the modulation function */
501   cmc &= ~((uint32_t) CCU4_CC4_CMC_MOS_Msk);
502   cmc |= ((uint32_t) event) << CCU4_CC4_CMC_MOS_Pos;
503   slice->CMC = cmc;
504 
505   /* Next, Modulation mode */
506   if (mod_mode == XMC_CCU4_SLICE_MODULATION_MODE_CLEAR_OUT)
507   {
508     tc |= (uint32_t) CCU4_CC4_TC_EMT_Msk;
509   }
510   else
511   {
512     tc &= ~((uint32_t) CCU4_CC4_TC_EMT_Msk);
513   }
514 
515   /* Synchronization of modulation effect with PWM cycle */
516   if (synch_with_pwm == (bool) true)
517   {
518     tc |= (uint32_t) CCU4_CC4_TC_EMS_Msk;
519   }
520   else
521   {
522     tc &= ~((uint32_t) CCU4_CC4_TC_EMS_Msk);
523   }
524 
525   slice->TC = tc;
526 }
527 
528 /* API to configure the slice count function */
XMC_CCU4_SLICE_CountConfig(XMC_CCU4_SLICE_t * const slice,const XMC_CCU4_SLICE_EVENT_t event)529 void XMC_CCU4_SLICE_CountConfig(XMC_CCU4_SLICE_t *const slice, const XMC_CCU4_SLICE_EVENT_t event)
530 {
531   uint32_t cmc;
532 
533   XMC_ASSERT("XMC_CCU4_SLICE_CountConfig:Invalid Slice Pointer", XMC_CCU4_IsValidSlice(slice));
534   XMC_ASSERT("XMC_CCU4_SLICE_CountConfig:Invalid Event ID", XMC_CCU4_SLICE_CHECK_EVENT_ID(event));
535 
536   /* Bind the event with the count function */
537   cmc = slice->CMC;
538   cmc &= ~((uint32_t) CCU4_CC4_CMC_CNTS_Msk);
539   cmc |= ((uint32_t) event) << CCU4_CC4_CMC_CNTS_Pos;
540 
541   slice->CMC = cmc;
542 }
543 
544 /* API to configure slice gate function */
XMC_CCU4_SLICE_GateConfig(XMC_CCU4_SLICE_t * const slice,const XMC_CCU4_SLICE_EVENT_t event)545 void XMC_CCU4_SLICE_GateConfig(XMC_CCU4_SLICE_t *const slice, const XMC_CCU4_SLICE_EVENT_t event)
546 {
547   uint32_t cmc;
548 
549   XMC_ASSERT("XMC_CCU4_SLICE_GateConfig:Invalid Slice Pointer", XMC_CCU4_IsValidSlice(slice));
550   XMC_ASSERT("XMC_CCU4_SLICE_GateConfig:Invalid Event ID", XMC_CCU4_SLICE_CHECK_EVENT_ID(event));
551 
552   /* Bind the event with the gate function */
553   cmc = slice->CMC;
554   cmc &= ~((uint32_t) CCU4_CC4_CMC_GATES_Msk);
555   cmc |= ((uint32_t) event) << CCU4_CC4_CMC_GATES_Pos;
556 
557   slice->CMC = cmc;
558 }
559 
560 /* API to configure Capture-0 function */
XMC_CCU4_SLICE_Capture0Config(XMC_CCU4_SLICE_t * const slice,const XMC_CCU4_SLICE_EVENT_t event)561 void XMC_CCU4_SLICE_Capture0Config(XMC_CCU4_SLICE_t *const slice, const XMC_CCU4_SLICE_EVENT_t event)
562 {
563   uint32_t cmc;
564 
565   XMC_ASSERT("XMC_CCU4_SLICE_Capture0Config:Invalid Slice Pointer", XMC_CCU4_IsValidSlice(slice));
566   XMC_ASSERT("XMC_CCU4_SLICE_Capture0Config:Invalid Event ID", XMC_CCU4_SLICE_CHECK_EVENT_ID(event));
567 
568   /* Bind the event with the gate function */
569   cmc = slice->CMC;
570   cmc &= ~((uint32_t) CCU4_CC4_CMC_CAP0S_Msk);
571   cmc |= ((uint32_t) event) << CCU4_CC4_CMC_CAP0S_Pos;
572 
573   slice->CMC = cmc;
574 }
575 
576 /* API to configure Capture-1 function */
XMC_CCU4_SLICE_Capture1Config(XMC_CCU4_SLICE_t * const slice,const XMC_CCU4_SLICE_EVENT_t event)577 void XMC_CCU4_SLICE_Capture1Config(XMC_CCU4_SLICE_t *const slice, const XMC_CCU4_SLICE_EVENT_t event)
578 {
579   uint32_t cmc;
580 
581   XMC_ASSERT("XMC_CCU4_SLICE_Capture1Config:Invalid Slice Pointer", XMC_CCU4_IsValidSlice(slice));
582   XMC_ASSERT("XMC_CCU4_SLICE_Capture1Config:Invalid Event ID", XMC_CCU4_SLICE_CHECK_EVENT_ID(event));
583 
584   /* Bind the event with the gate function */
585   cmc = slice->CMC;
586   cmc &= ~((uint32_t) CCU4_CC4_CMC_CAP1S_Msk);
587   cmc |= ((uint32_t) event) << CCU4_CC4_CMC_CAP1S_Pos;
588 
589   slice->CMC = cmc;
590 }
591 
592 /* API to configure direction function */
XMC_CCU4_SLICE_DirectionConfig(XMC_CCU4_SLICE_t * const slice,const XMC_CCU4_SLICE_EVENT_t event)593 void XMC_CCU4_SLICE_DirectionConfig(XMC_CCU4_SLICE_t *const slice, const XMC_CCU4_SLICE_EVENT_t event)
594 {
595   uint32_t cmc;
596 
597   XMC_ASSERT("XMC_CCU4_SLICE_DirectionConfig:Invalid Slice Pointer", XMC_CCU4_IsValidSlice(slice));
598   XMC_ASSERT("XMC_CCU4_SLICE_DirectionConfig:Invalid Event ID", XMC_CCU4_SLICE_CHECK_EVENT_ID(event));
599 
600   /* Bind the event with the direction function */
601   cmc = slice->CMC;
602   cmc &= ~((uint32_t) CCU4_CC4_CMC_UDS_Msk);
603   cmc |= ((uint32_t) event) << CCU4_CC4_CMC_UDS_Pos;
604 
605   slice->CMC = cmc;
606 }
607 
608 /* API to configure slice status bit override function */
XMC_CCU4_SLICE_StatusBitOverrideConfig(XMC_CCU4_SLICE_t * const slice)609 void XMC_CCU4_SLICE_StatusBitOverrideConfig(XMC_CCU4_SLICE_t *const slice)
610 {
611   uint32_t cmc;
612 
613   XMC_ASSERT("XMC_CCU4_SLICE_StatusBitOverrideConfig:Invalid Slice Pointer", XMC_CCU4_IsValidSlice(slice));
614 
615   /* Bind the event with the override function */
616   cmc = slice->CMC;
617   /* Map status bit trigger override to Event 1 &
618          status bit value override to Event 2 */
619   cmc &= ~((uint32_t) CCU4_CC4_CMC_OFS_Msk);
620   cmc |= ((uint32_t) 1) << CCU4_CC4_CMC_OFS_Pos;
621 
622   slice->CMC = cmc;
623 }
624 
625 /* API to configure trap function */
XMC_CCU4_SLICE_TrapConfig(XMC_CCU4_SLICE_t * const slice,const XMC_CCU4_SLICE_TRAP_EXIT_MODE_t exit_mode,const bool synch_with_pwm)626 void XMC_CCU4_SLICE_TrapConfig(XMC_CCU4_SLICE_t *const slice,
627                                const XMC_CCU4_SLICE_TRAP_EXIT_MODE_t exit_mode,
628                                const bool synch_with_pwm)
629 {
630   uint32_t cmc;
631   uint32_t tc;
632 
633   XMC_ASSERT("XMC_CCU4_SLICE_TrapConfig:Invalid Slice Pointer", XMC_CCU4_IsValidSlice(slice));
634   XMC_ASSERT("XMC_CCU4_SLICE_TrapConfig:Invalid Exit Mode", ((exit_mode == XMC_CCU4_SLICE_TRAP_EXIT_MODE_AUTOMATIC) ||\
635                                                              (exit_mode == XMC_CCU4_SLICE_TRAP_EXIT_MODE_SW)));
636 
637   /* First, Map trap function to Event 2 */
638   cmc = slice->CMC;
639   cmc &= ~((uint32_t) CCU4_CC4_CMC_TS_Msk);
640   cmc |= ((uint32_t) 1) << CCU4_CC4_CMC_TS_Pos;
641   slice->CMC = cmc;
642 
643   /* Next, Configure synchronization option */
644   tc = slice->TC;
645 
646   if (synch_with_pwm == (bool) true)
647   {
648     tc |= (uint32_t) CCU4_CC4_TC_TRPSE_Msk;
649   }
650   else
651   {
652     tc &= ~((uint32_t) CCU4_CC4_TC_TRPSE_Msk);
653   }
654 
655   /* Configure exit mode */
656   if (exit_mode == XMC_CCU4_SLICE_TRAP_EXIT_MODE_SW)
657   {
658     tc |= (uint32_t) CCU4_CC4_TC_TRPSW_Msk;
659   }
660   else
661   {
662     tc &= ~((uint32_t) CCU4_CC4_TC_TRPSW_Msk);
663   }
664 
665   slice->TC = tc;
666 }
667 
668 /* API to configure a slice Status Bit Override event */
XMC_CCU4_SLICE_ConfigureStatusBitOverrideEvent(XMC_CCU4_SLICE_t * const slice,const XMC_CCU4_SLICE_EVENT_CONFIG_t * const ev1_config,const XMC_CCU4_SLICE_EVENT_CONFIG_t * const ev2_config)669 void XMC_CCU4_SLICE_ConfigureStatusBitOverrideEvent(XMC_CCU4_SLICE_t *const slice,
670                                                     const XMC_CCU4_SLICE_EVENT_CONFIG_t *const ev1_config,
671                                                     const XMC_CCU4_SLICE_EVENT_CONFIG_t *const ev2_config)
672 {
673   uint32_t ins;
674 
675   XMC_ASSERT("XMC_CCU4_SLICE_ConfigureStatusBitOverrideEvent:Invalid Slice Pointer", XMC_CCU4_IsValidSlice(slice));
676   XMC_ASSERT("XMC_CCU4_SLICE_ConfigureStatusBitOverrideEvent:Invalid Input",
677          XMC_CCU4_SLICE_IsInputvalid(ev1_config->mapped_input));
678   XMC_ASSERT("XMC_CCU4_SLICE_ConfigureStatusBitOverrideEvent:Invalid Edge Sensitivity",
679              XMC_CCU4_SLICE_CHECK_EDGE_SENSITIVITY(ev1_config->edge));
680   XMC_ASSERT("XMC_CCU4_SLICE_ConfigureStatusBitOverrideEvent:Invalid Level Sensitivity",
681              ((ev1_config->level == XMC_CCU4_SLICE_EVENT_LEVEL_SENSITIVITY_ACTIVE_HIGH) ||\
682               (ev1_config->level == XMC_CCU4_SLICE_EVENT_LEVEL_SENSITIVITY_ACTIVE_LOW)));
683   XMC_ASSERT("XMC_CCU4_SLICE_ConfigureStatusBitOverrideEvent:Invalid Debounce Period",
684              XMC_CCU4_SLICE_CHECK_EVENT_FILTER(ev1_config->duration));
685   XMC_ASSERT("XMC_CCU4_SLICE_ConfigureStatusBitOverrideEvent:Invalid Input",
686          XMC_CCU4_SLICE_IsInputvalid(ev2_config->mapped_input));
687   XMC_ASSERT("XMC_CCU4_SLICE_ConfigureStatusBitOverrideEvent:Invalid Edge Sensitivity",
688              XMC_CCU4_SLICE_CHECK_EDGE_SENSITIVITY(ev2_config->edge));
689   XMC_ASSERT("XMC_CCU4_SLICE_ConfigureStatusBitOverrideEvent:Invalid Level Sensitivity",
690              ((ev2_config->level == XMC_CCU4_SLICE_EVENT_LEVEL_SENSITIVITY_ACTIVE_HIGH) ||\
691               (ev2_config->level == XMC_CCU4_SLICE_EVENT_LEVEL_SENSITIVITY_ACTIVE_LOW)));
692   XMC_ASSERT("XMC_CCU4_SLICE_ConfigureStatusBitOverrideEvent:Invalid Debounce Period",
693              XMC_CCU4_SLICE_CHECK_EVENT_FILTER(ev2_config->duration));
694 #if defined(CCU4V3) /* Defined for XMC1400 devices only */
695   ins = slice->INS2;
696 
697   /* Configure the edge sensitivity for event 1 */
698   ins &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_EDGE_CONFIG_MASK) << CCU4_CC4_INS2_EV1EM_Pos);
699   ins |= ((uint32_t) ev1_config->edge) << CCU4_CC4_INS2_EV1EM_Pos;
700 
701   /* Configure the edge sensitivity for event 2 */
702   ins &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_EDGE_CONFIG_MASK) << CCU4_CC4_INS2_EV2EM_Pos);
703   ins |= ((uint32_t) ev2_config->edge) << CCU4_CC4_INS2_EV2EM_Pos;
704 
705   /* Configure the level sensitivity for event 1 */
706   ins &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_LEVEL_CONFIG_MASK) << CCU4_CC4_INS2_EV1LM_Pos);
707   ins |= ((uint32_t) ev1_config->level) << CCU4_CC4_INS2_EV1LM_Pos;
708 
709   /* Configure the level sensitivity for event 2 */
710   ins &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_LEVEL_CONFIG_MASK) << CCU4_CC4_INS2_EV2LM_Pos);
711   ins |= ((uint32_t) ev2_config->level) << CCU4_CC4_INS2_EV2LM_Pos;
712 
713   /* Configure the debounce filter for event 1 */
714   ins &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_FILTER_CONFIG_MASK) << CCU4_CC4_INS2_LPF1M_Pos);
715   ins |= ((uint32_t) ev1_config->duration) << CCU4_CC4_INS2_LPF1M_Pos;
716 
717   /* Configure the debounce filter for event 2 */
718   ins &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_FILTER_CONFIG_MASK) << CCU4_CC4_INS2_LPF2M_Pos);
719   ins |= ((uint32_t) ev2_config->duration) << CCU4_CC4_INS2_LPF2M_Pos;
720 
721   slice->INS2 = ins;
722 
723   ins = slice->INS1;
724 
725   /* Next, the input for Event1 */
726   ins &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_INPUT_CONFIG_MASK) << CCU4_CC4_INS1_EV1IS_Pos);
727   ins |= ((uint32_t) ev1_config->mapped_input) << CCU4_CC4_INS1_EV1IS_Pos;
728 
729   /* Finally, the input for Event2 */
730   ins &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_INPUT_CONFIG_MASK) << CCU4_CC4_INS1_EV2IS_Pos);
731   ins |= ((uint32_t) ev2_config->mapped_input) << CCU4_CC4_INS1_EV2IS_Pos;
732 
733   slice->INS1 = ins;
734 #else
735   ins = slice->INS;
736 
737   /* Configure the edge sensitivity for event 1 */
738   ins &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_EDGE_CONFIG_MASK) << CCU4_CC4_INS_EV1EM_Pos);
739   ins |= ((uint32_t) ev1_config->edge) << CCU4_CC4_INS_EV1EM_Pos;
740 
741   /* Configure the edge sensitivity for event 2 */
742   ins &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_EDGE_CONFIG_MASK) << CCU4_CC4_INS_EV2EM_Pos);
743   ins |= ((uint32_t) ev2_config->edge) << CCU4_CC4_INS_EV2EM_Pos;
744 
745   /* Configure the level sensitivity for event 1 */
746   ins &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_LEVEL_CONFIG_MASK) << CCU4_CC4_INS_EV1LM_Pos);
747   ins |= ((uint32_t) ev1_config->level) << CCU4_CC4_INS_EV1LM_Pos;
748 
749   /* Configure the level sensitivity for event 2 */
750   ins &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_LEVEL_CONFIG_MASK) << CCU4_CC4_INS_EV2LM_Pos);
751   ins |= ((uint32_t) ev2_config->level) << CCU4_CC4_INS_EV2LM_Pos;
752 
753   /* Configure the debounce filter for event 1 */
754   ins &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_FILTER_CONFIG_MASK) << CCU4_CC4_INS_LPF1M_Pos);
755   ins |= ((uint32_t) ev1_config->duration) << CCU4_CC4_INS_LPF1M_Pos;
756 
757   /* Configure the debounce filter for event 2 */
758   ins &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_FILTER_CONFIG_MASK) << CCU4_CC4_INS_LPF2M_Pos);
759   ins |= ((uint32_t) ev2_config->duration) << CCU4_CC4_INS_LPF2M_Pos;
760 
761   /* Next, the input for Event1 */
762   ins &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_INPUT_CONFIG_MASK) << CCU4_CC4_INS_EV1IS_Pos);
763   ins |= ((uint32_t) ev1_config->mapped_input) << CCU4_CC4_INS_EV1IS_Pos;
764 
765   /* Finally, the input for Event2 */
766   ins &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_INPUT_CONFIG_MASK) << CCU4_CC4_INS_EV2IS_Pos);
767   ins |= ((uint32_t) ev2_config->mapped_input) << CCU4_CC4_INS_EV2IS_Pos;
768 
769   slice->INS = ins;
770 #endif
771 }
772 
773 /* API to configure a slice trigger event */
XMC_CCU4_SLICE_ConfigureEvent(XMC_CCU4_SLICE_t * const slice,const XMC_CCU4_SLICE_EVENT_t event,const XMC_CCU4_SLICE_EVENT_CONFIG_t * const config)774 void XMC_CCU4_SLICE_ConfigureEvent(XMC_CCU4_SLICE_t *const slice,
775                                    const XMC_CCU4_SLICE_EVENT_t event,
776                                    const XMC_CCU4_SLICE_EVENT_CONFIG_t *const config)
777 {
778   uint32_t ins;
779   uint8_t  pos;
780   uint8_t  offset;
781 
782   XMC_ASSERT("XMC_CCU4_SLICE_ConfigureEvent:Invalid Slice Pointer", XMC_CCU4_IsValidSlice(slice));
783   XMC_ASSERT("XMC_CCU4_SLICE_ConfigureEvent:Invalid Event ID", XMC_CCU4_SLICE_CHECK_EVENT_ID(event));
784   XMC_ASSERT("XMC_CCU4_SLICE_ConfigureEvent:Invalid Input", XMC_CCU4_SLICE_IsInputvalid(config->mapped_input));
785   XMC_ASSERT("XMC_CCU4_SLICE_ConfigureEvent:Invalid Edge Sensitivity",
786              XMC_CCU4_SLICE_CHECK_EDGE_SENSITIVITY(config->edge));
787   XMC_ASSERT("XMC_CCU4_SLICE_ConfigureEvent:Invalid Level Sensitivity",
788              ((config->level == XMC_CCU4_SLICE_EVENT_LEVEL_SENSITIVITY_ACTIVE_HIGH) ||\
789               (config->level == XMC_CCU4_SLICE_EVENT_LEVEL_SENSITIVITY_ACTIVE_LOW)));
790   XMC_ASSERT("XMC_CCU4_SLICE_ConfigureEvent:Invalid Debounce Period",
791              XMC_CCU4_SLICE_CHECK_EVENT_FILTER(config->duration));
792   /* Calculate offset with reference to event */
793   offset = ((uint8_t) event) - 1U;
794 
795 #if defined(CCU4V3) /* Defined for XMC1400 devices only */
796   ins = slice->INS2;
797 
798   /* First, configure the edge sensitivity */
799   pos = ((uint8_t) CCU4_CC4_INS2_EV0EM_Pos) + (uint8_t)(offset << 2U);
800   ins &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_EDGE_CONFIG_MASK) << pos);
801   ins |= ((uint32_t) config->edge) << pos;
802 
803   /* Next, the level */
804   pos = ((uint8_t) CCU4_CC4_INS2_EV0LM_Pos) + (uint8_t)(offset << 2U);
805   ins &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_LEVEL_CONFIG_MASK) << pos);
806   ins |= ((uint32_t) config->level) << pos;
807 
808   /* Next, the debounce filter */
809   pos = ((uint8_t) CCU4_CC4_INS2_LPF0M_Pos) + (uint8_t)(offset << 2U);
810   ins &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_FILTER_CONFIG_MASK) << pos);
811   ins |= ((uint32_t) config->duration) << pos;
812 
813   slice->INS2 = ins;
814 
815   ins = slice->INS1;
816 
817   /* Finally the input */
818   pos = ((uint8_t) CCU4_CC4_INS1_EV0IS_Pos) + (uint8_t)(offset << 3U);
819   ins &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_INPUT_CONFIG_MASK) << pos);
820   ins |= ((uint32_t) config->mapped_input) << pos;
821 
822   slice->INS1 = ins;
823 
824 #else
825   ins = slice->INS;
826 
827   /* First, configure the edge sensitivity */
828   pos = ((uint8_t) CCU4_CC4_INS_EV0EM_Pos) + (uint8_t)(offset << 1U);
829   ins &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_EDGE_CONFIG_MASK) << pos);
830   ins |= ((uint32_t) config->edge) << pos;
831 
832   /* Next, the level */
833   pos = ((uint8_t) CCU4_CC4_INS_EV0LM_Pos) + offset;
834   ins &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_LEVEL_CONFIG_MASK) << pos);
835   ins |= ((uint32_t) config->level) << pos;
836 
837   /* Next, the debounce filter */
838   pos = ((uint8_t) CCU4_CC4_INS_LPF0M_Pos) + (uint8_t)(offset << 1U);
839   ins &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_FILTER_CONFIG_MASK) << pos);
840   ins |= ((uint32_t) config->duration) << pos;
841 
842   /* Finally the input */
843   pos = ((uint8_t) CCU4_CC4_INS_EV0IS_Pos) + (uint8_t)(offset << 2U);
844   ins &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_INPUT_CONFIG_MASK) << pos);
845   ins |= ((uint32_t) config->mapped_input) << pos;
846 
847   slice->INS = ins;
848 #endif
849 }
850 
851 /* API to bind an input to a slice trigger event */
XMC_CCU4_SLICE_SetInput(XMC_CCU4_SLICE_t * const slice,const XMC_CCU4_SLICE_EVENT_t event,const XMC_CCU4_SLICE_INPUT_t input)852 void XMC_CCU4_SLICE_SetInput(XMC_CCU4_SLICE_t *const slice,
853                          const XMC_CCU4_SLICE_EVENT_t event,
854                              const XMC_CCU4_SLICE_INPUT_t input)
855 {
856   uint32_t ins;
857   uint8_t  pos;
858   uint8_t  offset;
859 
860   XMC_ASSERT("XMC_CCU4_SLICE_SetInput:Invalid Slice Pointer", XMC_CCU4_IsValidSlice(slice));
861   XMC_ASSERT("XMC_CCU4_SLICE_SetInput:Invalid Event ID", XMC_CCU4_SLICE_CHECK_EVENT_ID(event));
862   XMC_ASSERT("XMC_CCU4_SLICE_SetInput:Invalid Input", XMC_CCU4_SLICE_IsInputvalid(input));
863 
864   /* Calculate offset with reference to event */
865   offset = ((uint8_t) event) - 1U;
866 
867 #if defined(CCU4V3) /* Defined for XMC1400 devices only */
868   pos = ((uint8_t) CCU4_CC4_INS1_EV0IS_Pos) + (uint8_t) (offset << 3U);
869 
870   ins = slice->INS1;
871   ins &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_INPUT_CONFIG_MASK) << pos);
872   ins |= ((uint32_t) input) << pos;
873 
874   slice->INS1 = ins;
875 #else
876   pos = ((uint8_t) CCU4_CC4_INS_EV0IS_Pos) + (uint8_t) (offset << 2U);
877 
878   ins = slice->INS;
879   ins &= ~(((uint32_t) XMC_CCU4_SLICE_EVENT_INPUT_CONFIG_MASK) << pos);
880   ins |= ((uint32_t) input) << pos;
881 
882   slice->INS = ins;
883 #endif
884 }
885 
886 /* API to program timer repeat mode - Single shot vs repeat */
XMC_CCU4_SLICE_SetTimerRepeatMode(XMC_CCU4_SLICE_t * const slice,const XMC_CCU4_SLICE_TIMER_REPEAT_MODE_t mode)887 void XMC_CCU4_SLICE_SetTimerRepeatMode(XMC_CCU4_SLICE_t *const slice, const XMC_CCU4_SLICE_TIMER_REPEAT_MODE_t mode)
888 {
889   XMC_ASSERT("XMC_CCU4_SLICE_SetTimerRepeatMode:Invalid Slice Pointer", XMC_CCU4_IsValidSlice(slice));
890   XMC_ASSERT("XMC_CCU4_SLICE_SetTimerRepeatMode:Invalid Timer Repeat Mode",
891              ((mode == XMC_CCU4_SLICE_TIMER_REPEAT_MODE_REPEAT) ||\
892           (mode == XMC_CCU4_SLICE_TIMER_REPEAT_MODE_SINGLE)));
893 
894   if (XMC_CCU4_SLICE_TIMER_REPEAT_MODE_REPEAT == mode)
895   {
896     slice->TC &= ~((uint32_t) CCU4_CC4_TC_TSSM_Msk);
897   }
898   else
899   {
900     slice->TC |= (uint32_t) CCU4_CC4_TC_TSSM_Msk;
901   }
902 }
903 
904 /* Programs timer counting mode */
XMC_CCU4_SLICE_SetTimerCountingMode(XMC_CCU4_SLICE_t * const slice,const XMC_CCU4_SLICE_TIMER_COUNT_MODE_t mode)905 void XMC_CCU4_SLICE_SetTimerCountingMode(XMC_CCU4_SLICE_t *const slice, const XMC_CCU4_SLICE_TIMER_COUNT_MODE_t mode)
906 {
907   XMC_ASSERT("XMC_CCU4_SLICE_SetTimerCountingMode:Invalid Slice Pointer", XMC_CCU4_IsValidSlice(slice));
908   XMC_ASSERT("XMC_CCU4_SLICE_SetTimerCountingMode:Invalid Timer Count Mode", ((mode == XMC_CCU4_SLICE_TIMER_COUNT_MODE_EA) ||\
909                                                                               (mode == XMC_CCU4_SLICE_TIMER_COUNT_MODE_CA)));
910 
911   if (XMC_CCU4_SLICE_TIMER_COUNT_MODE_EA == mode)
912   {
913     slice->TC &= ~((uint32_t) CCU4_CC4_TC_TCM_Msk);
914   }
915   else
916   {
917     slice->TC |= (uint32_t) CCU4_CC4_TC_TCM_Msk;
918   }
919 }
920 
921 /* Retrieves desired capture register value */
XMC_CCU4_SLICE_GetCaptureRegisterValue(const XMC_CCU4_SLICE_t * const slice,const uint8_t reg_num)922 uint32_t XMC_CCU4_SLICE_GetCaptureRegisterValue(const XMC_CCU4_SLICE_t *const slice, const uint8_t reg_num)
923 {
924   XMC_ASSERT("XMC_CCU4_SLICE_GetCaptureRegisterValue:Invalid Slice Pointer", XMC_CCU4_IsValidSlice(slice));
925   XMC_ASSERT("XMC_CCU4_SLICE_GetCaptureRegisterValue:Invalid register number", (reg_num < 4U));
926   return(slice->CV[reg_num]);
927 }
928 
929 /* @brief Retrieves the latest captured timer value */
XMC_CCU4_SLICE_GetLastCapturedTimerValue(const XMC_CCU4_SLICE_t * const slice,const XMC_CCU4_SLICE_CAP_REG_SET_t set,uint32_t * val_ptr)930 XMC_CCU4_STATUS_t XMC_CCU4_SLICE_GetLastCapturedTimerValue(const XMC_CCU4_SLICE_t *const slice,
931                                                            const XMC_CCU4_SLICE_CAP_REG_SET_t set,
932                                                            uint32_t *val_ptr)
933 {
934   XMC_CCU4_STATUS_t retval;
935   uint8_t i;
936   uint8_t start;
937   uint8_t end;
938 
939   XMC_ASSERT("XMC_CCU4_SLICE_GetLastCapturedTimerValue:Invalid Slice Pointer", XMC_CCU4_IsValidSlice(slice));
940   XMC_ASSERT("XMC_CCU4_SLICE_GetLastCapturedTimerValue:Invalid Register Set", ((set == XMC_CCU4_SLICE_CAP_REG_SET_LOW) ||\
941                                                                                (set == XMC_CCU4_SLICE_CAP_REG_SET_HIGH)));
942 
943   retval = XMC_CCU4_STATUS_ERROR;
944 
945   /* First check if extended capture mode is enabled */
946   if ((slice->TC) & CCU4_CC4_TC_ECM_Msk)
947   {
948     /* Extended capture mode has been enabled. So start with the lowest capture register and work your way up */
949     start = 0U;
950     end = XMC_CCU4_NUM_SLICES_PER_MODULE;
951   }
952   else
953   {
954     /* Extended capture mode is not enabled */
955     if (set == XMC_CCU4_SLICE_CAP_REG_SET_HIGH)
956     {
957       start = ((uint8_t) XMC_CCU4_NUM_SLICES_PER_MODULE) >> 1U;
958       end   = (uint8_t) XMC_CCU4_NUM_SLICES_PER_MODULE;
959     }
960     else
961     {
962       start = 0U;
963       end = ((uint8_t) XMC_CCU4_NUM_SLICES_PER_MODULE) >> 1U;
964     }
965   }
966 
967   for(i=start; i < end; i++)
968   {
969     if ( (slice->CV[i]) & CCU4_CC4_CV_FFL_Msk )
970     {
971       *val_ptr = slice->CV[i];
972       retval = XMC_CCU4_STATUS_OK;
973       break;
974     }
975   }
976 
977   return retval;
978 }
979 
980 /* Retrieves timer capture value from a FIFO made of capture registers */
981 #if defined(CCU4V1) /* Defined for XMC4500, XMC400, XMC4200, XMC4100 devices only */
XMC_CCU4_GetCapturedValueFromFifo(const XMC_CCU4_MODULE_t * const module,const uint8_t slice_number)982 int32_t XMC_CCU4_GetCapturedValueFromFifo(const XMC_CCU4_MODULE_t *const module, const uint8_t slice_number)
983 {
984   int32_t   cap;
985   uint32_t  extracted_slice;
986 
987   XMC_ASSERT("XMC_CCU4_GetCapturedValueFromFifo:Invalid Slice Pointer", XMC_CCU4_IsValidModule(module));
988 
989   /* First read the global fifo register */
990   cap = (int32_t) module->ECRD;
991 
992   extracted_slice = (((uint32_t) cap) & ((uint32_t) CCU4_ECRD_SPTR_Msk)) >> CCU4_ECRD_SPTR_Pos;
993 
994   /* Return captured result only if it were applicable to this slice */
995   if(extracted_slice != ((uint32_t)slice_number))
996   {
997     cap = -1;
998   }
999 
1000   return (cap);
1001 }
1002 #else
XMC_CCU4_SLICE_GetCapturedValueFromFifo(const XMC_CCU4_SLICE_t * const slice,const XMC_CCU4_SLICE_CAP_REG_SET_t set)1003 uint32_t XMC_CCU4_SLICE_GetCapturedValueFromFifo(const XMC_CCU4_SLICE_t *const slice,
1004                                              const XMC_CCU4_SLICE_CAP_REG_SET_t set)
1005 {
1006   uint32_t cap;
1007 
1008   XMC_ASSERT("XMC_CCU4_SLICE_GetCapturedValueFromFifo:Invalid Slice Pointer", XMC_CCU4_IsValidSlice(slice));
1009   XMC_ASSERT("XMC_CCU4_SLICE_GetCapturedValueFromFifo:Invalid Register Set",
1010       ((set == XMC_CCU4_SLICE_CAP_REG_SET_LOW) ||\
1011        (set == XMC_CCU4_SLICE_CAP_REG_SET_HIGH)));
1012 
1013   if(XMC_CCU4_SLICE_CAP_REG_SET_LOW == set)
1014   {
1015     cap = slice->ECRD0;
1016   }
1017   else
1018   {
1019     cap = slice->ECRD1;
1020   }
1021 
1022   return cap;
1023 }
1024 #endif
1025 
1026 /* Enables PWM dithering feature */
XMC_CCU4_SLICE_EnableDithering(XMC_CCU4_SLICE_t * const slice,const bool period_dither,const bool duty_dither,const uint8_t spread)1027 void XMC_CCU4_SLICE_EnableDithering(XMC_CCU4_SLICE_t *const slice,
1028                                     const bool period_dither,
1029                                     const bool duty_dither,
1030                                     const uint8_t spread)
1031 {
1032   uint32_t tc;
1033 
1034   XMC_ASSERT("XMC_CCU4_SLICE_EnableDithering:Invalid Slice Pointer", XMC_CCU4_IsValidSlice(slice));
1035 
1036   tc = slice->TC;
1037   tc &= ~((uint32_t) CCU4_CC4_TC_DITHE_Msk);
1038 
1039   if ((bool) true == period_dither)
1040   {
1041     tc |= (((uint32_t) XMC_CCU4_SLICE_DITHER_PERIOD_MASK) << CCU4_CC4_TC_DITHE_Pos);
1042   }
1043   if ((bool) true == duty_dither)
1044   {
1045     tc |= (((uint32_t) XMC_CCU4_SLICE_DITHER_DUTYCYCLE_MASK) << CCU4_CC4_TC_DITHE_Pos);
1046   }
1047 
1048   slice->TC = tc;
1049 
1050   XMC_CCU4_SLICE_SetDitherCompareValue((XMC_CCU4_SLICE_t *)slice, (uint8_t)spread);
1051 }
1052 
1053 /* Programs Pre-scalar divider  */
XMC_CCU4_SLICE_SetPrescaler(XMC_CCU4_SLICE_t * const slice,const XMC_CCU4_SLICE_PRESCALER_t div_val)1054 void XMC_CCU4_SLICE_SetPrescaler(XMC_CCU4_SLICE_t *const slice, const XMC_CCU4_SLICE_PRESCALER_t div_val)
1055 {
1056   uint32_t fpc;
1057 
1058   XMC_ASSERT("XMC_CCU4_SLICE_SetPrescaler:Invalid Slice Pointer", XMC_CCU4_IsValidSlice(slice));
1059 
1060   fpc = slice->FPC;
1061   fpc &= ~((uint32_t) CCU4_CC4_FPC_PVAL_Msk);
1062   fpc |= ((uint32_t) div_val) << CCU4_CC4_FPC_PVAL_Pos;
1063   slice->FPC = fpc;
1064   /*
1065    * In any case, update the initial value of the divider which is to be loaded once the prescaler increments to the
1066    * compare value.
1067    */
1068   slice->PSC = (uint32_t) div_val;
1069 }
1070 
1071 /* Binds a capcom event to an NVIC node  */
XMC_CCU4_SLICE_SetInterruptNode(XMC_CCU4_SLICE_t * const slice,const XMC_CCU4_SLICE_IRQ_ID_t event,const XMC_CCU4_SLICE_SR_ID_t sr)1072 void XMC_CCU4_SLICE_SetInterruptNode(XMC_CCU4_SLICE_t *const slice,
1073                                      const XMC_CCU4_SLICE_IRQ_ID_t event,
1074                                      const XMC_CCU4_SLICE_SR_ID_t sr)
1075 {
1076   uint32_t srs;
1077   uint32_t pos;
1078   uint32_t mask;
1079 
1080   XMC_ASSERT("XMC_CCU4_SLICE_SetInterruptNode:Invalid Slice Pointer", XMC_CCU4_IsValidSlice(slice));
1081   XMC_ASSERT("XMC_CCU4_SLICE_SetInterruptNode:Invalid SR ID ", XMC_CCU4_SLICE_CHECK_SR_ID(sr));
1082   XMC_ASSERT("XMC_CCU4_SLICE_SetInterruptNode:Invalid event", XMC_CCU4_SLICE_CHECK_INTERRUPT(event));
1083 
1084   srs = slice->SRS;
1085 
1086   switch(event)
1087   {
1088     case XMC_CCU4_SLICE_IRQ_ID_PERIOD_MATCH:
1089     case XMC_CCU4_SLICE_IRQ_ID_ONE_MATCH:
1090       mask = ((uint32_t) CCU4_CC4_SRS_POSR_Msk);
1091       pos  = CCU4_CC4_SRS_POSR_Pos;
1092       break;
1093 
1094     case XMC_CCU4_SLICE_IRQ_ID_COMPARE_MATCH_UP:
1095     case XMC_CCU4_SLICE_IRQ_ID_COMPARE_MATCH_DOWN:
1096       mask = ((uint32_t) CCU4_CC4_SRS_CMSR_Msk);
1097       pos  = CCU4_CC4_SRS_CMSR_Pos;
1098       break;
1099 
1100     case XMC_CCU4_SLICE_IRQ_ID_EVENT0:
1101       mask = ((uint32_t) CCU4_CC4_SRS_E0SR_Msk);
1102       pos  = CCU4_CC4_SRS_E0SR_Pos;
1103       break;
1104 
1105     case XMC_CCU4_SLICE_IRQ_ID_EVENT1:
1106       mask = ((uint32_t) CCU4_CC4_SRS_E1SR_Msk);
1107       pos  = CCU4_CC4_SRS_E1SR_Pos;
1108       break;
1109 
1110     default:
1111       mask = ((uint32_t) CCU4_CC4_SRS_E2SR_Msk);
1112       pos  = CCU4_CC4_SRS_E2SR_Pos;
1113       break;
1114   }
1115 
1116   srs &= ~mask;
1117   srs |= (uint32_t)sr << pos;
1118   slice->SRS = srs;
1119 }
1120 
1121 /* Asserts passive level for the slice output */
XMC_CCU4_SLICE_SetPassiveLevel(XMC_CCU4_SLICE_t * const slice,const XMC_CCU4_SLICE_OUTPUT_PASSIVE_LEVEL_t level)1122 void XMC_CCU4_SLICE_SetPassiveLevel(XMC_CCU4_SLICE_t *const slice,
1123                                     const XMC_CCU4_SLICE_OUTPUT_PASSIVE_LEVEL_t level)
1124 {
1125   uint32_t psl;
1126 
1127   XMC_ASSERT("XMC_CCU4_SLICE_SetPassiveLevel:Invalid Slice Pointer", XMC_CCU4_IsValidSlice(slice));
1128   XMC_ASSERT("XMC_CCU4_SLICE_SetPassiveLevel:Invalid Passive level", ((level == XMC_CCU4_SLICE_OUTPUT_PASSIVE_LEVEL_LOW) ||\
1129                                                                       (level == XMC_CCU4_SLICE_OUTPUT_PASSIVE_LEVEL_HIGH)));
1130 
1131   psl = slice->PSL;
1132   psl &= ~((uint32_t) CCU4_CC4_PSL_PSL_Msk);
1133   psl |= (uint32_t) level;
1134 
1135   /* Program CC4 slice output passive level */
1136   slice->PSL = psl;
1137 }
1138 
1139 #endif /* CCU40 */
1140