1 /**
2  * @file xmc_usic.c
3  * @date 2019-07-01
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 draft <br>
41  *     - Documentation improved <br>
42  *
43  * 2015-05-08:
44  *     - Clearing bit fields PDIV, PCTQ, PPPEN in XMC_USIC_CH_SetBaudrate() API <br>
45  *
46  * 2015-06-20:
47  *     - Removed version macros and declaration of GetDriverVersion API <br>
48  *
49  * 2015-08-27:
50  *     - Added APIs for external input for BRG configuration:XMC_USIC_CH_ConfigExternalInputSignalToBRG() <br>
51  *
52  * 2015-08-28:
53  *     - Added asserts to XMC_USIC_CH_ConfigExternalInputSignalToBRG() <br>
54  *
55  * 2015-09-01:
56  *     - Fixed warning in the asserts <br>
57  *
58  * 2018-09-29:
59  *     - Added XMC_USIC_CH_SetBaudrateEx which uses the integer divider instead of the fractional divider <br>
60  *
61  * 2019-03-30:
62  *     - Changed XMC_USIC_Enable() adding polling to check clock ungate
63  *
64  * 2019-05-07:
65  *     - Added XMC_USIC_CH_GetBaudrate(), XMC_USIC_CH_GetSCLKFrequency() and XMC_USIC_CH_GetMCLKFrequency()
66  *
67  * 2019-07-01:
68  *     - XMC_USIC_CH_SetBaudrateEx() change type of input parameters
69  *
70  * @endcond
71  *
72  */
73 
74 /*******************************************************************************
75  * HEADER FILES
76  *******************************************************************************/
77 
78 #include "xmc_usic.h"
79 #include "xmc_scu.h"
80 
81 #include <stdlib.h>     /* abs */
82 
83 /*******************************************************************************
84  * MACROS
85  *******************************************************************************/
86 
87 #define USIC_CH_INPR_Msk       (0x7UL)
88 
89 /*******************************************************************************
90  * API IMPLEMENTATION
91  *******************************************************************************/
92 
XMC_USIC_CH_Enable(XMC_USIC_CH_t * const channel)93 void XMC_USIC_CH_Enable(XMC_USIC_CH_t *const channel)
94 {
95   XMC_ASSERT("XMC_USIC_CH_Enable: channel not valid", XMC_USIC_IsChannelValid(channel));
96 
97   if ((channel == XMC_USIC0_CH0) || (channel == XMC_USIC0_CH1))
98   {
99     XMC_USIC_Enable(XMC_USIC0);
100   }
101 #if defined(USIC1)
102   else if((channel == XMC_USIC1_CH0) || (channel == XMC_USIC1_CH1))
103   {
104     XMC_USIC_Enable(XMC_USIC1);
105   }
106 #endif
107 #if defined(USIC2)
108   else if((channel == XMC_USIC2_CH0) || (channel == XMC_USIC2_CH1))
109   {
110     XMC_USIC_Enable(XMC_USIC2);
111   }
112 #endif
113   else
114   {
115     XMC_ASSERT("USIC module not available", 0U/*Always*/);
116   }
117 
118   /* USIC channel switched on*/
119   channel->KSCFG = (USIC_CH_KSCFG_MODEN_Msk | USIC_CH_KSCFG_BPMODEN_Msk);
120   while ((channel->KSCFG & USIC_CH_KSCFG_MODEN_Msk) == 0U)
121   {
122     /* Wait till the channel is enabled */
123   }
124 
125   /* Set USIC channel in IDLE mode */
126   channel->CCR &= (uint32_t)~USIC_CH_CCR_MODE_Msk;
127 }
128 
XMC_USIC_CH_Disable(XMC_USIC_CH_t * const channel)129 void XMC_USIC_CH_Disable(XMC_USIC_CH_t *const channel)
130 {
131   channel->KSCFG = (uint32_t)((channel->KSCFG & (~USIC_CH_KSCFG_MODEN_Msk)) | USIC_CH_KSCFG_BPMODEN_Msk);
132 }
133 
XMC_USIC_CH_SetBaudrate(XMC_USIC_CH_t * const channel,uint32_t rate,uint32_t oversampling)134 XMC_USIC_CH_STATUS_t XMC_USIC_CH_SetBaudrate(XMC_USIC_CH_t *const channel, uint32_t rate, uint32_t oversampling)
135 {
136   XMC_USIC_CH_STATUS_t status;
137 
138   uint32_t peripheral_clock;
139 
140   uint32_t clock_divider;
141   uint32_t clock_divider_min;
142 
143   uint32_t pdiv;
144   uint32_t pdiv_int;
145   uint32_t pdiv_int_min;
146 
147   uint32_t pdiv_frac;
148   uint32_t pdiv_frac_min;
149 
150   /* The rate and peripheral clock are divided by 100 to be able to use only 32bit arithmetic */
151   if ((rate >= 100U) && (oversampling != 0U))
152   {
153     peripheral_clock = XMC_SCU_CLOCK_GetPeripheralClockFrequency() / 100U;
154     rate = rate / 100U;
155 
156     clock_divider_min = 1U;
157     pdiv_int_min = 1U;
158     pdiv_frac_min = 0x3ffU;
159 
160     for(clock_divider = 1023U; clock_divider > 0U; --clock_divider)
161     {
162       pdiv = ((peripheral_clock * clock_divider) / (rate * oversampling));
163       pdiv_int = pdiv >> 10U;
164       pdiv_frac = pdiv & 0x3ffU;
165 
166       if ((pdiv_int < 1024U) && (pdiv_frac < pdiv_frac_min))
167       {
168         pdiv_frac_min = pdiv_frac;
169         pdiv_int_min = pdiv_int;
170         clock_divider_min = clock_divider;
171       }
172     }
173 
174     channel->FDR = XMC_USIC_CH_BRG_CLOCK_DIVIDER_MODE_FRACTIONAL |
175                    (clock_divider_min << USIC_CH_FDR_STEP_Pos);
176 
177     channel->BRG = (channel->BRG & ~(USIC_CH_BRG_DCTQ_Msk |
178                                      USIC_CH_BRG_PDIV_Msk |
179                                      USIC_CH_BRG_PCTQ_Msk |
180                                      USIC_CH_BRG_PPPEN_Msk)) |
181                    ((oversampling - 1U) << USIC_CH_BRG_DCTQ_Pos) |
182                    ((pdiv_int_min - 1U) << USIC_CH_BRG_PDIV_Pos);
183 
184     status = XMC_USIC_CH_STATUS_OK;
185   }
186   else
187   {
188     status = XMC_USIC_CH_STATUS_ERROR;
189   }
190 
191   return status;
192 }
193 
XMC_USIC_CH_SetBaudrateEx(XMC_USIC_CH_t * const channel,int32_t rate,int32_t oversampling)194 XMC_USIC_CH_STATUS_t XMC_USIC_CH_SetBaudrateEx(XMC_USIC_CH_t *const channel, int32_t rate, int32_t oversampling)
195 {
196   int32_t peripheral_clock = XMC_SCU_CLOCK_GetPeripheralClockFrequency();
197   int32_t brg_clock = rate * oversampling;
198   int32_t actual_rate_upper;
199   int32_t actual_rate_lower;
200   uint32_t pdiv = 1;
201   uint32_t divider_step;
202   XMC_USIC_CH_STATUS_t status;
203 
204   if (peripheral_clock > brg_clock)
205   {
206     divider_step = peripheral_clock / brg_clock; // integer division gets truncated
207     while (divider_step >= 1023)
208     {
209       pdiv++;
210       brg_clock = rate * oversampling * pdiv;
211       divider_step = peripheral_clock / brg_clock; // integer division gets truncated
212     }
213     actual_rate_upper = peripheral_clock / (divider_step * oversampling * pdiv);
214     actual_rate_lower = peripheral_clock / ((divider_step + 1) * oversampling * pdiv);
215 
216     // choose better approximation if the peripheral frequency is not a multiple of the baudrate
217     if (abs(rate - actual_rate_lower) < abs(rate - actual_rate_upper))
218     {
219       divider_step += 1;
220     }
221 
222     divider_step = 1024 - divider_step;
223 
224 
225     channel->FDR = XMC_USIC_CH_BRG_CLOCK_DIVIDER_MODE_NORMAL |
226                    (divider_step << USIC_CH_FDR_STEP_Pos);
227 
228     channel->BRG = (channel->BRG & ~(USIC_CH_BRG_DCTQ_Msk |
229                                      USIC_CH_BRG_PDIV_Msk |
230                                      USIC_CH_BRG_PCTQ_Msk |
231                                      USIC_CH_BRG_PPPEN_Msk)) |
232                    ((oversampling - 1U) << USIC_CH_BRG_DCTQ_Pos) |
233 				   ((pdiv -1) << USIC_CH_BRG_PDIV_Pos);
234 
235     status = XMC_USIC_CH_STATUS_OK;
236   }
237   else
238   {
239     status = XMC_USIC_CH_STATUS_ERROR;
240   }
241 
242   return status;
243 }
244 
XMC_USIC_CH_GetBaudrate(XMC_USIC_CH_t * const channel)245 uint32_t XMC_USIC_CH_GetBaudrate(XMC_USIC_CH_t *const channel)
246 {
247   uint32_t divider;
248   if ((channel->BRG & USIC_CH_BRG_CTQSEL_Msk) == USIC_CH_BRG_CTQSEL_Msk)
249   {
250 	// CTQSEL = 3
251     divider = 2;
252   }
253   else
254   {
255 	// CTQSEL = 0, 1, or 2
256     divider = (channel->BRG & USIC_CH_BRG_PPPEN_Msk) ? 2 : 1;
257 
258     if ((((channel->BRG & USIC_CH_BRG_CTQSEL_Msk) >> USIC_CH_BRG_CTQSEL_Pos) & 0x1) == 0)
259     {
260 	  // CTQSEL = 0 or 2
261       divider *= ((channel->BRG & USIC_CH_BRG_PDIV_Msk) >> USIC_CH_BRG_PDIV_Pos) + 1;
262       if ((((channel->BRG & USIC_CH_BRG_CTQSEL_Msk) >> USIC_CH_BRG_CTQSEL_Pos) & 0x2) != 0)
263       {
264         // CTQSEL = 2
265         divider *= 2;
266       }
267     }
268   }
269 
270   divider *= ((channel->BRG & USIC_CH_BRG_PCTQ_Msk) >> USIC_CH_BRG_PCTQ_Pos) + 1;
271   divider *= ((channel->BRG & USIC_CH_BRG_DCTQ_Msk) >> USIC_CH_BRG_DCTQ_Pos) + 1;
272 
273   uint32_t fperi = XMC_SCU_CLOCK_GetPeripheralClockFrequency();
274   float baudrate;
275   if ((channel->FDR & USIC_CH_FDR_DM_Msk) == XMC_USIC_CH_BRG_CLOCK_DIVIDER_MODE_FRACTIONAL)
276   {
277 	baudrate = fperi * (((channel->FDR & USIC_CH_FDR_STEP_Msk) >> USIC_CH_FDR_STEP_Pos) / 1024.0F);
278   }
279   else
280   {
281     /* Normal divider mode */
282     baudrate = fperi * (1.0F / (1024 - ((channel->FDR & USIC_CH_FDR_STEP_Msk) >> USIC_CH_FDR_STEP_Pos)));
283   }
284 
285   baudrate /= divider;
286 
287   return baudrate;
288 }
289 
XMC_USIC_CH_GetSCLKFrequency(XMC_USIC_CH_t * const channel)290 uint32_t XMC_USIC_CH_GetSCLKFrequency(XMC_USIC_CH_t *const channel)
291 {
292   uint32_t divider;
293   divider = (channel->BRG & USIC_CH_BRG_PPPEN_Msk) ? 2 : 1;
294   divider *= ((channel->BRG & USIC_CH_BRG_PDIV_Msk) >> USIC_CH_BRG_PDIV_Pos) + 1;
295   divider *= 2;
296 
297   uint32_t fperi = XMC_SCU_CLOCK_GetPeripheralClockFrequency();
298   float baudrate;
299   if ((channel->FDR & USIC_CH_FDR_DM_Msk) == XMC_USIC_CH_BRG_CLOCK_DIVIDER_MODE_FRACTIONAL)
300   {
301     /* Fractional divider mode */
302     baudrate = fperi * (((channel->FDR & USIC_CH_FDR_STEP_Msk) >> USIC_CH_FDR_STEP_Pos) / 1024.0F);
303   }
304   else
305   {
306     /* Normal divider mode */
307     baudrate = fperi * (1.0F / (1024 - ((channel->FDR & USIC_CH_FDR_STEP_Msk) >> USIC_CH_FDR_STEP_Pos)));
308   }
309 
310   baudrate /= divider;
311 
312   return baudrate;
313 }
314 
XMC_USIC_CH_GetMCLKFrequency(XMC_USIC_CH_t * const channel)315 uint32_t XMC_USIC_CH_GetMCLKFrequency(XMC_USIC_CH_t *const channel)
316 {
317   uint32_t fperi = XMC_SCU_CLOCK_GetPeripheralClockFrequency();
318 
319   float baudrate;
320   if ((channel->FDR & USIC_CH_FDR_DM_Msk) == XMC_USIC_CH_BRG_CLOCK_DIVIDER_MODE_FRACTIONAL)
321   {
322     /* Fractional divider mode */
323     baudrate = fperi * (1.0F / (1024 - ((channel->FDR & USIC_CH_FDR_STEP_Msk) >> USIC_CH_FDR_STEP_Pos)));
324   }
325   else
326   {
327     /* Normal divider mode */
328     baudrate = fperi / (((channel->FDR & USIC_CH_FDR_STEP_Msk) >> USIC_CH_FDR_STEP_Pos) / 1024.0F);
329   }
330 
331   baudrate /= 2;
332 
333   return baudrate;
334 }
335 
336 
XMC_USIC_CH_ConfigExternalInputSignalToBRG(XMC_USIC_CH_t * const channel,const uint16_t pdiv,const uint32_t oversampling,const XMC_USIC_CH_INPUT_COMBINATION_MODE_t combination_mode)337 void XMC_USIC_CH_ConfigExternalInputSignalToBRG(XMC_USIC_CH_t *const channel,
338 		                                        const uint16_t pdiv,
339 												const uint32_t oversampling,
340 												const XMC_USIC_CH_INPUT_COMBINATION_MODE_t combination_mode)
341 {
342   XMC_ASSERT("XMC_USIC_CH_ConfigExternalInputSignalToBRG: Divider out of range", ((1U < pdiv) || (pdiv < 1024U)));
343   XMC_ASSERT("XMC_USIC_CH_ConfigExternalInputSignalToBRG: Oversampling out of range", ((1U < oversampling) || (oversampling < 32U)));
344 
345   /* Setting the external input frequency source through DX1 */
346   XMC_USIC_CH_SetBRGInputClockSource(channel, XMC_USIC_CH_BRG_CLOCK_SOURCE_DX1T);
347 
348   /* Setting the trigger combination mode */
349   XMC_USIC_CH_SetInputTriggerCombinationMode(channel,XMC_USIC_CH_INPUT_DX1,combination_mode);
350 
351   /* Configuring the dividers and oversampling */
352   channel->BRG = (channel->BRG & ~(USIC_CH_BRG_DCTQ_Msk |
353                                    USIC_CH_BRG_PDIV_Msk |
354                                    USIC_CH_BRG_PCTQ_Msk |
355                                    USIC_CH_BRG_PPPEN_Msk)) |
356                   (((oversampling) - 1U) << USIC_CH_BRG_DCTQ_Pos) |
357                   (((pdiv) - 1U) << USIC_CH_BRG_PDIV_Pos);
358 }
359 
XMC_USIC_CH_TXFIFO_Configure(XMC_USIC_CH_t * const channel,const uint32_t data_pointer,const XMC_USIC_CH_FIFO_SIZE_t size,const uint32_t limit)360 void XMC_USIC_CH_TXFIFO_Configure(XMC_USIC_CH_t *const channel,
361                                   const uint32_t data_pointer,
362                                   const XMC_USIC_CH_FIFO_SIZE_t size,
363                                   const uint32_t limit)
364 {
365   /* Disable FIFO */
366   channel->TBCTR &= (uint32_t)~USIC_CH_TBCTR_SIZE_Msk;
367 
368   /* LOF = 0, A standard transmit buffer event occurs when the filling level equals the limit value and gets
369    * lower due to transmission of a data word
370    * STBTEN = 0, the trigger of the standard transmit buffer event is based on the transition of the fill level
371    *  from equal to below the limit, not the fact being below
372    */
373   channel->TBCTR = (uint32_t)(channel->TBCTR & (uint32_t)~(USIC_CH_TBCTR_LIMIT_Msk |
374                                                            USIC_CH_TBCTR_DPTR_Msk |
375                                                            USIC_CH_TBCTR_SIZE_Msk)) |
376                    (uint32_t)((limit << USIC_CH_TBCTR_LIMIT_Pos) |
377                    (data_pointer << USIC_CH_TBCTR_DPTR_Pos) |
378                    ((uint32_t)size << USIC_CH_TBCTR_SIZE_Pos));
379 }
380 
381 
XMC_USIC_CH_RXFIFO_Configure(XMC_USIC_CH_t * const channel,const uint32_t data_pointer,const XMC_USIC_CH_FIFO_SIZE_t size,const uint32_t limit)382 void XMC_USIC_CH_RXFIFO_Configure(XMC_USIC_CH_t *const channel,
383                                   const uint32_t data_pointer,
384                                   const XMC_USIC_CH_FIFO_SIZE_t size,
385                                   const uint32_t limit)
386 {
387   /* Disable FIFO */
388   channel->RBCTR &= (uint32_t)~USIC_CH_RBCTR_SIZE_Msk;
389 
390   /* LOF = 1, A standard receive buffer event occurs when the filling level equals the limit value and gets bigger
391    *  due to the reception of a new data word
392    */
393   channel->RBCTR = (uint32_t)((channel->RBCTR & (uint32_t)~(USIC_CH_RBCTR_LIMIT_Msk |
394                                                             USIC_CH_RBCTR_DPTR_Msk |
395                                                             USIC_CH_RBCTR_LOF_Msk)) |
396                    ((limit << USIC_CH_RBCTR_LIMIT_Pos) |
397                    (data_pointer << USIC_CH_RBCTR_DPTR_Pos) |
398                    ((uint32_t)size << USIC_CH_RBCTR_SIZE_Pos) |
399                    (uint32_t)USIC_CH_RBCTR_LOF_Msk));
400 }
401 
XMC_USIC_CH_TXFIFO_SetSizeTriggerLimit(XMC_USIC_CH_t * const channel,const XMC_USIC_CH_FIFO_SIZE_t size,const uint32_t limit)402 void XMC_USIC_CH_TXFIFO_SetSizeTriggerLimit(XMC_USIC_CH_t *const channel,
403                                             const XMC_USIC_CH_FIFO_SIZE_t size,
404                                             const uint32_t limit)
405 {
406   /* Disable FIFO */
407   channel->TBCTR &= (uint32_t)~USIC_CH_TBCTR_SIZE_Msk;
408 
409   /* STBTEN = 0, the trigger of the standard transmit buffer event is based on the transition of the fill level
410    *  from equal to below the limit, not the fact being below
411    */
412   channel->TBCTR = (uint32_t)((uint32_t)(channel->TBCTR & (uint32_t)~USIC_CH_TBCTR_LIMIT_Msk) |
413                    (limit << USIC_CH_TBCTR_LIMIT_Pos) |
414                    ((uint32_t)size << USIC_CH_TBCTR_SIZE_Pos));
415 }
416 
XMC_USIC_CH_RXFIFO_SetSizeTriggerLimit(XMC_USIC_CH_t * const channel,const XMC_USIC_CH_FIFO_SIZE_t size,const uint32_t limit)417 void XMC_USIC_CH_RXFIFO_SetSizeTriggerLimit(XMC_USIC_CH_t *const channel,
418                                             const XMC_USIC_CH_FIFO_SIZE_t size,
419                                             const uint32_t limit)
420 {
421   /* Disable FIFO */
422   channel->RBCTR &= (uint32_t)~USIC_CH_RBCTR_SIZE_Msk;
423 
424   channel->RBCTR = (uint32_t)((uint32_t)(channel->RBCTR & (uint32_t)~USIC_CH_RBCTR_LIMIT_Msk) |
425                    (limit << USIC_CH_RBCTR_LIMIT_Pos) |
426                    ((uint32_t)size << USIC_CH_RBCTR_SIZE_Pos));
427 }
428 
XMC_USIC_CH_SetInterruptNodePointer(XMC_USIC_CH_t * const channel,const XMC_USIC_CH_INTERRUPT_NODE_POINTER_t interrupt_node,const uint32_t service_request)429 void XMC_USIC_CH_SetInterruptNodePointer(XMC_USIC_CH_t *const channel,
430                                          const XMC_USIC_CH_INTERRUPT_NODE_POINTER_t interrupt_node,
431                                          const uint32_t service_request)
432 {
433   channel->INPR = (uint32_t)((channel->INPR & (~(uint32_t)(USIC_CH_INPR_Msk << (uint32_t)interrupt_node))) |
434                   (service_request << (uint32_t)interrupt_node));
435 }
436 
XMC_USIC_CH_TXFIFO_SetInterruptNodePointer(XMC_USIC_CH_t * const channel,const XMC_USIC_CH_TXFIFO_INTERRUPT_NODE_POINTER_t interrupt_node,const uint32_t service_request)437 void XMC_USIC_CH_TXFIFO_SetInterruptNodePointer(XMC_USIC_CH_t *const channel,
438                                                 const XMC_USIC_CH_TXFIFO_INTERRUPT_NODE_POINTER_t interrupt_node,
439                                                 const uint32_t service_request)
440 {
441   channel->TBCTR = (uint32_t)((channel->TBCTR & (~(uint32_t)(USIC_CH_INPR_Msk << (uint32_t)interrupt_node))) |
442                    (service_request << (uint32_t)interrupt_node));
443 }
444 
XMC_USIC_CH_RXFIFO_SetInterruptNodePointer(XMC_USIC_CH_t * const channel,const XMC_USIC_CH_RXFIFO_INTERRUPT_NODE_POINTER_t interrupt_node,const uint32_t service_request)445 void XMC_USIC_CH_RXFIFO_SetInterruptNodePointer(XMC_USIC_CH_t *const channel,
446                                                 const XMC_USIC_CH_RXFIFO_INTERRUPT_NODE_POINTER_t interrupt_node,
447                                                 const uint32_t service_request)
448 {
449   channel->RBCTR = (uint32_t)((channel->RBCTR & (~(uint32_t)(USIC_CH_INPR_Msk << (uint32_t)interrupt_node))) |
450                    (service_request << (uint32_t)interrupt_node));
451 }
452 
XMC_USIC_Enable(XMC_USIC_t * const usic)453 void XMC_USIC_Enable(XMC_USIC_t *const usic)
454 {
455   if (usic == USIC0)
456   {
457 #if defined(CLOCK_GATING_SUPPORTED)
458     XMC_SCU_CLOCK_UngatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_USIC0);
459     while (XMC_SCU_CLOCK_IsPeripheralClockGated(XMC_SCU_PERIPHERAL_CLOCK_USIC0));
460 #endif
461 #if defined(PERIPHERAL_RESET_SUPPORTED)
462     XMC_SCU_RESET_DeassertPeripheralReset(XMC_SCU_PERIPHERAL_RESET_USIC0);
463     while (XMC_SCU_RESET_IsPeripheralResetAsserted(XMC_SCU_PERIPHERAL_RESET_USIC0));
464 #endif
465   }
466 #if defined(USIC1)
467   else if (usic == USIC1)
468   {
469 #if defined(CLOCK_GATING_SUPPORTED)
470     XMC_SCU_CLOCK_UngatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_USIC1);
471     while (XMC_SCU_CLOCK_IsPeripheralClockGated(XMC_SCU_PERIPHERAL_CLOCK_USIC1));
472 #endif
473 #if defined(PERIPHERAL_RESET_SUPPORTED)
474     XMC_SCU_RESET_DeassertPeripheralReset(XMC_SCU_PERIPHERAL_RESET_USIC1);
475     while (XMC_SCU_RESET_IsPeripheralResetAsserted(XMC_SCU_PERIPHERAL_RESET_USIC1));
476 #endif
477   }
478 #endif
479 #if defined(USIC2)
480   else if (usic == USIC2)
481   {
482 #if defined(CLOCK_GATING_SUPPORTED)
483     XMC_SCU_CLOCK_UngatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_USIC2);
484     while (XMC_SCU_CLOCK_IsPeripheralClockGated(XMC_SCU_PERIPHERAL_CLOCK_USIC2));
485 #endif
486 #if defined(PERIPHERAL_RESET_SUPPORTED)
487     XMC_SCU_RESET_DeassertPeripheralReset(XMC_SCU_PERIPHERAL_RESET_USIC2);
488     while (XMC_SCU_RESET_IsPeripheralResetAsserted(XMC_SCU_PERIPHERAL_RESET_USIC2));
489 #endif
490   }
491 #endif
492   else
493   {
494     XMC_ASSERT("USIC module not available", 0/*Always*/);
495   }
496 }
497 
XMC_USIC_Disable(XMC_USIC_t * const usic)498 void XMC_USIC_Disable(XMC_USIC_t *const usic)
499 {
500   if (usic == (XMC_USIC_t *)USIC0)
501   {
502 #if defined(PERIPHERAL_RESET_SUPPORTED)
503     XMC_SCU_RESET_AssertPeripheralReset(XMC_SCU_PERIPHERAL_RESET_USIC0);
504 #endif
505 #if defined(CLOCK_GATING_SUPPORTED)
506     XMC_SCU_CLOCK_GatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_USIC0);
507 #endif
508   }
509 #if defined(USIC1)
510   else if (usic == (XMC_USIC_t *)USIC1)
511   {
512 #if defined(PERIPHERAL_RESET_SUPPORTED)
513     XMC_SCU_RESET_AssertPeripheralReset(XMC_SCU_PERIPHERAL_RESET_USIC1);
514 #endif
515 #if defined(CLOCK_GATING_SUPPORTED)
516     XMC_SCU_CLOCK_GatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_USIC1);
517 #endif
518   }
519 #endif
520 #if defined(USIC2)
521   else if (usic == (XMC_USIC_t *)USIC2)
522   {
523 #if defined(PERIPHERAL_RESET_SUPPORTED)
524     XMC_SCU_RESET_AssertPeripheralReset(XMC_SCU_PERIPHERAL_RESET_USIC2);
525 #endif
526 #if defined(CLOCK_GATING_SUPPORTED)
527     XMC_SCU_CLOCK_GatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_USIC2);
528 #endif
529   }
530 #endif
531   else
532   {
533 	  XMC_ASSERT("USIC module not available", 0/*Always*/);
534   }
535 
536 }
537