1 /**
2  * @file xmc4_scu.c
3  * @date 2018-06-21
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-05-20:
43  *     - XMC_ASSERT() hanging issues have fixed.  <br>
44  *     - Line indentation aligned with 120 characters. <br>
45  *
46  * 2015-06-20:
47  *     - XMC_SCU_INTERRUPT_EnableEvent,XMC_SCU_INTERRUPT_DisableEvent,
48  *     - XMC_SCU_INTERRUPT_TriggerEvent,XMC_SCU_INTERUPT_GetEventStatus,
49  *     - XMC_SCU_INTERRUPT_ClearEventStatus are added
50  *     - Added Weak implementation for OSCHP_GetFrequency()
51  *
52  * 2015-11-30:
53  *     - Documentation improved <br>
54  *     - Following API functionalities are improved
55  *       XMC_SCU_CLOCK_GatePeripheralClock, XMC_SCU_CLOCK_UngatePeripheralClock, XMC_SCU_CLOCK_IsPeripheralClockGated
56  *       XMC_SCU_RESET_AssertPeripheralReset, XMC_SCU_RESET_DeassertPeripheralReset, XMC_SCU_RESET_IsPeripheralResetAsserted
57  *
58  * 2015-12-08:
59  *     - XMC_SCU_GetTemperature renamed to XMC_SCU_GetTemperatureMeasurement
60  *
61  * 2016-03-09:
62  *     - Optimize write only registers
63  *     - Added XMC_SCU_HIB_SetPinMode
64  *     - Added XMC_SCU_HIB_GetHibernateControlStatus,
65  *             XMC_SCU_HIB_GetEventStatus, XMC_SCU_HIB_ClearEventStatus, XMC_SCU_HIB_TriggerEvent,
66  *             XMC_SCU_HIB_EnableEvent, XMC_SCU_HIB_DisableEvent
67  *     - Added XMC_SCU_HIB_SetWakeupTriggerInput, XMC_SCU_HIB_SetPinMode, XMC_SCU_HIB_SetOutputPinLevel,
68  *             XMC_SCU_HIB_SetInput0, XMC_SCU_HIB_EnterHibernateState
69  *
70  * 2016-04-06:
71  *     - Fixed XMC_SCU_ReadFromRetentionMemory functionality
72  *
73  * 2016-05-19:
74  *     - Changed XMC_SCU_CLOCK_StartSystemPll to avoid using floating point calculation which might have an impact on interrupt latency if ISR uses also the FPU
75  *     - Added XMC_SCU_CLOCK_IsLowPowerOscillatorStable() and XMC_SCU_CLOCK_IsHighPerformanceOscillatorStable()
76  *     - Added XMC_SCU_CLOCK_EnableLowPowerOscillatorGeneralPurposeInput(),
77  *             XMC_SCU_CLOCK_DisableLowPowerOscillatorGeneralPurposeInput(),
78  *             XMC_SCU_CLOCK_GetLowPowerOscillatorGeneralPurposeInputStatus()
79  *     - Added XMC_SCU_CLOCK_EnableHighPerformanceOscillatorGeneralPurposeInput(),
80  *             XMC_SCU_CLOCK_DisableHighPerformanceOscillatorGeneralPurposeInput(),
81  *             XMC_SCU_CLOCK_GetHighPerformanceOscillatorGeneralPurposeInputStatus()
82  *
83  * 2016-06-15:
84  *     - Added XMC_SCU_HIB_EnterHibernateStateEx() which allows to select between external or internal hibernate mode. This last mode only available in XMC44, XMC42 and XMC41 series.
85  *     - Extended wakeup hibernate events using LPAC wakeup on events. Only available in XMC44, XMC42 and XMC41 series
86  *     - Added LPAC APIs. Only available in XMC44, XMC42 and XMC41 series.
87  *
88  * 2018-06-21:
89  *     - Fixed XMC_SCU_HIB_SetSR1Input()
90  *     - Fixed XMC_SCU_CLOCK_EnableLowPowerOscillator()
91  *
92  * @endcond
93  *
94  */
95 
96 /**
97  *
98  * @brief SCU low level driver API prototype definition for XMC4 family of microcontrollers.
99  *
100  * <b>Detailed description of file:</b> <br>
101  * APIs provided in this file cover the following functional blocks of SCU: <br>
102  * -- GCU (APIs prefixed with XMC_SCU_GEN_) <br>
103  * ------ Temperature Monitoring, Bootmode selection, CCU Start, Comparator configuration etc  <br>
104  * -- CCU (APIs prefixed with XMC_SCU_CLOCK_) <br>
105  * ------ Clock sources init, Clock tree init, Clock gating, Sleep Management etc <br>
106  * -- RCU (APIs prefixed with XMC_SCU_RESET_) <br>
107  * ------ Reset Init, Cause, Manual Reset Assert/Deassert <br>
108  * -- INTERRUPT (APIs prefixed with XMC_SCU_INTERRUPT_) <br>
109  * ------ Init, Manual Assert/Deassert, Acknowledge etc <br>
110  * -- PARITY (APIs prefixed with XMC_SCU_PARITY_) <br>
111  * ------ Init, Acknowledge etc <br>
112  * -- HIBERNATION (APIs prefixed with XMC_SCU_HIB_) <br>
113  * ------ Hibernation entry/exit config, entry/wakeup sequences, LPAC configuration etc <br>
114  * -- TRAP (APIs prefixed with XMC_SCU_TRAP_) <br>
115  * ------ Init, Enable/Disable, Acknowledge etc <br>
116  *
117  */
118 
119 /*********************************************************************************************************************
120  * HEADER FILES
121  ********************************************************************************************************************/
122 #include <xmc_scu.h>
123 
124 #if UC_FAMILY == XMC4
125 
126 /*********************************************************************************************************************
127  * MACROS
128  ********************************************************************************************************************/
129 #define FOSCREF   (2500000UL)    /**< Oscillator reference frequency (fOSCREF) monitored by Oscillator watchdog  */
130 #define FREQ_1MHZ (1000000UL)    /**< Used during calculation. */
131 
132 #ifndef OFI_FREQUENCY
133 #define OFI_FREQUENCY (24000000UL)    /**< Fast internal backup clock source. */
134 #endif
135 
136 #ifndef OSI_FREQUENCY
137 #define OSI_FREQUENCY (32768UL)    /**< Internal slow clock source. */
138 #endif
139 
140 #ifndef OSCHP_FREQUENCY
141 #define OSCHP_FREQUENCY (12000000U)    /**< External crystal High Precision Oscillator. */
142 #endif
143 
144 #define XMC_SCU_PLL_PLLSTAT_OSC_USABLE  (SCU_PLL_PLLSTAT_PLLHV_Msk | \
145                                          SCU_PLL_PLLSTAT_PLLLV_Msk | \
146                                          SCU_PLL_PLLSTAT_PLLSP_Msk)  /**< Used to verify the OSC frequency is
147                                                                           usable or not.*/
148 
149 #define XMC_SCU_ORC_ADC_START_GROUP    (0UL)    /**< The ADC group whose channel input is compared by Out of Range
150                                                      Comparator (ORC) to serves the purpose of overvoltage monitoring
151                                                      for analog input pins of the chip and ORC start measurements from
152                                                      this group number. */
153 #define XMC_SCU_ORC_ADC_END_GROUP      (1UL)    /**< The ADC group whose channel input is compared by Out of Range
154                                                      Comparator (ORC) to serves the purpose of overvoltage monitoring
155                                                      for analog input pins of the chip and ORC end measurements at
156                                                      this group number. */
157 #define XMC_SCU_ORC_START_ADC_CHANNEL  (6UL)    /**< The ADC channel whose channel input is compared by Out of Range
158                                                      Comparator (ORC) to serves the purpose of overvoltage monitoring
159                                                      for analog input pins of the chip and ORC start measurements from
160                                                      this channel number. */
161 #define XMC_SCU_ORC_END_ADC_CHANNEL    (7UL)    /**< The ADC channel whose channel input is compared by Out of Range
162                                                      Comparator (ORC) to serves the purpose of overvoltage monitoring
163                                                      for analog input pins of the chip and ORC ends measurements at
164                                                      this channel number. */
165 
166 #define XMC_SCU_CHECK_GRPNUM(GROUP_NUM)   (((GROUP_NUM) == XMC_SCU_ORC_ADC_START_GROUP) || \
167                                         ((GROUP_NUM) == XMC_SCU_ORC_ADC_END_GROUP) ) /**< Used to verify whether
168                                                                                       provided ADC group number lies
169                                                                                       within specified ADC start and
170                                                                                       end group number or not. */
171 
172 #define XMC_SCU_CHECK_CHNUM(CH_NUM)       (((CH_NUM) == XMC_SCU_ORC_START_ADC_CHANNEL) || \
173                                         ((CH_NUM) == XMC_SCU_ORC_END_ADC_CHANNEL) )  /**< Used to verify whether
174                                                                                       provided ADC channel number lies
175                                                                                       within specified ADC start and
176                                                                                       end channel number or not. */
177 
178 #define XMC_SCU_INTERRUPT_EVENT_MAX            (32U)      /**< Maximum supported SCU events. */
179 
180 #define SCU_HIBERNATE_HDCR_HIBIOSEL_Size (4U)
181 
182 #define SCU_HIBERNATE_OSCULCTRL_MODE_OSC_POWER_DOWN (0x2U)
183 
184 #define XMC_SCU_POWER_LSB13V (0.0058F)
185 #define XMC_SCU_POWER_LSB33V (0.0225F)
186 
187 /*********************************************************************************************************************
188  * LOCAL DATA
189  ********************************************************************************************************************/
190 XMC_SCU_INTERRUPT_EVENT_HANDLER_t event_handler_list[XMC_SCU_INTERRUPT_EVENT_MAX]; /**< For registering callback
191                                                                                         functions on SCU event
192                                                                                         occurrence. */
193 
194 /*********************************************************************************************************************
195  * LOCAL ROUTINES
196  ********************************************************************************************************************/
197  #if defined(UC_ID)
198 /* This is a non-weak function, which retrieves high precision external oscillator frequency. */
OSCHP_GetFrequency(void)199 __WEAK uint32_t OSCHP_GetFrequency(void)
200 {
201   return (OSCHP_FREQUENCY);
202 }
203 #endif
204 
205 /* This is a local function used to generate the delay until register get updated with new configured value.  */
206 static void XMC_SCU_lDelay(uint32_t cycles);
207 
208 /*********************************************************************************************************************
209  * API IMPLEMENTATION
210  ********************************************************************************************************************/
211 /* This is a local function used to generate the delay until register get updated with new configured value.  */
XMC_SCU_lDelay(uint32_t delay)212 void XMC_SCU_lDelay(uint32_t delay)
213 {
214   uint32_t i;
215 
216   SystemCoreClockUpdate();
217   delay =  delay * (uint32_t)(SystemCoreClock / FREQ_1MHZ);
218 
219   for (i = 0U; i < delay; ++i)
220   {
221     __NOP();
222   }
223 }
224 
225 /* API to enable the SCU event */
XMC_SCU_INTERRUPT_EnableEvent(const XMC_SCU_INTERRUPT_EVENT_t event)226 void XMC_SCU_INTERRUPT_EnableEvent(const XMC_SCU_INTERRUPT_EVENT_t event)
227 {
228   SCU_INTERRUPT->SRMSK |= (uint32_t)event;
229 }
230 
231 /* API to disable the SCU event */
XMC_SCU_INTERRUPT_DisableEvent(const XMC_SCU_INTERRUPT_EVENT_t event)232 void XMC_SCU_INTERRUPT_DisableEvent(const XMC_SCU_INTERRUPT_EVENT_t event)
233 {
234   SCU_INTERRUPT->SRMSK &= (uint32_t)~event;
235 }
236 
237 /* API to trigger the SCU event */
XMC_SCU_INTERRUPT_TriggerEvent(const XMC_SCU_INTERRUPT_EVENT_t event)238 void XMC_SCU_INTERRUPT_TriggerEvent(const XMC_SCU_INTERRUPT_EVENT_t event)
239 {
240   SCU_INTERRUPT->SRSET |= (uint32_t)event;
241 }
242 
243 /* API to retrieve the SCU event status */
XMC_SCU_INTERUPT_GetEventStatus(void)244 XMC_SCU_INTERRUPT_EVENT_t XMC_SCU_INTERUPT_GetEventStatus(void)
245 {
246   return (SCU_INTERRUPT->SRRAW);
247 }
248 
249 /* API to clear the SCU event status */
XMC_SCU_INTERRUPT_ClearEventStatus(const XMC_SCU_INTERRUPT_EVENT_t event)250 void XMC_SCU_INTERRUPT_ClearEventStatus(const XMC_SCU_INTERRUPT_EVENT_t event)
251 {
252   SCU_INTERRUPT->SRCLR = (uint32_t)event;
253 }
254 
255 
256 /* API to retrieve the currently deployed device bootmode */
XMC_SCU_GetBootMode(void)257 uint32_t XMC_SCU_GetBootMode(void)
258 {
259   return (uint32_t)(SCU_GENERAL->STCON & SCU_GENERAL_STCON_SWCON_Msk);
260 }
261 
262 /* API to program a new device bootmode */
XMC_SCU_SetBootMode(const XMC_SCU_BOOTMODE_t bootmode)263 void XMC_SCU_SetBootMode(const XMC_SCU_BOOTMODE_t bootmode)
264 {
265   SCU_GENERAL->STCON = (uint32_t)bootmode;
266 }
267 
268 /* API to read from General purpose register */
XMC_SCU_ReadGPR(const uint32_t index)269 uint32_t XMC_SCU_ReadGPR(const uint32_t index)
270 {
271   return (SCU_GENERAL->GPR[index]);
272 }
273 
274 /* API to write to GPR */
XMC_SCU_WriteGPR(const uint32_t index,const uint32_t data)275 void XMC_SCU_WriteGPR(const uint32_t index, const uint32_t data)
276 {
277   SCU_GENERAL->GPR[index] = data;
278 }
279 
280 /* API to enable Out of Range Comparator(ORC) for a desired group and a desired channel input */
XMC_SCU_EnableOutOfRangeComparator(const uint32_t group,const uint32_t channel)281 void XMC_SCU_EnableOutOfRangeComparator(const uint32_t group, const uint32_t channel)
282 {
283   XMC_ASSERT("XMC_SCU_EnableOutOfangeComparator:Wrong Group Number",XMC_SCU_CHECK_GRPNUM(group));
284   XMC_ASSERT("XMC_SCU_EnableOutOfangeComparator:Wrong Channel Number",XMC_SCU_CHECK_CHNUM(channel));
285 
286   SCU_GENERAL->GORCEN[group] |= (uint32_t)(1UL << channel);
287 }
288 
289 /* API to enable Out of Range Comparator(ORC) for a desired group and a desired channel input */
XMC_SCU_DisableOutOfRangeComparator(const uint32_t group,const uint32_t channel)290 void XMC_SCU_DisableOutOfRangeComparator(const uint32_t group, const uint32_t channel)
291 {
292   XMC_ASSERT("XMC_SCU_DisableOutOfRangeComparator:Wrong Group Number",XMC_SCU_CHECK_GRPNUM(group));
293   XMC_ASSERT("XMC_SCU_DisableOutOfRangeComparator:Wrong Channel Number",XMC_SCU_CHECK_CHNUM(channel));
294 
295   SCU_GENERAL->GORCEN[group] &= (uint32_t)~(1UL << channel);
296 }
297 
298 /* API to calibrate temperature sensor */
XMC_SCU_CalibrateTemperatureSensor(uint32_t offset,uint32_t gain)299 void XMC_SCU_CalibrateTemperatureSensor(uint32_t offset, uint32_t gain)
300 {
301   SCU_GENERAL->DTSCON = ((uint32_t)(offset << SCU_GENERAL_DTSCON_OFFSET_Pos) |
302                         (uint32_t)(gain << SCU_GENERAL_DTSCON_GAIN_Pos) |
303                         (uint32_t)(0x4UL << SCU_GENERAL_DTSCON_REFTRIM_Pos) |
304                         (uint32_t)(0x8UL << SCU_GENERAL_DTSCON_BGTRIM_Pos));
305 }
306 /* API to enable die temperature measurement by powering the DTS module. */
XMC_SCU_EnableTemperatureSensor(void)307 void XMC_SCU_EnableTemperatureSensor(void)
308 {
309   SCU_GENERAL->DTSCON &= (uint32_t)~(SCU_GENERAL_DTSCON_PWD_Msk);
310 }
311 
312 /* API to disable die temperature measurement by powering the DTS module off. */
XMC_SCU_DisableTemperatureSensor(void)313 void XMC_SCU_DisableTemperatureSensor(void)
314 {
315   SCU_GENERAL->DTSCON |= (uint32_t)SCU_GENERAL_DTSCON_PWD_Msk;
316 }
317 
318 /* API to provide the die temperature sensor power status. */
XMC_SCU_IsTemperatureSensorEnabled(void)319 bool XMC_SCU_IsTemperatureSensorEnabled(void)
320 {
321   return ((SCU_GENERAL->DTSCON & SCU_GENERAL_DTSCON_PWD_Msk) == 0U);
322 }
323 
324 /* API to check if the die temperature sensor is ready to start a measurement. */
XMC_SCU_IsTemperatureSensorReady(void)325 bool XMC_SCU_IsTemperatureSensorReady(void)
326 {
327   return ((SCU_GENERAL->DTSSTAT & SCU_GENERAL_DTSSTAT_RDY_Msk) != 0U);
328 }
329 /* API to start device temperature measurements */
XMC_SCU_StartTemperatureMeasurement(void)330 XMC_SCU_STATUS_t XMC_SCU_StartTemperatureMeasurement(void)
331 {
332   XMC_SCU_STATUS_t status = XMC_SCU_STATUS_OK;
333 
334   if (XMC_SCU_IsTemperatureSensorEnabled() == false)
335   {
336     status = XMC_SCU_STATUS_ERROR;
337   }
338 
339   if (XMC_SCU_IsTemperatureSensorBusy() == true)
340   {
341     status = XMC_SCU_STATUS_BUSY;
342   }
343 
344   /* And start the measurement */
345   SCU_GENERAL->DTSCON |= (uint32_t)SCU_GENERAL_DTSCON_START_Msk;
346 
347   return (status);
348 }
349 
350 /* API to retrieve the temperature measured */
XMC_SCU_GetTemperatureMeasurement(void)351 uint32_t XMC_SCU_GetTemperatureMeasurement(void)
352 {
353   uint32_t temperature;
354 
355   if (XMC_SCU_IsTemperatureSensorEnabled() == false)
356   {
357     temperature = 0x7FFFFFFFUL;
358   }
359   else
360   {
361     temperature = (uint32_t)((SCU_GENERAL->DTSSTAT & SCU_GENERAL_DTSSTAT_RESULT_Msk) >> SCU_GENERAL_DTSSTAT_RESULT_Pos);
362   }
363 
364   return ((uint32_t)temperature);
365 }
366 
367 /* API to know whether Die temperature sensor is busy */
XMC_SCU_IsTemperatureSensorBusy(void)368 bool XMC_SCU_IsTemperatureSensorBusy(void)
369 {
370   return ((SCU_GENERAL->DTSSTAT & SCU_GENERAL_DTSSTAT_BUSY_Msk) != 0U);
371 }
372 
373 
374 #if defined(SCU_GENERAL_DTEMPLIM_LOWER_Msk) && defined(SCU_GENERAL_DTEMPLIM_UPPER_Msk)
375 /* API to determine if device temperature has gone past the ceiling */
XMC_SCU_HighTemperature(void)376 bool XMC_SCU_HighTemperature(void)
377 {
378   bool ret_val;
379   uint32_t   dtscon;
380   uint32_t   dtempalarm;
381   dtscon = SCU_GENERAL->DTSCON;
382   dtscon = dtscon & SCU_GENERAL_DTSCON_PWD_Msk;
383 
384   ret_val = false;
385 
386   /* Any audit makes sense only if the DTS were powered up */
387   if(dtscon)
388   {
389     /* Powered down - return false */
390     ret_val = false;
391   }
392   else
393   {
394     /* Powered up - Read the overflow bit and decide accordingly*/
395     dtempalarm = SCU_GENERAL->DTEMPALARM;
396     dtempalarm = dtempalarm & SCU_GENERAL_DTEMPALARM_OVERFL_Msk;
397 
398     if(dtempalarm)
399     {
400       ret_val = true;
401     }
402     else
403     {
404       ret_val = false;
405     }
406   }
407   return (ret_val);
408 }
409 
410 /* API to program raw values of temperature limits into the DTS */
XMC_SCU_SetRawTempLimits(const uint32_t lower_temp,const uint32_t upper_temp)411 void XMC_SCU_SetRawTempLimits(const uint32_t lower_temp, const uint32_t upper_temp)
412 {
413   /* Power up the DTS module */
414   SCU_GENERAL->DTSCON &= (uint32_t)~SCU_GENERAL_DTSCON_PWD_Msk;
415   SCU_GENERAL->DTEMPLIM = 0;
416   SCU_GENERAL->DTEMPLIM = (lower_temp & SCU_GENERAL_DTEMPLIM_LOWER_Msk);
417   SCU_GENERAL->DTEMPLIM |= (uint32_t)((upper_temp & SCU_GENERAL_DTEMPLIM_LOWER_Msk) << SCU_GENERAL_DTEMPLIM_UPPER_Pos);
418 }
419 
420 /* API to determine if device temperature has gone below the stipulated limit */
XMC_SCU_LowTemperature(void)421 bool XMC_SCU_LowTemperature(void)
422 {
423   bool ret_val;
424   uint32_t   dtscon;
425   uint32_t   dtempalarm;
426   dtscon = SCU_GENERAL->DTSCON;
427   dtscon = dtscon & SCU_GENERAL_DTSCON_PWD_Msk;
428 
429   ret_val = false;
430 
431   /* Any audit makes sense only if the DTS were powered up */
432   if(dtscon)
433   {
434     /* Powered down - return false */
435     ret_val = false;
436   }
437   else
438   {
439     /* Powered up - Read the overflow bit and decide accordingly*/
440     dtempalarm = SCU_GENERAL->DTEMPALARM;
441     dtempalarm = dtempalarm & SCU_GENERAL_DTEMPALARM_UNDERFL_Msk;
442 
443     if(dtempalarm)
444     {
445       ret_val = true;
446     }
447     else
448     {
449       ret_val = false;
450     }
451   }
452 
453   return (ret_val);
454 }
455 #endif
456 
457 /* API to write into Retention memory in hibernate domain */
XMC_SCU_WriteToRetentionMemory(uint32_t address,uint32_t data)458 void XMC_SCU_WriteToRetentionMemory(uint32_t address, uint32_t data)
459 {
460   uint32_t rmacr;
461 
462   /* Get the address right */
463   rmacr = (uint32_t)((address << SCU_GENERAL_RMACR_ADDR_Pos) & (uint32_t)SCU_GENERAL_RMACR_ADDR_Msk);
464 
465   /* Transfer from RMDATA to Retention memory */
466   rmacr |= (uint32_t)(SCU_GENERAL_RMACR_RDWR_Msk);
467 
468   /* Write desired data into RMDATA register */
469   SCU_GENERAL->RMDATA = data;
470 
471   /* Write address & direction of transfer into RMACR register */
472   SCU_GENERAL->RMACR = rmacr;
473 
474   /* Wait until the update of RMX register in hibernate domain is completed */
475   while((SCU_GENERAL->MIRRSTS) & SCU_GENERAL_MIRRSTS_RMX_Msk)
476   {
477   }
478 }
479 
480 /* API to read from Retention memory in hibernate domain */
XMC_SCU_ReadFromRetentionMemory(uint32_t address)481 uint32_t XMC_SCU_ReadFromRetentionMemory(uint32_t address)
482 {
483   uint32_t rmacr;
484 
485   /* Get the address right */
486   rmacr = ((uint32_t)(address << SCU_GENERAL_RMACR_ADDR_Pos) & (uint32_t)SCU_GENERAL_RMACR_ADDR_Msk);
487 
488   /* Transfer from RMDATA to Retention memory */
489   rmacr &= ~((uint32_t)(SCU_GENERAL_RMACR_RDWR_Msk));
490 
491   /* Writing an adress & direction of transfer into RMACR register */
492   SCU_GENERAL->RMACR = rmacr;
493 
494   /* Wait until the update of RMX register in hibernate domain is completed */
495   while((SCU_GENERAL->MIRRSTS) & SCU_GENERAL_MIRRSTS_RMX_Msk)
496   {
497   }
498 
499   return (SCU_GENERAL->RMDATA);
500 }
501 
502 /* API to initialize the clock tree */
XMC_SCU_CLOCK_Init(const XMC_SCU_CLOCK_CONFIG_t * const config)503 void XMC_SCU_CLOCK_Init(const XMC_SCU_CLOCK_CONFIG_t *const config)
504 {
505   XMC_ASSERT("", config->fsys_clkdiv != 0);
506   XMC_ASSERT("", config->fcpu_clkdiv != 0);
507   XMC_ASSERT("", config->fccu_clkdiv != 0);
508   XMC_ASSERT("", config->fperipheral_clkdiv != 0);
509   XMC_ASSERT("", ((config->syspll_config.p_div != 0) &&
510                   (config->syspll_config.mode == XMC_SCU_CLOCK_SYSPLL_MODE_NORMAL)) ||
511                   (config->syspll_config.mode == XMC_SCU_CLOCK_SYSPLL_MODE_PRESCALAR));
512   XMC_ASSERT("", ((config->syspll_config.n_div != 0) &&
513                   (config->syspll_config.mode == XMC_SCU_CLOCK_SYSPLL_MODE_NORMAL)) ||
514                   (config->syspll_config.mode == XMC_SCU_CLOCK_SYSPLL_MODE_PRESCALAR));
515   XMC_ASSERT("", (config->syspll_config.k_div != 0) &&
516                  ((config->syspll_config.mode == XMC_SCU_CLOCK_SYSPLL_MODE_NORMAL) ||
517                   (config->syspll_config.mode == XMC_SCU_CLOCK_SYSPLL_MODE_PRESCALAR)));
518   XMC_ASSERT("", ((config->fsys_clksrc == XMC_SCU_CLOCK_SYSCLKSRC_PLL) ||
519                  (config->fsys_clksrc == XMC_SCU_CLOCK_SYSCLKSRC_OFI)) &&
520                  ((config->syspll_config.mode == XMC_SCU_CLOCK_SYSPLL_MODE_NORMAL) ||
521                   (config->syspll_config.mode == XMC_SCU_CLOCK_SYSPLL_MODE_PRESCALAR)));
522   XMC_ASSERT("", ((config->fstdby_clksrc == XMC_SCU_HIB_STDBYCLKSRC_OSCULP) && (config->enable_osculp == true)) ||
523                  (config->fstdby_clksrc != XMC_SCU_HIB_STDBYCLKSRC_OSCULP));
524   XMC_ASSERT("", ((config->syspll_config.clksrc == XMC_SCU_CLOCK_SYSPLLCLKSRC_OSCHP) &&
525                  (config->enable_oschp == true)) || (config->syspll_config.clksrc != XMC_SCU_CLOCK_SYSPLLCLKSRC_OSCHP));
526 
527   XMC_SCU_CLOCK_SetSystemClockSource(XMC_SCU_CLOCK_SYSCLKSRC_OFI);
528 
529   XMC_SCU_HIB_EnableHibernateDomain();
530 
531   if (config->enable_osculp == true)
532   {
533     XMC_SCU_CLOCK_EnableLowPowerOscillator();
534     while (XMC_SCU_CLOCK_IsLowPowerOscillatorStable() == false);
535   }
536 
537   XMC_SCU_HIB_SetStandbyClockSource(config->fstdby_clksrc);
538   while (XMC_SCU_GetMirrorStatus() != 0)
539   {
540     /* Wait until update of the stanby clock source is done in the HIB domain */
541   }
542 
543   XMC_SCU_CLOCK_SetBackupClockCalibrationMode(config->calibration_mode);
544 
545   XMC_SCU_CLOCK_SetSystemClockDivider((uint32_t)config->fsys_clkdiv);
546   XMC_SCU_CLOCK_SetCpuClockDivider((uint32_t)config->fcpu_clkdiv);
547   XMC_SCU_CLOCK_SetCcuClockDivider((uint32_t)config->fccu_clkdiv);
548   XMC_SCU_CLOCK_SetPeripheralClockDivider((uint32_t)config->fperipheral_clkdiv);
549 
550   if (config->enable_oschp == true)
551   {
552     XMC_SCU_CLOCK_EnableHighPerformanceOscillator();
553     while(XMC_SCU_CLOCK_IsHighPerformanceOscillatorStable() == false);
554   }
555 
556   if (config->syspll_config.mode == XMC_SCU_CLOCK_SYSPLL_MODE_DISABLED)
557   {
558     XMC_SCU_CLOCK_DisableSystemPll();
559   }
560   else
561   {
562 
563     XMC_SCU_CLOCK_EnableSystemPll();
564     XMC_SCU_CLOCK_StartSystemPll(config->syspll_config.clksrc,
565                                  config->syspll_config.mode,
566                                  (uint32_t)config->syspll_config.p_div,
567                                  (uint32_t)config->syspll_config.n_div,
568                                  (uint32_t)config->syspll_config.k_div);
569   }
570 
571   /* use SYSPLL? */
572   if (config->fsys_clksrc == XMC_SCU_CLOCK_SYSCLKSRC_PLL)
573   {
574     XMC_SCU_CLOCK_SetSystemClockSource(XMC_SCU_CLOCK_SYSCLKSRC_PLL);
575   }
576   SystemCoreClockUpdate();
577 }
578 
579 /* API to enable a trap source */
XMC_SCU_TRAP_Enable(const uint32_t trap)580 void XMC_SCU_TRAP_Enable(const uint32_t trap)
581 {
582   SCU_TRAP->TRAPDIS &= (uint32_t)~trap;
583 }
584 
585 /* API to disable a trap source */
XMC_SCU_TRAP_Disable(const uint32_t trap)586 void XMC_SCU_TRAP_Disable(const uint32_t trap)
587 {
588   SCU_TRAP->TRAPDIS |= (uint32_t)trap;
589 }
590 
591 /* API to determine if a trap source has generated event */
XMC_SCU_TRAP_GetStatus(void)592 uint32_t XMC_SCU_TRAP_GetStatus(void)
593 {
594   return (SCU_TRAP->TRAPRAW);
595 }
596 
597 /* API to manually trigger a trap event */
XMC_SCU_TRAP_Trigger(const uint32_t trap)598 void XMC_SCU_TRAP_Trigger(const uint32_t trap)
599 {
600   SCU_TRAP->TRAPSET = (uint32_t)trap;
601 }
602 
603 /* API to clear a trap event */
XMC_SCU_TRAP_ClearStatus(const uint32_t trap)604 void XMC_SCU_TRAP_ClearStatus(const uint32_t trap)
605 {
606   SCU_TRAP->TRAPCLR = (uint32_t)trap;
607 }
608 
609 /* API to clear parity error event */
XMC_SCU_PARITY_ClearStatus(const uint32_t memory)610 void XMC_SCU_PARITY_ClearStatus(const uint32_t memory)
611 {
612   SCU_PARITY->PEFLAG |= (uint32_t)memory;
613 }
614 
615 /* API to determine if the specified parity error has occured or not */
XMC_SCU_PARITY_GetStatus(void)616 uint32_t XMC_SCU_PARITY_GetStatus(void)
617 {
618   return (SCU_PARITY->PEFLAG);
619 }
620 
621 /* API to enable parity error checking for the selected on-chip RAM type */
XMC_SCU_PARITY_Enable(const uint32_t memory)622 void XMC_SCU_PARITY_Enable(const uint32_t memory)
623 {
624   SCU_PARITY->PEEN |= (uint32_t)memory;
625 }
626 
627 /* API to disable parity error checking for the selected on-chip RAM type */
XMC_SCU_PARITY_Disable(const uint32_t memory)628 void XMC_SCU_PARITY_Disable(const uint32_t memory)
629 {
630   SCU_PARITY->PEEN &= (uint32_t)~memory;
631 }
632 
633 /* API to enable trap assertion for the parity error source */
XMC_SCU_PARITY_EnableTrapGeneration(const uint32_t memory)634 void XMC_SCU_PARITY_EnableTrapGeneration(const uint32_t memory)
635 {
636   SCU_PARITY->PETE |= (uint32_t)memory;
637 }
638 
639 /* API to disable the assertion of trap for the parity error source */
XMC_SCU_PARITY_DisableTrapGeneration(const uint32_t memory)640 void XMC_SCU_PARITY_DisableTrapGeneration(const uint32_t memory)
641 {
642   SCU_PARITY->PETE &= (uint32_t)~memory;
643 }
644 
645 /* Enables a NMI source */
XMC_SCU_INTERRUPT_EnableNmiRequest(const uint32_t request)646 void XMC_SCU_INTERRUPT_EnableNmiRequest(const uint32_t request)
647 {
648   SCU_INTERRUPT->NMIREQEN |= (uint32_t)request;
649 }
650 
651 /* Disables a NMI source */
XMC_SCU_INTERRUPT_DisableNmiRequest(const uint32_t request)652 void XMC_SCU_INTERRUPT_DisableNmiRequest(const uint32_t request)
653 {
654   SCU_INTERRUPT->NMIREQEN &= (uint32_t)~request;
655 }
656 
657 /* API to manually assert a reset request */
XMC_SCU_RESET_AssertPeripheralReset(const XMC_SCU_PERIPHERAL_RESET_t peripheral)658 void XMC_SCU_RESET_AssertPeripheralReset(const XMC_SCU_PERIPHERAL_RESET_t peripheral)
659 {
660   uint32_t index = (uint32_t)((((uint32_t)peripheral) & 0xf0000000UL) >> 28UL);
661   uint32_t mask = (((uint32_t)peripheral) & ((uint32_t)~0xf0000000UL));
662 
663   *(uint32_t *)(&(SCU_RESET->PRSET0) + (index * 3U)) = (uint32_t)mask;
664 }
665 
666 /* API to manually de-assert a reset request */
XMC_SCU_RESET_DeassertPeripheralReset(const XMC_SCU_PERIPHERAL_RESET_t peripheral)667 void XMC_SCU_RESET_DeassertPeripheralReset(const XMC_SCU_PERIPHERAL_RESET_t peripheral)
668 {
669   uint32_t index = (uint32_t)((((uint32_t)peripheral) & 0xf0000000UL) >> 28UL);
670   uint32_t mask = (((uint32_t)peripheral) & ((uint32_t)~0xf0000000UL));
671 
672   *(uint32_t *)(&(SCU_RESET->PRCLR0) + (index * 3U)) = (uint32_t)mask;
673 }
674 
675 /* Find out if the peripheral reset is asserted */
XMC_SCU_RESET_IsPeripheralResetAsserted(const XMC_SCU_PERIPHERAL_RESET_t peripheral)676 bool XMC_SCU_RESET_IsPeripheralResetAsserted(const XMC_SCU_PERIPHERAL_RESET_t peripheral)
677 {
678   uint32_t index = (uint32_t)((((uint32_t)peripheral) & 0xf0000000UL) >> 28UL);
679   uint32_t mask = (((uint32_t)peripheral) & ((uint32_t)~0xf0000000UL));
680 
681   return ((*(uint32_t *)(&(SCU_RESET->PRSTAT0) + (index * 3U)) & mask) != 0U);
682 }
683 
684 /*
685  * API to retrieve frequency of System PLL output clock
686  */
XMC_SCU_CLOCK_GetSystemPllClockFrequency(void)687 uint32_t XMC_SCU_CLOCK_GetSystemPllClockFrequency(void)
688 {
689   uint32_t clock_frequency;
690   uint32_t p_div;
691   uint32_t n_div;
692   uint32_t k2_div;
693 
694   clock_frequency = XMC_SCU_CLOCK_GetSystemPllClockSourceFrequency();
695   if(SCU_PLL->PLLSTAT & SCU_PLL_PLLSTAT_VCOBYST_Msk)
696   {
697     /* Prescalar mode - fOSC is the parent*/
698     clock_frequency = (uint32_t)(clock_frequency /
699                       ((((SCU_PLL->PLLCON1) & SCU_PLL_PLLCON1_K1DIV_Msk) >> SCU_PLL_PLLCON1_K1DIV_Pos) + 1UL));
700   }
701   else
702   {
703     p_div  = (uint32_t)((((SCU_PLL->PLLCON1) & SCU_PLL_PLLCON1_PDIV_Msk) >> SCU_PLL_PLLCON1_PDIV_Pos) + 1UL);
704     n_div  = (uint32_t)((((SCU_PLL->PLLCON1) & SCU_PLL_PLLCON1_NDIV_Msk) >> SCU_PLL_PLLCON1_NDIV_Pos) + 1UL);
705     k2_div = (uint32_t)((((SCU_PLL->PLLCON1) & SCU_PLL_PLLCON1_K2DIV_Msk) >> SCU_PLL_PLLCON1_K2DIV_Pos) + 1UL);
706 
707     clock_frequency = (clock_frequency * n_div) / (p_div * k2_div);
708   }
709 
710   return (clock_frequency);
711 }
712 
713 /**
714  * API to retrieve frequency of System PLL VCO input clock
715  */
XMC_SCU_CLOCK_GetSystemPllClockSourceFrequency(void)716 uint32_t XMC_SCU_CLOCK_GetSystemPllClockSourceFrequency(void)
717 {
718   uint32_t clock_frequency;
719 
720   /* Prescalar mode - fOSC is the parent*/
721   if((SCU_PLL->PLLCON2 & SCU_PLL_PLLCON2_PINSEL_Msk) == (uint32_t)XMC_SCU_CLOCK_SYSPLLCLKSRC_OSCHP)
722   {
723     clock_frequency = OSCHP_GetFrequency();
724   }
725   else
726   {
727     clock_frequency = OFI_FREQUENCY;
728   }
729 
730   return (clock_frequency);
731 }
732 
733 /*
734  * API to retrieve frequency of USB PLL output clock
735  */
XMC_SCU_CLOCK_GetUsbPllClockFrequency(void)736 uint32_t XMC_SCU_CLOCK_GetUsbPllClockFrequency(void)
737 {
738   uint32_t clock_frequency;
739   uint32_t n_div;
740   uint32_t p_div;
741 
742   clock_frequency = OSCHP_GetFrequency();
743   if((SCU_PLL->USBPLLSTAT & SCU_PLL_USBPLLSTAT_VCOBYST_Msk) == 0U)
744   {
745     /* Normal mode - fVCO is the parent*/
746     n_div = (uint32_t)((((SCU_PLL->USBPLLCON) & SCU_PLL_USBPLLCON_NDIV_Msk) >> SCU_PLL_USBPLLCON_NDIV_Pos) + 1UL);
747     p_div = (uint32_t)((((SCU_PLL->USBPLLCON) & SCU_PLL_USBPLLCON_PDIV_Msk) >> SCU_PLL_USBPLLCON_PDIV_Pos) + 1UL);
748     clock_frequency = (uint32_t)((clock_frequency * n_div)/ (uint32_t)(p_div * 2UL));
749   }
750   return (clock_frequency);
751 }
752 
753 /*
754  * API to retrieve frequency of CCU clock frequency
755  */
XMC_SCU_CLOCK_GetCcuClockFrequency(void)756 uint32_t XMC_SCU_CLOCK_GetCcuClockFrequency(void)
757 {
758   uint32_t frequency = 0UL;
759   frequency = XMC_SCU_CLOCK_GetSystemClockFrequency();
760 
761   return (uint32_t)(frequency >> ((uint32_t)((SCU_CLK->CCUCLKCR & SCU_CLK_CCUCLKCR_CCUDIV_Msk) >>
762                                               SCU_CLK_CCUCLKCR_CCUDIV_Pos)));
763 }
764 
765 /*
766  * API to retrieve USB and SDMMC clock frequency
767  */
XMC_SCU_CLOCK_GetUsbClockFrequency(void)768 uint32_t XMC_SCU_CLOCK_GetUsbClockFrequency(void)
769 {
770   uint32_t frequency = 0UL;
771   XMC_SCU_CLOCK_USBCLKSRC_t clksrc;
772 
773   clksrc = XMC_SCU_CLOCK_GetUsbClockSource();
774 
775   if (clksrc == XMC_SCU_CLOCK_USBCLKSRC_SYSPLL)
776   {
777     frequency = XMC_SCU_CLOCK_GetSystemPllClockFrequency();
778   }
779   else if (clksrc == XMC_SCU_CLOCK_USBCLKSRC_USBPLL)
780   {
781     frequency = XMC_SCU_CLOCK_GetUsbPllClockFrequency();
782   }
783   else
784   {
785   }
786 
787   return (uint32_t)(frequency / (((SCU_CLK->USBCLKCR & SCU_CLK_USBCLKCR_USBDIV_Msk) >>
788                                    SCU_CLK_USBCLKCR_USBDIV_Pos) + 1UL));
789 }
790 
791 #if defined(EBU)
792 /*
793  * API to retrieve EBU clock frequency
794  */
XMC_SCU_CLOCK_GetEbuClockFrequency(void)795 uint32_t XMC_SCU_CLOCK_GetEbuClockFrequency(void)
796 {
797   uint32_t frequency = XMC_SCU_CLOCK_GetSystemPllClockFrequency();
798 
799   return (uint32_t)((frequency /(((SCU_CLK->EBUCLKCR & SCU_CLK_EBUCLKCR_EBUDIV_Msk) >>
800                                    SCU_CLK_EBUCLKCR_EBUDIV_Pos) + 1UL)));
801 }
802 #endif
803 
804 #if defined(ECAT0)
805 /*
806  * API to retrieve ECAT clock frequency
807  */
XMC_SCU_CLOCK_GetECATClockFrequency(void)808 uint32_t XMC_SCU_CLOCK_GetECATClockFrequency(void)
809 {
810   uint32_t frequency;
811 
812   if ((SCU_CLK->ECATCLKCR & SCU_CLK_ECATCLKCR_ECATSEL_Msk) != 0U)
813   {
814     frequency =  XMC_SCU_CLOCK_GetSystemPllClockFrequency();
815   }
816   else
817   {
818     frequency =  XMC_SCU_CLOCK_GetUsbPllClockFrequency();
819   }
820 
821   return (uint32_t)((frequency / (XMC_SCU_CLOCK_GetECATClockDivider() + 1UL)));
822 }
823 #endif
824 
825 /*
826  * API to retrieve WDT clock frequency
827  */
XMC_SCU_CLOCK_GetWdtClockFrequency(void)828 uint32_t XMC_SCU_CLOCK_GetWdtClockFrequency(void)
829 {
830   uint32_t frequency = 0UL;
831   XMC_SCU_CLOCK_WDTCLKSRC_t clksrc;
832 
833   clksrc = XMC_SCU_CLOCK_GetWdtClockSource();
834 
835   if (clksrc == XMC_SCU_CLOCK_WDTCLKSRC_PLL)
836   {
837     frequency = XMC_SCU_CLOCK_GetSystemPllClockFrequency();
838   }
839   else if (clksrc == XMC_SCU_CLOCK_WDTCLKSRC_OFI)
840   {
841     frequency = OFI_FREQUENCY;
842   }
843   else if (clksrc == XMC_SCU_CLOCK_WDTCLKSRC_STDBY)
844   {
845     frequency = OSI_FREQUENCY;
846   }
847   else
848   {
849 
850   }
851 
852   return (uint32_t)((frequency / (((SCU_CLK->WDTCLKCR & SCU_CLK_WDTCLKCR_WDTDIV_Msk) >>
853                                     SCU_CLK_WDTCLKCR_WDTDIV_Pos) + 1UL)));
854 }
855 
856 /**
857  * @brief API to retrieve EXTERNAL-OUT clock frequency
858  * @retval Clock frequency
859  */
XMC_SCU_CLOCK_GetExternalOutputClockFrequency(void)860 uint32_t XMC_SCU_CLOCK_GetExternalOutputClockFrequency(void)
861 {
862   uint32_t frequency = 0UL;
863   XMC_SCU_CLOCK_EXTOUTCLKSRC_t clksrc;
864 
865   clksrc = XMC_SCU_CLOCK_GetExternalOutputClockSource();
866 
867   if (clksrc == XMC_SCU_CLOCK_EXTOUTCLKSRC_PLL)
868   {
869     frequency = XMC_SCU_CLOCK_GetSystemPllClockFrequency();
870 
871     frequency = (uint32_t)((frequency / ((((SCU_CLK->EXTCLKCR) & SCU_CLK_EXTCLKCR_ECKDIV_Msk) >>
872                  SCU_CLK_EXTCLKCR_ECKDIV_Pos)+ 1UL)));
873   }
874   else if (clksrc == XMC_SCU_CLOCK_EXTOUTCLKSRC_SYS)
875   {
876     frequency = XMC_SCU_CLOCK_GetSystemClockFrequency();
877   }
878   else if (clksrc == XMC_SCU_CLOCK_EXTOUTCLKSRC_USB)
879   {
880     frequency = XMC_SCU_CLOCK_GetUsbPllClockFrequency();
881 
882     frequency = (uint32_t)((frequency / ((((SCU_CLK->EXTCLKCR) & SCU_CLK_EXTCLKCR_ECKDIV_Msk) >>
883                  SCU_CLK_EXTCLKCR_ECKDIV_Pos)+ 1UL)));
884   }
885   else
886   {
887 
888   }
889 
890   return (frequency);
891 }
892 
893 /*
894  * API to retrieve clock frequency of peripherals on the peripheral bus using a shared functional clock
895  */
XMC_SCU_CLOCK_GetPeripheralClockFrequency(void)896 uint32_t XMC_SCU_CLOCK_GetPeripheralClockFrequency(void)
897 {
898   return (uint32_t)(XMC_SCU_CLOCK_GetCpuClockFrequency() >>
899          ((SCU_CLK->PBCLKCR & SCU_CLK_PBCLKCR_PBDIV_Msk) >> SCU_CLK_PBCLKCR_PBDIV_Pos));
900 }
901 
902 /* API to select fSYS */
XMC_SCU_CLOCK_SetSystemClockSource(const XMC_SCU_CLOCK_SYSCLKSRC_t source)903 void XMC_SCU_CLOCK_SetSystemClockSource(const XMC_SCU_CLOCK_SYSCLKSRC_t source)
904 {
905   SCU_CLK->SYSCLKCR = (SCU_CLK->SYSCLKCR & ((uint32_t)~SCU_CLK_SYSCLKCR_SYSSEL_Msk)) |
906                       ((uint32_t)source);
907 }
908 
909 /* API to select fUSB */
XMC_SCU_CLOCK_SetUsbClockSource(const XMC_SCU_CLOCK_USBCLKSRC_t source)910 void XMC_SCU_CLOCK_SetUsbClockSource(const XMC_SCU_CLOCK_USBCLKSRC_t source)
911 {
912   SCU_CLK->USBCLKCR = (SCU_CLK->USBCLKCR & ((uint32_t)~SCU_CLK_USBCLKCR_USBSEL_Msk)) |
913                       ((uint32_t)source);
914 }
915 
916 /* API to select fWDT */
XMC_SCU_CLOCK_SetWdtClockSource(const XMC_SCU_CLOCK_WDTCLKSRC_t source)917 void XMC_SCU_CLOCK_SetWdtClockSource(const XMC_SCU_CLOCK_WDTCLKSRC_t source)
918 {
919   SCU_CLK->WDTCLKCR = (SCU_CLK->WDTCLKCR & ((uint32_t)~SCU_CLK_WDTCLKCR_WDTSEL_Msk)) |
920                       ((uint32_t)source);
921 }
922 
923 /* API to select fEXT */
XMC_SCU_CLOCK_SetExternalOutputClockSource(const XMC_SCU_CLOCK_EXTOUTCLKSRC_t source)924 void XMC_SCU_CLOCK_SetExternalOutputClockSource(const XMC_SCU_CLOCK_EXTOUTCLKSRC_t source)
925 {
926   SCU_CLK->EXTCLKCR = (SCU_CLK->EXTCLKCR & ((uint32_t)~SCU_CLK_EXTCLKCR_ECKSEL_Msk)) |
927                       ((uint32_t)source);
928 }
929 
930 /* API to select fPLL */
XMC_SCU_CLOCK_SetSystemPllClockSource(const XMC_SCU_CLOCK_SYSPLLCLKSRC_t source)931 void XMC_SCU_CLOCK_SetSystemPllClockSource(const XMC_SCU_CLOCK_SYSPLLCLKSRC_t source)
932 {
933   /* Check input clock */
934   if (source == XMC_SCU_CLOCK_SYSPLLCLKSRC_OSCHP) /* Select PLLClockSource */
935   {
936     SCU_PLL->PLLCON2 &= (uint32_t)~(SCU_PLL_PLLCON2_PINSEL_Msk | SCU_PLL_PLLCON2_K1INSEL_Msk);
937   }
938   else
939   {
940     SCU_PLL->PLLCON2 |= (uint32_t)(SCU_PLL_PLLCON2_PINSEL_Msk | SCU_PLL_PLLCON2_K1INSEL_Msk);
941   }
942 }
943 
944 /* API to select fRTC */
XMC_SCU_HIB_SetRtcClockSource(const XMC_SCU_HIB_RTCCLKSRC_t source)945 void XMC_SCU_HIB_SetRtcClockSource(const XMC_SCU_HIB_RTCCLKSRC_t source)
946 {
947   /* Wait until the update of HDCR register in hibernate domain is completed */
948   while((SCU_GENERAL->MIRRSTS) & SCU_GENERAL_MIRRSTS_HDCR_Msk)
949   {
950   }
951 
952   SCU_HIBERNATE->HDCR = (SCU_HIBERNATE->HDCR & ((uint32_t)~SCU_HIBERNATE_HDCR_RCS_Msk)) |
953                         ((uint32_t)source);
954 }
955 
956 /* API to select fSTDBY */
XMC_SCU_HIB_SetStandbyClockSource(const XMC_SCU_HIB_STDBYCLKSRC_t source)957 void XMC_SCU_HIB_SetStandbyClockSource(const XMC_SCU_HIB_STDBYCLKSRC_t source)
958 {
959   while((SCU_GENERAL->MIRRSTS) & SCU_GENERAL_MIRRSTS_HDCR_Msk)
960   {
961     /* check SCU_MIRRSTS to ensure that no transfer over serial interface is pending */
962   }
963   SCU_HIBERNATE->HDCR = (SCU_HIBERNATE->HDCR & ((uint32_t)~SCU_HIBERNATE_HDCR_STDBYSEL_Msk)) |
964                         ((uint32_t)source);
965 }
966 
967 /* API to program the divider placed between fsys and its parent */
XMC_SCU_CLOCK_SetSystemClockDivider(const uint32_t divider)968 void XMC_SCU_CLOCK_SetSystemClockDivider(const uint32_t divider)
969 {
970   XMC_ASSERT("XMC_SCU_CLOCK_SetSystemClockDivider:Wrong clock divider value",
971               (divider <= (SCU_CLK_SYSCLKCR_SYSDIV_Msk + 1UL)) );
972 
973   SCU_CLK->SYSCLKCR = (SCU_CLK->SYSCLKCR & ((uint32_t)~SCU_CLK_SYSCLKCR_SYSDIV_Msk)) |
974                       ((uint32_t)(((uint32_t)(divider - 1UL)) << SCU_CLK_SYSCLKCR_SYSDIV_Pos));
975 }
976 
977 /* API to program the divider placed between fccu and its parent */
XMC_SCU_CLOCK_SetCcuClockDivider(const uint32_t divider)978 void XMC_SCU_CLOCK_SetCcuClockDivider(const uint32_t divider)
979 {
980   XMC_ASSERT("XMC_SCU_CLOCK_SetCapcomClockDivider:Wrong clock divider value", (divider <= 2UL) );
981 
982   SCU_CLK->CCUCLKCR = (SCU_CLK->CCUCLKCR & ((uint32_t)~SCU_CLK_CCUCLKCR_CCUDIV_Msk)) |
983                       (uint32_t)((uint32_t)(divider - 1UL) << SCU_CLK_CCUCLKCR_CCUDIV_Pos);
984 }
985 
986 /* API to program the divider placed between fcpu and its parent */
XMC_SCU_CLOCK_SetCpuClockDivider(const uint32_t divider)987 void XMC_SCU_CLOCK_SetCpuClockDivider(const uint32_t divider)
988 {
989   XMC_ASSERT("XMC_SCU_CLOCK_SetCpuClockDivider:Wrong clock divider value", (divider <= 2UL) );
990 
991   SCU_CLK->CPUCLKCR = (SCU_CLK->CPUCLKCR & ((uint32_t)~SCU_CLK_CPUCLKCR_CPUDIV_Msk)) |
992                       (uint32_t)((uint32_t)(divider - 1UL) << SCU_CLK_CPUCLKCR_CPUDIV_Pos);
993 }
994 
995 /* API to program the divider placed between fperiph and its parent */
XMC_SCU_CLOCK_SetPeripheralClockDivider(const uint32_t divider)996 void XMC_SCU_CLOCK_SetPeripheralClockDivider(const uint32_t divider)
997 {
998   XMC_ASSERT("XMC_SCU_CLOCK_SetPeripheralClockDivider:Wrong clock divider value", (divider <= 2UL) );
999 
1000   SCU_CLK->PBCLKCR = (SCU_CLK->PBCLKCR & ((uint32_t)~SCU_CLK_PBCLKCR_PBDIV_Msk)) |
1001                      ((uint32_t)((uint32_t)(divider - 1UL) << SCU_CLK_PBCLKCR_PBDIV_Pos));
1002 }
1003 
1004 /* API to program the divider placed between fsdmmc and its parent */
XMC_SCU_CLOCK_SetUsbClockDivider(const uint32_t divider)1005 void XMC_SCU_CLOCK_SetUsbClockDivider(const uint32_t divider)
1006 {
1007   XMC_ASSERT("XMC_SCU_CLOCK_SetSdmmcClockDivider:Wrong clock divider value",
1008               (divider <= (SCU_CLK_USBCLKCR_USBDIV_Msk + 1UL)) );
1009 
1010   SCU_CLK->USBCLKCR = (SCU_CLK->USBCLKCR & ((uint32_t)~SCU_CLK_USBCLKCR_USBDIV_Msk)) |
1011                       (uint32_t)((uint32_t)(divider - 1UL) << SCU_CLK_USBCLKCR_USBDIV_Pos);
1012 }
1013 
1014 #if defined(EBU)
1015 /* API to program the divider placed between febu and its parent */
XMC_SCU_CLOCK_SetEbuClockDivider(const uint32_t divider)1016 void XMC_SCU_CLOCK_SetEbuClockDivider(const uint32_t divider)
1017 {
1018   XMC_ASSERT("XMC_SCU_CLOCK_SetEbuClockDivider:Wrong clock divider value",
1019               (divider <= (SCU_CLK_EBUCLKCR_EBUDIV_Msk + 1UL) ) );
1020 
1021   SCU_CLK->EBUCLKCR = (SCU_CLK->EBUCLKCR & ((uint32_t)~SCU_CLK_EBUCLKCR_EBUDIV_Msk)) |
1022                       (uint32_t)(((uint32_t)(divider - 1UL)) << SCU_CLK_EBUCLKCR_EBUDIV_Pos);
1023 }
1024 #endif
1025 
1026 /* API to program the divider placed between fwdt and its parent */
XMC_SCU_CLOCK_SetWdtClockDivider(const uint32_t divider)1027 void XMC_SCU_CLOCK_SetWdtClockDivider(const uint32_t divider)
1028 {
1029   XMC_ASSERT("XMC_SCU_CLOCK_SetWdtClockDivider:Wrong clock divider value",
1030               (divider <= (SCU_CLK_WDTCLKCR_WDTDIV_Msk + 1UL) ) );
1031 
1032   SCU_CLK->WDTCLKCR = (SCU_CLK->WDTCLKCR & ((uint32_t)~SCU_CLK_WDTCLKCR_WDTDIV_Msk)) |
1033                       (uint32_t)(((uint32_t)(divider - 1UL)) << SCU_CLK_WDTCLKCR_WDTDIV_Pos);
1034 }
1035 
1036 /* API to program the divider placed between fext and its parent */
XMC_SCU_CLOCK_SetExternalOutputClockDivider(const uint32_t divider)1037 void XMC_SCU_CLOCK_SetExternalOutputClockDivider(const uint32_t divider)
1038 {
1039   XMC_ASSERT("XMC_SCU_CLOCK_SetExternalOutputClockDivider:Wrong clock divider value",
1040               (divider <= (SCU_CLK_EXTCLKCR_ECKDIV_Msk + 1UL) ) );
1041 
1042   SCU_CLK->EXTCLKCR = (SCU_CLK->EXTCLKCR & ((uint32_t)~SCU_CLK_EXTCLKCR_ECKDIV_Msk)) |
1043                       (uint32_t)(((uint32_t)(divider - 1UL)) << SCU_CLK_EXTCLKCR_ECKDIV_Pos);
1044 }
1045 
1046 #if defined(ECAT0)
1047 /* API to configure the ECAT clock by setting the clock divider for the ECAT clock source */
XMC_SCU_CLOCK_SetECATClockDivider(const uint32_t divider)1048 void XMC_SCU_CLOCK_SetECATClockDivider(const uint32_t divider)
1049 {
1050   SCU_CLK->ECATCLKCR = (SCU_CLK->ECATCLKCR & ~SCU_CLK_ECATCLKCR_ECADIV_Msk) |
1051                        (uint32_t)(((uint32_t)(divider - 1UL)) << SCU_CLK_ECATCLKCR_ECADIV_Pos);
1052 }
1053 #endif
1054 
1055 /* API to enable a given module clock */
XMC_SCU_CLOCK_EnableClock(const XMC_SCU_CLOCK_t clock)1056 void XMC_SCU_CLOCK_EnableClock(const XMC_SCU_CLOCK_t clock)
1057 {
1058   SCU_CLK->CLKSET = ((uint32_t)clock);
1059 }
1060 
1061 /* API to disable a given module clock */
XMC_SCU_CLOCK_DisableClock(const XMC_SCU_CLOCK_t clock)1062 void XMC_SCU_CLOCK_DisableClock(const XMC_SCU_CLOCK_t clock)
1063 {
1064   SCU_CLK->CLKCLR = ((uint32_t)clock);
1065 }
1066 
1067 /* API to determine if module clock of the given peripheral is enabled */
XMC_SCU_CLOCK_IsClockEnabled(const XMC_SCU_CLOCK_t clock)1068 bool XMC_SCU_CLOCK_IsClockEnabled(const XMC_SCU_CLOCK_t clock)
1069 {
1070   return (bool)(SCU_CLK->CLKSTAT & ((uint32_t)clock));
1071 }
1072 
1073 #if defined(CLOCK_GATING_SUPPORTED)
1074 /* API to gate a given module clock */
XMC_SCU_CLOCK_GatePeripheralClock(const XMC_SCU_PERIPHERAL_CLOCK_t peripheral)1075 void XMC_SCU_CLOCK_GatePeripheralClock(const XMC_SCU_PERIPHERAL_CLOCK_t peripheral)
1076 {
1077   uint32_t index = (peripheral & 0xf0000000UL) >> 28UL;
1078   uint32_t mask = (peripheral & (uint32_t)~0xf0000000UL);
1079 
1080   *(uint32_t *)((&(SCU_CLK->CGATSET0)) + (index * 3U)) = (uint32_t)mask;
1081 }
1082 
1083 /* API to ungate a given module clock */
XMC_SCU_CLOCK_UngatePeripheralClock(const XMC_SCU_PERIPHERAL_CLOCK_t peripheral)1084 void XMC_SCU_CLOCK_UngatePeripheralClock(const XMC_SCU_PERIPHERAL_CLOCK_t peripheral)
1085 {
1086   uint32_t index = (uint32_t)((peripheral & 0xf0000000UL) >> 28UL);
1087   uint32_t mask = (peripheral & (uint32_t)~0xf0000000UL);
1088 
1089   *(uint32_t *)(&(SCU_CLK->CGATCLR0) + (index * 3U)) = (uint32_t)mask;
1090 }
1091 
1092 /* API to ungate a given module clock */
XMC_SCU_CLOCK_IsPeripheralClockGated(const XMC_SCU_PERIPHERAL_CLOCK_t peripheral)1093 bool XMC_SCU_CLOCK_IsPeripheralClockGated(const XMC_SCU_PERIPHERAL_CLOCK_t peripheral)
1094 {
1095   uint32_t index = ((peripheral & 0xf0000000UL) >> 28UL);
1096   uint32_t mask = (peripheral & (uint32_t)~0xf0000000UL);
1097 
1098   return ((*(uint32_t *)(&(SCU_CLK->CGATSTAT0) + (index * 3U)) & mask) != 0U);
1099 }
1100 #endif
1101 
XMC_SCU_POWER_GetEVR13Voltage(void)1102 float XMC_SCU_POWER_GetEVR13Voltage(void)
1103 {
1104   return (SCU_POWER->EVRVADCSTAT & SCU_POWER_EVRVADCSTAT_VADC13V_Msk) * XMC_SCU_POWER_LSB13V;
1105 }
1106 
XMC_SCU_POWER_GetEVR33Voltage(void)1107 float XMC_SCU_POWER_GetEVR33Voltage(void)
1108 {
1109   return ((SCU_POWER->EVRVADCSTAT & SCU_POWER_EVRVADCSTAT_VADC33V_Msk) >> SCU_POWER_EVRVADCSTAT_VADC33V_Pos) * XMC_SCU_POWER_LSB33V;
1110 }
1111 
1112 /* API to enable USB PLL for USB clock */
XMC_SCU_CLOCK_EnableUsbPll(void)1113 void XMC_SCU_CLOCK_EnableUsbPll(void)
1114 {
1115   SCU_PLL->USBPLLCON &= (uint32_t)~(SCU_PLL_USBPLLCON_VCOPWD_Msk | SCU_PLL_USBPLLCON_PLLPWD_Msk);
1116 }
1117 
1118 /* API to disable USB PLL for USB clock */
XMC_SCU_CLOCK_DisableUsbPll(void)1119 void XMC_SCU_CLOCK_DisableUsbPll(void)
1120 {
1121   SCU_PLL->USBPLLCON |= (uint32_t)(SCU_PLL_USBPLLCON_VCOPWD_Msk | SCU_PLL_USBPLLCON_PLLPWD_Msk);
1122 }
1123 
1124 /* API to configure USB PLL */
XMC_SCU_CLOCK_StartUsbPll(uint32_t pdiv,uint32_t ndiv)1125 void XMC_SCU_CLOCK_StartUsbPll(uint32_t pdiv, uint32_t ndiv)
1126 {
1127   /* Go to bypass the USB PLL */
1128   SCU_PLL->USBPLLCON |= (uint32_t)SCU_PLL_USBPLLCON_VCOBYP_Msk;
1129 
1130   /* disconnect Oscillator from USB PLL */
1131   SCU_PLL->USBPLLCON |= (uint32_t)SCU_PLL_USBPLLCON_FINDIS_Msk;
1132 
1133   /* Setup Divider settings for USB PLL */
1134   SCU_PLL->USBPLLCON = (uint32_t)((uint32_t)((ndiv -1U) << SCU_PLL_USBPLLCON_NDIV_Pos) |
1135                        (uint32_t)((pdiv - 1U) << SCU_PLL_USBPLLCON_PDIV_Pos));
1136 
1137   /* Set OSCDISCDIS */
1138   SCU_PLL->USBPLLCON |= (uint32_t)SCU_PLL_USBPLLCON_OSCDISCDIS_Msk;
1139 
1140   /* connect Oscillator to USB PLL */
1141   SCU_PLL->USBPLLCON &= (uint32_t)~SCU_PLL_USBPLLCON_FINDIS_Msk;
1142 
1143   /* restart PLL Lock detection */
1144   SCU_PLL->USBPLLCON |= (uint32_t)SCU_PLL_USBPLLCON_RESLD_Msk;
1145 
1146   while ((SCU_PLL->USBPLLSTAT & SCU_PLL_USBPLLSTAT_VCOLOCK_Msk) == 0U)
1147   {
1148     /* wait for PLL Lock */
1149   }
1150 
1151 }
1152 
1153 /* API to disable USB PLL operation */
XMC_SCU_CLOCK_StopUsbPll(void)1154 void XMC_SCU_CLOCK_StopUsbPll(void)
1155 {
1156   SCU_PLL->USBPLLCON = (uint32_t)(SCU_PLL_USBPLLCON_VCOPWD_Msk | SCU_PLL_USBPLLCON_PLLPWD_Msk |
1157                                   SCU_PLL_USBPLLCON_VCOBYP_Msk);
1158 }
1159 
1160 /* API to onfigure the calibration mode for internal oscillator */
XMC_SCU_CLOCK_SetBackupClockCalibrationMode(XMC_SCU_CLOCK_FOFI_CALIBRATION_MODE_t mode)1161 void XMC_SCU_CLOCK_SetBackupClockCalibrationMode(XMC_SCU_CLOCK_FOFI_CALIBRATION_MODE_t mode)
1162 {
1163   /* Enable factory calibration based trimming */
1164   SCU_PLL->PLLCON0 |= (uint32_t)SCU_PLL_PLLCON0_FOTR_Msk;
1165 
1166   if (mode == XMC_SCU_CLOCK_FOFI_CALIBRATION_MODE_AUTOMATIC)
1167   {
1168     /* Disable factory calibration based trimming */
1169     SCU_PLL->PLLCON0 &= (uint32_t)~SCU_PLL_PLLCON0_FOTR_Msk;
1170     XMC_SCU_lDelay(100UL);
1171 
1172     /* Enable automatic calibration */
1173     SCU_PLL->PLLCON0 |= (uint32_t)SCU_PLL_PLLCON0_AOTREN_Msk;
1174   }
1175 
1176   XMC_SCU_lDelay(100UL);
1177 }
1178 
1179 
1180 
1181 /* API to enable USB Phy and comparator */
XMC_SCU_POWER_EnableUsb(void)1182 void XMC_SCU_POWER_EnableUsb(void)
1183 {
1184 #if defined(USB_OTG_SUPPORTED)
1185   SCU_POWER->PWRSET = (uint32_t)(SCU_POWER_PWRSET_USBOTGEN_Msk | SCU_POWER_PWRSET_USBPHYPDQ_Msk);
1186 #else
1187   SCU_POWER->PWRSET = (uint32_t)SCU_POWER_PWRSET_USBPHYPDQ_Msk;
1188 #endif
1189 }
1190 
1191 /* API to power down USB Phy and comparator */
XMC_SCU_POWER_DisableUsb(void)1192 void XMC_SCU_POWER_DisableUsb(void)
1193 {
1194 #if defined(USB_OTG_SUPPORTED)
1195   SCU_POWER->PWRCLR = (uint32_t)(SCU_POWER_PWRCLR_USBOTGEN_Msk | SCU_POWER_PWRSET_USBPHYPDQ_Msk);
1196 #else
1197   SCU_POWER->PWRCLR = (uint32_t)SCU_POWER_PWRCLR_USBPHYPDQ_Msk;
1198 #endif
1199 }
1200 
1201 /* API to check USB PLL is locked or not */
XMC_SCU_CLOCK_IsUsbPllLocked(void)1202 bool XMC_SCU_CLOCK_IsUsbPllLocked(void)
1203 {
1204   return (bool)((SCU_PLL->USBPLLSTAT & SCU_PLL_USBPLLSTAT_VCOLOCK_Msk) != 0UL);
1205 }
1206 
1207 /* API to power up the hibernation domain */
XMC_SCU_HIB_EnableHibernateDomain(void)1208 void XMC_SCU_HIB_EnableHibernateDomain(void)
1209 {
1210   /* Power up HIB domain if and only if it is currently powered down */
1211   if((SCU_POWER->PWRSTAT & SCU_POWER_PWRSTAT_HIBEN_Msk) == 0UL)
1212   {
1213     SCU_POWER->PWRSET = (uint32_t)SCU_POWER_PWRSET_HIB_Msk;
1214 
1215     while((SCU_POWER->PWRSTAT & SCU_POWER_PWRSTAT_HIBEN_Msk) == 0UL)
1216     {
1217       /* wait until HIB domain is enabled */
1218     }
1219   }
1220 
1221   /* Remove the reset only if HIB domain were in a state of reset */
1222   if((SCU_RESET->RSTSTAT) & SCU_RESET_RSTSTAT_HIBRS_Msk)
1223   {
1224     SCU_RESET->RSTCLR = (uint32_t)SCU_RESET_RSTCLR_HIBRS_Msk;
1225     while((SCU_RESET->RSTSTAT & SCU_RESET_RSTSTAT_HIBRS_Msk) != 0UL)
1226     {
1227       /* wait until HIB domain is enabled */
1228     }
1229   }
1230 }
1231 
1232 /* API to power down the hibernation domain */
XMC_SCU_HIB_DisableHibernateDomain(void)1233 void XMC_SCU_HIB_DisableHibernateDomain(void)
1234 {
1235   /* Disable hibernate domain */
1236   SCU_POWER->PWRCLR = (uint32_t)SCU_POWER_PWRCLR_HIB_Msk;
1237   /* Reset of hibernate domain reset */
1238   SCU_RESET->RSTSET = (uint32_t)SCU_RESET_RSTSET_HIBRS_Msk;
1239 }
1240 
1241 /* API to check the hibernation domain is enabled or not */
XMC_SCU_HIB_IsHibernateDomainEnabled(void)1242 bool XMC_SCU_HIB_IsHibernateDomainEnabled(void)
1243 {
1244   return ((bool)(SCU_POWER->PWRSTAT & SCU_POWER_PWRSTAT_HIBEN_Msk) &&
1245           !(bool)(SCU_RESET->RSTSTAT & SCU_RESET_RSTSTAT_HIBRS_Msk));
1246 }
1247 
1248 /* API to enable internal slow clock - fOSI (32.768kHz) in hibernate domain */
XMC_SCU_HIB_EnableInternalSlowClock(void)1249 void XMC_SCU_HIB_EnableInternalSlowClock(void)
1250 {
1251   while((SCU_GENERAL->MIRRSTS) & SCU_GENERAL_MIRRSTS_OSCSICTRL_Msk)
1252   {
1253     /* Wait until OSCSICTRL register in hibernate domain is ready to accept a write */
1254   }
1255   SCU_HIBERNATE->OSCSICTRL &= (uint32_t)~(SCU_HIBERNATE_OSCSICTRL_PWD_Msk);
1256 }
1257 
1258 /* API to disable internal slow clock - fOSI (32.768kHz) in hibernate domain */
XMC_SCU_HIB_DisableInternalSlowClock(void)1259 void XMC_SCU_HIB_DisableInternalSlowClock(void)
1260 {
1261   while((SCU_GENERAL->MIRRSTS) & SCU_GENERAL_MIRRSTS_OSCSICTRL_Msk)
1262   {
1263     /* Wait until OSCSICTRL register in hibernate domain is ready to accept a write */
1264   }
1265   SCU_HIBERNATE->OSCSICTRL |= (uint32_t)SCU_HIBERNATE_OSCSICTRL_PWD_Msk;
1266 }
1267 
XMC_SCU_HIB_ClearEventStatus(int32_t event)1268 void XMC_SCU_HIB_ClearEventStatus(int32_t event)
1269 {
1270   while((SCU_GENERAL->MIRRSTS) & SCU_GENERAL_MIRRSTS_HDCLR_Msk)
1271   {
1272     /* Wait until HDCLR register in hibernate domain is ready to accept a write */
1273   }
1274   SCU_HIBERNATE->HDCLR = event;
1275 }
1276 
XMC_SCU_HIB_TriggerEvent(int32_t event)1277 void XMC_SCU_HIB_TriggerEvent(int32_t event)
1278 {
1279   while((SCU_GENERAL->MIRRSTS) & SCU_GENERAL_MIRRSTS_HDSET_Msk)
1280   {
1281     /* Wait until HDSET register in hibernate domain is ready to accept a write */
1282   }
1283   SCU_HIBERNATE->HDSET = event;
1284 }
1285 
XMC_SCU_HIB_EnableEvent(int32_t event)1286 void XMC_SCU_HIB_EnableEvent(int32_t event)
1287 {
1288 #if (defined(DOXYGEN) || (UC_SERIES == XMC44) || (UC_SERIES == XMC42) || (UC_SERIES == XMC41))
1289   event = ((event & XMC_SCU_HIB_EVENT_LPAC_VBAT_POSEDGE) << (SCU_HIBERNATE_HDCR_VBATHI_Pos - SCU_HIBERNATE_HDSTAT_VBATPEV_Pos)) | (event & (uint32_t)~XMC_SCU_HIB_EVENT_LPAC_VBAT_POSEDGE);
1290   event = ((event & XMC_SCU_HIB_EVENT_LPAC_VBAT_NEGEDGE) << (SCU_HIBERNATE_HDCR_VBATLO_Pos - SCU_HIBERNATE_HDSTAT_VBATNEV_Pos)) | (event & (uint32_t)~XMC_SCU_HIB_EVENT_LPAC_VBAT_NEGEDGE);
1291   event = ((event & XMC_SCU_HIB_EVENT_LPAC_HIB_IO_0_POSEDGE) << (SCU_HIBERNATE_HDCR_AHIBIO0HI_Pos - SCU_HIBERNATE_HDSTAT_AHIBIO0PEV_Pos)) | (event & (uint32_t)~XMC_SCU_HIB_EVENT_LPAC_HIB_IO_0_POSEDGE);
1292   event = ((event & XMC_SCU_HIB_EVENT_LPAC_HIB_IO_0_NEGEDGE) << (SCU_HIBERNATE_HDCR_AHIBIO0LO_Pos - SCU_HIBERNATE_HDSTAT_AHIBIO0NEV_Pos)) | (event & (uint32_t)~XMC_SCU_HIB_EVENT_LPAC_HIB_IO_0_NEGEDGE);
1293 #if (defined(DOXYGEN) || ((UC_SERIES == XMC44) && (UC_PACKAGE == LQFP100)))
1294   event = ((event & XMC_SCU_HIB_EVENT_LPAC_HIB_IO_1_POSEDGE) << (SCU_HIBERNATE_HDCR_AHIBIO1HI_Pos - SCU_HIBERNATE_HDSTAT_AHIBIO1PEV_Pos)) | (event & (uint32_t)~XMC_SCU_HIB_EVENT_LPAC_HIB_IO_1_POSEDGE);
1295   event = ((event & XMC_SCU_HIB_EVENT_LPAC_HIB_IO_1_NEGEDGE) << (SCU_HIBERNATE_HDCR_AHIBIO1LO_Pos - SCU_HIBERNATE_HDSTAT_AHIBIO1NEV_Pos)) | (event & (uint32_t)~XMC_SCU_HIB_EVENT_LPAC_HIB_IO_1_NEGEDGE);
1296 #endif
1297 #endif
1298 
1299   while((SCU_GENERAL->MIRRSTS) & SCU_GENERAL_MIRRSTS_HDCR_Msk)
1300   {
1301     /* Wait until HDCR register in hibernate domain is ready to accept a write */
1302   }
1303   SCU_HIBERNATE->HDCR |= event;
1304 }
1305 
XMC_SCU_HIB_DisableEvent(int32_t event)1306 void XMC_SCU_HIB_DisableEvent(int32_t event)
1307 {
1308 #if (defined(DOXYGEN) || (UC_SERIES == XMC44) || (UC_SERIES == XMC42) || (UC_SERIES == XMC41))
1309   event = ((event & XMC_SCU_HIB_EVENT_LPAC_VBAT_POSEDGE) << (SCU_HIBERNATE_HDCR_VBATHI_Pos - SCU_HIBERNATE_HDSTAT_VBATPEV_Pos)) | (event & (uint32_t)~XMC_SCU_HIB_EVENT_LPAC_VBAT_POSEDGE);
1310   event = ((event & XMC_SCU_HIB_EVENT_LPAC_VBAT_NEGEDGE) << (SCU_HIBERNATE_HDCR_VBATLO_Pos - SCU_HIBERNATE_HDSTAT_VBATNEV_Pos)) | (event & (uint32_t)~XMC_SCU_HIB_EVENT_LPAC_VBAT_NEGEDGE);
1311   event = ((event & XMC_SCU_HIB_EVENT_LPAC_HIB_IO_0_POSEDGE) << (SCU_HIBERNATE_HDCR_AHIBIO0HI_Pos - SCU_HIBERNATE_HDSTAT_AHIBIO0PEV_Pos)) | (event & (uint32_t)~XMC_SCU_HIB_EVENT_LPAC_HIB_IO_0_POSEDGE);
1312   event = ((event & XMC_SCU_HIB_EVENT_LPAC_HIB_IO_0_NEGEDGE) << (SCU_HIBERNATE_HDCR_AHIBIO0LO_Pos - SCU_HIBERNATE_HDSTAT_AHIBIO0NEV_Pos)) | (event & (uint32_t)~XMC_SCU_HIB_EVENT_LPAC_HIB_IO_0_NEGEDGE);
1313 #if (defined(DOXYGEN) || ((UC_SERIES == XMC44) && (UC_PACKAGE == LQFP100)))
1314   event = ((event & XMC_SCU_HIB_EVENT_LPAC_HIB_IO_1_POSEDGE) << (SCU_HIBERNATE_HDCR_AHIBIO1HI_Pos - SCU_HIBERNATE_HDSTAT_AHIBIO1PEV_Pos)) | (event & (uint32_t)~XMC_SCU_HIB_EVENT_LPAC_HIB_IO_1_POSEDGE);
1315   event = ((event & XMC_SCU_HIB_EVENT_LPAC_HIB_IO_1_NEGEDGE) << (SCU_HIBERNATE_HDCR_AHIBIO1LO_Pos - SCU_HIBERNATE_HDSTAT_AHIBIO1NEV_Pos)) | (event & (uint32_t)~XMC_SCU_HIB_EVENT_LPAC_HIB_IO_1_NEGEDGE);
1316 #endif
1317 #endif
1318 
1319   while((SCU_GENERAL->MIRRSTS) & SCU_GENERAL_MIRRSTS_HDCR_Msk)
1320   {
1321     /* Wait until HDCR register in hibernate domain is ready to accept a write */
1322   }
1323   SCU_HIBERNATE->HDCR &= ~event;
1324 }
1325 
XMC_SCU_HIB_EnterHibernateState(void)1326 void XMC_SCU_HIB_EnterHibernateState(void)
1327 {
1328   while((SCU_GENERAL->MIRRSTS) & SCU_GENERAL_MIRRSTS_HDCR_Msk)
1329   {
1330     /* Wait until HDCR register in hibernate domain is ready to accept a write */
1331   }
1332   SCU_HIBERNATE->HDCR |= SCU_HIBERNATE_HDCR_HIB_Msk;
1333 }
1334 
XMC_SCU_HIB_EnterHibernateStateEx(XMC_SCU_HIB_HIBERNATE_MODE_t mode)1335 void XMC_SCU_HIB_EnterHibernateStateEx(XMC_SCU_HIB_HIBERNATE_MODE_t mode)
1336 {
1337   if (mode == XMC_SCU_HIB_HIBERNATE_MODE_EXTERNAL)
1338   {
1339     XMC_SCU_HIB_EnterHibernateState();
1340   }
1341 #if ((UC_SERIES == XMC44) || (UC_SERIES == XMC42) || (UC_SERIES == XMC41))
1342   if (mode == XMC_SCU_HIB_HIBERNATE_MODE_INTERNAL)
1343   {
1344     while((SCU_GENERAL->MIRRSTS) & SCU_GENERAL_MIRRSTS_HINTSET_Msk)
1345     {
1346       /* Wait until HDCR register in hibernate domain is ready to accept a write */
1347     }
1348     SCU_HIBERNATE->HINTSET = SCU_HIBERNATE_HINTSET_HIBNINT_Msk;
1349   }
1350 #endif
1351 }
1352 
XMC_SCU_HIB_SetWakeupTriggerInput(XMC_SCU_HIB_IO_t pin)1353 void XMC_SCU_HIB_SetWakeupTriggerInput(XMC_SCU_HIB_IO_t pin)
1354 {
1355   while((SCU_GENERAL->MIRRSTS) & SCU_GENERAL_MIRRSTS_HDCR_Msk)
1356   {
1357     /* Wait until HDCR register in hibernate domain is ready to accept a write */
1358   }
1359 
1360   if (pin == XMC_SCU_HIB_IO_0)
1361   {
1362     SCU_HIBERNATE->HDCR |= SCU_HIBERNATE_HDCR_WKUPSEL_Msk;
1363   }
1364   else
1365   {
1366     SCU_HIBERNATE->HDCR &= ~SCU_HIBERNATE_HDCR_WKUPSEL_Msk;
1367   }
1368 }
1369 
XMC_SCU_HIB_SetPinMode(XMC_SCU_HIB_IO_t pin,XMC_SCU_HIB_PIN_MODE_t mode)1370 void XMC_SCU_HIB_SetPinMode(XMC_SCU_HIB_IO_t pin, XMC_SCU_HIB_PIN_MODE_t mode)
1371 {
1372   while((SCU_GENERAL->MIRRSTS) & SCU_GENERAL_MIRRSTS_HDCR_Msk)
1373   {
1374     /* Wait until HDCR register in hibernate domain is ready to accept a write */
1375   }
1376   SCU_HIBERNATE->HDCR = (SCU_HIBERNATE->HDCR & ~(SCU_HIBERNATE_HDCR_HIBIO0SEL_Msk << (SCU_HIBERNATE_HDCR_HIBIOSEL_Size * pin))) |
1377                         (mode << (SCU_HIBERNATE_HDCR_HIBIOSEL_Size * pin));
1378 }
1379 
XMC_SCU_HIB_SetPinOutputLevel(XMC_SCU_HIB_IO_t pin,XMC_SCU_HIB_IO_OUTPUT_LEVEL_t level)1380 void XMC_SCU_HIB_SetPinOutputLevel(XMC_SCU_HIB_IO_t pin, XMC_SCU_HIB_IO_OUTPUT_LEVEL_t level)
1381 {
1382   while((SCU_GENERAL->MIRRSTS) & SCU_GENERAL_MIRRSTS_HDCR_Msk)
1383   {
1384     /* Wait until HDCR register in hibernate domain is ready to accept a write */
1385   }
1386   SCU_HIBERNATE->HDCR = (SCU_HIBERNATE->HDCR & ~(SCU_HIBERNATE_HDCR_HIBIO0POL_Msk << pin)) |
1387                         (level << pin);
1388 }
1389 
XMC_SCU_HIB_SetInput0(XMC_SCU_HIB_IO_t pin)1390 void XMC_SCU_HIB_SetInput0(XMC_SCU_HIB_IO_t pin)
1391 {
1392   while((SCU_GENERAL->MIRRSTS) & SCU_GENERAL_MIRRSTS_HDCR_Msk)
1393   {
1394     /* Wait until HDCR register in hibernate domain is ready to accept a write */
1395   }
1396 
1397   if (pin == XMC_SCU_HIB_IO_0)
1398   {
1399     SCU_HIBERNATE->HDCR |= SCU_HIBERNATE_HDCR_GPI0SEL_Msk;
1400   }
1401   else
1402   {
1403     SCU_HIBERNATE->HDCR &= ~SCU_HIBERNATE_HDCR_GPI0SEL_Msk;
1404   }
1405 }
1406 
XMC_SCU_HIB_SetSR0Input(XMC_SCU_HIB_SR0_INPUT_t input)1407 void XMC_SCU_HIB_SetSR0Input(XMC_SCU_HIB_SR0_INPUT_t input)
1408 {
1409   while((SCU_GENERAL->MIRRSTS) & SCU_GENERAL_MIRRSTS_HDCR_Msk)
1410   {
1411     /* Wait until HDCR register in hibernate domain is ready to accept a write */
1412   }
1413 #if ((UC_SERIES == XMC44) || (UC_SERIES == XMC42) || (UC_SERIES == XMC41))
1414   SCU_HIBERNATE->HDCR = (SCU_HIBERNATE->HDCR & (uint32_t)~(SCU_HIBERNATE_HDCR_GPI0SEL_Msk | SCU_HIBERNATE_HDCR_ADIG0SEL_Msk)) |
1415 #else
1416   SCU_HIBERNATE->HDCR = (SCU_HIBERNATE->HDCR & (uint32_t)~(SCU_HIBERNATE_HDCR_GPI0SEL_Msk)) |
1417 #endif
1418                         input;
1419 }
1420 
1421 #if ((UC_SERIES == XMC44) || (UC_SERIES == XMC42) || (UC_SERIES == XMC41))
1422 
1423 #if ((UC_SERIES == XMC44) && (UC_PACKAGE == LQFP100))
XMC_SCU_HIB_SetSR1Input(XMC_SCU_HIB_SR1_INPUT_t input)1424 void XMC_SCU_HIB_SetSR1Input(XMC_SCU_HIB_SR1_INPUT_t input)
1425 {
1426   while((SCU_GENERAL->MIRRSTS) & SCU_GENERAL_MIRRSTS_HDCR_Msk)
1427   {
1428     /* Wait until HDCR register in hibernate domain is ready to accept a write */
1429   }
1430   SCU_HIBERNATE->HDCR = (SCU_HIBERNATE->HDCR & (uint32_t)~(SCU_HIBERNATE_HDCR_GPI1SEL_Msk | SCU_HIBERNATE_HDCR_ADIG1SEL_Msk | SCU_HIBERNATE_HDCR_XTALGPI1SEL_Msk)) |
1431                         input;
1432 }
1433 #endif
1434 
XMC_SCU_HIB_LPAC_SetInput(XMC_SCU_HIB_LPAC_INPUT_t input)1435 void XMC_SCU_HIB_LPAC_SetInput(XMC_SCU_HIB_LPAC_INPUT_t input)
1436 {
1437   while((SCU_GENERAL->MIRRSTS) & SCU_GENERAL_MIRRSTS_LPACCONF_Msk)
1438   {
1439     /* Wait until HDCR register in hibernate domain is ready to accept a write */
1440   }
1441   SCU_HIBERNATE->LPACCONF = (SCU_HIBERNATE->LPACCONF &  (uint32_t)~SCU_HIBERNATE_LPACCONF_CMPEN_Msk) |
1442                             input;
1443 }
1444 
XMC_SCU_HIB_LPAC_SetTrigger(XMC_SCU_HIB_LPAC_TRIGGER_t trigger)1445 void XMC_SCU_HIB_LPAC_SetTrigger(XMC_SCU_HIB_LPAC_TRIGGER_t trigger)
1446 {
1447   while((SCU_GENERAL->MIRRSTS) & SCU_GENERAL_MIRRSTS_LPACCONF_Msk)
1448   {
1449     /* Wait until HDCR register in hibernate domain is ready to accept a write */
1450   }
1451   SCU_HIBERNATE->LPACCONF = (SCU_HIBERNATE->LPACCONF &  (uint32_t)~SCU_HIBERNATE_LPACCONF_TRIGSEL_Msk) |
1452                             trigger;
1453 }
1454 
XMC_SCU_HIB_LPAC_SetTiming(bool enable_delay,uint16_t interval_count,uint8_t settle_count)1455 void XMC_SCU_HIB_LPAC_SetTiming(bool enable_delay, uint16_t interval_count, uint8_t settle_count)
1456 {
1457   uint32_t config = 0;
1458 
1459   if (enable_delay)
1460   {
1461     config = SCU_HIBERNATE_LPACCONF_CONVDEL_Msk;
1462   }
1463 
1464   config |= interval_count << SCU_HIBERNATE_LPACCONF_INTERVCNT_Pos;
1465   config |= settle_count << SCU_HIBERNATE_LPACCONF_SETTLECNT_Pos;
1466 
1467   while((SCU_GENERAL->MIRRSTS) & SCU_GENERAL_MIRRSTS_LPACCONF_Msk)
1468   {
1469     /* Wait until HDCR register in hibernate domain is ready to accept a write */
1470   }
1471 
1472   SCU_HIBERNATE->LPACCONF = (SCU_HIBERNATE->LPACCONF &  (uint32_t)~(SCU_HIBERNATE_LPACCONF_CONVDEL_Msk |
1473                                                                     SCU_HIBERNATE_LPACCONF_INTERVCNT_Msk |
1474                                                                     SCU_HIBERNATE_LPACCONF_SETTLECNT_Msk)) |
1475                             config;
1476 
1477 }
1478 
XMC_SCU_HIB_LPAC_SetVBATThresholds(uint8_t lower,uint8_t upper)1479 void XMC_SCU_HIB_LPAC_SetVBATThresholds(uint8_t lower, uint8_t upper)
1480 {
1481 
1482   while((SCU_GENERAL->MIRRSTS) & SCU_GENERAL_MIRRSTS_LPACTH0_Msk)
1483   {
1484     /* Wait until HDCR register in hibernate domain is ready to accept a write */
1485   }
1486 
1487   SCU_HIBERNATE->LPACTH0 = (lower << SCU_HIBERNATE_LPACTH0_VBATLO_Pos) | (upper << SCU_HIBERNATE_LPACTH0_VBATHI_Pos);
1488 
1489 
1490 
1491 }
1492 
XMC_SCU_HIB_LPAC_SetHIBIO0Thresholds(uint8_t lower,uint8_t upper)1493 void XMC_SCU_HIB_LPAC_SetHIBIO0Thresholds(uint8_t lower, uint8_t upper)
1494 {
1495 
1496   while((SCU_GENERAL->MIRRSTS) & SCU_GENERAL_MIRRSTS_LPACTH1_Msk)
1497   {
1498     /* Wait until HDCR register in hibernate domain is ready to accept a write */
1499   }
1500 
1501   SCU_HIBERNATE->LPACTH1 = (SCU_HIBERNATE->LPACTH1 & (uint32_t)~(SCU_HIBERNATE_LPACTH1_AHIBIO0LO_Msk | SCU_HIBERNATE_LPACTH1_AHIBIO0HI_Msk)) |
1502                            (lower << SCU_HIBERNATE_LPACTH1_AHIBIO0LO_Pos) |
1503                            (upper << SCU_HIBERNATE_LPACTH1_AHIBIO0HI_Pos);
1504 
1505 }
1506 #if ((UC_SERIES == XMC44) && (UC_PACKAGE == LQFP100))
XMC_SCU_HIB_LPAC_SetHIBIO1Thresholds(uint8_t lower,uint8_t upper)1507 void XMC_SCU_HIB_LPAC_SetHIBIO1Thresholds(uint8_t lower, uint8_t upper)
1508 {
1509 
1510   while((SCU_GENERAL->MIRRSTS) & SCU_GENERAL_MIRRSTS_LPACTH1_Msk)
1511   {
1512     /* Wait until HDCR register in hibernate domain is ready to accept a write */
1513   }
1514 
1515   SCU_HIBERNATE->LPACTH1 = (SCU_HIBERNATE->LPACTH1 & (uint32_t)~(SCU_HIBERNATE_LPACTH1_AHIBIO1LO_Msk | SCU_HIBERNATE_LPACTH1_AHIBIO1HI_Msk)) |
1516                            (lower << SCU_HIBERNATE_LPACTH1_AHIBIO1LO_Pos) |
1517                            (upper << SCU_HIBERNATE_LPACTH1_AHIBIO1HI_Pos);
1518 
1519 }
1520 #endif
XMC_SCU_HIB_LPAC_GetStatus(void)1521 int32_t XMC_SCU_HIB_LPAC_GetStatus(void)
1522 {
1523   return SCU_HIBERNATE->LPACST;
1524 }
1525 
XMC_SCU_HIB_LPAC_ClearStatus(int32_t status)1526 void XMC_SCU_HIB_LPAC_ClearStatus(int32_t status)
1527 {
1528   while((SCU_GENERAL->MIRRSTS) & SCU_GENERAL_MIRRSTS_LPACCLR_Msk)
1529   {
1530     /* Wait until LPACCLR register in hibernate domain is ready to accept a write */
1531   }
1532   SCU_HIBERNATE->LPACCLR = status;;
1533 }
1534 
XMC_SCU_HIB_LPAC_TriggerCompare(XMC_SCU_HIB_LPAC_INPUT_t input)1535 void XMC_SCU_HIB_LPAC_TriggerCompare(XMC_SCU_HIB_LPAC_INPUT_t input)
1536 {
1537   while((SCU_GENERAL->MIRRSTS) & SCU_GENERAL_MIRRSTS_LPACSET_Msk)
1538   {
1539     /* Wait until LPACSET register in hibernate domain is ready to accept a write */
1540   }
1541 
1542   SCU_HIBERNATE->LPACSET = input;
1543 }
1544 
1545 #endif
1546 
XMC_SCU_CLOCK_IsLowPowerOscillatorStable(void)1547 bool XMC_SCU_CLOCK_IsLowPowerOscillatorStable(void)
1548 {
1549   return ((SCU_HIBERNATE->HDSTAT & SCU_HIBERNATE_HDSTAT_ULPWDG_Msk) == 0UL);
1550 }
1551 
1552 /* API to configure the 32khz Ultra Low Power oscillator */
XMC_SCU_CLOCK_EnableLowPowerOscillator(void)1553 void XMC_SCU_CLOCK_EnableLowPowerOscillator(void)
1554 {
1555   /* Enable OSC_ULP */
1556   XMC_SCU_INTERRUPT_ClearEventStatus(XMC_SCU_INTERRUPT_EVENT_OSCULCTRL_UPDATED);
1557   SCU_HIBERNATE->OSCULCTRL &= ~SCU_HIBERNATE_OSCULCTRL_MODE_Msk;
1558   while ((XMC_SCU_INTERUPT_GetEventStatus() & XMC_SCU_INTERRUPT_EVENT_OSCULCTRL_UPDATED) == 0);
1559 
1560   /* Clear ULP WDG status */
1561   XMC_SCU_INTERRUPT_ClearEventStatus(XMC_SCU_INTERRUPT_EVENT_HDCLR_UPDATED);
1562   SCU_HIBERNATE->HDCLR = (uint32_t)SCU_HIBERNATE_HDCLR_ULPWDG_Msk;
1563   while ((XMC_SCU_INTERUPT_GetEventStatus() & XMC_SCU_INTERRUPT_EVENT_HDCLR_UPDATED) == 0);
1564 
1565   /* Enable ULP WDG */
1566   XMC_SCU_INTERRUPT_ClearEventStatus(XMC_SCU_INTERRUPT_EVENT_HDCR_UPDATED);
1567   SCU_HIBERNATE->HDCR |= (uint32_t)SCU_HIBERNATE_HDCR_ULPWDGEN_Msk;
1568   while ((XMC_SCU_INTERUPT_GetEventStatus() & XMC_SCU_INTERRUPT_EVENT_HDCR_UPDATED) == 0);
1569 }
1570 
1571 /* API to configure the 32khz Ultra Low Power oscillator */
XMC_SCU_CLOCK_DisableLowPowerOscillator(void)1572 void XMC_SCU_CLOCK_DisableLowPowerOscillator(void)
1573 {
1574   while((SCU_GENERAL->MIRRSTS) & SCU_GENERAL_MIRRSTS_OSCULCTRL_Msk)
1575   {
1576     /* Wait until OSCULCTRL register in hibernate domain is ready to accept a write */
1577   }
1578   SCU_HIBERNATE->OSCULCTRL |= (uint32_t)SCU_HIBERNATE_OSCULCTRL_MODE_Msk;
1579 }
1580 
XMC_SCU_CLOCK_EnableLowPowerOscillatorGeneralPurposeInput(void)1581 void XMC_SCU_CLOCK_EnableLowPowerOscillatorGeneralPurposeInput(void)
1582 {
1583   while((SCU_GENERAL->MIRRSTS) & SCU_GENERAL_MIRRSTS_OSCULCTRL_Msk)
1584   {
1585     /* Wait until OSCULCTRL register in hibernate domain is ready to accept a write */
1586   }
1587   SCU_HIBERNATE->OSCULCTRL |= SCU_HIBERNATE_OSCULCTRL_X1DEN_Msk | SCU_HIBERNATE_OSCULCTRL_MODE_Msk;
1588 }
1589 
XMC_SCU_CLOCK_DisableLowPowerOscillatorGeneralPurposeInput(void)1590 void XMC_SCU_CLOCK_DisableLowPowerOscillatorGeneralPurposeInput(void)
1591 {
1592   while((SCU_GENERAL->MIRRSTS) & SCU_GENERAL_MIRRSTS_OSCULCTRL_Msk)
1593   {
1594     /* Wait until OSCULCTRL register in hibernate domain is ready to accept a write */
1595   }
1596   SCU_HIBERNATE->OSCULCTRL = (SCU_HIBERNATE->OSCULCTRL & ~(uint32_t)(SCU_HIBERNATE_OSCULCTRL_X1DEN_Msk | SCU_HIBERNATE_OSCULCTRL_MODE_Msk)) |
1597                              (SCU_HIBERNATE_OSCULCTRL_MODE_OSC_POWER_DOWN << SCU_HIBERNATE_OSCULCTRL_MODE_Pos);
1598 }
1599 
XMC_SCU_CLOCK_GetLowPowerOscillatorGeneralPurposeInputStatus(void)1600 uint32_t XMC_SCU_CLOCK_GetLowPowerOscillatorGeneralPurposeInputStatus(void)
1601 {
1602   return (SCU_HIBERNATE->OSCULSTAT & SCU_HIBERNATE_OSCULSTAT_X1D_Msk);
1603 }
1604 
1605 /* API to enable High Precision High Speed oscillator */
XMC_SCU_CLOCK_EnableHighPerformanceOscillator(void)1606 void XMC_SCU_CLOCK_EnableHighPerformanceOscillator(void)
1607 {
1608   SCU_PLL->PLLCON0 &= (uint32_t)~SCU_PLL_PLLCON0_PLLPWD_Msk;
1609 
1610   SCU_OSC->OSCHPCTRL = (uint32_t)((SCU_OSC->OSCHPCTRL & ~(SCU_OSC_OSCHPCTRL_MODE_Msk | SCU_OSC_OSCHPCTRL_OSCVAL_Msk)) |
1611                                   (((OSCHP_GetFrequency() / FOSCREF) - 1UL) << SCU_OSC_OSCHPCTRL_OSCVAL_Pos));
1612 
1613   /* restart OSC Watchdog */
1614   SCU_PLL->PLLCON0 &= (uint32_t)~SCU_PLL_PLLCON0_OSCRES_Msk;
1615 }
1616 
XMC_SCU_CLOCK_IsHighPerformanceOscillatorStable(void)1617 bool XMC_SCU_CLOCK_IsHighPerformanceOscillatorStable(void)
1618 {
1619   return ((SCU_PLL->PLLSTAT & XMC_SCU_PLL_PLLSTAT_OSC_USABLE) == XMC_SCU_PLL_PLLSTAT_OSC_USABLE);
1620 }
1621 
1622 /* API to disable High Precision High Speed oscillator */
XMC_SCU_CLOCK_DisableHighPerformanceOscillator(void)1623 void XMC_SCU_CLOCK_DisableHighPerformanceOscillator(void)
1624 {
1625   SCU_OSC->OSCHPCTRL |= (uint32_t)SCU_OSC_OSCHPCTRL_MODE_Msk;
1626 }
1627 
XMC_SCU_CLOCK_EnableHighPerformanceOscillatorGeneralPurposeInput(void)1628 void XMC_SCU_CLOCK_EnableHighPerformanceOscillatorGeneralPurposeInput(void)
1629 {
1630   SCU_OSC->OSCHPCTRL |= SCU_OSC_OSCHPCTRL_X1DEN_Msk;
1631 }
1632 
XMC_SCU_CLOCK_DisableHighPerformanceOscillatorGeneralPurposeInput(void)1633 void XMC_SCU_CLOCK_DisableHighPerformanceOscillatorGeneralPurposeInput(void)
1634 {
1635   SCU_OSC->OSCHPCTRL &= ~SCU_OSC_OSCHPCTRL_X1DEN_Msk;
1636 }
1637 
XMC_SCU_CLOCK_GetHighPerformanceOscillatorGeneralPurposeInputStatus(void)1638 uint32_t XMC_SCU_CLOCK_GetHighPerformanceOscillatorGeneralPurposeInputStatus(void)
1639 {
1640   return (SCU_OSC->OSCHPSTAT & SCU_OSC_OSCHPSTAT_X1D_Msk);
1641 }
1642 
1643 /* API to enable main PLL */
XMC_SCU_CLOCK_EnableSystemPll(void)1644 void XMC_SCU_CLOCK_EnableSystemPll(void)
1645 {
1646   SCU_PLL->PLLCON0 &= (uint32_t)~(SCU_PLL_PLLCON0_VCOPWD_Msk | SCU_PLL_PLLCON0_PLLPWD_Msk);
1647 }
1648 
1649 /* API to disable main PLL */
XMC_SCU_CLOCK_DisableSystemPll(void)1650 void XMC_SCU_CLOCK_DisableSystemPll(void)
1651 {
1652   SCU_PLL->PLLCON0 |= (uint32_t)(SCU_PLL_PLLCON0_VCOPWD_Msk | SCU_PLL_PLLCON0_PLLPWD_Msk);
1653 }
1654 
1655 /* API to configure main PLL */
XMC_SCU_CLOCK_StartSystemPll(XMC_SCU_CLOCK_SYSPLLCLKSRC_t source,XMC_SCU_CLOCK_SYSPLL_MODE_t mode,uint32_t pdiv,uint32_t ndiv,uint32_t kdiv)1656 void XMC_SCU_CLOCK_StartSystemPll(XMC_SCU_CLOCK_SYSPLLCLKSRC_t source,
1657                                   XMC_SCU_CLOCK_SYSPLL_MODE_t mode,
1658                                   uint32_t pdiv,
1659                                   uint32_t ndiv,
1660                                   uint32_t kdiv)
1661 {
1662 
1663   uint32_t vco_frequency; /* Q10.22, max VCO frequency = 520MHz */
1664   uint32_t kdiv_temp;
1665 
1666   XMC_SCU_CLOCK_SetSystemPllClockSource(source);
1667 
1668   if (mode == XMC_SCU_CLOCK_SYSPLL_MODE_NORMAL)
1669   {
1670     /* Calculate initial step to be close to fOFI */
1671     if (source == XMC_SCU_CLOCK_SYSPLLCLKSRC_OSCHP)
1672     {
1673       vco_frequency = (OSCHP_GetFrequency() / 1000000U) << 22;
1674     }
1675     else
1676     {
1677       vco_frequency = (OFI_FREQUENCY / 1000000U) << 22;
1678     }
1679     vco_frequency = ((vco_frequency * ndiv) / pdiv);
1680     kdiv_temp = (vco_frequency / (OFI_FREQUENCY / 1000000U)) >> 22;
1681 
1682     /* Switch to prescaler mode */
1683     SCU_PLL->PLLCON0 |= (uint32_t)SCU_PLL_PLLCON0_VCOBYP_Msk;
1684 
1685     /* disconnect Oscillator from PLL */
1686     SCU_PLL->PLLCON0 |= (uint32_t)SCU_PLL_PLLCON0_FINDIS_Msk;
1687 
1688     /* Setup divider settings for main PLL */
1689     SCU_PLL->PLLCON1 = (uint32_t)((SCU_PLL->PLLCON1 & ~(SCU_PLL_PLLCON1_NDIV_Msk | SCU_PLL_PLLCON1_K2DIV_Msk |
1690                                    SCU_PLL_PLLCON1_PDIV_Msk)) | ((ndiv - 1UL) << SCU_PLL_PLLCON1_NDIV_Pos) |
1691                                    ((kdiv_temp - 1UL) << SCU_PLL_PLLCON1_K2DIV_Pos) |
1692                                    ((pdiv - 1UL)<< SCU_PLL_PLLCON1_PDIV_Pos));
1693 
1694     /* Set OSCDISCDIS, OSC clock remains connected to the VCO in case of loss of lock */
1695     SCU_PLL->PLLCON0 |= (uint32_t)SCU_PLL_PLLCON0_OSCDISCDIS_Msk;
1696 
1697     /* connect Oscillator to PLL */
1698     SCU_PLL->PLLCON0 &= (uint32_t)~SCU_PLL_PLLCON0_FINDIS_Msk;
1699 
1700     /* restart PLL Lock detection */
1701     SCU_PLL->PLLCON0 |= (uint32_t)SCU_PLL_PLLCON0_RESLD_Msk;
1702     while ((SCU_PLL->PLLSTAT & SCU_PLL_PLLSTAT_VCOLOCK_Msk) == 0U)
1703     {
1704       /* wait for PLL Lock */
1705     }
1706 
1707     /* Switch to normal mode */
1708     SCU_PLL->PLLCON0 &= (uint32_t)~SCU_PLL_PLLCON0_VCOBYP_Msk;
1709     while ((SCU_PLL->PLLSTAT & SCU_PLL_PLLSTAT_VCOBYST_Msk) != 0U)
1710     {
1711       /* wait for normal mode */
1712     }
1713 
1714     /* Ramp up PLL frequency in steps */
1715     kdiv_temp = (vco_frequency / 60UL) >> 22;
1716     if (kdiv < kdiv_temp)
1717     {
1718       XMC_SCU_CLOCK_StepSystemPllFrequency(kdiv_temp);
1719     }
1720 
1721     kdiv_temp = (vco_frequency / 90UL) >> 22;
1722     if (kdiv < kdiv_temp)
1723     {
1724       XMC_SCU_CLOCK_StepSystemPllFrequency(kdiv_temp);
1725     }
1726 
1727     XMC_SCU_CLOCK_StepSystemPllFrequency(kdiv);
1728   }
1729   else
1730   {
1731     SCU_PLL->PLLCON1 = (uint32_t)((SCU_PLL->PLLCON1 & ~SCU_PLL_PLLCON1_K1DIV_Msk) |
1732                        ((kdiv -1UL) << SCU_PLL_PLLCON1_K1DIV_Pos));
1733 
1734     /* Switch to prescaler mode */
1735     SCU_PLL->PLLCON0 |= (uint32_t)SCU_PLL_PLLCON0_VCOBYP_Msk;
1736 
1737     while ((SCU_PLL->PLLSTAT & SCU_PLL_PLLSTAT_VCOBYST_Msk) == 0U)
1738     {
1739       /* wait for prescaler mode */
1740     }
1741   }
1742 }
1743 
1744 /* API to stop main PLL operation */
XMC_SCU_CLOCK_StopSystemPll(void)1745 void XMC_SCU_CLOCK_StopSystemPll(void)
1746 {
1747   SCU_PLL->PLLCON0 |= (uint32_t)SCU_PLL_PLLCON0_PLLPWD_Msk;
1748 }
1749 
1750 /* API to step up/down the main PLL frequency */
XMC_SCU_CLOCK_StepSystemPllFrequency(uint32_t kdiv)1751 void XMC_SCU_CLOCK_StepSystemPllFrequency(uint32_t kdiv)
1752 {
1753   SCU_PLL->PLLCON1 = (uint32_t)((SCU_PLL->PLLCON1 & ~SCU_PLL_PLLCON1_K2DIV_Msk) |
1754                      ((kdiv - 1UL) << SCU_PLL_PLLCON1_K2DIV_Pos));
1755 
1756   XMC_SCU_lDelay(50U);
1757 }
1758 
1759 /* API to check main PLL is locked or not */
XMC_SCU_CLOCK_IsSystemPllLocked(void)1760 bool XMC_SCU_CLOCK_IsSystemPllLocked(void)
1761 {
1762   return (bool)((SCU_PLL->PLLSTAT & SCU_PLL_PLLSTAT_VCOLOCK_Msk) != 0UL);
1763 }
1764 
1765 /*
1766  * API to assign the event handler function to be executed on occurrence of the selected event.
1767  */
XMC_SCU_INTERRUPT_SetEventHandler(const XMC_SCU_INTERRUPT_EVENT_t event,const XMC_SCU_INTERRUPT_EVENT_HANDLER_t handler)1768 XMC_SCU_STATUS_t XMC_SCU_INTERRUPT_SetEventHandler(const XMC_SCU_INTERRUPT_EVENT_t event,
1769                                                    const XMC_SCU_INTERRUPT_EVENT_HANDLER_t handler)
1770 {
1771   uint32_t index;
1772   XMC_SCU_STATUS_t status;
1773 
1774   index = 0U;
1775   while (((event & ((XMC_SCU_INTERRUPT_EVENT_t)1 << index)) == 0U) && (index < XMC_SCU_INTERRUPT_EVENT_MAX))
1776   {
1777     index++;
1778   }
1779 
1780   if (index == XMC_SCU_INTERRUPT_EVENT_MAX)
1781   {
1782     status = XMC_SCU_STATUS_ERROR;
1783   }
1784   else
1785   {
1786     event_handler_list[index] = handler;
1787     status = XMC_SCU_STATUS_OK;
1788   }
1789 
1790   return (status);
1791 }
1792 
1793 /*
1794  * API to execute callback functions for multiple events.
1795  */
XMC_SCU_IRQHandler(uint32_t sr_num)1796 void XMC_SCU_IRQHandler(uint32_t sr_num)
1797 {
1798   uint32_t index;
1799   XMC_SCU_INTERRUPT_EVENT_t event;
1800   XMC_SCU_INTERRUPT_EVENT_HANDLER_t event_handler;
1801 
1802   XMC_UNUSED_ARG(sr_num);
1803 
1804   index = 0U;
1805   event = XMC_SCU_INTERUPT_GetEventStatus();
1806   while (index < XMC_SCU_INTERRUPT_EVENT_MAX)
1807   {
1808     if ((event & ((XMC_SCU_INTERRUPT_EVENT_t)1 << index)) != 0U)
1809     {
1810       event_handler = event_handler_list[index];
1811       if (event_handler != NULL)
1812       {
1813           (event_handler)();
1814       }
1815 
1816       XMC_SCU_INTERRUPT_ClearEventStatus((uint32_t)(1UL << index));
1817 
1818       break;
1819     }
1820     index++;
1821   }
1822 }
1823 
1824 #endif /* UC_FAMILY == XMC4 */
1825