1 /***************************************************************************//**
2 * \file cy_syspm_v2.c
3 * \version 5.94
4 *
5 * This driver provides the source code for API power management.
6 *
7 ********************************************************************************
8 * \copyright
9 * Copyright (c) (2016-2023), Cypress Semiconductor Corporation (an Infineon company) or
10 * an affiliate of Cypress Semiconductor Corporation.
11 * SPDX-License-Identifier: Apache-2.0
12 *
13 * Licensed under the Apache License, Version 2.0 (the "License");
14 * you may not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 *     http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS,
21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
24 *******************************************************************************/
25 
26 #include "cy_device.h"
27 #include "cy_sysclk.h"
28 
29 #if defined (CY_IP_MXS40SSRSS)
30 
31 #include "cy_syspm.h"
32 #if  defined (CY_IP_MXS40SSRSS)
33 #include "cy_syspm_ppu.h"
34 #endif
35 
36 
37 /*******************************************************************************
38 *       Internal Functions
39 *******************************************************************************/
40 __WEAK void Cy_SysPm_Dsramoff_Entry(void);
41 
42 #ifdef ENABLE_MEM_VOLTAGE_TRIMS
43 /* RAM and ROM Voltage TRIM functions */
44 static void SetMemoryVoltageTrims(cy_en_syspm_sdr_voltage_t voltage);
45 static bool IsVoltageChangePossible(void);
46 #endif /* ENABLE_MEM_VOLTAGE_TRIMS */
47 
48 /*******************************************************************************
49 *       Internal Defines
50 *******************************************************************************/
51 
52 /* The define for number of callback roots */
53 #define CALLBACK_ROOT_NR                (7U)
54 
55 /* The mask to unlock the Hibernate power mode */
56 #define HIBERNATE_UNLOCK_VAL                 ((uint32_t) 0x3Au << SRSS_PWR_HIBERNATE_UNLOCK_Pos)
57 
58 /* The mask to set the Hibernate power mode */
59 #define SET_HIBERNATE_MODE                   ((HIBERNATE_UNLOCK_VAL |\
60                                                SRSS_PWR_HIBERNATE_FREEZE_Msk |\
61                                                SRSS_PWR_HIBERNATE_HIBERNATE_Msk))
62 
63 /* The mask to retain the Hibernate power mode status */
64 #define HIBERNATE_RETAIN_STATUS_MASK         ((SRSS_PWR_HIBERNATE_TOKEN_Msk |\
65                                                SRSS_PWR_HIBERNATE_MASK_HIBALARM_Msk |\
66                                                SRSS_PWR_HIBERNATE_MASK_HIBWDT_Msk |\
67                                                SRSS_PWR_HIBERNATE_POLARITY_HIBPIN_Msk |\
68                                                SRSS_PWR_HIBERNATE_MASK_HIBPIN_Msk))
69 
70 /** The mask for the Hibernate wakeup sources */
71 #define HIBERNATE_WAKEUP_MASK               ((SRSS_PWR_HIB_WAKE_CTL_HIB_WAKE_SRC_Msk |\
72                                               SRSS_PWR_HIB_WAKE_CTL_HIB_WAKE_CSV_BAK_Msk |\
73                                               SRSS_PWR_HIB_WAKE_CTL_HIB_WAKE_RTC_Msk |\
74                                               SRSS_PWR_HIB_WAKE_CTL_HIB_WAKE_WDT_Msk))
75 
76 /** The define to update the token to indicate the transition into Hibernate */
77 #define HIBERNATE_TOKEN                    ((uint32_t) 0x1BU << SRSS_PWR_HIBERNATE_TOKEN_Pos)
78 
79 /* The wait time for transition into the minimum regulator current mode
80 */
81 #define SET_MIN_CURRENT_MODE_DELAY_US        (1U)
82 
83 /* The wait delay time that occurs before the active reference is settled.
84 *  Intermediate delay is used in transition into the normal regulator current
85 *  mode
86 */
87 #define ACT_REF_SETTLE_DELAY_US              (6U)
88 
89 /* The wait delay time that occurs after the active reference is settled.
90 *  Final delay is used in transition into the normal regulator current mode
91 */
92 #define SET_NORMAL_CURRENT_MODE_DELAY_US     (1U)
93 
94 /* The internal define of the tries number in the
95 * Cy_SysPm_SystemSetMinRegulatorCurrent() function
96 */
97 #define WAIT_DELAY_TRIES                (100U)
98 
99 /* The internal define of the tries number in the
100 * Cy_SysPm_SystemSetMinRegulatorCurrent() function
101 */
102 #define CY_SYSPM_CBUCK_BUSY_RETRY_COUNT         (100U)
103 #define CY_SYSPM_CBUCK_BUSY_RETRY_DELAY_MS      (1U)
104 
105 /* Define for ROM trim for 0.9V */
106 #define CPUSS_TRIM_ROM_VOLT_0_900         (0x00000012U)
107 
108 /* Define for ROM trim for 1.0V */
109 #define CPUSS_TRIM_ROM_VOLT_1_000         (0x00000012U)
110 
111 /* Define for ROM trim for 1.1V */
112 #define CPUSS_TRIM_ROM_VOLT_1_100         (0x00000013U)
113 
114 /* Define for RAM trim for 0.9V */
115 #define CPUSS_TRIM_RAM_VOLT_0_900         (0x00006012U)
116 
117 /* Define for RAM trim for 1.0V */
118 #define CPUSS_TRIM_RAM_VOLT_1_000         (0x00005012U)
119 
120 /* Define for RAM trim for 1.1V */
121 #define CPUSS_TRIM_RAM_VOLT_1_100         (0x00004013U)
122 
123 /* Mask for the RAM write check bits */
124 #define CPUSS_TRIM_RAM_CTL_WC_MASK        (0x3UL << 10U)
125 
126 /*******************************************************************************
127 *       Internal Variables
128 *******************************************************************************/
129 
130 /* Array of the callback roots */
131 static cy_stc_syspm_callback_t* pmCallbackRoot[CALLBACK_ROOT_NR] = {(void *)0, (void *)0, (void *)0, (void *)0, (void *)0, (void *)0, (void *)0};
132 
133 /* The array of the pointers to failed callback */
134 static cy_stc_syspm_callback_t* failedCallback[CALLBACK_ROOT_NR] = {(void *)0, (void *)0, (void *)0, (void *)0, (void *)0, (void *)0, (void *)0};
135 
136 
Cy_SysPm_Init(void)137 void Cy_SysPm_Init(void)
138 {
139     if(CY_SYSPM_WARM_BOOT_MODE != Cy_SysPm_GetBootMode())
140     {
141         (void)cy_pd_ppu_init((struct ppu_v1_reg *)CY_PPU_MAIN_BASE); /* Suppress a compiler warning about unused return value */
142         (void)cy_pd_ppu_init((struct ppu_v1_reg *)CY_PPU_CPUSS_BASE); /* Suppress a compiler warning about unused return value */
143         (void)cy_pd_ppu_init((struct ppu_v1_reg *)CY_PPU_SRAM_BASE); /* Suppress a compiler warning about unused return value */
144 
145         /* Set Default mode to DEEPSLEEP */
146         (void)Cy_SysPm_SetDeepSleepMode(CY_SYSPM_MODE_DEEPSLEEP);
147     }
148 }
149 
Cy_SysPm_CpuEnterSleep(cy_en_syspm_waitfor_t waitFor)150 cy_en_syspm_status_t Cy_SysPm_CpuEnterSleep(cy_en_syspm_waitfor_t waitFor)
151 {
152     uint32_t interruptState;
153     uint32_t cbSleepRootIdx = (uint32_t) CY_SYSPM_SLEEP;
154     cy_en_syspm_status_t retVal = CY_SYSPM_SUCCESS;
155 
156     CY_ASSERT_L3(CY_SYSPM_IS_WAIT_FOR_VALID(waitFor));
157 
158     /* Call registered callback functions with CY_SYSPM_CHECK_READY parameter */
159     if (pmCallbackRoot[cbSleepRootIdx] != NULL)
160     {
161         retVal = Cy_SysPm_ExecuteCallback(CY_SYSPM_SLEEP, CY_SYSPM_CHECK_READY);
162     }
163 
164     /* The CPU can switch into the Sleep power mode only when
165     *  all executed registered callback functions with the CY_SYSPM_CHECK_READY
166     *  parameter return CY_SYSPM_SUCCESS.
167     */
168     if(retVal == CY_SYSPM_SUCCESS)
169     {
170         /* Call the registered callback functions with
171         * CY_SYSPM_BEFORE_TRANSITION parameter
172         */
173         interruptState = Cy_SysLib_EnterCriticalSection();
174         if (pmCallbackRoot[cbSleepRootIdx] != NULL)
175         {
176             (void) Cy_SysPm_ExecuteCallback(CY_SYSPM_SLEEP, CY_SYSPM_BEFORE_TRANSITION);
177         }
178 
179         /* The CPU enters the Sleep power mode upon execution of WFI/WFE */
180         SCB_SCR &= (uint32_t) ~SCB_SCR_SLEEPDEEP_Msk;
181 
182         if(waitFor != CY_SYSPM_WAIT_FOR_EVENT)
183         {
184             __WFI();
185         }
186         else
187         {
188             __WFE();
189         }
190         Cy_SysLib_ExitCriticalSection(interruptState);
191 
192         /* Call the registered callback functions with the
193         *  CY_SYSPM_AFTER_TRANSITION parameter
194         */
195         if (pmCallbackRoot[cbSleepRootIdx] != NULL)
196         {
197             (void) Cy_SysPm_ExecuteCallback(CY_SYSPM_SLEEP, CY_SYSPM_AFTER_TRANSITION);
198         }
199     }
200     else
201     {
202         /* Execute callback functions with the CY_SYSPM_CHECK_FAIL parameter to
203         *  undo everything done in the callback with the CY_SYSPM_CHECK_READY
204         *  parameter
205         */
206         (void) Cy_SysPm_ExecuteCallback(CY_SYSPM_SLEEP, CY_SYSPM_CHECK_FAIL);
207         retVal = CY_SYSPM_FAIL;
208     }
209     return retVal;
210 }
211 
Cy_SysPm_SystemLpActiveEnter(void)212 cy_en_syspm_status_t Cy_SysPm_SystemLpActiveEnter(void)
213 {
214     uint32_t interruptState;
215     uint32_t cbSleepRootIdx = (uint32_t)CY_SYSPM_LPACTIVE_ENTER;
216     cy_en_syspm_status_t retVal = CY_SYSPM_SUCCESS;
217 
218     /* Step-1: Wait until PWR_CTL.LPM_READY==1 to indicate low power circuits are ready. */
219     if(!Cy_SysPm_IsLpmReady())
220     {
221         retVal = CY_SYSPM_FAIL;
222     }
223     else
224     {
225         /* Call registered callback functions with CY_SYSPM_CHECK_READY parameter */
226         if (pmCallbackRoot[cbSleepRootIdx] != NULL)
227         {
228             retVal = Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbSleepRootIdx, CY_SYSPM_CHECK_READY);
229         }
230 
231         if (retVal == CY_SYSPM_SUCCESS)
232         {
233             /* The CPU can switch into the LPACTIVE power mode only when
234             *  all executed registered callback functions with the CY_SYSPM_CHECK_READY
235             *  parameter return CY_SYSPM_SUCCESS.
236             */
237             /* Call the registered callback functions with
238             * CY_SYSPM_BEFORE_TRANSITION parameter
239             */
240             interruptState = Cy_SysLib_EnterCriticalSection();
241             if (pmCallbackRoot[cbSleepRootIdx] != NULL)
242             {
243                 (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbSleepRootIdx, CY_SYSPM_BEFORE_TRANSITION); /* Suppress a compiler warning about unused return value */
244             }
245 
246             //Enabling Low Power Profile
247             /* Step-2: Clock for clk_hf0 is selected as IMO, which runs at 8MHz Nominal. */
248             (void)Cy_SysClk_ClkHfDirectSel(0U, true);
249 
250             //Disable FLL if enabled
251             if(Cy_SysClk_FllIsEnabled())
252             {
253                 (void)Cy_SysClk_FllDisable(); /* Suppress a compiler warning about unused return value */
254             }
255 
256             /* Step-3: If reducing the regulator output voltage for RegSetB, perform the extra requester sequence.
257              * Call API-Cy_SysPm_LdoExtraRequesterConfig before calling this if the voltage needs to be reduced
258              */
259 
260             /* Step-4: If lowest power is required; perform the following writes to PWR_CTL2 */
261             retVal = Cy_SysPm_SystemSetMinRegulatorCurrent();
262 
263             Cy_SysLib_ExitCriticalSection(interruptState);
264 
265             /* Call the registered callback functions with the
266             *  CY_SYSPM_AFTER_TRANSITION parameter
267             */
268             if (pmCallbackRoot[cbSleepRootIdx] != NULL)
269             {
270                 (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbSleepRootIdx, CY_SYSPM_AFTER_TRANSITION); /* Suppress a compiler warning about unused return value */
271             }
272         }
273         else
274         {
275             /* Execute callback functions with the CY_SYSPM_CHECK_FAIL parameter to
276             *  undo everything done in the callback with the CY_SYSPM_CHECK_READY
277             *  parameter
278             */
279             (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbSleepRootIdx, CY_SYSPM_CHECK_FAIL); /* Suppress a compiler warning about unused return value */
280             retVal = CY_SYSPM_FAIL;
281         }
282     }
283     return retVal;
284 }
285 
Cy_SysPm_SystemLpActiveExit(void)286 cy_en_syspm_status_t Cy_SysPm_SystemLpActiveExit(void)
287 {
288     uint32_t interruptState;
289     uint32_t cbSleepRootIdx = (uint32_t)CY_SYSPM_LPACTIVE_EXIT;
290     cy_en_syspm_status_t retVal = CY_SYSPM_SUCCESS;
291 
292     /* Call registered callback functions with CY_SYSPM_CHECK_READY parameter */
293     if (pmCallbackRoot[cbSleepRootIdx] != NULL)
294     {
295         retVal = Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbSleepRootIdx, CY_SYSPM_CHECK_READY);
296     }
297 
298     if (retVal == CY_SYSPM_SUCCESS)
299     {
300         /* The CPU can switch into the LPACTIVE power mode only when
301         *  all executed registered callback functions with the CY_SYSPM_CHECK_READY
302         *  parameter return CY_SYSPM_SUCCESS.
303         */
304         /* Call the registered callback functions with
305         * CY_SYSPM_BEFORE_TRANSITION parameter
306         */
307         interruptState = Cy_SysLib_EnterCriticalSection();
308         if (pmCallbackRoot[cbSleepRootIdx] != NULL)
309         {
310             (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbSleepRootIdx, CY_SYSPM_BEFORE_TRANSITION); /* Suppress a compiler warning about unused return value */
311         }
312 
313         /* Step-1: Reverse the writes to PWR_CTL2 which are done in Cy_SysPm_SystemLpActiveEnter*/
314         retVal = Cy_SysPm_SystemSetNormalRegulatorCurrent();
315 
316         /* Step-2: If increasing the regulator output voltage for RegSetB, perform the extra requester sequence.
317          * Call API-Cy_SysPm_LdoExtraRequesterConfig before calling this if the voltage needs to be increased
318          */
319 
320         /* Step-3: High Frequency clocks could be enabled */
321         (void)Cy_SysClk_FllEnable(0UL);
322         if (CY_SYSCLK_SUCCESS != Cy_SysClk_FllEnable(0UL))
323         {
324             retVal = CY_SYSPM_FAIL;
325         }
326         (void)Cy_SysClk_ClkHfDirectSel(0U, false);
327 
328         Cy_SysLib_ExitCriticalSection(interruptState);
329 
330         /* Call the registered callback functions with the
331         *  CY_SYSPM_AFTER_TRANSITION parameter
332         */
333         if (pmCallbackRoot[cbSleepRootIdx] != NULL)
334         {
335             (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbSleepRootIdx, CY_SYSPM_AFTER_TRANSITION); /* Suppress a compiler warning about unused return value */
336         }
337     }
338     else
339     {
340         /* Execute callback functions with the CY_SYSPM_CHECK_FAIL parameter to
341         *  undo everything done in the callback with the CY_SYSPM_CHECK_READY
342         *  parameter
343         */
344         (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbSleepRootIdx, CY_SYSPM_CHECK_FAIL); /* Suppress a compiler warning about unused return value */
345         retVal = CY_SYSPM_FAIL;
346     }
347     return retVal;
348 }
349 
Cy_SysPm_IsSystemLpActiveEnabled(void)350 bool Cy_SysPm_IsSystemLpActiveEnabled(void)
351 {
352     return (_FLD2BOOL(SRSS_PWR_CTL2_REFV_DIS, SRSS_PWR_CTL2)? true : false);
353 }
354 
Cy_SysPm_SetDeepSleepMode(cy_en_syspm_deep_sleep_mode_t deepSleepMode)355 cy_en_syspm_status_t Cy_SysPm_SetDeepSleepMode(cy_en_syspm_deep_sleep_mode_t deepSleepMode)
356 {
357     cy_en_syspm_status_t retVal = CY_SYSPM_FAIL;
358 
359     switch(deepSleepMode)
360     {
361         case CY_SYSPM_MODE_DEEPSLEEP:
362         {
363             (void)cy_pd_ppu_set_power_mode((struct ppu_v1_reg *)CY_PPU_MAIN_BASE, (uint32_t)CY_SYSTEM_MAIN_PPU_DEEPSLEEP_MODE); /* Suppress a compiler warning about unused return value */
364             (void)cy_pd_ppu_set_power_mode((struct ppu_v1_reg *)CY_PPU_CPUSS_BASE, (uint32_t)CY_SYSTEM_CPUSS_PPU_DEEPSLEEP_MODE); /* Suppress a compiler warning about unused return value */
365             (void)cy_pd_ppu_set_power_mode((struct ppu_v1_reg *)CY_PPU_SRAM_BASE, (uint32_t)CY_SYSTEM_SRAM_PPU_DEEPSLEEP_MODE); /* Suppress a compiler warning about unused return value */
366             retVal = CY_SYSPM_SUCCESS;
367         }
368         break;
369 
370         case CY_SYSPM_MODE_DEEPSLEEP_RAM:
371         {
372             (void)cy_pd_ppu_set_power_mode((struct ppu_v1_reg *)CY_PPU_MAIN_BASE, (uint32_t)CY_SYSTEM_MAIN_PPU_DEEPSLEEP_RAM_MODE); /* Suppress a compiler warning about unused return value */
373             (void)cy_pd_ppu_set_power_mode((struct ppu_v1_reg *)CY_PPU_CPUSS_BASE, (uint32_t)CY_SYSTEM_CPUSS_PPU_DEEPSLEEP_RAM_MODE); /* Suppress a compiler warning about unused return value */
374             (void)cy_pd_ppu_set_power_mode((struct ppu_v1_reg *)CY_PPU_SRAM_BASE, (uint32_t)CY_SYSTEM_SRAM_PPU_DEEPSLEEP_RAM_MODE); /* Suppress a compiler warning about unused return value */
375             retVal = CY_SYSPM_SUCCESS;
376         }
377         break;
378 
379         case CY_SYSPM_MODE_DEEPSLEEP_OFF:
380         {
381             (void)cy_pd_ppu_set_power_mode((struct ppu_v1_reg *)CY_PPU_MAIN_BASE, (uint32_t)CY_SYSTEM_MAIN_PPU_DEEPSLEEP_OFF_MODE); /* Suppress a compiler warning about unused return value */
382             (void)cy_pd_ppu_set_power_mode((struct ppu_v1_reg *)CY_PPU_CPUSS_BASE, (uint32_t)CY_SYSTEM_CPUSS_PPU_DEEPSLEEP_OFF_MODE); /* Suppress a compiler warning about unused return value */
383             (void)cy_pd_ppu_set_power_mode((struct ppu_v1_reg *)CY_PPU_SRAM_BASE, (uint32_t)CY_SYSTEM_SRAM_PPU_DEEPSLEEP_OFF_MODE); /* Suppress a compiler warning about unused return value */
384             retVal = CY_SYSPM_SUCCESS;
385         }
386         break;
387 
388         default:
389             retVal = CY_SYSPM_BAD_PARAM;
390         break;
391     }
392     return retVal;
393 }
394 
Cy_SysPm_GetDeepSleepMode(void)395 cy_en_syspm_deep_sleep_mode_t Cy_SysPm_GetDeepSleepMode(void)
396 {
397     uint32_t mode;
398     cy_en_syspm_deep_sleep_mode_t deepSleepMode;
399 
400     mode = (uint32_t)cy_pd_ppu_get_programmed_power_mode((struct ppu_v1_reg *)CY_PPU_MAIN_BASE);
401 
402     switch(mode)
403     {
404         case CY_SYSTEM_DEEPSLEEP_PPU_MODES:
405         {
406             deepSleepMode = CY_SYSPM_MODE_DEEPSLEEP;
407         }
408         break;
409 
410         case CY_SYSTEM_DEEPSLEEP_RAM_PPU_MODES:
411         {
412             deepSleepMode = CY_SYSPM_MODE_DEEPSLEEP_RAM;
413         }
414         break;
415 
416         case CY_SYSTEM_DEEPSLEEP_OFF_PPU_MODES:
417         {
418             deepSleepMode = CY_SYSPM_MODE_DEEPSLEEP_OFF;
419         }
420         break;
421 
422         default:
423         {
424             deepSleepMode = CY_SYSPM_MODE_DEEPSLEEP_NONE;
425         }
426         break;
427     }
428 
429     CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to cy_en_syspm_deep_sleep_mode_t enum.');
430     return ((cy_en_syspm_deep_sleep_mode_t)deepSleepMode);
431 }
432 
Cy_SysPm_GetBootMode(void)433 cy_en_syspm_boot_mode_t Cy_SysPm_GetBootMode(void)
434 {
435     uint32_t resCause, resCause2;
436     cy_en_syspm_boot_mode_t deepSleepWakeMode = CY_SYSPM_POR_BOOT_MODE;
437 
438     resCause = SRSS_RES_CAUSE;
439     resCause2 = SRSS_RES_CAUSE2;
440 
441     if((resCause == 0UL) || (resCause2 == 0UL))
442     {
443         switch(Cy_SysPm_GetDeepSleepMode())
444         {
445             case CY_SYSPM_MODE_DEEPSLEEP_RAM:
446             {
447                 deepSleepWakeMode = CY_SYSPM_WARM_BOOT_MODE;
448             }
449             break;
450 
451             case CY_SYSPM_MODE_DEEPSLEEP_OFF:
452             {
453                 deepSleepWakeMode = CY_SYSPM_COLD_BOOT_MODE;
454             }
455             break;
456 
457             default:
458             {
459                 deepSleepWakeMode = CY_SYSPM_POR_BOOT_MODE;
460             }
461             break;
462         }
463 
464     }
465 
466     return ((cy_en_syspm_boot_mode_t)deepSleepWakeMode);
467 }
468 
Cy_SysPm_CpuEnterDeepSleep(cy_en_syspm_waitfor_t waitFor)469 cy_en_syspm_status_t Cy_SysPm_CpuEnterDeepSleep(cy_en_syspm_waitfor_t waitFor)
470 {
471     uint32_t interruptState;
472     uint32_t cbDeepSleepRootIdx = (uint32_t) Cy_SysPm_GetDeepSleepMode();
473     cy_en_syspm_status_t retVal = CY_SYSPM_SUCCESS;
474 
475     CY_ASSERT_L3(CY_SYSPM_IS_WAIT_FOR_VALID(waitFor));
476     CY_ASSERT_L3(CY_SYSPM_IS_DEEPSLEEP_MODE_VALID(cbDeepSleepRootIdx));
477 
478     //Check if LPM is ready
479     if(!Cy_SysPm_IsLpmReady())
480     {
481         retVal = CY_SYSPM_FAIL;
482     }
483     else
484     {
485         /* Call the registered callback functions with the CY_SYSPM_CHECK_READY
486         *  parameter
487         */
488         if (pmCallbackRoot[cbDeepSleepRootIdx] != NULL)
489         {
490             retVal = Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbDeepSleepRootIdx, CY_SYSPM_CHECK_READY);
491         }
492 
493         /* The CPU can switch into the Deep Sleep power mode only when
494         *  all executed registered callback functions with the CY_SYSPM_CHECK_READY
495         *  parameter return CY_SYSPM_SUCCESS
496         */
497         if (retVal == CY_SYSPM_SUCCESS)
498         {
499             /* Call the registered callback functions with the
500             * CY_SYSPM_BEFORE_TRANSITION parameter
501             */
502             interruptState = Cy_SysLib_EnterCriticalSection();
503             if (pmCallbackRoot[cbDeepSleepRootIdx] != NULL)
504             {
505                 (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbDeepSleepRootIdx, CY_SYSPM_BEFORE_TRANSITION);
506             }
507                 /* The CPU enters Deep Sleep mode upon execution of WFI/WFE
508                  * use Cy_SysPm_SetDeepSleepMode to set various deepsleep modes TBD*/
509                 SCB_SCR |= SCB_SCR_SLEEPDEEP_Msk;
510 
511                 if(waitFor != CY_SYSPM_WAIT_FOR_EVENT)
512                 {
513                     __WFI();
514                 }
515                 else
516                 {
517                     __WFE();
518                 }
519 
520             /* Call the registered callback functions with the CY_SYSPM_AFTER_DS_WFI_TRANSITION
521             *  parameter
522             */
523             if (pmCallbackRoot[cbDeepSleepRootIdx] != NULL)
524             {
525                 (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbDeepSleepRootIdx, CY_SYSPM_AFTER_DS_WFI_TRANSITION);
526             }
527 
528             Cy_SysLib_ExitCriticalSection(interruptState);
529         }
530         if (retVal == CY_SYSPM_SUCCESS)
531         {
532             /* Call the registered callback functions with the CY_SYSPM_AFTER_TRANSITION
533             *  parameter
534             */
535             if (pmCallbackRoot[cbDeepSleepRootIdx] != NULL)
536             {
537                 (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbDeepSleepRootIdx, CY_SYSPM_AFTER_TRANSITION);
538             }
539         }
540         else
541         {
542             /* Execute callback functions with the CY_SYSPM_CHECK_FAIL parameter to
543             *  undo everything done in the callback with the CY_SYSPM_CHECK_READY
544             *  parameter
545             */
546             if (pmCallbackRoot[cbDeepSleepRootIdx] != NULL)
547             {
548                 (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbDeepSleepRootIdx, CY_SYSPM_CHECK_FAIL);
549             }
550         }
551     }
552     return retVal;
553 }
554 
Cy_SysPm_SetupDeepSleepRAM(cy_en_syspm_dsram_checks_t dsramCheck,uint32_t * dsramIntState)555 cy_en_syspm_status_t Cy_SysPm_SetupDeepSleepRAM(cy_en_syspm_dsram_checks_t dsramCheck, uint32_t *dsramIntState)
556 {
557     uint32_t cbDeepSleepRootIdx = (uint32_t) Cy_SysPm_GetDeepSleepMode();
558     cy_en_syspm_status_t retVal = CY_SYSPM_SUCCESS;
559 
560     CY_ASSERT_L3(CY_SYSPM_IS_DSRAM_CHECK_VALID(dsramCheck));
561     CY_ASSERT_L3(CY_SYSPM_IS_DEEPSLEEP_MODE_VALID(cbDeepSleepRootIdx));
562 
563     //Check if LPM is ready
564     if(!Cy_SysPm_IsLpmReady())
565     {
566         retVal = CY_SYSPM_FAIL;
567     }
568     else
569     {
570         if(dsramCheck == CY_SYSPM_PRE_DSRAM)
571         {
572             /* Clear the Warm Boot Entry status Flag */
573             Cy_SysLib_ClearDSRAMWarmBootEntryStatus();
574 
575             /* Call the registered callback functions with the CY_SYSPM_CHECK_READY
576             *  parameter
577             */
578             if (pmCallbackRoot[cbDeepSleepRootIdx] != NULL)
579             {
580                 retVal = Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbDeepSleepRootIdx, CY_SYSPM_CHECK_READY);
581             }
582 
583             /* The CPU can switch into the Deep Sleep power mode only when
584             *  all executed registered callback functions with the CY_SYSPM_CHECK_READY
585             *  parameter return CY_SYSPM_SUCCESS
586             */
587             if (retVal == CY_SYSPM_SUCCESS)
588             {
589                 /* Call the registered callback functions with the
590                 * CY_SYSPM_BEFORE_TRANSITION parameter
591                 */
592                 *dsramIntState = Cy_SysLib_EnterCriticalSection();
593 
594                 if (pmCallbackRoot[cbDeepSleepRootIdx] != NULL)
595                 {
596                     (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbDeepSleepRootIdx, CY_SYSPM_BEFORE_TRANSITION);
597                 }
598                     /* The CPU enters Deep Sleep mode upon execution of WFI/WFE
599                      * use Cy_SysPm_SetDeepSleepMode to set various deepsleep modes TBD*/
600                     SCB_SCR |= SCB_SCR_SLEEPDEEP_Msk;
601 
602             }
603             else
604             {
605                 /* Execute callback functions with the CY_SYSPM_CHECK_FAIL parameter to
606                 *  undo everything done in the callback with the CY_SYSPM_CHECK_READY
607                 *  parameter
608                 */
609                 if (pmCallbackRoot[cbDeepSleepRootIdx] != NULL)
610                 {
611                     (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbDeepSleepRootIdx, CY_SYSPM_CHECK_FAIL);
612                 }
613             }
614         }
615         else
616         {
617             /* Call the registered callback functions with the CY_SYSPM_AFTER_DS_WFI_TRANSITION
618             *  parameter
619             */
620             if (pmCallbackRoot[cbDeepSleepRootIdx] != NULL)
621             {
622                 (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbDeepSleepRootIdx, CY_SYSPM_AFTER_DS_WFI_TRANSITION);
623             }
624 
625             Cy_SysLib_ExitCriticalSection(*dsramIntState);
626 
627             /* Call the registered callback functions with the CY_SYSPM_AFTER_TRANSITION
628             *  parameter
629             */
630             if (pmCallbackRoot[cbDeepSleepRootIdx] != NULL)
631             {
632                 (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbDeepSleepRootIdx, CY_SYSPM_AFTER_TRANSITION);
633             }
634         }
635     }
636     return retVal;
637 }
638 
Cy_SysPm_SystemEnterHibernate(void)639 cy_en_syspm_status_t Cy_SysPm_SystemEnterHibernate(void)
640 {
641     cy_en_syspm_status_t retVal = CY_SYSPM_SUCCESS;
642     uint32_t cbHibernateRootIdx = (uint32_t) CY_SYSPM_HIBERNATE;
643     /* Call the registered callback functions with the
644     * CY_SYSPM_CHECK_READY parameter
645     */
646     if (pmCallbackRoot[cbHibernateRootIdx] != NULL)
647     {
648         retVal = Cy_SysPm_ExecuteCallback(CY_SYSPM_HIBERNATE, CY_SYSPM_CHECK_READY);
649     }
650 
651     /* The system can switch into Hibernate power mode only when
652     *  all executed registered callback functions with CY_SYSPM_CHECK_READY
653     *  parameter return CY_SYSPM_SUCCESS.
654     */
655     if(retVal == CY_SYSPM_SUCCESS)
656     {
657         /* Call registered callback functions with CY_SYSPM_BEFORE_TRANSITION
658         *  parameter
659         */
660         (void) Cy_SysLib_EnterCriticalSection();
661         if (pmCallbackRoot[cbHibernateRootIdx] != NULL)
662         {
663             (void) Cy_SysPm_ExecuteCallback(CY_SYSPM_HIBERNATE, CY_SYSPM_BEFORE_TRANSITION);
664         }
665 
666         /* Preserve the token that will be retained through a wakeup sequence.
667          * This could be used by Cy_SysLib_GetResetReason() to differentiate
668          * Wakeup from a general reset event.
669          * Preserve the wakeup source(s) configuration.
670          */
671         SRSS_PWR_HIBERNATE = (SRSS_PWR_HIBERNATE  | HIBERNATE_TOKEN);
672 
673         /* Clear Previous Wakeup Reasons */
674         Cy_SysPm_ClearHibernateWakeupCause();
675 
676         /* Disable overriding by the peripherals the next pin-freeze command */
677         SRSS_PWR_HIBERNATE |= SET_HIBERNATE_MODE;
678 
679         /* The second write causes freezing of I/O cells to save the I/O-cell state */
680         SRSS_PWR_HIBERNATE |= SET_HIBERNATE_MODE;
681 
682         /* Third write cause system to enter Hibernate */
683         SRSS_PWR_HIBERNATE |= SET_HIBERNATE_MODE;
684 
685         /* Read register to make sure it is settled */
686         (void) SRSS_PWR_HIBERNATE;
687 
688         /* Wait for transition */
689         __WFI();
690 
691         /* The callback function calls with the CY_SYSPM_AFTER_TRANSITION
692         * parameter in the Hibernate power mode are not applicable as system
693         * wake-up was made on system reboot.
694         */
695 
696         /* A wakeup from Hibernate is performed by toggling of the wakeup
697         * pins, or WDT matches, or Backup domain alarm expires. This depends on
698         * what item is configured in the Hibernate register. After a wakeup
699         * event, a normal Boot procedure occurs.
700         * There is no need to exit from the critical section.
701         */
702     }
703     else
704     {
705         /* Execute callback functions with the CY_SYSPM_CHECK_FAIL parameter to
706         * undo everything done in the callback with the CY_SYSPM_CHECK_READY
707         * parameter. The return value should be CY_SYSPM_SUCCESS.
708         */
709         (void) Cy_SysPm_ExecuteCallback(CY_SYSPM_HIBERNATE, CY_SYSPM_CHECK_FAIL);
710         retVal = CY_SYSPM_FAIL;
711     }
712     return retVal;
713 }
714 
Cy_SysPm_SystemSetMinRegulatorCurrent(void)715 cy_en_syspm_status_t Cy_SysPm_SystemSetMinRegulatorCurrent(void)
716 {
717     cy_en_syspm_status_t retVal = CY_SYSPM_CANCELED;
718 
719     /* Check if the power circuits are ready to enter into regulator minimum
720     *  current mode
721     */
722     if (Cy_SysPm_IsLpmReady())
723     {
724         SRSS_PWR_CTL2 |= (SRSS_PWR_CTL2_LINREG_LPMODE_Msk |
725                           SRSS_PWR_CTL2_PORBOD_LPMODE_Msk |
726                           SRSS_PWR_CTL2_BGREF_LPMODE_Msk |
727                           SRSS_PWR_CTL2_REFI_LPMODE_Msk);
728 
729         /* This wait time allows the circuits to remove their dependence on
730         *  the Active mode circuits, such as active Reference
731         */
732         Cy_SysLib_DelayUs(SET_MIN_CURRENT_MODE_DELAY_US);
733 
734         /* Disable active reference */
735         SRSS_PWR_CTL2 |= SRSS_PWR_CTL2_REFV_DIS_Msk;
736 
737         retVal = CY_SYSPM_SUCCESS;
738     }
739 
740     return retVal;
741 }
742 
Cy_SysPm_SystemSetNormalRegulatorCurrent(void)743 cy_en_syspm_status_t Cy_SysPm_SystemSetNormalRegulatorCurrent(void)
744 {
745     cy_en_syspm_status_t retVal = CY_SYSPM_TIMEOUT;
746 
747     uint32_t timeOut = WAIT_DELAY_TRIES;
748 
749     /* Configure the regulator normal current mode for the POR/BOD circuits
750     *  and for the Voltage References
751     */
752 
753     /* Bring Regulators Power Circuit out of LPMODE */
754     SRSS_PWR_CTL2 &= (uint32_t)~(SRSS_PWR_CTL2_REFV_DIS_Msk      |
755                                  SRSS_PWR_CTL2_LINREG_LPMODE_Msk |
756                                  SRSS_PWR_CTL2_PORBOD_LPMODE_Msk |
757                                  SRSS_PWR_CTL2_REFI_LPMODE_Msk);
758 
759     /* This wait time allows setting active Reference */
760     Cy_SysLib_DelayUs(ACT_REF_SETTLE_DELAY_US);
761 
762     while ((0U == _FLD2VAL(SRSS_PWR_CTL2_REFV_OK, SRSS_PWR_CTL2)) && (0U != timeOut))
763     {
764         timeOut--;
765     }
766 
767     if (0U != timeOut)
768     {
769         /* Disable the low-power for Bandgap reference circuit */
770         SRSS_PWR_CTL2 &= (uint32_t) ~SRSS_PWR_CTL2_BGREF_LPMODE_Msk;
771 
772         /* Delay to finally set the normal current mode */
773         Cy_SysLib_DelayUs(SET_NORMAL_CURRENT_MODE_DELAY_US);
774 
775         retVal= CY_SYSPM_SUCCESS;
776     }
777 
778     return retVal;
779 }
780 
Cy_SysPm_SystemIsMinRegulatorCurrentSet(void)781 bool Cy_SysPm_SystemIsMinRegulatorCurrentSet(void)
782 {
783     uint32_t regMask = Cy_SysPm_LdoIsEnabled() ? CY_SYSPM_PWR_CIRCUITS_LPMODE_ACTIVE_LDO_MASK : CY_SYSPM_PWR_CIRCUITS_LPMODE_ACTIVE_BUCK_MASK;
784 
785     return ((SRSS_PWR_CTL & regMask) == regMask);
786 }
787 
Cy_SysPm_LdoSetMode(cy_en_syspm_ldo_mode_t mode)788 cy_en_syspm_status_t Cy_SysPm_LdoSetMode(cy_en_syspm_ldo_mode_t mode)
789 {
790     CY_ASSERT_L3(CY_SYSPM_IS_LDO_MODE_VALID(mode));
791 
792     cy_en_syspm_status_t retVal = CY_SYSPM_CANCELED;
793 
794     switch (mode)
795     {
796         case CY_SYSPM_LDO_MODE_NORMAL:
797         {
798             retVal = Cy_SysPm_SystemSetNormalRegulatorCurrent();
799         }
800         break;
801 
802         case CY_SYSPM_LDO_MODE_MIN:
803         {
804             retVal = Cy_SysPm_SystemSetMinRegulatorCurrent();
805         }
806         break;
807 
808         case CY_SYSPM_LDO_MODE_DISABLED:
809         {
810             /* Disable the LDO, Deep Sleep and Retention regulators */
811             SRSS_PWR_CTL2 |= (_VAL2FLD(SRSS_PWR_CTL2_DPSLP_REG_DIS, 1U) |
812                              _VAL2FLD(SRSS_PWR_CTL2_RET_REG_DIS, 1U) |
813                              _VAL2FLD(SRSS_PWR_CTL2_LINREG_DIS, 1U));
814 
815             retVal = CY_SYSPM_SUCCESS;
816         }
817         break;
818 
819         default:
820             retVal = CY_SYSPM_FAIL;
821         break;
822     }
823 
824     return retVal;
825 }
826 
Cy_SysPm_LdoGetMode(void)827 cy_en_syspm_ldo_mode_t Cy_SysPm_LdoGetMode(void)
828 {
829     cy_en_syspm_ldo_mode_t retVal;
830 
831     if (!Cy_SysPm_LdoIsEnabled())
832     {
833         retVal = CY_SYSPM_LDO_MODE_DISABLED;
834     }
835     else if (Cy_SysPm_SystemIsMinRegulatorCurrentSet())
836     {
837         retVal = CY_SYSPM_LDO_MODE_MIN;
838     }
839     else
840     {
841         retVal = CY_SYSPM_LDO_MODE_NORMAL;
842     }
843 
844     return retVal;
845 }
846 
Cy_SysPm_LdoIsEnabled(void)847 bool Cy_SysPm_LdoIsEnabled(void)
848 {
849     return ((0U != _FLD2VAL(SRSS_PWR_CTL2_LINREG_DIS, SRSS_PWR_CTL2)) ? false : true);
850 }
851 
852 
Cy_SysPm_CpuSleepOnExit(bool enable)853 void Cy_SysPm_CpuSleepOnExit(bool enable)
854 {
855     if(enable)
856     {
857         /* Enable sleep-on-exit feature */
858         SCB_SCR |= SCB_SCR_SLEEPONEXIT_Msk;
859     }
860     else
861     {
862         /* Disable sleep-on-exit feature */
863         SCB_SCR &= (uint32_t) ~(SCB_SCR_SLEEPONEXIT_Msk);
864     }
865 }
866 
Cy_SysPm_SetHibernateWakeupSource(uint32_t wakeupSource)867 void Cy_SysPm_SetHibernateWakeupSource(uint32_t wakeupSource)
868 {
869     CY_ASSERT_L3(CY_SYSPM_IS_WAKE_UP_SOURCE_VALID(wakeupSource));
870 
871     uint32_t polarityMask = 0U;
872     uint32_t wakeSrcMask = 0U;
873 
874     /* LPCOMP0 & LPCOMP1 */
875     if ((0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_LPCOMP0_LOW)) || (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_LPCOMP0_HIGH)))
876     {
877         wakeSrcMask |= CY_SYSPM_HIB_WAKEUP_LPCOMP0_MASK;
878     }
879 
880     if ((0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_LPCOMP1_LOW)) || (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_LPCOMP1_HIGH)))
881     {
882         wakeSrcMask |= CY_SYSPM_HIB_WAKEUP_LPCOMP1_MASK;
883     }
884 
885     /* PIN0 & PIN1 */
886     if ((0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_PIN0_LOW)) || (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_PIN0_HIGH)))
887     {
888         wakeSrcMask |= CY_SYSPM_HIB_WAKEUP_PIN0_MASK;
889     }
890 
891     if ((0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_PIN1_LOW)) || (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_PIN1_HIGH)))
892     {
893         wakeSrcMask |= CY_SYSPM_HIB_WAKEUP_PIN1_MASK;
894     }
895 
896     /* RTC */
897     if (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_RTC_ALARM))
898     {
899         wakeSrcMask |= CY_SYSPM_HIB_WAKEUP_RTC_MASK;
900     }
901 
902     /* WDT */
903     if (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_WDT))
904     {
905         wakeSrcMask |= CY_SYSPM_HIB_WAKEUP_WDT_MASK;
906     }
907 
908     /* Polarity Mask */
909     if (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_LPCOMP0_HIGH))
910     {
911         polarityMask |= CY_SYSPM_HIB_WAKEUP_LPCOMP0_POLARITY_HIGH_MASK;
912     }
913 
914     if (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_LPCOMP1_HIGH))
915     {
916         polarityMask |= CY_SYSPM_HIB_WAKEUP_LPCOMP1_POLARITY_HIGH_MASK;
917     }
918 
919     if (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_PIN0_HIGH))
920     {
921         polarityMask |= CY_SYSPM_HIB_WAKEUP_PIN0_POLARITY_HIGH_MASK;
922     }
923 
924     if (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_PIN1_HIGH))
925     {
926         polarityMask |= CY_SYSPM_HIB_WAKEUP_PIN1_POLARITY_HIGH_MASK;
927     }
928 
929     SRSS_PWR_HIB_WAKE_CTL = (SRSS_PWR_HIB_WAKE_CTL | wakeSrcMask);
930     SRSS_PWR_HIB_WAKE_CTL2 = (SRSS_PWR_HIB_WAKE_CTL2 | polarityMask);
931 
932     /* Read registers to make sure it is settled */
933     (void) SRSS_PWR_HIB_WAKE_CTL;
934     (void) SRSS_PWR_HIB_WAKE_CTL2;
935 
936 }
937 
Cy_SysPm_ClearHibernateWakeupSource(uint32_t wakeupSource)938 void Cy_SysPm_ClearHibernateWakeupSource(uint32_t wakeupSource)
939 {
940     CY_ASSERT_L3(CY_SYSPM_IS_WAKE_UP_SOURCE_VALID(wakeupSource));
941 
942     uint32_t polarityMask = 0U;
943     uint32_t wakeSrcMask = 0U;
944 
945     /* LPCOMP0 & LPCOMP1 */
946     if ((0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_LPCOMP0_LOW)) || (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_LPCOMP0_HIGH)))
947     {
948         wakeSrcMask |= CY_SYSPM_HIB_WAKEUP_LPCOMP0_MASK;
949     }
950 
951     if ((0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_LPCOMP1_LOW)) || (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_LPCOMP1_HIGH)))
952     {
953         wakeSrcMask |= CY_SYSPM_HIB_WAKEUP_LPCOMP1_MASK;
954     }
955 
956     /* PIN0 & PIN1 */
957     if ((0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_PIN0_LOW)) || (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_PIN0_HIGH)))
958     {
959         wakeSrcMask |= CY_SYSPM_HIB_WAKEUP_PIN0_MASK;
960     }
961 
962     if ((0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_PIN1_LOW)) || (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_PIN1_HIGH)))
963     {
964         wakeSrcMask |= CY_SYSPM_HIB_WAKEUP_PIN1_MASK;
965     }
966 
967     /* RTC */
968     if (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_RTC_ALARM))
969     {
970         wakeSrcMask |= CY_SYSPM_HIB_WAKEUP_RTC_MASK;
971     }
972 
973     /* WDT */
974     if (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_WDT))
975     {
976         wakeSrcMask |= CY_SYSPM_HIB_WAKEUP_WDT_MASK;
977     }
978 
979     /* Polarity Mask */
980     if (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_LPCOMP0_HIGH))
981     {
982         polarityMask |= CY_SYSPM_HIB_WAKEUP_LPCOMP0_POLARITY_HIGH_MASK;
983     }
984 
985     if (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_LPCOMP1_HIGH))
986     {
987         polarityMask |= CY_SYSPM_HIB_WAKEUP_LPCOMP1_POLARITY_HIGH_MASK;
988     }
989 
990     if (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_PIN0_HIGH))
991     {
992         polarityMask |= CY_SYSPM_HIB_WAKEUP_PIN0_POLARITY_HIGH_MASK;
993     }
994 
995     if (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_PIN1_HIGH))
996     {
997         polarityMask |= CY_SYSPM_HIB_WAKEUP_PIN1_POLARITY_HIGH_MASK;
998     }
999 
1000     SRSS_PWR_HIB_WAKE_CTL = (SRSS_PWR_HIB_WAKE_CTL & (~wakeSrcMask));
1001     SRSS_PWR_HIB_WAKE_CTL2 = (SRSS_PWR_HIB_WAKE_CTL2 & (~polarityMask));
1002 
1003     /* Read registers to make sure it is settled */
1004     (void) SRSS_PWR_HIB_WAKE_CTL;
1005     (void) SRSS_PWR_HIB_WAKE_CTL2;
1006 }
1007 
Cy_SysPm_GetHibernateWakeupCause(void)1008 cy_en_syspm_hibernate_wakeup_source_t Cy_SysPm_GetHibernateWakeupCause(void)
1009 {
1010     uint32_t wakeupCause;
1011     uint32_t wakeupCausePolarity;
1012 
1013     wakeupCause = SRSS_PWR_HIB_WAKE_CAUSE;
1014 
1015     wakeupCausePolarity = (wakeupCause & (uint32_t)(CY_SYSPM_HIB_WAKEUP_LPCOMP0_POLARITY_HIGH_MASK |
1016                                           CY_SYSPM_HIB_WAKEUP_LPCOMP1_POLARITY_HIGH_MASK |
1017                                           CY_SYSPM_HIB_WAKEUP_PIN0_POLARITY_HIGH_MASK    |
1018                                           CY_SYSPM_HIB_WAKEUP_PIN1_POLARITY_HIGH_MASK ));
1019 
1020     switch(wakeupCause)
1021     {
1022         case CY_SYSPM_HIB_WAKEUP_PIN0_POS:
1023         {
1024             if (0U != (wakeupCausePolarity & (uint32_t)CY_SYSPM_HIB_WAKEUP_PIN0_POLARITY_HIGH_MASK))
1025             {
1026                 wakeupCause = ((uint32_t)CY_SYSPM_HIBERNATE_PIN0_HIGH);
1027             }
1028             else
1029             {
1030                 wakeupCause = ((uint32_t)CY_SYSPM_HIBERNATE_PIN0_LOW);
1031             }
1032         }
1033         break;
1034 
1035         case CY_SYSPM_HIB_WAKEUP_PIN1_POS:
1036         {
1037             if (0U != (wakeupCausePolarity & (uint32_t)CY_SYSPM_HIB_WAKEUP_PIN1_POLARITY_HIGH_MASK))
1038             {
1039                 wakeupCause = ((uint32_t)CY_SYSPM_HIBERNATE_PIN1_HIGH);
1040             }
1041             else
1042             {
1043                 wakeupCause = ((uint32_t)CY_SYSPM_HIBERNATE_PIN1_LOW);
1044             }
1045         }
1046         break;
1047 
1048         case CY_SYSPM_HIB_WAKEUP_LPCOMP0_POS:
1049         {
1050             if (0U != (wakeupCausePolarity & (uint32_t)CY_SYSPM_HIB_WAKEUP_LPCOMP0_POLARITY_HIGH_MASK))
1051             {
1052                 wakeupCause = ((uint32_t)CY_SYSPM_HIBERNATE_LPCOMP0_HIGH);
1053             }
1054             else
1055             {
1056                 wakeupCause = ((uint32_t)CY_SYSPM_HIBERNATE_LPCOMP0_LOW);
1057             }
1058         }
1059         break;
1060 
1061         case CY_SYSPM_HIB_WAKEUP_LPCOMP1_POS:
1062         {
1063             if (0U != (wakeupCausePolarity & (uint32_t)CY_SYSPM_HIB_WAKEUP_LPCOMP1_POLARITY_HIGH_MASK))
1064             {
1065                 wakeupCause = ((uint32_t)CY_SYSPM_HIBERNATE_LPCOMP1_HIGH);
1066             }
1067             else
1068             {
1069                 wakeupCause = ((uint32_t)CY_SYSPM_HIBERNATE_LPCOMP1_LOW);
1070             }
1071         }
1072         break;
1073 
1074         case CY_SYSPM_HIB_WAKEUP_RTC_MASK:
1075         {
1076             wakeupCause = ((uint32_t)CY_SYSPM_HIBERNATE_RTC_ALARM);
1077         }
1078         break;
1079 
1080         case CY_SYSPM_HIB_WAKEUP_WDT_MASK:
1081         {
1082             wakeupCause = ((uint32_t)CY_SYSPM_HIBERNATE_WDT);
1083         }
1084         break;
1085 
1086         default:
1087             CY_ASSERT_L2(false);
1088         break;
1089     }
1090 
1091     return (cy_en_syspm_hibernate_wakeup_source_t)wakeupCause;
1092 }
1093 
Cy_SysPm_ClearHibernateWakeupCause(void)1094 void Cy_SysPm_ClearHibernateWakeupCause(void)
1095 {
1096     uint32_t temp = SRSS_PWR_HIB_WAKE_CAUSE;
1097     SRSS_PWR_HIB_WAKE_CAUSE = temp;
1098 }
1099 
Cy_SysPm_CoreBuckSetVoltage(cy_en_syspm_core_buck_voltage_t voltage)1100 cy_en_syspm_status_t Cy_SysPm_CoreBuckSetVoltage(cy_en_syspm_core_buck_voltage_t voltage)
1101 {
1102     CY_ASSERT_L2(CY_SYSPM_IS_CORE_BUCK_VOLTAGE_VALID(voltage));
1103 
1104     CY_REG32_CLR_SET(SRSS_PWR_CBUCK_CTL, SRSS_PWR_CBUCK_CTL_CBUCK_VSEL, voltage);
1105 
1106     /* Since voltage is changed , use it for the CBUCK setting decision */
1107     CY_REG32_CLR_SET(SRSS_PWR_CBUCK_CTL2, SRSS_PWR_CBUCK_CTL2_CBUCK_USE_SETTINGS, 1UL);
1108 
1109     return Cy_SysPm_CoreBuckStatus();
1110 }
1111 
Cy_SysPm_CoreBuckGetVoltage(void)1112 cy_en_syspm_core_buck_voltage_t Cy_SysPm_CoreBuckGetVoltage(void)
1113 {
1114     CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to cy_en_syspm_core_buck_voltage_t enum.');
1115     return (cy_en_syspm_core_buck_voltage_t)(_FLD2VAL(SRSS_PWR_CBUCK_CTL_CBUCK_VSEL, SRSS_PWR_CBUCK_CTL));
1116 }
1117 
Cy_SysPm_CoreBuckSetMode(cy_en_syspm_core_buck_mode_t mode)1118 void Cy_SysPm_CoreBuckSetMode(cy_en_syspm_core_buck_mode_t mode)
1119 {
1120     CY_ASSERT_L2(CY_SYSPM_IS_CORE_BUCK_MODE_VALID(mode));
1121 
1122     CY_REG32_CLR_SET(SRSS_PWR_CBUCK_CTL, SRSS_PWR_CBUCK_CTL_CBUCK_MODE, mode);
1123 }
1124 
Cy_SysPm_CoreBuckGetMode(void)1125 cy_en_syspm_core_buck_mode_t Cy_SysPm_CoreBuckGetMode(void)
1126 {
1127     CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to cy_en_syspm_core_buck_mode_t enum.');
1128     return (cy_en_syspm_core_buck_mode_t)(_FLD2VAL(SRSS_PWR_CBUCK_CTL_CBUCK_MODE, SRSS_PWR_CBUCK_CTL));
1129 }
1130 
Cy_SysPm_CoreBuckSetInrushLimit(cy_en_syspm_core_inrush_limit_t inrushLimit)1131 void Cy_SysPm_CoreBuckSetInrushLimit(cy_en_syspm_core_inrush_limit_t inrushLimit)
1132 {
1133     CY_ASSERT_L2(CY_SYSPM_IS_CORE_BUCK_INRUSH_LIMIT_VALID(inrushLimit));
1134 
1135     CY_REG32_CLR_SET(SRSS_PWR_CBUCK_CTL3, SRSS_PWR_CBUCK_CTL3_CBUCK_INRUSH_SEL, inrushLimit);
1136 }
1137 
Cy_SysPm_CoreBuckGetInrushLimit(void)1138 cy_en_syspm_core_inrush_limit_t Cy_SysPm_CoreBuckGetInrushLimit(void)
1139 {
1140     CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to cy_en_syspm_core_inrush_limit_t enum.');
1141     return (cy_en_syspm_core_inrush_limit_t)(_FLD2VAL(SRSS_PWR_CBUCK_CTL3_CBUCK_INRUSH_SEL, SRSS_PWR_CBUCK_CTL3));
1142 }
1143 
Cy_SysPm_CoreBuckConfig(cy_stc_syspm_core_buck_params_t * config)1144 cy_en_syspm_status_t Cy_SysPm_CoreBuckConfig(cy_stc_syspm_core_buck_params_t *config)
1145 {
1146     CY_ASSERT_L2(CY_SYSPM_IS_CORE_BUCK_VOLTAGE_VALID(config->voltageSel));
1147     CY_ASSERT_L2(CY_SYSPM_IS_CORE_BUCK_MODE_VALID(config->mode));
1148     CY_ASSERT_L2(CY_SYSPM_IS_CORE_BUCK_INRUSH_LIMIT_VALID(config->inRushLimitSel));
1149 
1150     SRSS_PWR_CBUCK_CTL = _VAL2FLD(SRSS_PWR_CBUCK_CTL_CBUCK_VSEL, config->voltageSel) |
1151                          _VAL2FLD(SRSS_PWR_CBUCK_CTL_CBUCK_MODE, config->mode);
1152 
1153     SRSS_PWR_CBUCK_CTL2 = _VAL2FLD(SRSS_PWR_CBUCK_CTL2_CBUCK_OVERRIDE, ((config->override) ? 1UL : 0UL)) |
1154                          _VAL2FLD(SRSS_PWR_CBUCK_CTL2_CBUCK_COPY_SETTINGS, ((config->copySettings) ? 1UL : 0UL)) |
1155                          _VAL2FLD(SRSS_PWR_CBUCK_CTL2_CBUCK_USE_SETTINGS, ((config->useSettings) ? 1UL : 0UL));
1156 
1157     SRSS_PWR_CBUCK_CTL3 = _VAL2FLD(SRSS_PWR_CBUCK_CTL3_CBUCK_INRUSH_SEL, config->inRushLimitSel);
1158 
1159     /* Check if the CBUCK transition is Successful */
1160     return Cy_SysPm_CoreBuckStatus();
1161 }
1162 
Cy_SysPm_CoreBuckStatus(void)1163 cy_en_syspm_status_t Cy_SysPm_CoreBuckStatus(void)
1164 {
1165     cy_en_syspm_status_t retVal = CY_SYSPM_TIMEOUT;
1166     uint32_t syspmCbuckRetry = CY_SYSPM_CBUCK_BUSY_RETRY_COUNT;
1167 
1168     while((_FLD2VAL(SRSS_PWR_CBUCK_STATUS_PMU_DONE, SRSS_PWR_CBUCK_STATUS) == 0U) && (syspmCbuckRetry != 0U))
1169     {
1170         syspmCbuckRetry--;
1171         Cy_SysLib_Delay(CY_SYSPM_CBUCK_BUSY_RETRY_DELAY_MS);
1172     }
1173 
1174     if(syspmCbuckRetry != 0UL)
1175     {
1176         retVal = CY_SYSPM_SUCCESS;
1177     }
1178 
1179     return retVal;
1180 }
1181 
1182 #ifdef ENABLE_MEM_VOLTAGE_TRIMS
Cy_SysPm_SdrConfigure(cy_en_syspm_sdr_t sdr,cy_stc_syspm_sdr_params_t * config)1183 void Cy_SysPm_SdrConfigure(cy_en_syspm_sdr_t sdr, cy_stc_syspm_sdr_params_t *config)
1184 {
1185     CY_ASSERT_L2(CY_SYSPM_IS_SDR_NUM_VALID(sdr));
1186     CY_ASSERT_L2(CY_SYSPM_IS_CORE_BUCK_VOLTAGE_VALID(config->coreBuckVoltSel));
1187     CY_ASSERT_L2(CY_SYSPM_IS_CORE_BUCK_MODE_VALID(config->coreBuckMode));
1188     CY_ASSERT_L2(CY_SYSPM_IS_SDR_VOLTAGE_VALID(config->sdrVoltSel));
1189 
1190     CY_SYSPM_CORE_BUCK_PAUSE_ENABLE(1U);
1191 
1192     if(sdr == CY_SYSPM_SDR_0)
1193     {
1194         cy_en_syspm_sdr_voltage_t currSdr0Volt = Cy_SysPm_SdrGetVoltage(CY_SYSPM_SDR_0);
1195 
1196         CY_ASSERT_L2(CY_SYSPM_IS_SDR_VOLTAGE_VALID(config->sdr0DpSlpVoltSel));
1197         CY_ASSERT_L2(CY_SYSPM_IS_CORE_BUCK_VOLTAGE_VALID(config->coreBuckDpSlpVoltSel));
1198         CY_ASSERT_L2(CY_SYSPM_IS_CORE_BUCK_MODE_VALID(config->coreBuckDpSlpMode));
1199 
1200         /* High to Low voltage --> TRIM first , Set Voltage next */
1201         if(config->sdrVoltSel < ((uint8_t)currSdr0Volt))
1202         {
1203             if(IsVoltageChangePossible())
1204             {
1205                 SetMemoryVoltageTrims((cy_en_syspm_sdr_voltage_t)config->sdrVoltSel);
1206             }
1207 
1208             SRSS_PWR_SDR0_CTL =  _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_CBUCK_VSEL, config->coreBuckVoltSel) |
1209                               _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_CBUCK_MODE, config->coreBuckMode) |
1210                               _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_VSEL, config->sdrVoltSel) |
1211                               _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_CBUCK_DPSLP_VSEL, config->coreBuckDpSlpVoltSel) |
1212                               _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_CBUCK_DPSLP_MODE, config->coreBuckDpSlpMode) |
1213                               _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_DPSLP_VSEL, config->sdr0DpSlpVoltSel) |
1214                               _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_ALLOW_BYPASS, ((config->sdr0Allowbypass) ? 1UL : 0UL));
1215 
1216         }
1217         else if(config->sdrVoltSel > ((uint8_t)currSdr0Volt))  /* Low to High voltage --> Set Voltage first , Trim next */
1218         {
1219             SRSS_PWR_SDR0_CTL =  _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_CBUCK_VSEL, config->coreBuckVoltSel) |
1220                               _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_CBUCK_MODE, config->coreBuckMode) |
1221                               _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_VSEL, config->sdrVoltSel) |
1222                               _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_CBUCK_DPSLP_VSEL, config->coreBuckDpSlpVoltSel) |
1223                               _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_CBUCK_DPSLP_MODE, config->coreBuckDpSlpMode) |
1224                               _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_DPSLP_VSEL, config->sdr0DpSlpVoltSel) |
1225                               _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_ALLOW_BYPASS, ((config->sdr0Allowbypass) ? 1UL : 0UL));
1226 
1227             if(IsVoltageChangePossible())
1228             {
1229                 SetMemoryVoltageTrims((cy_en_syspm_sdr_voltage_t)config->sdrVoltSel);
1230             }
1231         }
1232         else
1233         {
1234             SRSS_PWR_SDR0_CTL =  _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_CBUCK_VSEL, config->coreBuckVoltSel) |
1235                               _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_CBUCK_MODE, config->coreBuckMode) |
1236                               _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_VSEL, config->sdrVoltSel) |
1237                               _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_CBUCK_DPSLP_VSEL, config->coreBuckDpSlpVoltSel) |
1238                               _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_CBUCK_DPSLP_MODE, config->coreBuckDpSlpMode) |
1239                               _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_DPSLP_VSEL, config->sdr0DpSlpVoltSel) |
1240                               _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_ALLOW_BYPASS, ((config->sdr0Allowbypass) ? 1UL : 0UL));
1241         }
1242     }
1243     else
1244     {
1245         SRSS_PWR_SDR1_CTL =  _VAL2FLD(SRSS_PWR_SDR1_CTL_SDR1_CBUCK_VSEL, config->coreBuckVoltSel) |
1246                              _VAL2FLD(SRSS_PWR_SDR1_CTL_SDR1_CBUCK_MODE, config->coreBuckMode) |
1247                              _VAL2FLD(SRSS_PWR_SDR1_CTL_SDR1_VSEL, config->sdrVoltSel) |
1248                              _VAL2FLD(SRSS_PWR_SDR1_CTL_SDR1_HW_SEL, ((config->sdr1HwControl) ? 1UL : 0UL)) |
1249                              _VAL2FLD(SRSS_PWR_SDR1_CTL_SDR1_ENABLE, ((config->sdr1Enable) ? 1UL : 0UL));
1250     }
1251 
1252     CY_SYSPM_CORE_BUCK_PAUSE_ENABLE(0U);
1253 }
1254 
Cy_SysPm_SdrSetVoltage(cy_en_syspm_sdr_t sdr,cy_en_syspm_sdr_voltage_t voltage)1255 void Cy_SysPm_SdrSetVoltage(cy_en_syspm_sdr_t sdr, cy_en_syspm_sdr_voltage_t voltage)
1256 {
1257     CY_ASSERT_L2(CY_SYSPM_IS_SDR_NUM_VALID(sdr));
1258     CY_ASSERT_L2(CY_SYSPM_IS_SDR_VOLTAGE_VALID(voltage));
1259 
1260     CY_SYSPM_CORE_BUCK_PAUSE_ENABLE(1U);
1261 
1262     if(sdr == CY_SYSPM_SDR_0)
1263     {
1264         cy_en_syspm_sdr_voltage_t currSdr0Volt = Cy_SysPm_SdrGetVoltage(CY_SYSPM_SDR_0);
1265         /* High to Low voltage --> Set TRIM's first , Set Voltage next */
1266         if(voltage < currSdr0Volt)
1267         {
1268             if(IsVoltageChangePossible())
1269             {
1270                 SetMemoryVoltageTrims(voltage);
1271             }
1272 
1273             CY_REG32_CLR_SET(SRSS_PWR_SDR0_CTL, SRSS_PWR_SDR0_CTL_SDR0_VSEL, voltage);
1274         }
1275         /* Low to High voltage --> Set Voltage first , Set TRIM's next */
1276         else if (voltage > currSdr0Volt)
1277         {
1278             CY_REG32_CLR_SET(SRSS_PWR_SDR0_CTL, SRSS_PWR_SDR0_CTL_SDR0_VSEL, voltage);
1279 
1280             if(IsVoltageChangePossible())
1281             {
1282                 SetMemoryVoltageTrims(voltage);
1283             }
1284         }
1285         else
1286         {
1287         }
1288     }
1289     else
1290     {
1291         CY_REG32_CLR_SET(SRSS_PWR_SDR1_CTL, SRSS_PWR_SDR1_CTL_SDR1_VSEL, voltage);
1292     }
1293 
1294     CY_SYSPM_CORE_BUCK_PAUSE_ENABLE(0U);
1295 }
1296 #endif /* ENABLE_MEM_VOLTAGE_TRIMS */
1297 
Cy_SysPm_SdrGetVoltage(cy_en_syspm_sdr_t sdr)1298 cy_en_syspm_sdr_voltage_t Cy_SysPm_SdrGetVoltage(cy_en_syspm_sdr_t sdr)
1299 {
1300     CY_ASSERT_L2(CY_SYSPM_IS_SDR_NUM_VALID(sdr));
1301 
1302     if(sdr == CY_SYSPM_SDR_0)
1303     {
1304         CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to cy_en_syspm_sdr_voltage_t enum.');
1305         return (cy_en_syspm_sdr_voltage_t)(_FLD2VAL(SRSS_PWR_SDR0_CTL_SDR0_VSEL, SRSS_PWR_SDR0_CTL));
1306     }
1307     else
1308     {
1309         CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to cy_en_syspm_sdr_voltage_t enum.');
1310         return (cy_en_syspm_sdr_voltage_t)(_FLD2VAL(SRSS_PWR_SDR1_CTL_SDR1_VSEL, SRSS_PWR_SDR1_CTL));
1311     }
1312 }
1313 
Cy_SysPm_SdrEnable(cy_en_syspm_sdr_t sdr,bool enable)1314 void Cy_SysPm_SdrEnable(cy_en_syspm_sdr_t sdr, bool enable)
1315 {
1316     CY_ASSERT_L2(CY_SYSPM_IS_SDR_NUM_VALID(sdr));
1317 
1318     if(sdr == CY_SYSPM_SDR_1)
1319     {
1320         CY_REG32_CLR_SET(SRSS_PWR_SDR1_CTL, SRSS_PWR_SDR1_CTL_SDR1_ENABLE, ((enable) ? 1UL : 0UL));
1321     }
1322 }
1323 
Cy_SysPm_IsSdrEnabled(cy_en_syspm_sdr_t sdr)1324 bool Cy_SysPm_IsSdrEnabled(cy_en_syspm_sdr_t sdr)
1325 {
1326     CY_ASSERT_L2(CY_SYSPM_IS_SDR_NUM_VALID(sdr));
1327     if(sdr == CY_SYSPM_SDR_0)
1328     {
1329         return (_FLD2BOOL(SRSS_PWR_SDR0_CTL_SDR0_ALLOW_BYPASS, SRSS_PWR_SDR0_CTL)? false : true);
1330     }
1331     else
1332     {
1333         return (_FLD2BOOL(SRSS_PWR_SDR1_CTL_SDR1_ENABLE, SRSS_PWR_SDR1_CTL)? true : false);
1334     }
1335 }
1336 
Cy_SysPm_HvLdoConfigure(cy_stc_syspm_hvldo_params_t * config)1337 void Cy_SysPm_HvLdoConfigure(cy_stc_syspm_hvldo_params_t *config)
1338 {
1339     CY_ASSERT_L2(CY_SYSPM_IS_HVLDO_VOLTAGE_VALID(config->voltageSel));
1340 
1341     SRSS_PWR_HVLDO0_CTL = _VAL2FLD(SRSS_PWR_HVLDO0_CTL_HVLDO0_VSEL, config->voltageSel) |
1342                           _VAL2FLD(SRSS_PWR_HVLDO0_CTL_HVLDO0_HW_SEL, ((config->hwSel) ? 1UL : 0UL)) |
1343                           _VAL2FLD(SRSS_PWR_HVLDO0_CTL_HVLDO0_ENABLE, ((config->hvldoEnable) ? 1UL : 0UL));
1344 }
1345 
Cy_SysPm_HvLdoEnable(bool enable)1346 void Cy_SysPm_HvLdoEnable(bool enable)
1347 {
1348     CY_REG32_CLR_SET(SRSS_PWR_HVLDO0_CTL, SRSS_PWR_HVLDO0_CTL_HVLDO0_ENABLE, ((enable) ? 1UL : 0UL));
1349 }
1350 
Cy_SysPm_IsHvLdoEnabled(void)1351 bool Cy_SysPm_IsHvLdoEnabled(void)
1352 {
1353     return (_FLD2BOOL(SRSS_PWR_HVLDO0_CTL_HVLDO0_ENABLE, SRSS_PWR_HVLDO0_CTL)? true : false);
1354 }
1355 
Cy_SysPm_HvLdoSetVoltage(cy_en_syspm_hvldo_voltage_t voltage)1356 void Cy_SysPm_HvLdoSetVoltage(cy_en_syspm_hvldo_voltage_t voltage)
1357 {
1358     CY_ASSERT_L2(CY_SYSPM_IS_HVLDO_VOLTAGE_VALID(voltage));
1359 
1360     CY_REG32_CLR_SET(SRSS_PWR_HVLDO0_CTL, SRSS_PWR_HVLDO0_CTL_HVLDO0_VSEL, voltage);
1361 }
1362 
Cy_SysPm_HvLdoGetVoltage(void)1363 cy_en_syspm_hvldo_voltage_t Cy_SysPm_HvLdoGetVoltage(void)
1364 {
1365     CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to cy_en_syspm_hvldo_voltage_t enum.');
1366     return (cy_en_syspm_hvldo_voltage_t)(_FLD2VAL(SRSS_PWR_HVLDO0_CTL_HVLDO0_VSEL, SRSS_PWR_HVLDO0_CTL));
1367 }
1368 
1369 
Cy_SysPm_LdoExtraRequesterConfig(cy_stc_syspm_extraReq_params_t * extraReqConfig)1370 cy_en_syspm_status_t Cy_SysPm_LdoExtraRequesterConfig(cy_stc_syspm_extraReq_params_t *extraReqConfig)
1371 {
1372     cy_en_syspm_status_t retVal = CY_SYSPM_FAIL;
1373 
1374     CY_ASSERT_L2(CY_SYSPM_IS_CORE_BUCK_VOLTAGE_VALID(extraReqConfig->coreBuckVoltSel));
1375     CY_ASSERT_L2(CY_SYSPM_IS_CORE_BUCK_VOLTAGE_VALID(extraReqConfig->sdr0Config->coreBuckVoltSel));
1376     CY_ASSERT_L2(CY_SYSPM_IS_CORE_BUCK_MODE_VALID(extraReqConfig->sdr0Config->coreBuckMode));
1377     CY_ASSERT_L2(CY_SYSPM_IS_SDR_VOLTAGE_VALID(extraReqConfig->sdr0Config->sdrVoltSel));
1378     CY_ASSERT_L2(CY_SYSPM_IS_CORE_BUCK_VOLTAGE_VALID(extraReqConfig->sdr1Config->coreBuckVoltSel));
1379     CY_ASSERT_L2(CY_SYSPM_IS_CORE_BUCK_MODE_VALID(extraReqConfig->sdr1Config->coreBuckMode));
1380     CY_ASSERT_L2(CY_SYSPM_IS_SDR_VOLTAGE_VALID(extraReqConfig->sdr1Config->sdrVoltSel));
1381 
1382 
1383     /* Extra Requester Sequence */
1384 
1385     /* 1. Prevent dynamic setting changes by writing PWR_CBUCK_CTL.CBUCK_PAUSE=1. */
1386     CY_SYSPM_CORE_BUCK_PAUSE_ENABLE(1U);
1387 
1388     /* 2. Enable PWR_CBUCK_CTL.CBUCK_COPY_SETTINGS */
1389     CY_SYSPM_CORE_BUCK_COPY_SETTINGS_ENABLE(1U);
1390 
1391     /* 3. If the intention is to request higher operational state
1392      * (eg. higher CBUCK target voltage or higher CBUCK mode), load  the
1393      * desired settings into the extra requester
1394      * (PWR_CBUCK_CTL.CBUCK_VSEL/MODE). Do not reduce any of the
1395      * settings, because the intention is that the eventual
1396      * composite CBUCK mode matches the extra requester
1397      */
1398     (void)Cy_SysPm_CoreBuckSetVoltage((cy_en_syspm_core_buck_voltage_t)extraReqConfig->coreBuckVoltSel);
1399 
1400     (void)Cy_SysPm_CoreBuckSetMode((cy_en_syspm_core_buck_mode_t)extraReqConfig->coreBuckMode);
1401 
1402     /* 4. Override the normal harmonization logic which internally selects the
1403      * scratch profile using PWR_CBUCK_CTL.CBUCK_OVERRIDE).
1404      */
1405     CY_SYSPM_CORE_BUCK_OVERRRIDE_ENABLE(1U);
1406 
1407     /* 5. Wait until the status register indicates the transition is completed.
1408      * See PWR_CBUCK_STATUS.PMU_DONE.
1409      */
1410     retVal = Cy_SysPm_CoreBuckStatus();
1411 
1412     if(retVal == CY_SYSPM_SUCCESS)
1413     {
1414         /* 6. Update the desired SDR requester.  This is safe to do, because it is
1415          * not the selected profile and there is no transition in progress, so it
1416          * will not have any effect on a CBUCK profile.
1417          */
1418 
1419         SRSS_PWR_SDR0_CTL =  _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_CBUCK_VSEL, extraReqConfig->sdr0Config->coreBuckVoltSel) |
1420                  _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_CBUCK_MODE, extraReqConfig->sdr0Config->coreBuckMode) |
1421                  _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_VSEL, extraReqConfig->sdr0Config->sdrVoltSel) |
1422                  _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_ALLOW_BYPASS, ((extraReqConfig->sdr0Config->sdr0Allowbypass) ? 1UL : 0UL));
1423 
1424         SRSS_PWR_SDR1_CTL =  _VAL2FLD(SRSS_PWR_SDR1_CTL_SDR1_CBUCK_VSEL, extraReqConfig->sdr1Config->coreBuckVoltSel) |
1425                  _VAL2FLD(SRSS_PWR_SDR1_CTL_SDR1_CBUCK_MODE, extraReqConfig->sdr1Config->coreBuckMode) |
1426                  _VAL2FLD(SRSS_PWR_SDR1_CTL_SDR1_VSEL, extraReqConfig->sdr1Config->sdrVoltSel) |
1427                  _VAL2FLD(SRSS_PWR_SDR1_CTL_SDR1_HW_SEL, ((extraReqConfig->sdr1Config->sdr1HwControl) ? 1UL : 0UL)) |
1428                  _VAL2FLD(SRSS_PWR_SDR1_CTL_SDR1_ENABLE, ((extraReqConfig->sdr1Config->sdr1Enable) ? 1UL : 0UL));
1429 
1430     }
1431 
1432     /* 7. Remove overrides by clearing CBUCK_OVERRIDE and CBUCK_PAUSE */
1433     CY_SYSPM_CORE_BUCK_OVERRRIDE_ENABLE(0U);
1434     CY_SYSPM_CORE_BUCK_PAUSE_ENABLE(0U);
1435 
1436     /* 8. Wait until the status register indicates the transition is
1437      * completed. See PWR_CBUCK_STATUS.PMU_DONE.
1438      */
1439     retVal = Cy_SysPm_CoreBuckStatus();
1440 
1441     return retVal;
1442 }
1443 
1444 
Cy_SysPm_RegisterCallback(cy_stc_syspm_callback_t * handler)1445 bool Cy_SysPm_RegisterCallback(cy_stc_syspm_callback_t* handler)
1446 {
1447     bool retVal = false;
1448 
1449     /* Verify the input parameters. */
1450     if ((handler != NULL) && (handler->callbackParams != NULL) && (handler->callback != NULL))
1451     {
1452         uint32_t callbackRootIdx = (uint32_t) handler->type;
1453 
1454         /* If the callback list is not empty. */
1455         if (pmCallbackRoot[callbackRootIdx] != NULL)
1456         {
1457             cy_stc_syspm_callback_t* curCallback = pmCallbackRoot[callbackRootIdx];
1458             cy_stc_syspm_callback_t* insertPos  = curCallback;
1459 
1460             /* Find the callback after which the new callback is to be
1461              * inserted. Ensure the given callback has not been registered.
1462              */
1463             while ((NULL != curCallback->nextItm) && (curCallback != handler))
1464             {
1465                 curCallback = curCallback->nextItm;
1466                 /* Callbacks with the same order value are stored in the order
1467                  * they are registered.
1468                  */
1469                 if (curCallback->order <= handler->order)
1470                 {
1471                     insertPos = curCallback;
1472                 }
1473             }
1474             /* If the callback has not been registered. */
1475             if (curCallback != handler)
1476             {
1477                 /* If the callback is to be inserted at the beginning of the list. */
1478                 if ((insertPos->prevItm == NULL) && (handler->order < insertPos->order))
1479                 {
1480                     handler->nextItm = insertPos;
1481                     handler->prevItm = NULL;
1482                     handler->nextItm->prevItm = handler;
1483                     pmCallbackRoot[callbackRootIdx] = handler;
1484                 }
1485                 else
1486                 {
1487                     handler->nextItm = insertPos->nextItm;
1488                     handler->prevItm = insertPos;
1489 
1490                     /* If the callback is not inserted at the end of the list. */
1491                     if (handler->nextItm != NULL)
1492                     {
1493                         handler->nextItm->prevItm = handler;
1494                     }
1495                     insertPos->nextItm = handler;
1496                 }
1497                 retVal = true;
1498             }
1499         }
1500         else
1501         {
1502             /* The callback list is empty. */
1503             pmCallbackRoot[callbackRootIdx] = handler;
1504             handler->nextItm = NULL;
1505             handler->prevItm = NULL;
1506             retVal = true;
1507         }
1508     }
1509     return retVal;
1510 }
1511 
Cy_SysPm_UnregisterCallback(cy_stc_syspm_callback_t const * handler)1512 bool Cy_SysPm_UnregisterCallback(cy_stc_syspm_callback_t const *handler)
1513 {
1514     bool retVal = false;
1515 
1516     if (handler != NULL)
1517     {
1518         uint32_t callbackRootIdx = (uint32_t) handler->type;
1519         cy_stc_syspm_callback_t* curCallback = pmCallbackRoot[callbackRootIdx];
1520 
1521         /* Search requested callback item in the linked list */
1522         while (curCallback != NULL)
1523         {
1524             /* Requested callback is found */
1525             if (curCallback == handler)
1526             {
1527                 retVal = true;
1528                 break;
1529             }
1530 
1531             /* Go to next callback item in the linked list */
1532             curCallback = curCallback->nextItm;
1533         }
1534 
1535         if (retVal)
1536         {
1537             /* Requested callback is first in the list */
1538             if (pmCallbackRoot[callbackRootIdx] == handler)
1539             {
1540                 /* Check whether this the only callback registered */
1541                 if (pmCallbackRoot[callbackRootIdx]->nextItm != NULL)
1542                 {
1543                     pmCallbackRoot[callbackRootIdx] = pmCallbackRoot[callbackRootIdx]->nextItm;
1544                     pmCallbackRoot[callbackRootIdx]->prevItm = NULL;
1545                 }
1546                 else
1547                 {
1548                     /* We had only one callback */
1549                     pmCallbackRoot[callbackRootIdx] = NULL;
1550                 }
1551             }
1552             else
1553             {
1554                 /* Update links of related to unregistered callback items */
1555                 curCallback->prevItm->nextItm = curCallback->nextItm;
1556 
1557                 if (curCallback->nextItm != NULL)
1558                 {
1559                     curCallback->nextItm->prevItm = curCallback->prevItm;
1560                 }
1561             }
1562         }
1563     }
1564 
1565     return retVal;
1566 }
1567 
Cy_SysPm_ExecuteCallback(cy_en_syspm_callback_type_t type,cy_en_syspm_callback_mode_t mode)1568 cy_en_syspm_status_t Cy_SysPm_ExecuteCallback(cy_en_syspm_callback_type_t type, cy_en_syspm_callback_mode_t mode)
1569 {
1570     CY_ASSERT_L3(CY_SYSPM_IS_CALLBACK_TYPE_VALID(type));
1571     CY_ASSERT_L3(CY_SYSPM_IS_CALLBACK_MODE_VALID(mode));
1572 
1573     static cy_stc_syspm_callback_t* lastExecutedCallback = NULL;
1574     cy_en_syspm_status_t retVal = CY_SYSPM_SUCCESS;
1575     cy_stc_syspm_callback_t* curCallback = pmCallbackRoot[(uint32_t) type];
1576     cy_stc_syspm_callback_params_t curParams;
1577 
1578     if ((mode == CY_SYSPM_BEFORE_TRANSITION) || (mode == CY_SYSPM_CHECK_READY))
1579     {
1580         /* Execute registered callbacks with order from first registered to the
1581         *  last registered. Stop executing if CY_SYSPM_FAIL was returned in
1582         *  CY_SYSPM_CHECK_READY mode
1583         */
1584         while ((curCallback != NULL) && ((retVal != CY_SYSPM_FAIL) || (mode != CY_SYSPM_CHECK_READY)))
1585         {
1586             /* The modes defined in the .skipMode element are not executed */
1587             if (0UL == ((uint32_t) mode & curCallback->skipMode))
1588             {
1589                 /* Update elements for local callback parameter values */
1590                 curParams.base = curCallback->callbackParams->base;
1591                 curParams.context = curCallback->callbackParams->context;
1592 
1593                 retVal = curCallback->callback(&curParams, mode);
1594 
1595                 /* Update callback pointer with value of executed callback.
1596                 * Such update is required to execute further callbacks in
1597                 * backward order after exit from LP mode or to undo
1598                 * configuration after callback returned fail: from last called
1599                 * to first registered.
1600                 */
1601                 lastExecutedCallback = curCallback;
1602             }
1603             curCallback = curCallback->nextItm;
1604         }
1605 
1606         if (mode == CY_SYSPM_CHECK_READY)
1607         {
1608             /* Update the pointer to  the failed callback with the result of the callback execution.
1609             *  If the callback fails, the value of the pointer will be updated
1610             *  with the address of the callback which returned CY_SYSPM_FAIL, else,
1611             *  it will be updated with NULL.
1612             */
1613             if(retVal == CY_SYSPM_FAIL)
1614             {
1615                 failedCallback[(uint32_t) type] = lastExecutedCallback;
1616             }
1617             else
1618             {
1619                 failedCallback[(uint32_t) type] = NULL;
1620             }
1621         }
1622     }
1623     else
1624     {
1625         /* Execute registered callbacks with order from lastCallback or last
1626         * executed to the first registered callback. Such a flow is required if
1627         * a previous callback function returned CY_SYSPM_FAIL or a previous
1628         * callback mode was CY_SYSPM_BEFORE_TRANSITION. Such an order is
1629         * required to undo configurations in correct backward order.
1630         */
1631         if (mode != CY_SYSPM_CHECK_FAIL)
1632         {
1633             while (curCallback->nextItm != NULL)
1634             {
1635                 curCallback = curCallback->nextItm;
1636             }
1637         }
1638         else
1639         {
1640             /* Skip last executed callback that returns CY_SYSPM_FAIL, as this
1641             *  callback already knows that it failed.
1642             */
1643             curCallback = lastExecutedCallback;
1644 
1645             if (curCallback != NULL)
1646             {
1647                 curCallback = curCallback->prevItm;
1648             }
1649         }
1650 
1651         /* Execute callback functions with required type and mode */
1652         while (curCallback != NULL)
1653         {
1654             /* The modes defined in the .skipMode element are not executed */
1655             if (0UL == ((uint32_t) mode & curCallback->skipMode))
1656             {
1657                 /* Update elements for local callback parameter values */
1658                 curParams.base = curCallback->callbackParams->base;
1659                 curParams.context = curCallback->callbackParams->context;
1660 
1661                 retVal = curCallback->callback(&curParams, mode);
1662             }
1663             curCallback = curCallback->prevItm;
1664         }
1665     }
1666 
1667     return retVal;
1668 }
1669 
Cy_SysPm_GetFailedCallback(cy_en_syspm_callback_type_t type)1670 cy_stc_syspm_callback_t* Cy_SysPm_GetFailedCallback(cy_en_syspm_callback_type_t type)
1671 {
1672     return failedCallback[(uint32_t) type];
1673 }
1674 
Cy_SysPm_IoUnfreeze(void)1675 void Cy_SysPm_IoUnfreeze(void)
1676 {
1677     uint32_t interruptState;
1678     interruptState = Cy_SysLib_EnterCriticalSection();
1679 
1680     /* Preserve the last reset reason and wakeup polarity. Then, unfreeze I/O:
1681      * write PWR_HIBERNATE.FREEZE=0, .UNLOCK=0x3A, .HIBERANTE=0
1682      */
1683     SRSS_PWR_HIBERNATE = (SRSS_PWR_HIBERNATE & HIBERNATE_RETAIN_STATUS_MASK) | HIBERNATE_UNLOCK_VAL;
1684 
1685     /* Lock the Hibernate mode:
1686     * write PWR_HIBERNATE.HIBERNATE=0, UNLOCK=0x00, HIBERANTE=0
1687     */
1688     SRSS_PWR_HIBERNATE &= HIBERNATE_RETAIN_STATUS_MASK;
1689 
1690     /* Read register to make sure it is settled */
1691     (void) SRSS_PWR_HIBERNATE;
1692 
1693     Cy_SysLib_ExitCriticalSection(interruptState);
1694 }
1695 
Cy_SysPm_IoIsFrozen(void)1696 bool Cy_SysPm_IoIsFrozen(void)
1697 {
1698     return (0U != _FLD2VAL(SRSS_PWR_HIBERNATE_FREEZE, SRSS_PWR_HIBERNATE));
1699 }
1700 
Cy_SysPm_DeepSleepIoUnfreeze(void)1701 void Cy_SysPm_DeepSleepIoUnfreeze(void)
1702 {
1703     uint32_t interruptState;
1704     interruptState = Cy_SysLib_EnterCriticalSection();
1705 
1706     /* Unfreeze IO's which are frozen during DEEPSLEEP-RAM/OFF
1707     * Entry
1708     */
1709     SRSS_PWR_CTL2 |= SRSS_PWR_CTL2_FREEZE_DPSLP_Msk;
1710 
1711     Cy_SysLib_ExitCriticalSection(interruptState);
1712 }
1713 
Cy_SysPm_DeepSleepIoIsFrozen(void)1714 bool Cy_SysPm_DeepSleepIoIsFrozen(void)
1715 {
1716     return (0U != _FLD2VAL(SRSS_PWR_CTL2_FREEZE_DPSLP, SRSS_PWR_CTL2));
1717 }
1718 
1719 
Cy_SysPm_CpuSendWakeupEvent(void)1720 void Cy_SysPm_CpuSendWakeupEvent(void)
1721 {
1722     __SEV();
1723 }
1724 
Cy_SysPm_IsLpmReady(void)1725 bool Cy_SysPm_IsLpmReady(void)
1726 {
1727     return (_FLD2BOOL(SRSS_PWR_CTL_LPM_READY, SRSS_PWR_CTL)? true : false);
1728 }
1729 
Cy_SysPm_BackupSetSupply(cy_en_syspm_vddbackup_control_t vddBackControl)1730 void Cy_SysPm_BackupSetSupply(cy_en_syspm_vddbackup_control_t vddBackControl)
1731 {
1732     CY_ASSERT_L3(CY_SYSPM_IS_VDDBACKUP_VALID(vddBackControl));
1733 
1734     BACKUP_CTL = _CLR_SET_FLD32U((BACKUP_CTL), BACKUP_CTL_VDDBAK_CTL, (uint32_t) vddBackControl);
1735 }
1736 
1737 
Cy_SysPm_BackupGetSupply(void)1738 cy_en_syspm_vddbackup_control_t Cy_SysPm_BackupGetSupply(void)
1739 {
1740     uint32_t retVal;
1741     retVal = _FLD2VAL(BACKUP_CTL_VDDBAK_CTL, BACKUP_CTL);
1742 
1743     return ((cy_en_syspm_vddbackup_control_t) retVal);
1744 }
1745 
1746 
Cy_SysPm_BackupEnableVoltageMeasurement(void)1747 void Cy_SysPm_BackupEnableVoltageMeasurement(void)
1748 {
1749     BACKUP_CTL |= BACKUP_CTL_VBACKUP_MEAS_Msk;
1750 }
1751 
1752 
Cy_SysPm_BackupDisableVoltageMeasurement(void)1753 void Cy_SysPm_BackupDisableVoltageMeasurement(void)
1754 {
1755     BACKUP_CTL &= ((uint32_t) ~BACKUP_CTL_VBACKUP_MEAS_Msk);
1756 }
1757 
1758 
Cy_SysPm_BackupSuperCapCharge(cy_en_syspm_sc_charge_key_t key)1759 void Cy_SysPm_BackupSuperCapCharge(cy_en_syspm_sc_charge_key_t key)
1760 {
1761     CY_ASSERT_L3(CY_SYSPM_IS_SC_CHARGE_KEY_VALID(key));
1762 
1763     if(key == CY_SYSPM_SC_CHARGE_ENABLE)
1764     {
1765         BACKUP_CTL = _CLR_SET_FLD32U((BACKUP_CTL), BACKUP_CTL_EN_CHARGE_KEY, (uint32_t) CY_SYSPM_SC_CHARGE_ENABLE);
1766     }
1767     else
1768     {
1769         BACKUP_CTL &= ((uint32_t) ~BACKUP_CTL_EN_CHARGE_KEY_Msk);
1770     }
1771 }
1772 
Cy_SysPm_BackupWordStore(uint32_t wordIndex,uint32_t * wordSrcPointer,uint32_t wordSize)1773 void Cy_SysPm_BackupWordStore(uint32_t wordIndex, uint32_t *wordSrcPointer, uint32_t wordSize)
1774 {
1775     CY_ASSERT_L3(CY_SYSPM_IS_WORD_INDEX_VALID(wordIndex));
1776     CY_ASSERT_L3(CY_SYSPM_IS_WORD_SIZE_VALID(wordSize + wordIndex));
1777 
1778     while(wordSize != 0UL)
1779     {
1780         if(wordIndex < CY_SRSS_BACKUP_BREG1_START_POS)
1781         {
1782             BACKUP_BREG_SET0[wordIndex] = *wordSrcPointer;
1783         }
1784         else if(wordIndex < CY_SRSS_BACKUP_BREG2_START_POS)
1785         {
1786             BACKUP_BREG_SET1[wordIndex - CY_SRSS_BACKUP_BREG1_START_POS] = *wordSrcPointer;
1787         }
1788         else if(wordIndex < CY_SRSS_BACKUP_BREG3_START_POS)
1789         {
1790             BACKUP_BREG_SET2[wordIndex - CY_SRSS_BACKUP_BREG2_START_POS] = *wordSrcPointer;
1791         }
1792         else
1793         {
1794             BACKUP_BREG_SET3[wordIndex - CY_SRSS_BACKUP_BREG3_START_POS] = *wordSrcPointer;
1795         }
1796 
1797         wordIndex++;
1798         wordSrcPointer++;
1799         wordSize--;
1800     }
1801 }
1802 
Cy_SysPm_BackupWordReStore(uint32_t wordIndex,uint32_t * wordDstPointer,uint32_t wordSize)1803 void Cy_SysPm_BackupWordReStore(uint32_t wordIndex, uint32_t *wordDstPointer, uint32_t wordSize)
1804 {
1805     CY_ASSERT_L3(CY_SYSPM_IS_WORD_INDEX_VALID(wordIndex));
1806     CY_ASSERT_L3(CY_SYSPM_IS_WORD_SIZE_VALID(wordSize + wordIndex));
1807 
1808     while(wordSize != 0UL)
1809     {
1810 
1811         if(wordIndex < CY_SRSS_BACKUP_BREG1_START_POS)
1812         {
1813             *wordDstPointer = BACKUP_BREG_SET0[wordIndex];
1814         }
1815         else if(wordIndex < CY_SRSS_BACKUP_BREG2_START_POS)
1816         {
1817             *wordDstPointer = BACKUP_BREG_SET1[wordIndex - CY_SRSS_BACKUP_BREG1_START_POS];
1818         }
1819         else if(wordIndex < CY_SRSS_BACKUP_BREG3_START_POS)
1820         {
1821             *wordDstPointer = BACKUP_BREG_SET2[wordIndex - CY_SRSS_BACKUP_BREG2_START_POS];
1822         }
1823         else
1824         {
1825             *wordDstPointer = BACKUP_BREG_SET3[wordIndex - CY_SRSS_BACKUP_BREG3_START_POS];
1826         }
1827 
1828         wordIndex++;
1829         wordDstPointer++;
1830         wordSize--;
1831     }
1832 }
1833 
1834 /* This API is an inline version of Cy_SysPm_SetSRAMMacroPwrMode */
Cy_SysPm_SetSRAMMacroPwrModeInline(cy_en_syspm_sram_index_t sramNum,uint32_t sramMacroNum,cy_en_syspm_sram_pwr_mode_t sramPwrMode)1835 __STATIC_FORCEINLINE cy_en_syspm_status_t Cy_SysPm_SetSRAMMacroPwrModeInline(cy_en_syspm_sram_index_t sramNum, uint32_t sramMacroNum, cy_en_syspm_sram_pwr_mode_t sramPwrMode)
1836 {
1837     CY_ASSERT_L3(sramNum == CY_SYSPM_SRAM0_MEMORY);
1838     CY_ASSERT_L3((sramPwrMode == CY_SYSPM_SRAM_PWR_MODE_ON) || (sramPwrMode == CY_SYSPM_SRAM_PWR_MODE_OFF));
1839     CY_ASSERT_L3(sramMacroNum < CY_CPUSS_RAMC0_MACRO_NR);
1840 
1841     CY_UNUSED_PARAM(sramNum);
1842 
1843     /* Unlock PWR MACRO Control */
1844     /* Clear bit 0(CLR0)*/
1845     MXSRAMC_PWR_MACRO_CTL_LOCK = MXSRAMC_PWR_MACRO_CTL_LOCK_CLR0;
1846     /* Clear bit 1(CLR1)*/
1847     MXSRAMC_PWR_MACRO_CTL_LOCK = MXSRAMC_PWR_MACRO_CTL_LOCK_CLR1;
1848 
1849     if(sramPwrMode == CY_SYSPM_SRAM_PWR_MODE_ON)
1850     {
1851         /* Enable the Macro Number */
1852         MXSRAMC_PWR_MACRO_CTL &= ~(0x1UL << (uint32_t)sramMacroNum);
1853     }
1854     else
1855     {
1856         /* Disable the Macro Number */
1857         MXSRAMC_PWR_MACRO_CTL |= (0x1UL << (uint32_t)sramMacroNum);
1858     }
1859     /* Wait for the PWR_DONE status */
1860     while(!_FLD2BOOL(RAMC_STATUS_PWR_DONE, MXSRAMC_STATUS)){}
1861 
1862     /* Lock PWR MACRO Control(Set SET01) */
1863     MXSRAMC_PWR_MACRO_CTL_LOCK = MXSRAMC_PWR_MACRO_CTL_LOCK_SET01;
1864 
1865     return CY_SYSPM_SUCCESS;
1866 }
1867 
Cy_SysPm_SetSRAMMacroPwrMode(cy_en_syspm_sram_index_t sramNum,uint32_t sramMacroNum,cy_en_syspm_sram_pwr_mode_t sramPwrMode)1868 cy_en_syspm_status_t Cy_SysPm_SetSRAMMacroPwrMode(cy_en_syspm_sram_index_t sramNum, uint32_t sramMacroNum, cy_en_syspm_sram_pwr_mode_t sramPwrMode)
1869 {
1870     return Cy_SysPm_SetSRAMMacroPwrModeInline(sramNum, sramMacroNum, sramPwrMode);
1871 }
1872 
Cy_SysPm_GetSRAMMacroPwrMode(cy_en_syspm_sram_index_t sramNum,uint32_t sramMacroNum)1873 cy_en_syspm_sram_pwr_mode_t Cy_SysPm_GetSRAMMacroPwrMode(cy_en_syspm_sram_index_t sramNum, uint32_t sramMacroNum)
1874 {
1875     cy_en_syspm_sram_pwr_mode_t value;
1876 
1877     CY_ASSERT_L3(sramNum == CY_SYSPM_SRAM0_MEMORY);
1878     CY_ASSERT_L3(sramMacroNum < CY_CPUSS_RAMC0_MACRO_NR);
1879 
1880     CY_UNUSED_PARAM(sramNum);
1881 
1882     /* Unlock PWR MACRO Control */
1883     /* Clear bit 0(CLR0)*/
1884     MXSRAMC_PWR_MACRO_CTL_LOCK = MXSRAMC_PWR_MACRO_CTL_LOCK_CLR0;
1885     /* Clear bit 1(CLR1)*/
1886     MXSRAMC_PWR_MACRO_CTL_LOCK = MXSRAMC_PWR_MACRO_CTL_LOCK_CLR1;
1887 
1888     value = ((MXSRAMC_PWR_MACRO_CTL & (0x1UL << (uint32_t)sramMacroNum)) != 0UL) ? CY_SYSPM_SRAM_PWR_MODE_OFF:CY_SYSPM_SRAM_PWR_MODE_ON;
1889 
1890     /* Lock PWR MACRO Control(Set SET01) */
1891     MXSRAMC_PWR_MACRO_CTL_LOCK = MXSRAMC_PWR_MACRO_CTL_LOCK_SET01;
1892 
1893     return value;
1894 
1895 }
1896 
1897 
Cy_SysPm_SetSRAMPwrMode(cy_en_syspm_sram_index_t sramNum,cy_en_syspm_sram_pwr_mode_t sramPwrMode)1898 cy_en_syspm_status_t Cy_SysPm_SetSRAMPwrMode(cy_en_syspm_sram_index_t sramNum, cy_en_syspm_sram_pwr_mode_t sramPwrMode)
1899 {
1900     CY_ASSERT_L3(sramNum == CY_SYSPM_SRAM0_MEMORY);
1901     CY_ASSERT_L3((sramPwrMode == CY_SYSPM_SRAM_PWR_MODE_ON) || (sramPwrMode == CY_SYSPM_SRAM_PWR_MODE_OFF));
1902 
1903     CY_UNUSED_PARAM(sramNum);
1904 
1905     (void)Cy_SysPm_SetSRAMMacroPwrMode(CY_SYSPM_SRAM0_MEMORY, (uint32_t)CY_SYSPM_SRAM0_MACRO_0, sramPwrMode);
1906     (void)Cy_SysPm_SetSRAMMacroPwrMode(CY_SYSPM_SRAM0_MEMORY, (uint32_t)CY_SYSPM_SRAM0_MACRO_1, sramPwrMode);
1907 
1908     return CY_SYSPM_SUCCESS;
1909 }
1910 
1911 /*This reset handler will be implemented as part of HCI ROM app*/
Cy_SysPm_Dsramoff_Entry(void)1912 __WEAK void Cy_SysPm_Dsramoff_Entry(void)
1913 {
1914     while(true) {}
1915 }
1916 
Cy_SysPm_CpuEnterRAMOffDeepSleep(void)1917 cy_en_syspm_status_t Cy_SysPm_CpuEnterRAMOffDeepSleep(void)
1918 {
1919     uint32_t interruptState;
1920     uint32_t cbDeepSleepRootIdx = (uint32_t) Cy_SysPm_GetDeepSleepMode();
1921     cy_en_syspm_status_t retVal = CY_SYSPM_SUCCESS;
1922 
1923     CY_ASSERT_L3(CY_SYSPM_IS_DEEPSLEEP_MODE_VALID(cbDeepSleepRootIdx));
1924 
1925     //Check if LPM is ready
1926     if(!Cy_SysPm_IsLpmReady())
1927     {
1928         retVal = CY_SYSPM_FAIL;
1929     }
1930     else
1931     {
1932         //TBD Check if PDCM Dependencies are set properly
1933 
1934         /* Call the registered callback functions with the CY_SYSPM_CHECK_READY
1935         *  parameter
1936         */
1937         if (pmCallbackRoot[cbDeepSleepRootIdx] != NULL)
1938         {
1939             retVal = Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbDeepSleepRootIdx, CY_SYSPM_CHECK_READY);
1940         }
1941 
1942         /* The CPU can switch into the Deep Sleep power mode only when
1943         *  all executed registered callback functions with the CY_SYSPM_CHECK_READY
1944         *  parameter return CY_SYSPM_SUCCESS
1945         */
1946         if (retVal == CY_SYSPM_SUCCESS)
1947         {
1948             /* Call the registered callback functions with the
1949             * CY_SYSPM_BEFORE_TRANSITION parameter
1950             */
1951             interruptState = Cy_SysLib_EnterCriticalSection();
1952             if (pmCallbackRoot[cbDeepSleepRootIdx] != NULL)
1953             {
1954                 (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbDeepSleepRootIdx, CY_SYSPM_BEFORE_TRANSITION);
1955             }
1956             /* The CPU enters Deep Sleep mode upon execution of WFI/WFE
1957              * use Cy_SysPm_SetDeepSleepMode to set various deepsleep modes TBD*/
1958             SCB_SCR |= SCB_SCR_SLEEPDEEP_Msk;
1959 
1960             /* Disable SRAM Macros to save power */
1961             (void)Cy_SysPm_SetSRAMMacroPwrModeInline(CY_SYSPM_SRAM0_MEMORY, (uint32_t)CY_SYSPM_SRAM0_MACRO_0, CY_SYSPM_SRAM_PWR_MODE_OFF);
1962 
1963             __WFI();
1964 
1965             /* Enable SRAM Macros as DEEPSLEEP_RAM might have failed if we reach this point */
1966             (void)Cy_SysPm_SetSRAMMacroPwrModeInline(CY_SYSPM_SRAM0_MEMORY, (uint32_t)CY_SYSPM_SRAM0_MACRO_0, CY_SYSPM_SRAM_PWR_MODE_ON);
1967 
1968             /* Jump to HCI ROM app Reset handler */
1969             Cy_SysPm_Dsramoff_Entry();
1970 
1971             Cy_SysLib_ExitCriticalSection(interruptState);
1972         }
1973         else
1974         {
1975             /* Execute callback functions with the CY_SYSPM_CHECK_FAIL parameter to
1976             *  undo everything done in the callback with the CY_SYSPM_CHECK_READY
1977             *  parameter
1978             */
1979             if (pmCallbackRoot[cbDeepSleepRootIdx] != NULL)
1980             {
1981                 (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbDeepSleepRootIdx, CY_SYSPM_CHECK_FAIL);
1982             }
1983         }
1984     }
1985     return retVal;
1986 }
1987 
Cy_SysPm_TriggerSoftReset(void)1988 void Cy_SysPm_TriggerSoftReset(void)
1989 {
1990     SRSS_RES_SOFT_CTL = SRSS_RES_SOFT_CTL_TRIGGER_SOFT_Msk;
1991 }
1992 
1993 #ifdef ENABLE_MEM_VOLTAGE_TRIMS
1994 /*******************************************************************************
1995 * Function Name: SetMemoryVoltageTrims
1996 ****************************************************************************//**
1997 *
1998 * This is the internal function that updates the trim values for the
1999 * RAM and ROM. The trim update is done during transition of regulator voltage
2000 * from higher to a lower one.
2001 *
2002 *******************************************************************************/
SetMemoryVoltageTrims(cy_en_syspm_sdr_voltage_t voltage)2003 static void SetMemoryVoltageTrims(cy_en_syspm_sdr_voltage_t voltage)
2004 {
2005     uint32_t ramVoltgeTrim = CPUSS_TRIM_RAM_CTL;
2006     uint32_t romVoltgeTrim = CPUSS_TRIM_ROM_CTL;
2007 
2008     CY_ASSERT_L3(CY_SYSPM_IS_SDR_TRIM_VOLTAGE_VALID(voltage));
2009 
2010     switch(voltage)
2011     {
2012         case CY_SYSPM_SDR_VOLTAGE_0_900V:
2013         {
2014             ramVoltgeTrim = CPUSS_TRIM_RAM_VOLT_0_900;
2015             romVoltgeTrim = CPUSS_TRIM_ROM_VOLT_0_900;
2016         }
2017         break;
2018 
2019         case CY_SYSPM_SDR_VOLTAGE_1_000V:
2020         {
2021             ramVoltgeTrim = CPUSS_TRIM_RAM_VOLT_1_000;
2022             romVoltgeTrim = CPUSS_TRIM_ROM_VOLT_1_000;
2023         }
2024         break;
2025 
2026         case CY_SYSPM_SDR_VOLTAGE_1_100V:
2027         {
2028             ramVoltgeTrim = CPUSS_TRIM_RAM_VOLT_1_100;
2029             romVoltgeTrim = CPUSS_TRIM_ROM_VOLT_1_100;
2030         }
2031         break;
2032 
2033         default:
2034         {
2035             CY_ASSERT_L2(false);
2036         }
2037         break;
2038     }
2039 
2040     CPUSS_TRIM_RAM_CTL = ramVoltgeTrim;
2041     CPUSS_TRIM_ROM_CTL = romVoltgeTrim;
2042 
2043 }
2044 
2045 
2046 /*******************************************************************************
2047 * Function Name: IsVoltageChangePossible
2048 ****************************************************************************//**
2049 *
2050 * The internal function that checks wherever it is possible to change the core
2051 * voltage. The voltage change is possible only when the protection context is
2052 * set to zero (PC = 0), or the device supports modifying registers via syscall.
2053 *
2054 *******************************************************************************/
IsVoltageChangePossible(void)2055 static bool IsVoltageChangePossible(void)
2056 {
2057 
2058     bool retVal = false;
2059 
2060 #if (CY_SYSLIB_GET_SILICON_REV_ID != CY_SYSLIB_20829A0_SILICON_REV)
2061     {
2062         uint32_t trimRamCheckVal = (CPUSS_TRIM_RAM_CTL & CPUSS_TRIM_RAM_CTL_WC_MASK);
2063 
2064         CPUSS_TRIM_RAM_CTL &= ~CPUSS_TRIM_RAM_CTL_WC_MASK;
2065         CPUSS_TRIM_RAM_CTL |= ((~trimRamCheckVal) & CPUSS_TRIM_RAM_CTL_WC_MASK);
2066 
2067         retVal = (trimRamCheckVal != (CPUSS_TRIM_RAM_CTL & CPUSS_TRIM_RAM_CTL_WC_MASK));
2068     }
2069 #endif
2070     return retVal;
2071 }
2072 #endif /* ENABLE_MEM_VOLTAGE_TRIMS */
2073 
2074 #endif
2075 /* [] END OF FILE */
2076