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