1 /***************************************************************************//**
2 * \file cy_syspm.c
3 * \version 5.150
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 
28 #if defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION == 1)
29 
30 #include "cy_syspm.h"
31 #include "cy_ipc_drv.h"
32 #include "cy_prot.h"
33 
34 #if defined (CY_DEVICE_SECURE)
35 CY_MISRA_DEVIATE_BLOCK_START('MISRA C-2012 Rule 17.2', 4, \
36 'Checked manually. All the recursive cycles are handled properly.')
37 CY_MISRA_DEVIATE_BLOCK_START('MISRA C-2012 Rule 18.6', 3, \
38 'Checked manually. Assignment of Local to global variable does not create any issue.')
39 #endif
40 
41 #if ((CY_CPU_CORTEX_M0P) && (defined(CY_DEVICE_SECURE)))
42     #include "cy_pra_cfg.h"
43 #endif /* #if ((CY_CPU_CORTEX_M0P) && (defined(CY_DEVICE_SECURE))) */
44 
45 /*******************************************************************************
46 *       Internal Functions
47 *******************************************************************************/
48 static void EnterDeepSleepRam(cy_en_syspm_waitfor_t waitFor);
49 
50 #if !((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
51 static void SetReadMarginTrimUlp(void);
52 static void SetReadMarginTrimLp(void);
53 static void SetWriteAssistTrimUlp(void);
54 static void SetWriteAssistTrimLp(void);
55 static bool IsVoltageChangePossible(void);
56 #endif /* !((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
57 
58 
59 /*******************************************************************************
60 *       Internal Defines
61 *******************************************************************************/
62 #ifndef CY_PSOC6ABLE2_REV_0A_SUPPORT_DISABLE
63 
64     /** The internal define for clock divider */
65     #define SYSPM_CLK_DIVIDER         (9U)
66 
67     /* Mask for the fast clock divider value */
68     #define SYSPM_FAST_CLK_DIV_Msk    (0xFF000000UL)
69 
70     /* Position for the fast clock divider value */
71     #define SYSPM_FAST_CLK_DIV_Pos    (24UL)
72 
73     /* Mask for the slow clock divider value */
74     #define SYSPM_SLOW_CLK_DIV_Msk    (0x00FF0000UL)
75 
76     /* Position for the slow clock divider value */
77     #define SYSPM_SLOW_CLK_DIV_Pos    (16UL)
78 
79     /* Mask for both slow and fast mask clock dividers */
80     #define SYSPM_CLK_DIV_MASK        (SYSPM_FAST_CLK_DIV_Msk | SYSPM_SLOW_CLK_DIV_Msk)
81 #endif /* #ifndef CY_PSOC6ABLE2_REV_0A_SUPPORT_DISABLE */
82 
83 
84 #if (CY_CPU_CORTEX_M4)
85     #define CUR_CORE_DP_MASK      (0x01UL << 28u)
86     #define OTHER_CORE_DP_MASK    (0x02UL << 28u)
87 #else
88     #define CUR_CORE_DP_MASK      (0x02UL << 28u)
89     #define OTHER_CORE_DP_MASK    (0x01UL << 28u)
90 #endif
91 
92 #define SYSPM_IPC_STRUCT_ADDR_MASK    (0x0FFFFFFFUL)
93 #define SYSPM_IPC_STRUCT_UDB_DP_MASK  (0x04UL << 28u)
94 
95 /* The define for the current active bus master */
96 #if (CY_CPU_CORTEX_M0P)
97     #define ACTIVE_BUS_MASTER           CPUSS_MS_ID_CM0
98 #else
99     #define ACTIVE_BUS_MASTER           CPUSS_MS_ID_CM4
100 #endif /* (CY_CPU_CORTEX_M0P) */
101 
102 /* Define of MMIO group where UDB is located */
103 #define MMIO_UDB_GROUP_NR              (4U)
104 
105 /* Define of MMIO group where UDB is located */
106 #define MMIO_UDB_SLAVE_NR              (3U)
107 
108 /* The UDB placement on MMIO slave level */
109 #define PERI_UDB_SLAVE_ENABLED         ((uint32_t) 1UL << MMIO_UDB_GROUP_NR)
110 
111 /* The definition for the delay of the LDO after its output
112 * voltage is changed
113 */
114 #define LDO_STABILIZATION_DELAY_US     (9U)
115 
116 /* Define to indicate that a 10 us delay is needed */
117 #define NEED_DELAY                     (0x0U)
118 
119 /* Slow output register */
120 #define CLK_OUTPUT_SLOW_MASK           (0x06U)
121 
122 /* Slow control register */
123 #define TST_DDFT_FAST_CTL_MASK         (62U)
124 
125 /* Load value for the timer to count delay after exiting Deep Sleep */
126 #define IMO_10US_DELAY                 (68U)
127 
128 #if ((CY_CPU_CORTEX_M0P) && (defined(CY_DEVICE_SECURE)))
129     /* Define to indicate that a 10 us delay was done after exiting Deep Sleep */
130     #define DELAY_DONE                 (1U)
131 
132     /* Register address which is used to indicate delay done event */
133     #define DELAY_FLAG_REGISTER_ADDR   (&FLASHC_BIST_STATUS)
134 #else
135     #define DELAY_DONE                 (0xAAAAAAAAU)
136     #define DELAY_FLAG_REGISTER_ADDR   (&FLASHC_BIST_DATA_0)
137 #endif /* ((CY_CPU_CORTEX_M0P) && (defined(CY_DEVICE_SECURE))) */
138 
139 /* Define for transitional 0.95 V for the LDO regulator */
140 #define LDO_OUT_VOLTAGE_0_95V          (0x0BU)
141 
142 /* Define for transitional 1.1 V for the LDO regulator */
143 #define LDO_OUT_VOLTAGE_1_1V           (0x17U)
144 
145 /* Define for transitional 1.15 V for the LDO regulator */
146 #define LDO_OUT_VOLTAGE_1_15V          (0x1BU)
147 
148 /* The definition for the delay of the Buck supply regulator
149 * stabilization after it is configured with enabled Buck output 1 */
150 #define BUCK_INIT_STABILIZATION_US     (900U)
151 
152 /* The definition for the delay of the Buck supply regulator
153 * stabilization after it is configured with enabled Buck
154 * output 2 only
155 */
156 #define BUCK_OUT2_INIT_DELAY_US        (600U)
157 
158 /* The definition for the delay of the Buck regulator after its output
159 * voltage is changed
160 */
161 #define BUCK_OUT2_STABILIZATION_DELAY_US    (200U)
162 
163 /* Define for transitional 0.95 V for buck regulator */
164 #define BUCK_OUT1_VOLTAGE_0_95V             (3U)
165 
166 /* Define for a Buck regulator stabilization delay from 0.9 V to 0.95 V */
167 #define BUCK_OUT1_0_9V_TO_0_95V_DELAY_US    (52U)
168 
169 /* Define for a Buck regulator stabilization delay from 0.95 V to 1.1 V */
170 #define BUCK_OUT1_0_95V_TO_1_1V_DELAY_US    (145U)
171 
172 /* Define for an LDO stabilization delay from 0.9 V to 0.95 V */
173 #define LDO_0_9V_TO_0_95V_DELAY_US          (3U)
174 
175 /* Define for an LDO regulator stabilization delay from 0.95 V to 1.1 V */
176 #define LDO_0_95V_TO_1_1V_DELAY_US          (7U)
177 
178 /* Define for ROM trim in LP mode */
179 #define CPUSS_TRIM_ROM_LP                 (0x00000013U)
180 
181 /* Define for RAM trim in LP mode */
182 #define CPUSS_TRIM_RAM_LP                 (0x00004013U)
183 
184 /* Define for ROM trim in ULP mode   */
185 #define CPUSS_TRIM_ROM_ULP                (0x00000012U)
186 
187 /* Define for trim RAM in ULP mode */
188 #define CPUSS_TRIM_RAM_ULP                (0x00006012U)
189 
190 /* Define for IPC0 notification */
191 #define SYSPM_IPC_NOTIFY_STRUCT0          ((uint32_t) 0x1UL << CY_IPC_INTR_SYSCALL1)
192 
193 /* The define of bit positions of the syscall return status */
194 #define SYSCALL_STATUS_MASK               (0xFF000000U)
195 
196 /* The define for the success return status of the syscall */
197 #define SYSCALL_STATUS_SUCCESS            (0xA0000000U)
198 
199 /* The define for device TO *B Revision ID */
200 #define SYSPM_DEVICE_PSOC6ABLE2_REV_0B    (0x22U)
201 
202 /* The pointer to the Cy_EnterDeepSleep() function in the ROM */
203 #define ROM_ENTER_DEEP_SLEEP_ADDR         (*(uint32_t *) 0x00000D30UL)
204 
205 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
206     #define PM_HIBERNATE_ENTER_HIBERNATE    (0UL)
207     #define PM_HIBERNATE_IO_UNFREEZE        (1UL)
208 #endif /* ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
209 
210 /* The define to call the ROM Cy_EnterDeepSleep() function.
211 * The ROM Cy_EnterDeepSleep() function prepares the system for the Deep Sleep
212 * and restores the system after wakeup from the Deep Sleep. */
213 typedef void (*cy_cb_syspm_deep_sleep_t)(cy_en_syspm_waitfor_t waitFor, bool *wasEventSent);
214 
215 #define EnterDeepSleepSrom(waitFor, wasEventSent) \
216        ((cy_cb_syspm_deep_sleep_t) ROM_ENTER_DEEP_SLEEP_ADDR)((waitFor), &(wasEventSent))
217 
218 /* Mask for the RAM read assist bits */
219 #define CPUSS_TRIM_RAM_CTL_RA_MASK                   ((uint32_t) 0x3U << 8U)
220 
221 /* Mask for the RAM write check bits */
222 #define CPUSS_TRIM_RAM_CTL_WC_MASK                   (0x3UL << 10U)
223 
224 /* The define for SROM opcode to set the flash voltage bit */
225 #define FLASH_VOLTAGE_BIT_ULP_OPCODE                 (0x0C000003U)
226 
227 /* The define for SROM opcode to clear the flash voltage bit */
228 #define FLASH_VOLTAGE_BIT_LP_OPCODE                  (0x0C000001U)
229 
230 /* The define for SROM opcode to set the flash voltage bit */
231 #define FLASH_VOLTAGE_BIT_ULP_PSOC6ABLE2_OPCODE      (0x30000101U)
232 
233 /* The define for SROM to clear the flash voltage bit */
234 #define FLASH_VOLTAGE_BIT_LP_PSOC6ABLE2_OPCODE       (0x30000001U)
235 
236 /* The wait time for transition into the minimum regulator current mode
237 */
238 #define SET_MIN_CURRENT_MODE_DELAY_US        (1U)
239 
240 /* The wait delay time that occurs before the active reference is settled.
241 *  Intermediate delay is used in transition into the normal regulator current
242 *  mode
243 */
244 #define ACT_REF_SETTLE_DELAY_US              (8U)
245 
246 /* The wait delay time that occurs after the active reference is settled.
247 *  Final delay is used in transition into the normal regulator current mode
248 */
249 #define SET_NORMAL_CURRENT_MODE_DELAY_US     (1U)
250 
251 /* The internal define of the tries number in the
252 * Cy_SysPm_SystemSetMinRegulatorCurrent() function
253 */
254 #define WAIT_DELAY_TRYES                (100U)
255 
256 /* The define of retained power mode of the CM4 */
257 #define CM4_PWR_STS_RETAINED            (2UL)
258 
259 /* The define for number of callback roots */
260 #define CALLBACK_ROOT_NR                (5U)
261 
262 /* Mask for checking the CM4 Deep Sleep status */
263 #define CM4_DEEPSLEEP_MASK     (CPUSS_CM4_STATUS_SLEEPING_Msk | CPUSS_CM4_STATUS_SLEEPDEEP_Msk)
264 
265 /* Mask for checking the CM0P Deep Sleep status */
266 #define CM0_DEEPSLEEP_MASK     (CPUSS_CM0_STATUS_SLEEPING_Msk | CPUSS_CM0_STATUS_SLEEPDEEP_Msk)
267 
268 /* The mask to unlock the Hibernate power mode */
269 #define HIBERNATE_UNLOCK_VAL                 ((uint32_t) 0x3Au << SRSS_PWR_HIBERNATE_UNLOCK_Pos)
270 
271 /* The mask to set the Hibernate power mode */
272 #define SET_HIBERNATE_MODE                   ((HIBERNATE_UNLOCK_VAL |\
273                                                SRSS_PWR_HIBERNATE_FREEZE_Msk |\
274                                                SRSS_PWR_HIBERNATE_HIBERNATE_Msk))
275 
276 /* The mask to retain the Hibernate power mode status */
277 #define HIBERNATE_RETAIN_STATUS_MASK         ((SRSS_PWR_HIBERNATE_TOKEN_Msk |\
278                                                SRSS_PWR_HIBERNATE_MASK_HIBALARM_Msk |\
279                                                SRSS_PWR_HIBERNATE_MASK_HIBWDT_Msk |\
280                                                SRSS_PWR_HIBERNATE_POLARITY_HIBPIN_Msk |\
281                                                SRSS_PWR_HIBERNATE_MASK_HIBPIN_Msk))
282 
283 /** The mask for the Hibernate wakeup sources */
284 #define HIBERNATE_WAKEUP_MASK               ((SRSS_PWR_HIBERNATE_MASK_HIBALARM_Msk |\
285                                               SRSS_PWR_HIBERNATE_MASK_HIBWDT_Msk |\
286                                               SRSS_PWR_HIBERNATE_POLARITY_HIBPIN_Msk |\
287                                               SRSS_PWR_HIBERNATE_MASK_HIBPIN_Msk))
288 
289 /** The define to update the token to indicate the transition into Hibernate */
290 #define HIBERNATE_TOKEN                    ((uint32_t) 0x1BU << SRSS_PWR_HIBERNATE_TOKEN_Pos)
291 
292 
293 /* The mask for low power modes the power circuits (POR/BOD, Bandgap reference,
294 *  Reference buffer, Current reference) when active core regulator is LDO
295 */
296 #define PWR_CIRCUITS_SET_LPMODE_LDO_MASK        (SRSS_PWR_CTL_LINREG_LPMODE_Msk | PWR_CIRCUITS_SET_LPMODE_BUCK_MASK)
297 
298 /* The mask for low power modes the power circuits (POR/BOD, Bandgap reference,
299 *  Reference buffer, Current reference) when active core regulator is Buck
300 */
301 #define PWR_CIRCUITS_SET_LPMODE_BUCK_MASK       (SRSS_PWR_CTL_PORBOD_LPMODE_Msk |\
302                                                  SRSS_PWR_CTL_BGREF_LPMODE_Msk |\
303                                                  SRSS_PWR_CTL_VREFBUF_LPMODE_Msk |\
304                                                  SRSS_PWR_CTL_IREF_LPMODE_Msk)
305 
306 /* The wakeup holdoff for the system regulator minimum current mode.
307    Cypress ID DRV2123
308 */
309 #define SRSS_PWR_TRIM_WAKE_LP                   (0x50U)
310 
311 
312 /*******************************************************************************
313 *       Internal Variables
314 *******************************************************************************/
315 
316 /* Array of the callback roots */
317 static cy_stc_syspm_callback_t* pmCallbackRoot[CALLBACK_ROOT_NR] = {NULL, NULL, NULL, NULL, NULL};
318 
319 /* The array of the pointers to failed callback */
320 static cy_stc_syspm_callback_t* failedCallback[CALLBACK_ROOT_NR] = {NULL, NULL, NULL, NULL, NULL};
321 
322 #if (CY_CPU_CORTEX_M4)
323     /* Global boolean variable used to clear the  Event Register of the CM4 core */
324     static bool wasEventSent = false;
325 #endif /* (CY_CPU_CORTEX_M4) */
326 
327 
Cy_SysPm_ReadStatus(void)328 uint32_t Cy_SysPm_ReadStatus(void)
329 {
330     uint32_t pmStatus = 0UL;
331 
332     /* Check whether CM4 is in Deep Sleep mode */
333     if ((CPUSS_CM4_STATUS & CM4_DEEPSLEEP_MASK) == CM4_DEEPSLEEP_MASK)
334     {
335         pmStatus |= CY_SYSPM_STATUS_CM4_DEEPSLEEP;
336     }
337     /* Check whether CM4 is in Sleep mode */
338     else if(0U != _FLD2VAL(CPUSS_CM4_STATUS_SLEEPING, CPUSS_CM4_STATUS))
339     {
340         pmStatus |= CY_SYSPM_STATUS_CM4_SLEEP;
341     }
342     else
343     {
344         pmStatus |= CY_SYSPM_STATUS_CM4_ACTIVE;
345     }
346 
347 #if (__CORTEX_M == 0) || (defined (__CM0P_PRESENT) && (__CM0P_PRESENT == 1))
348     /* Check whether CM0p is in Deep Sleep mode */
349     if ((CPUSS_CM0_STATUS & CM0_DEEPSLEEP_MASK) == CM0_DEEPSLEEP_MASK)
350     {
351         pmStatus |= CY_SYSPM_STATUS_CM0_DEEPSLEEP;
352     }
353     /* Check whether CM0p is in Sleep mode*/
354     else if (0U != _FLD2VAL(CPUSS_CM0_STATUS_SLEEPING, CPUSS_CM0_STATUS))
355     {
356         pmStatus |= CY_SYSPM_STATUS_CM0_SLEEP;
357     }
358     else
359     {
360         pmStatus |= CY_SYSPM_STATUS_CM0_ACTIVE;
361     }
362 #endif /* (__CORTEX_M == 0) || (defined (__CM0P_PRESENT) && (__CM0P_PRESENT == 1)) */
363 
364     /* Check whether the device is in LP mode by reading
365     *  the core voltage:
366     *  - 0.9V (nominal) - System ULP mode
367     *  - 1.1V (nominal) - System LP mode
368     */
369 
370     /* Read current active regulator */
371     if (Cy_SysPm_LdoIsEnabled())
372     {
373         /* Current active regulator is LDO */
374         if (Cy_SysPm_LdoGetVoltage() != CY_SYSPM_LDO_VOLTAGE_ULP)
375         {
376             pmStatus |= CY_SYSPM_STATUS_SYSTEM_LP;
377         }
378         else
379         {
380             pmStatus |= CY_SYSPM_STATUS_SYSTEM_ULP;
381         }
382     }
383     else
384     {
385         /* Current active regulator is Buck */
386         if (Cy_SysPm_BuckGetVoltage1() != CY_SYSPM_BUCK_OUT1_VOLTAGE_ULP)
387         {
388             pmStatus |= CY_SYSPM_STATUS_SYSTEM_LP;
389         }
390         else
391         {
392             pmStatus |= CY_SYSPM_STATUS_SYSTEM_ULP;
393         }
394     }
395 
396     return pmStatus;
397 }
398 
399 
Cy_SysPm_CpuEnterSleep(cy_en_syspm_waitfor_t waitFor)400 cy_en_syspm_status_t Cy_SysPm_CpuEnterSleep(cy_en_syspm_waitfor_t waitFor)
401 {
402     uint32_t interruptState;
403     uint32_t cbSleepRootIdx = (uint32_t) CY_SYSPM_SLEEP;
404     cy_en_syspm_status_t retVal = CY_SYSPM_SUCCESS;
405 
406     CY_ASSERT_L3(CY_SYSPM_IS_WAIT_FOR_VALID(waitFor));
407 
408     /* Call registered callback functions with CY_SYSPM_CHECK_READY parameter */
409     if (pmCallbackRoot[cbSleepRootIdx] != NULL)
410     {
411         retVal = Cy_SysPm_ExecuteCallback(CY_SYSPM_SLEEP, CY_SYSPM_CHECK_READY);
412     }
413 
414     /* The CPU can switch into the Sleep power mode only when
415     *  all executed registered callback functions with the CY_SYSPM_CHECK_READY
416     *  parameter return CY_SYSPM_SUCCESS.
417     */
418     if(retVal == CY_SYSPM_SUCCESS)
419     {
420         /* Call the registered callback functions with
421         * CY_SYSPM_BEFORE_TRANSITION parameter
422         */
423         interruptState = Cy_SysLib_EnterCriticalSection();
424         if (pmCallbackRoot[cbSleepRootIdx] != NULL)
425         {
426             (void) Cy_SysPm_ExecuteCallback(CY_SYSPM_SLEEP, CY_SYSPM_BEFORE_TRANSITION);
427         }
428 
429         /* The CPU enters the Sleep power mode upon execution of WFI/WFE */
430         SCB_SCR &= (uint32_t) ~SCB_SCR_SLEEPDEEP_Msk;
431 
432         if(waitFor != CY_SYSPM_WAIT_FOR_EVENT)
433         {
434             __WFI();
435         }
436         else
437         {
438             __WFE();
439 
440         #if (CY_CPU_CORTEX_M4)
441             if (Cy_SysLib_GetDevice() == CY_SYSLIB_DEVICE_PSOC6ABLE2)
442             {
443                 /* For the CM4 CPU, the WFE instruction is called twice.
444                 *  The second WFE call clears the Event Register of CM4 CPU.
445                 *  Cypress ID #279077.
446                 */
447                 if(wasEventSent)
448                 {
449                     __WFE();
450                 }
451 
452                 wasEventSent = true;
453             }
454         #endif /* (CY_CPU_CORTEX_M4) */
455         }
456         Cy_SysLib_ExitCriticalSection(interruptState);
457 
458         /* Call the registered callback functions with the
459         *  CY_SYSPM_AFTER_TRANSITION parameter
460         */
461         if (pmCallbackRoot[cbSleepRootIdx] != NULL)
462         {
463             (void) Cy_SysPm_ExecuteCallback(CY_SYSPM_SLEEP, CY_SYSPM_AFTER_TRANSITION);
464         }
465     }
466     else
467     {
468         /* Execute callback functions with the CY_SYSPM_CHECK_FAIL parameter to
469         *  undo everything done in the callback with the CY_SYSPM_CHECK_READY
470         *  parameter
471         */
472         (void) Cy_SysPm_ExecuteCallback(CY_SYSPM_SLEEP, CY_SYSPM_CHECK_FAIL);
473         retVal = CY_SYSPM_FAIL;
474     }
475     return retVal;
476 }
477 
478 
Cy_SysPm_CpuEnterDeepSleep(cy_en_syspm_waitfor_t waitFor)479 cy_en_syspm_status_t Cy_SysPm_CpuEnterDeepSleep(cy_en_syspm_waitfor_t waitFor)
480 {
481     /* Structure for registers that should retain while Deep Sleep mode */
482 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
483     static cy_stc_syspm_backup_regs_t bkpRegs;
484     uint8_t deviceRev = Cy_SysLib_GetDeviceRevision();
485 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
486     uint32_t interruptState;
487     uint32_t cbDeepSleepRootIdx = (uint32_t) CY_SYSPM_DEEPSLEEP;
488     uint32_t ddftStructData = 0UL;
489     cy_en_syspm_status_t retVal = CY_SYSPM_SUCCESS;
490 
491     CY_ASSERT_L3(CY_SYSPM_IS_WAIT_FOR_VALID(waitFor));
492 
493     /* Call the registered callback functions with the CY_SYSPM_CHECK_READY
494     *  parameter
495     */
496     if (pmCallbackRoot[cbDeepSleepRootIdx] != NULL)
497     {
498         retVal = Cy_SysPm_ExecuteCallback(CY_SYSPM_DEEPSLEEP, CY_SYSPM_CHECK_READY);
499     }
500 
501     /* The CPU can switch into the Deep Sleep power mode only when
502     *  all executed registered callback functions with the CY_SYSPM_CHECK_READY
503     *  parameter return CY_SYSPM_SUCCESS
504     */
505     if (retVal == CY_SYSPM_SUCCESS)
506     {
507         /* Call the registered callback functions with the
508         * CY_SYSPM_BEFORE_TRANSITION parameter
509         */
510         interruptState = Cy_SysLib_EnterCriticalSection();
511         if (pmCallbackRoot[cbDeepSleepRootIdx] != NULL)
512         {
513             (void) Cy_SysPm_ExecuteCallback(CY_SYSPM_DEEPSLEEP, CY_SYSPM_BEFORE_TRANSITION);
514         }
515 
516         /* Preparation for the System Deep Sleep mode */
517 
518 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
519         /* Acquire the IPC to prevent changing of the shared resources at the same time */
520         while (0U == _FLD2VAL(IPC_STRUCT_ACQUIRE_SUCCESS, REG_IPC_STRUCT_ACQUIRE(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT))))
521         {
522             /* Wait until the IPC structure is released by another CPU */
523         }
524 
525         ddftStructData = REG_IPC_STRUCT_DATA(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT));
526 
527         if (0U != (ddftStructData & OTHER_CORE_DP_MASK))
528         {
529             ddftStructData &= ~SYSPM_IPC_STRUCT_ADDR_MASK;
530 
531             Cy_SysPm_SaveRegisters(&bkpRegs);
532 
533         #ifndef CY_PSOC6ABLE2_REV_0A_SUPPORT_DISABLE
534             if (deviceRev == CY_SYSLIB_DEVICE_REV_0A)
535             {
536                 /* Increase the clock divider for the slow and fast clocks to SYSPM_CLK_DIVIDER */
537                 CPUSS_CM0_CLOCK_CTL =
538                 _CLR_SET_FLD32U(CPUSS_CM0_CLOCK_CTL, CPUSS_CM0_CLOCK_CTL_SLOW_INT_DIV, SYSPM_CLK_DIVIDER);
539 
540                 CPUSS_CM4_CLOCK_CTL =
541                 _CLR_SET_FLD32U(CPUSS_CM4_CLOCK_CTL, CPUSS_CM4_CLOCK_CTL_FAST_INT_DIV, SYSPM_CLK_DIVIDER);
542             }
543             else
544         #endif /* #ifndef CY_PSOC6ABLE2_REV_0A_SUPPORT_DISABLE */
545             {
546                 /* Set the clock divider equal to 2 for the slow and fast clocks */
547                 CPUSS_CM0_CLOCK_CTL =
548                 _CLR_SET_FLD32U(CPUSS_CM0_CLOCK_CTL, CPUSS_CM0_CLOCK_CTL_SLOW_INT_DIV, 1);
549 
550                 CPUSS_CM4_CLOCK_CTL =
551                 _CLR_SET_FLD32U(CPUSS_CM4_CLOCK_CTL, CPUSS_CM4_CLOCK_CTL_FAST_INT_DIV, 1);
552             }
553 
554             ddftStructData |= (uint32_t) &bkpRegs;
555         }
556 
557         ddftStructData |= CUR_CORE_DP_MASK;
558 
559         /* Update pointer to the latest saved structure */
560         REG_IPC_STRUCT_DATA(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT)) = ddftStructData;
561 
562         /* Release the IPC */
563         REG_IPC_STRUCT_RELEASE(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT)) = 0U;
564 
565         /* Read the release value to make sure it is set */
566         (void) REG_IPC_STRUCT_RELEASE(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT));
567 
568 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
569 
570     #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
571         /* Trigger PRA access to CM0 core to allow CM0 to store configuration */
572         CY_PRA_FUNCTION_CALL_VOID_VOID(CY_PRA_MSG_TYPE_SECURE_ONLY, CY_PRA_PM_FUNC_CM4_DP_FLAG_SET);
573     #endif /* ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
574 
575         /* Different device families and revisions have a different Deep Sleep entries */
576         if (Cy_SysLib_GetDevice() == CY_SYSLIB_DEVICE_PSOC6ABLE2)
577         {
578             /* The CPU enters Deep Sleep and wakes up in the RAM */
579             EnterDeepSleepRam(waitFor);
580         }
581         else
582         {
583 
584         #if (CY_CPU_CORTEX_M0P)
585             /* Check if there is a pending syscall */
586             CY_MISRA_DEVIATE_BLOCK_START('MISRA C-2012 Rule 13.5', 1, \
587             'Inspected manually, no side effect during functions call.')
588             if (Cy_IPC_Drv_IsLockAcquired(Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_SYSCALL_CM0)) ||
589                 Cy_IPC_Drv_IsLockAcquired(Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_SYSCALL_CM4)))
590             {
591                 CY_MISRA_BLOCK_END('MISRA C-2012 Rule 13.5')
592                 /* Do not put the CPU into Deep Sleep and return pending status */
593                 retVal = CY_SYSPM_SYSCALL_PENDING;
594             }
595             else
596         #endif /* (CY_CPU_CORTEX_M0P) */
597             {
598             #if (CY_CPU_CORTEX_M4)
599                 /* Repeat the WFI/WFE instruction if a wake up was not intended.
600                 *  Cypress ID #272909
601                 */
602                 do
603                 {
604             #endif /* (CY_CPU_CORTEX_M4) */
605 
606                     /* The CPU enters Deep Sleep mode upon execution of WFI/WFE */
607                     SCB_SCR |= SCB_SCR_SLEEPDEEP_Msk;
608 
609                     if(waitFor != CY_SYSPM_WAIT_FOR_EVENT)
610                     {
611                         __WFI();
612                     }
613                     else
614                     {
615                         __WFE();
616                     }
617 
618             #if (CY_CPU_CORTEX_M4)
619                 } while (_FLD2VAL(CPUSS_CM4_PWR_CTL_PWR_MODE, CPUSS_CM4_PWR_CTL) == CM4_PWR_STS_RETAINED);
620         #if defined(CY_DEVICE_SECURE)
621                 CY_PRA_CM0_WAKEUP();
622         #endif /* (CY_DEVICE_SECURE) */
623             #endif /* (CY_CPU_CORTEX_M4) */
624             }
625         }
626 
627         /* Acquire the IPC to prevent changing of the shared resources at the same time */
628         while (0U == _FLD2VAL(IPC_STRUCT_ACQUIRE_SUCCESS, REG_IPC_STRUCT_ACQUIRE(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT))))
629         {
630             /* Wait until the IPC structure is released by another CPU */
631         }
632 
633         ddftStructData = REG_IPC_STRUCT_DATA(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT));
634 
635     /* Removed for the security devices as this part is done by CM0 only */
636     #if !((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
637         if (0U != (ddftStructData & OTHER_CORE_DP_MASK))
638         {
639             cy_stc_syspm_backup_regs_t *ptrRegs;
640 
641             ptrRegs = (cy_stc_syspm_backup_regs_t *) (SYSPM_IPC_STRUCT_ADDR_MASK & ddftStructData);
642 
643             /* Restore saved registers */
644             Cy_SysPm_RestoreRegisters(ptrRegs);
645         }
646     #endif /* !((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
647 
648         ddftStructData &= ~CUR_CORE_DP_MASK;
649 
650         /* Update pointer to the latest saved structure */
651         REG_IPC_STRUCT_DATA(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT)) = ddftStructData;
652 
653         /* Release the IPC */
654         REG_IPC_STRUCT_RELEASE(CY_IPC_STRUCT_PTR(CY_IPC_CHAN_DDFT)) = 0U;
655 
656         Cy_SysLib_ExitCriticalSection(interruptState);
657     }
658 
659     if (retVal == CY_SYSPM_SUCCESS)
660     {
661         /* Call the registered callback functions with the CY_SYSPM_AFTER_TRANSITION
662         *  parameter
663         */
664         if (pmCallbackRoot[cbDeepSleepRootIdx] != NULL)
665         {
666             (void) Cy_SysPm_ExecuteCallback(CY_SYSPM_DEEPSLEEP, CY_SYSPM_AFTER_TRANSITION);
667         }
668     }
669     else
670     {
671         /* Execute callback functions with the CY_SYSPM_CHECK_FAIL parameter to
672         *  undo everything done in the callback with the CY_SYSPM_CHECK_READY
673         *  parameter
674         */
675         if (pmCallbackRoot[cbDeepSleepRootIdx] != NULL)
676         {
677             (void) Cy_SysPm_ExecuteCallback(CY_SYSPM_DEEPSLEEP, CY_SYSPM_CHECK_FAIL);
678         }
679 
680         /* Rewrite return value to indicate fail */
681         if (retVal != CY_SYSPM_SYSCALL_PENDING)
682         {
683             retVal = CY_SYSPM_FAIL;
684         }
685     }
686     return retVal;
687 }
688 
689 
Cy_SysPm_SystemEnterHibernate(void)690 cy_en_syspm_status_t Cy_SysPm_SystemEnterHibernate(void)
691 {
692     cy_en_syspm_status_t retVal = CY_SYSPM_SUCCESS;
693     uint32_t cbHibernateRootIdx = (uint32_t) CY_SYSPM_HIBERNATE;
694     /* Call the registered callback functions with the
695     * CY_SYSPM_CHECK_READY parameter
696     */
697     if (pmCallbackRoot[cbHibernateRootIdx] != NULL)
698     {
699         retVal = Cy_SysPm_ExecuteCallback(CY_SYSPM_HIBERNATE, CY_SYSPM_CHECK_READY);
700     }
701 
702     /* The system can switch into Hibernate power mode only when
703     *  all executed registered callback functions with CY_SYSPM_CHECK_READY
704     *  parameter return CY_SYSPM_SUCCESS.
705     */
706     if(retVal == CY_SYSPM_SUCCESS)
707     {
708         /* Call registered callback functions with CY_SYSPM_BEFORE_TRANSITION
709         *  parameter
710         */
711         (void) Cy_SysLib_EnterCriticalSection();
712         if (pmCallbackRoot[cbHibernateRootIdx] != NULL)
713         {
714             (void) Cy_SysPm_ExecuteCallback(CY_SYSPM_HIBERNATE, CY_SYSPM_BEFORE_TRANSITION);
715         }
716 
717     #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
718         CY_PRA_FUNCTION_CALL_VOID_PARAM(CY_PRA_MSG_TYPE_SECURE_ONLY,
719                                         CY_PRA_PM_FUNC_HIBERNATE,
720                                         PM_HIBERNATE_ENTER_HIBERNATE);
721     #else
722         /* Preserve the token that will be retained through a wakeup sequence.
723          * This could be used by Cy_SysLib_GetResetReason() to differentiate
724          * Wakeup from a general reset event.
725          * Preserve the wakeup source(s) configuration.
726          */
727         SRSS_PWR_HIBERNATE = (SRSS_PWR_HIBERNATE & HIBERNATE_WAKEUP_MASK) | HIBERNATE_TOKEN;
728 
729         /* Disable overriding by the peripherals the next pin-freeze command */
730         SRSS_PWR_HIBERNATE |= SET_HIBERNATE_MODE;
731 
732         /* The second write causes freezing of I/O cells to save the I/O-cell state */
733         SRSS_PWR_HIBERNATE |= SET_HIBERNATE_MODE;
734 
735         /* Third write cause system to enter Hibernate */
736         SRSS_PWR_HIBERNATE |= SET_HIBERNATE_MODE;
737     #endif /* ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
738 
739         /* Read register to make sure it is settled */
740         (void) SRSS_PWR_HIBERNATE;
741 
742         /* Wait for transition */
743         __WFI();
744 
745         /* The callback function calls with the CY_SYSPM_AFTER_TRANSITION
746         * parameter in the Hibernate power mode are not applicable as system
747         * wake-up was made on system reboot.
748         */
749 
750         /* A wakeup from Hibernate is performed by toggling of the wakeup
751         * pins, or WDT matches, or Backup domain alarm expires. This depends on
752         * what item is configured in the Hibernate register. After a wakeup
753         * event, a normal Boot procedure occurs.
754         * There is no need to exit from the critical section.
755         */
756     }
757     else
758     {
759         /* Execute callback functions with the CY_SYSPM_CHECK_FAIL parameter to
760         * undo everything done in the callback with the CY_SYSPM_CHECK_READY
761         * parameter. The return value should be CY_SYSPM_SUCCESS.
762         */
763         (void) Cy_SysPm_ExecuteCallback(CY_SYSPM_HIBERNATE, CY_SYSPM_CHECK_FAIL);
764         retVal = CY_SYSPM_FAIL;
765     }
766     return retVal;
767 }
768 
769 
Cy_SysPm_SystemEnterLp(void)770 cy_en_syspm_status_t Cy_SysPm_SystemEnterLp(void)
771 {
772     uint32_t interruptState;
773     uint32_t cbLpRootIdx = (uint32_t) CY_SYSPM_LP;
774     cy_en_syspm_status_t retVal = CY_SYSPM_SUCCESS;
775 
776     /* Call the registered callback functions with the
777     * CY_SYSPM_CHECK_READY parameter
778     */
779     if (pmCallbackRoot[cbLpRootIdx] != NULL)
780     {
781         retVal = Cy_SysPm_ExecuteCallback(CY_SYSPM_LP, CY_SYSPM_CHECK_READY);
782     }
783 
784     /* The system can switch into LP only when
785     * all executed registered callback functions with the
786     * CY_SYSPM_CHECK_READY parameter return CY_SYSPM_SUCCESS
787     */
788     if (retVal == CY_SYSPM_SUCCESS)
789     {
790 
791         /* Call the registered callback functions with the
792         * CY_SYSPM_BEFORE_TRANSITION parameter
793         */
794         interruptState = Cy_SysLib_EnterCriticalSection();
795         if (pmCallbackRoot[cbLpRootIdx] != NULL)
796         {
797             (void) Cy_SysPm_ExecuteCallback(CY_SYSPM_LP, CY_SYSPM_BEFORE_TRANSITION);
798         }
799 
800         /* Read current active regulator and set LP voltage*/
801         if (Cy_SysPm_LdoIsEnabled())
802         {
803             /* Current active regulator is LDO */
804             if (Cy_SysPm_LdoGetVoltage() != CY_SYSPM_LDO_VOLTAGE_LP)
805             {
806                 retVal = Cy_SysPm_LdoSetVoltage(CY_SYSPM_LDO_VOLTAGE_LP);
807             }
808         }
809         else
810         {
811             /* Current active regulator is Buck */
812             if (Cy_SysPm_BuckGetVoltage1() != CY_SYSPM_BUCK_OUT1_VOLTAGE_LP)
813             {
814                 retVal = Cy_SysPm_BuckSetVoltage1(CY_SYSPM_BUCK_OUT1_VOLTAGE_LP);
815             }
816         }
817 
818         Cy_SysLib_ExitCriticalSection(interruptState);
819 
820         /* Call the registered callback functions with the
821         * CY_SYSPM_AFTER_TRANSITION parameter
822         */
823         if (pmCallbackRoot[cbLpRootIdx] != NULL)
824         {
825             (void) Cy_SysPm_ExecuteCallback(CY_SYSPM_LP, CY_SYSPM_AFTER_TRANSITION);
826         }
827     }
828     else
829     {
830         /* Execute callback functions with the CY_SYSPM_CHECK_FAIL parameter to
831         * undo everything done in the callback with the CY_SYSPM_CHECK_READY
832         * parameter
833         */
834         (void) Cy_SysPm_ExecuteCallback(CY_SYSPM_LP, CY_SYSPM_CHECK_FAIL);
835         retVal = CY_SYSPM_FAIL;
836     }
837 
838     return retVal;
839 }
840 
841 
Cy_SysPm_SystemEnterUlp(void)842 cy_en_syspm_status_t Cy_SysPm_SystemEnterUlp(void)
843 {
844     uint32_t interruptState;
845     cy_en_syspm_status_t retVal = CY_SYSPM_SUCCESS;
846     uint32_t cbUlpRootIdx = (uint32_t) CY_SYSPM_ULP;
847 
848     /* Call the registered callback functions with the
849     * CY_SYSPM_CHECK_READY parameter
850     */
851     if (pmCallbackRoot[cbUlpRootIdx] != NULL)
852     {
853         retVal = Cy_SysPm_ExecuteCallback(CY_SYSPM_ULP, CY_SYSPM_CHECK_READY);
854     }
855 
856     /* The system can switch into the ULP only when
857     * all executed registered callback functions with the
858     * CY_SYSPM_CHECK_READY parameter return CY_SYSPM_SUCCESS
859     */
860     if (retVal == CY_SYSPM_SUCCESS)
861     {
862         /* Call the registered callback functions with the
863         * CY_SYSPM_BEFORE_TRANSITION parameter
864         */
865         interruptState = Cy_SysLib_EnterCriticalSection();
866         if (pmCallbackRoot[cbUlpRootIdx] != NULL)
867         {
868             (void) Cy_SysPm_ExecuteCallback(CY_SYSPM_ULP, CY_SYSPM_BEFORE_TRANSITION);
869         }
870 
871         /* Read current active regulator and set ULP voltage*/
872         if (Cy_SysPm_LdoIsEnabled())
873         {
874             /* Current active regulator is LDO */
875             if (Cy_SysPm_LdoGetVoltage() != CY_SYSPM_LDO_VOLTAGE_ULP)
876             {
877                 retVal = Cy_SysPm_LdoSetVoltage(CY_SYSPM_LDO_VOLTAGE_ULP);
878             }
879         }
880         else
881         {
882             /* Current active regulator is Buck */
883             if (Cy_SysPm_BuckGetVoltage1() != CY_SYSPM_BUCK_OUT1_VOLTAGE_ULP)
884             {
885                 retVal = Cy_SysPm_BuckSetVoltage1(CY_SYSPM_BUCK_OUT1_VOLTAGE_ULP);
886             }
887         }
888 
889         Cy_SysLib_ExitCriticalSection(interruptState);
890 
891         /* Call the registered callback functions with the
892         * CY_SYSPM_AFTER_TRANSITION parameter
893         */
894         if (pmCallbackRoot[cbUlpRootIdx] != NULL)
895         {
896             (void) Cy_SysPm_ExecuteCallback(CY_SYSPM_ULP, CY_SYSPM_AFTER_TRANSITION);
897         }
898     }
899     else
900     {
901         /* Execute callback functions with the CY_SYSPM_CHECK_FAIL parameter to
902         * undo everything done in the callback with the CY_SYSPM_CHECK_READY
903         * parameter
904         */
905         (void) Cy_SysPm_ExecuteCallback(CY_SYSPM_ULP, CY_SYSPM_CHECK_FAIL);
906         retVal = CY_SYSPM_FAIL;
907     }
908 
909     return retVal;
910 }
911 
912 
Cy_SysPm_SystemSetMinRegulatorCurrent(void)913 cy_en_syspm_status_t Cy_SysPm_SystemSetMinRegulatorCurrent(void)
914 {
915     cy_en_syspm_status_t retVal = CY_SYSPM_CANCELED;
916 
917 #if defined (CY_DEVICE_SECURE)
918     retVal = (cy_en_syspm_status_t)CY_PRA_FUNCTION_CALL_RETURN_VOID(CY_PRA_MSG_TYPE_FUNC_POLICY,
919                                                                     CY_PRA_PM_FUNC_SET_MIN_CURRENT);
920 #endif /* defined (CY_DEVICE_SECURE) */
921 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
922     /* Check are the power circuits are ready to enter into regulator minimum
923     *  current mode
924     */
925     if (0U != _FLD2VAL(SRSS_PWR_CTL_LPM_READY, SRSS_PWR_CTL))
926     {
927         if(Cy_SysPm_LdoIsEnabled())
928         {
929             /* Configure the minimum current mode for LDO regulator */
930             SRSS_PWR_CTL |= PWR_CIRCUITS_SET_LPMODE_LDO_MASK;
931 
932             /* Extend wakeup time for LDO 1.1 V */
933             if (Cy_SysPm_LdoGetVoltage() == CY_SYSPM_LDO_VOLTAGE_1_1V)
934             {
935                 /* Cypress ID DRV2123 */
936                 SRSS_PWR_TRIM_WAKE_CTL = SRSS_PWR_TRIM_WAKE_LP;
937             }
938         }
939         else
940         {
941             /* Configure the minimum current mode for Buck regulator */
942             SRSS_PWR_CTL |= PWR_CIRCUITS_SET_LPMODE_BUCK_MASK;
943         }
944 
945         /* This wait time allows the circuits to remove their dependence on
946         *  the Active mode circuits, such as active Reference
947         */
948         Cy_SysLib_DelayUs(SET_MIN_CURRENT_MODE_DELAY_US);
949 
950         /* Disable active reference */
951         SRSS_PWR_CTL |= SRSS_PWR_CTL_ACT_REF_DIS_Msk;
952 
953         retVal = CY_SYSPM_SUCCESS;
954     }
955 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
956 
957     return retVal;
958 }
959 
960 
Cy_SysPm_SystemSetNormalRegulatorCurrent(void)961 cy_en_syspm_status_t Cy_SysPm_SystemSetNormalRegulatorCurrent(void)
962 {
963     cy_en_syspm_status_t retVal = CY_SYSPM_TIMEOUT;
964 
965 #if defined (CY_DEVICE_SECURE)
966     retVal = (cy_en_syspm_status_t)CY_PRA_FUNCTION_CALL_RETURN_VOID(CY_PRA_MSG_TYPE_FUNC_POLICY,
967                                                                     CY_PRA_PM_FUNC_SET_NORMAL_CURRENT);
968 #endif /* defined (CY_DEVICE_SECURE) */
969 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
970     uint32_t timeOut = WAIT_DELAY_TRYES;
971 
972     /* Configure the regulator normal current mode for the POR/BOD circuits
973     *  and for the Bandgap Voltage and Current References
974     */
975     if (Cy_SysPm_LdoIsEnabled())
976     {
977         SRSS_PWR_CTL &= (uint32_t) ~CY_SYSPM_PWR_CIRCUITS_LPMODE_ACTIVE_LDO_MASK;
978     }
979     else
980     {
981         SRSS_PWR_CTL &= (uint32_t) ~CY_SYSPM_PWR_CIRCUITS_LPMODE_ACTIVE_BUCK_MASK;
982     }
983 
984     /* This wait time allows setting active Reference */
985     Cy_SysLib_DelayUs(ACT_REF_SETTLE_DELAY_US);
986 
987     while ((0U == _FLD2VAL(SRSS_PWR_CTL_ACT_REF_OK, SRSS_PWR_CTL)) && (0U != timeOut))
988     {
989         timeOut--;
990     }
991 
992     if (0U != timeOut)
993     {
994         /* Disable the low-power for Bandgap reference circuit */
995         SRSS_PWR_CTL &= (uint32_t) ~SRSS_PWR_CTL_BGREF_LPMODE_Msk;
996 
997         /* Delay to finally set the normal current mode */
998         Cy_SysLib_DelayUs(SET_NORMAL_CURRENT_MODE_DELAY_US);
999 
1000         /* Restore original wakeup time in Normal for LDO 1.1 V */
1001         if (Cy_SysPm_LdoIsEnabled() && (Cy_SysPm_LdoGetVoltage() == CY_SYSPM_LDO_VOLTAGE_1_1V))
1002         {
1003             /* Cypress ID DRV2123 */
1004             SRSS_PWR_TRIM_WAKE_CTL = SFLASH_PWR_TRIM_WAKE_CTL;
1005         }
1006 
1007         retVal= CY_SYSPM_SUCCESS;
1008     }
1009 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
1010 
1011     return retVal;
1012 }
1013 
1014 
Cy_SysPm_CpuSleepOnExit(bool enable)1015 void Cy_SysPm_CpuSleepOnExit(bool enable)
1016 {
1017     if(enable)
1018     {
1019         /* Enable sleep-on-exit feature */
1020         SCB_SCR |= SCB_SCR_SLEEPONEXIT_Msk;
1021     }
1022     else
1023     {
1024         /* Disable sleep-on-exit feature */
1025         SCB_SCR &= (uint32_t) ~(SCB_SCR_SLEEPONEXIT_Msk);
1026     }
1027 }
1028 
1029 
Cy_SysPm_SetHibernateWakeupSource(uint32_t wakeupSource)1030 void Cy_SysPm_SetHibernateWakeupSource(uint32_t wakeupSource)
1031 {
1032     CY_ASSERT_L3(CY_SYSPM_IS_WAKE_UP_SOURCE_VALID(wakeupSource));
1033 
1034     uint32_t polarityMask = 0U;
1035 
1036     if (0U != _FLD2VAL(SRSS_PWR_HIBERNATE_POLARITY_HIBPIN, wakeupSource))
1037     {
1038         /* Reconfigure the wakeup pins and LPComp polarity based on the input */
1039         if (0U != (wakeupSource & CY_SYSPM_HIB_WAKEUP_LPCOMP0_MASK))
1040         {
1041             polarityMask |= CY_SYSPM_HIB_WAKEUP_LPCOMP0_POLARITY_HIGH_MASK;
1042         }
1043 
1044         if (0U != (wakeupSource & CY_SYSPM_HIB_WAKEUP_LPCOMP1_MASK))
1045         {
1046             polarityMask |= CY_SYSPM_HIB_WAKEUP_LPCOMP1_POLARITY_HIGH_MASK;
1047         }
1048 
1049         if (0U != (wakeupSource & CY_SYSPM_HIB_WAKEUP_PIN0_MASK))
1050         {
1051             polarityMask |= CY_SYSPM_HIB_WAKEUP_PIN0_POLARITY_HIGH_MASK;
1052         }
1053 
1054         if (0U != (wakeupSource & CY_SYSPM_HIB_WAKEUP_PIN1_MASK))
1055         {
1056             polarityMask |= CY_SYSPM_HIB_WAKEUP_PIN1_POLARITY_HIGH_MASK;
1057         }
1058     }
1059 
1060 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
1061     CY_PRA_REG32_SET(CY_PRA_INDX_SRSS_PWR_HIBERNATE, (SRSS_PWR_HIBERNATE & (uint32_t) ~polarityMask) | wakeupSource);
1062 #else
1063     SRSS_PWR_HIBERNATE = (SRSS_PWR_HIBERNATE & (uint32_t) ~polarityMask) | wakeupSource;
1064 #endif /* ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
1065 
1066     /* Read register to make sure it is settled */
1067     (void) SRSS_PWR_HIBERNATE;
1068 }
1069 
1070 
Cy_SysPm_ClearHibernateWakeupSource(uint32_t wakeupSource)1071 void Cy_SysPm_ClearHibernateWakeupSource(uint32_t wakeupSource)
1072 {
1073     CY_ASSERT_L3(CY_SYSPM_IS_WAKE_UP_SOURCE_VALID(wakeupSource));
1074 
1075     uint32_t clearWakeupSourceMask = wakeupSource & (uint32_t) ~SRSS_PWR_HIBERNATE_POLARITY_HIBPIN_Msk;
1076 
1077     if (0U != _FLD2VAL(SRSS_PWR_HIBERNATE_POLARITY_HIBPIN, wakeupSource))
1078     {
1079         /* Clear the high active level of the requested sources */
1080         if ((uint32_t) CY_SYSPM_HIBERNATE_LPCOMP0_HIGH == (wakeupSource & (uint32_t) CY_SYSPM_HIBERNATE_LPCOMP0_HIGH))
1081         {
1082             clearWakeupSourceMask |= CY_SYSPM_HIB_WAKEUP_LPCOMP0_POLARITY_HIGH_MASK;
1083         }
1084 
1085         if ((uint32_t) CY_SYSPM_HIBERNATE_LPCOMP1_HIGH == (wakeupSource & (uint32_t) CY_SYSPM_HIBERNATE_LPCOMP1_HIGH))
1086         {
1087             clearWakeupSourceMask |= CY_SYSPM_HIB_WAKEUP_LPCOMP1_POLARITY_HIGH_MASK;
1088         }
1089 
1090         if ((uint32_t) CY_SYSPM_HIBERNATE_PIN0_HIGH == (wakeupSource & (uint32_t) CY_SYSPM_HIBERNATE_PIN0_HIGH))
1091         {
1092             clearWakeupSourceMask |= CY_SYSPM_HIB_WAKEUP_PIN0_POLARITY_HIGH_MASK;
1093         }
1094 
1095         if ((uint32_t) CY_SYSPM_HIBERNATE_PIN1_HIGH == (wakeupSource & (uint32_t) CY_SYSPM_HIBERNATE_PIN1_HIGH))
1096         {
1097             clearWakeupSourceMask |= CY_SYSPM_HIB_WAKEUP_PIN1_POLARITY_HIGH_MASK;
1098         }
1099     }
1100 
1101 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
1102     CY_PRA_REG32_SET(CY_PRA_INDX_SRSS_PWR_HIBERNATE, (SRSS_PWR_HIBERNATE & (uint32_t) ~clearWakeupSourceMask));
1103 #else
1104     SRSS_PWR_HIBERNATE &= (uint32_t) ~clearWakeupSourceMask;
1105 #endif /* ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
1106 
1107     /* Read register to make sure it is settled */
1108     (void) SRSS_PWR_HIBERNATE;
1109 }
1110 
1111 
Cy_SysPm_BuckEnable(cy_en_syspm_buck_voltage1_t voltage)1112 cy_en_syspm_status_t Cy_SysPm_BuckEnable(cy_en_syspm_buck_voltage1_t voltage)
1113 {
1114     CY_ASSERT_L3(CY_SYSPM_IS_BUCK_VOLTAGE1_VALID(voltage));
1115 
1116     cy_en_syspm_status_t retVal = CY_SYSPM_INVALID_STATE;
1117 
1118 #if defined (CY_DEVICE_SECURE)
1119     retVal = (cy_en_syspm_status_t)CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY,
1120                                                                      CY_PRA_PM_FUNC_BUCK_ENABLE,
1121                                                                      voltage);
1122 #endif /* defined (CY_DEVICE_SECURE) */
1123 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
1124 
1125     /* Enable the Buck regulator only if it was not enabled previously.
1126     *  If the LDO is disabled, the device is sourced by the Buck regulator
1127     */
1128     if (Cy_SysPm_LdoIsEnabled())
1129     {
1130         uint32_t interruptState;
1131         interruptState = Cy_SysLib_EnterCriticalSection();
1132 
1133         /* Update the RAM and ROM trim values when final target Buck 0.9 V */
1134         if (CY_SYSPM_BUCK_OUT1_VOLTAGE_0_9V == voltage)
1135         {
1136             if (Cy_SysPm_LdoGetVoltage() != CY_SYSPM_LDO_VOLTAGE_0_9V)
1137             {
1138                 retVal = Cy_SysPm_LdoSetVoltage(CY_SYSPM_LDO_VOLTAGE_0_9V);
1139             }
1140             else
1141             {
1142                 retVal = CY_SYSPM_SUCCESS;
1143             }
1144 
1145             if (CY_SYSPM_SUCCESS == retVal)
1146             {
1147                 /* Increase LDO output voltage to 0.95 V nominal */
1148                 SRSS_PWR_TRIM_PWRSYS_CTL = _CLR_SET_FLD32U((SRSS_PWR_TRIM_PWRSYS_CTL),
1149                 SRSS_PWR_TRIM_PWRSYS_CTL_ACT_REG_TRIM, LDO_OUT_VOLTAGE_0_95V);
1150             }
1151         }
1152 
1153         /* Update the RAM and ROM trim values when the final target Buck 1.1 V */
1154         if (CY_SYSPM_BUCK_OUT1_VOLTAGE_1_1V == voltage)
1155         {
1156             if (Cy_SysPm_LdoGetVoltage() != CY_SYSPM_LDO_VOLTAGE_1_1V)
1157             {
1158                 retVal = Cy_SysPm_LdoSetVoltage(CY_SYSPM_LDO_VOLTAGE_1_1V);
1159             }
1160             else
1161             {
1162                 retVal = CY_SYSPM_SUCCESS;
1163             }
1164 
1165             if (CY_SYSPM_SUCCESS == retVal)
1166             {
1167                 /* Set the LDO 1.15 V as final Buck output is 1.1 V */
1168                 SRSS_PWR_TRIM_PWRSYS_CTL = _CLR_SET_FLD32U((SRSS_PWR_TRIM_PWRSYS_CTL),
1169                 SRSS_PWR_TRIM_PWRSYS_CTL_ACT_REG_TRIM, LDO_OUT_VOLTAGE_1_15V);
1170             }
1171         }
1172 
1173         /* Proceed only if previous settings were done successfully */
1174         if (CY_SYSPM_SUCCESS == retVal)
1175         {
1176             /* A delay for the supply to stabilize at the new voltage */
1177             Cy_SysLib_DelayUs(LDO_STABILIZATION_DELAY_US);
1178 
1179             /* Disable the Deep Sleep, nWell, and Retention regulators */
1180             SRSS_PWR_CTL |= (_VAL2FLD(SRSS_PWR_CTL_DPSLP_REG_DIS, 1U) |
1181                              _VAL2FLD(SRSS_PWR_CTL_RET_REG_DIS, 1U) |
1182                              _VAL2FLD(SRSS_PWR_CTL_NWELL_REG_DIS, 1U));
1183 
1184             /* Configure the Buck regulator */
1185             SRSS_PWR_BUCK_CTL =
1186             _CLR_SET_FLD32U((SRSS_PWR_BUCK_CTL), SRSS_PWR_BUCK_CTL_BUCK_OUT1_SEL, (uint32_t) voltage);
1187 
1188             SRSS_PWR_BUCK_CTL |= _VAL2FLD(SRSS_PWR_BUCK_CTL_BUCK_EN, 1U);
1189 
1190             SRSS_PWR_BUCK_CTL |= _VAL2FLD(SRSS_PWR_BUCK_CTL_BUCK_OUT1_EN, 1U);
1191 
1192             /* Wait until Buck output 1 is stable */
1193             Cy_SysLib_DelayUs(BUCK_INIT_STABILIZATION_US);
1194 
1195             /* Disable the LDO, because Vbuckout1 and LDO are shorted */
1196             SRSS_PWR_CTL |= _VAL2FLD(SRSS_PWR_CTL_LINREG_DIS, 1U);
1197 
1198             /* Remove additional wakeup delay from Deep Sleep for LDO.
1199             *  Cypress ID #290172
1200             */
1201             SRSS_PWR_TRIM_WAKE_CTL = 0UL;
1202         }
1203 
1204         Cy_SysLib_ExitCriticalSection(interruptState);
1205     }
1206     else
1207     {
1208         /* The Buck is already enabled, so just update the Buck voltage */
1209         cy_en_syspm_buck_voltage1_t curBuckVoltage = Cy_SysPm_BuckGetVoltage1();
1210 
1211         if (voltage != curBuckVoltage)
1212         {
1213             retVal = Cy_SysPm_BuckSetVoltage1(voltage);
1214         }
1215         else
1216         {
1217             retVal = CY_SYSPM_SUCCESS;
1218         }
1219     }
1220 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
1221 
1222     return retVal;
1223 }
1224 
1225 
Cy_SysPm_BuckSetVoltage1(cy_en_syspm_buck_voltage1_t voltage)1226 cy_en_syspm_status_t Cy_SysPm_BuckSetVoltage1(cy_en_syspm_buck_voltage1_t voltage)
1227 {
1228     CY_ASSERT_L3(CY_SYSPM_IS_BUCK_VOLTAGE1_VALID(voltage));
1229 
1230     cy_en_syspm_status_t retVal = CY_SYSPM_INVALID_STATE;
1231 
1232 #if defined (CY_DEVICE_SECURE)
1233     retVal = (cy_en_syspm_status_t)CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY,
1234                                                                      CY_PRA_PM_FUNC_BUCK_ENABLE,
1235                                                                      voltage);
1236 #endif /* defined (CY_DEVICE_SECURE) */
1237 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
1238 
1239     /* Change the voltage only if protection context is set to zero (PC = 0)
1240     *  or the device revision supports modifying registers via syscall
1241     */
1242     if (IsVoltageChangePossible())
1243     {
1244         uint32_t interruptState;
1245         interruptState = Cy_SysLib_EnterCriticalSection();
1246 
1247         if (CY_SYSPM_BUCK_OUT1_VOLTAGE_0_9V == voltage)
1248         {
1249             /* Set bit of the flash voltage control register before ULP mode is set */
1250             retVal = Cy_SysPm_WriteVoltageBitForFlash(CY_SYSPM_FLASH_VOLTAGE_BIT_ULP);
1251 
1252             if (CY_SYSPM_SUCCESS == retVal)
1253             {
1254                 /* Update read-write margin value for the ULP mode */
1255                 SetReadMarginTrimUlp();
1256             }
1257         }
1258         else
1259         {
1260             /* Increase Buck output voltage to 0.95 V nominal */
1261             SRSS_PWR_BUCK_CTL =
1262             _CLR_SET_FLD32U((SRSS_PWR_BUCK_CTL), SRSS_PWR_BUCK_CTL_BUCK_OUT1_SEL, BUCK_OUT1_VOLTAGE_0_95V);
1263 
1264             /* Wait until regulator is stable on higher intermediate voltage */
1265             Cy_SysLib_DelayUs(BUCK_OUT1_0_9V_TO_0_95V_DELAY_US);
1266 
1267             /* Update write assist value for the LP mode */
1268             SetWriteAssistTrimLp();
1269 
1270             retVal = CY_SYSPM_SUCCESS;
1271         }
1272 
1273         /* Proceed only if previous settings were done successfully */
1274         if (CY_SYSPM_SUCCESS == retVal)
1275         {
1276             /* The system may continue operating while the voltage on Vccd
1277             * discharges to the new voltage. The time it takes to reach the
1278             * new voltage depends on the conditions, including the load current
1279             * on Vccd and the external capacitor size.
1280             */
1281             SRSS_PWR_BUCK_CTL =
1282             _CLR_SET_FLD32U((SRSS_PWR_BUCK_CTL), SRSS_PWR_BUCK_CTL_BUCK_OUT1_SEL, (uint32_t) voltage);
1283 
1284             if (CY_SYSPM_BUCK_OUT1_VOLTAGE_0_9V == voltage)
1285             {
1286                 /* Update write assist value for the ULP mode */
1287                 SetWriteAssistTrimUlp();
1288             }
1289             else
1290             {
1291                 /* Delay stabilizing at the new voltage is required only
1292                 *  when changing from a lower voltage to a higher voltage
1293                 */
1294                 Cy_SysLib_DelayUs(BUCK_OUT1_0_95V_TO_1_1V_DELAY_US);
1295 
1296                 /* Update read-write margin value for the LP mode */
1297                 SetReadMarginTrimLp();
1298 
1299                 /* Clear bit of the flash voltage control register after
1300                 * the LP mode is set
1301                 */
1302                 retVal = Cy_SysPm_WriteVoltageBitForFlash(CY_SYSPM_FLASH_VOLTAGE_BIT_LP);
1303             }
1304         }
1305 
1306         Cy_SysLib_ExitCriticalSection(interruptState);
1307     }
1308 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
1309 
1310     return retVal;
1311 }
1312 
1313 
Cy_SysPm_BuckIsOutputEnabled(cy_en_syspm_buck_out_t output)1314 bool Cy_SysPm_BuckIsOutputEnabled(cy_en_syspm_buck_out_t output)
1315 {
1316     CY_ASSERT_L3(CY_SYSPM_IS_BUCK_OUTPUT_VALID(output));
1317 
1318     bool retVal = false;
1319 
1320     if (output == CY_SYSPM_BUCK_VBUCK_1)
1321     {
1322         retVal = (_FLD2BOOL(SRSS_PWR_BUCK_CTL_BUCK_OUT1_EN, SRSS_PWR_BUCK_CTL));
1323     }
1324 
1325     /* Return false if device does not have the second Buck output (SIMO) */
1326     if (0U != cy_device->sysPmSimoPresent)
1327     {
1328         if(output == CY_SYSPM_BUCK_VRF)
1329         {
1330             retVal = ((0U != _FLD2VAL(SRSS_PWR_BUCK_CTL2_BUCK_OUT2_HW_SEL, SRSS_PWR_BUCK_CTL2)) ||
1331                       (0U != _FLD2VAL(SRSS_PWR_BUCK_CTL2_BUCK_OUT2_EN, SRSS_PWR_BUCK_CTL2)));
1332         }
1333     }
1334 
1335     return(retVal);
1336 }
1337 
1338 
Cy_SysPm_BuckEnableVoltage2(void)1339 void Cy_SysPm_BuckEnableVoltage2(void)
1340 {
1341 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
1342     CY_PRA_FUNCTION_CALL_VOID_VOID(CY_PRA_MSG_TYPE_SECURE_ONLY,
1343                                    CY_PRA_PM_FUNC_BUCK_ENABLE_VOLTAGE2);
1344 #else
1345     /* Do nothing if device does not have the second Buck output (SIMO) */
1346     if (0U != cy_device->sysPmSimoPresent)
1347     {
1348         if (!Cy_SysPm_BuckIsEnabled())
1349         {
1350             /* Enable the SIMO Buck regulator */
1351             SRSS_PWR_BUCK_CTL |= _VAL2FLD(SRSS_PWR_BUCK_CTL_BUCK_EN, 1U);
1352         }
1353 
1354         /* Enable the SIMO Buck output 2 */
1355         SRSS_PWR_BUCK_CTL2 |= _VAL2FLD(SRSS_PWR_BUCK_CTL2_BUCK_OUT2_EN, 1U);
1356 
1357         /* Wait until the output is stable */
1358         Cy_SysLib_DelayUs(BUCK_OUT2_INIT_DELAY_US);
1359     }
1360 #endif /* ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
1361 }
1362 
1363 
Cy_SysPm_BuckSetVoltage2(cy_en_syspm_buck_voltage2_t voltage,bool waitToSettle)1364 void Cy_SysPm_BuckSetVoltage2(cy_en_syspm_buck_voltage2_t voltage, bool waitToSettle)
1365 {
1366 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
1367     cy_stc_pra_voltage2_t voltageSettings;
1368     voltageSettings.praVoltage = voltage;
1369     voltageSettings.praWaitToSettle = waitToSettle;
1370 
1371     CY_PRA_FUNCTION_CALL_VOID_PARAM(CY_PRA_MSG_TYPE_SECURE_ONLY,
1372                                     CY_PRA_PM_FUNC_BUCK_SET_VOLTAGE2,
1373                                     &voltageSettings);
1374 #else
1375     /* Do nothing if device does not have the second Buck output (SIMO) */
1376     if (0U != cy_device->sysPmSimoPresent)
1377     {
1378         uint32_t curVoltage;
1379 
1380         CY_ASSERT_L3(CY_SYSPM_IS_BUCK_VOLTAGE2_VALID(voltage));
1381 
1382         /* Get the current voltage */
1383         curVoltage = (uint32_t) Cy_SysPm_BuckGetVoltage2();
1384 
1385         if ((uint32_t) voltage != curVoltage)
1386         {
1387             SRSS_PWR_BUCK_CTL2 =
1388             _CLR_SET_FLD32U((SRSS_PWR_BUCK_CTL2), SRSS_PWR_BUCK_CTL2_BUCK_OUT2_SEL, (uint32_t) voltage);
1389 
1390             /* Delay stabilizing at the new voltage is required only
1391             *  when changing from a lower voltage to a higher voltage.
1392             */
1393             if(waitToSettle && ((uint32_t) voltage > curVoltage))
1394             {
1395                 Cy_SysLib_DelayUs(BUCK_OUT2_STABILIZATION_DELAY_US);
1396             }
1397         }
1398     }
1399 #endif /* ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
1400 }
1401 
1402 
Cy_SysPm_LdoSetVoltage(cy_en_syspm_ldo_voltage_t voltage)1403 cy_en_syspm_status_t Cy_SysPm_LdoSetVoltage(cy_en_syspm_ldo_voltage_t voltage)
1404 {
1405     CY_ASSERT_L3(CY_SYSPM_IS_LDO_VOLTAGE_VALID(voltage));
1406 
1407     cy_en_syspm_status_t retVal = CY_SYSPM_INVALID_STATE;
1408 
1409 #if defined (CY_DEVICE_SECURE)
1410     retVal = (cy_en_syspm_status_t)CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_FUNC_POLICY,
1411                                                                      CY_PRA_PM_FUNC_LDO_SET_VOLTAGE,
1412                                                                      voltage);
1413 #endif /* defined (CY_DEVICE_SECURE) */
1414 #if ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE)))
1415     /* Change the voltage only if protection context is set to zero (PC = 0),
1416     *  or the device revision supports modifying registers via syscall
1417     */
1418     if (IsVoltageChangePossible())
1419     {
1420         uint32_t interruptState;
1421         uint32_t trimVoltage;
1422 
1423         interruptState = Cy_SysLib_EnterCriticalSection();
1424 
1425         if (CY_SYSPM_LDO_VOLTAGE_0_9V == voltage)
1426         {
1427             /* Remove additional wakeup delay from Deep Sleep
1428             *  for 0.9 V LDO. Cypress ID #290172
1429             */
1430             SRSS_PWR_TRIM_WAKE_CTL = 0UL;
1431 
1432             trimVoltage =  SFLASH_LDO_0P9V_TRIM;
1433 
1434             /* Set bit of the flash voltage control register before the ULP is set */
1435             retVal = Cy_SysPm_WriteVoltageBitForFlash(CY_SYSPM_FLASH_VOLTAGE_BIT_ULP);
1436 
1437             if (CY_SYSPM_SUCCESS == retVal)
1438             {
1439                 /* Update read-write margin value for the ULP mode */
1440                 SetReadMarginTrimUlp();
1441             }
1442         }
1443         else
1444         {
1445             /* Configure additional wakeup delay from Deep Sleep
1446             *  for 1.1 V LDO. Cypress ID #290172
1447             */
1448             if (Cy_SysPm_SystemIsMinRegulatorCurrentSet())
1449             {
1450                 /* Cypress ID DRV2123 */
1451                 SRSS_PWR_TRIM_WAKE_CTL = SRSS_PWR_TRIM_WAKE_LP;
1452             }
1453             else
1454             {
1455                 SRSS_PWR_TRIM_WAKE_CTL = SFLASH_PWR_TRIM_WAKE_CTL;
1456             }
1457 
1458             trimVoltage = SFLASH_LDO_1P1V_TRIM;
1459 
1460             SRSS_PWR_TRIM_PWRSYS_CTL =
1461             _CLR_SET_FLD32U((SRSS_PWR_TRIM_PWRSYS_CTL), SRSS_PWR_TRIM_PWRSYS_CTL_ACT_REG_TRIM, LDO_OUT_VOLTAGE_0_95V);
1462 
1463             /* A delay for the supply to stabilize at the new higher voltage */
1464             Cy_SysLib_DelayUs(LDO_0_9V_TO_0_95V_DELAY_US);
1465 
1466             /* Update write assist value for the LP mode */
1467             SetWriteAssistTrimLp();
1468 
1469             retVal = CY_SYSPM_SUCCESS;
1470         }
1471 
1472         if (CY_SYSPM_SUCCESS == retVal)
1473         {
1474             /* The system may continue operating while the voltage on Vccd
1475             *  discharges to the new voltage. The time it takes to reach the
1476             *  new voltage depends on the conditions, including the load current
1477             *  on Vccd and the external capacitor size.
1478             */
1479             SRSS_PWR_TRIM_PWRSYS_CTL =
1480             _CLR_SET_FLD32U((SRSS_PWR_TRIM_PWRSYS_CTL), SRSS_PWR_TRIM_PWRSYS_CTL_ACT_REG_TRIM, trimVoltage);
1481 
1482             if (CY_SYSPM_LDO_VOLTAGE_0_9V == voltage)
1483             {
1484                 /* Update write assist value for the ULP mode */
1485                 SetWriteAssistTrimUlp();
1486             }
1487             else
1488             {
1489                 /* A delay for the supply to stabilize at the new intermediate voltage */
1490                 Cy_SysLib_DelayUs(LDO_0_95V_TO_1_1V_DELAY_US);
1491 
1492                 /* Update read-write margin value for the LP mode */
1493                 SetReadMarginTrimLp();
1494 
1495                 /* Clear bit of the flash voltage control register after
1496                 * the LP mode is set
1497                 */
1498                 retVal = Cy_SysPm_WriteVoltageBitForFlash(CY_SYSPM_FLASH_VOLTAGE_BIT_LP);
1499             }
1500         }
1501 
1502         Cy_SysLib_ExitCriticalSection(interruptState);
1503     }
1504 #endif /* ((CY_CPU_CORTEX_M0P) || (!defined(CY_DEVICE_SECURE))) */
1505 
1506     return retVal;
1507 }
1508 
1509 
Cy_SysPm_LdoSetMode(cy_en_syspm_ldo_mode_t mode)1510 cy_en_syspm_status_t Cy_SysPm_LdoSetMode(cy_en_syspm_ldo_mode_t mode)
1511 {
1512     CY_ASSERT_L3(CY_SYSPM_IS_LDO_MODE_VALID(mode));
1513 
1514     cy_en_syspm_status_t retVal = CY_SYSPM_CANCELED;
1515 
1516     switch (mode)
1517     {
1518         case CY_SYSPM_LDO_MODE_NORMAL:
1519         {
1520             retVal = Cy_SysPm_SystemSetNormalRegulatorCurrent();
1521         }
1522         break;
1523 
1524         case CY_SYSPM_LDO_MODE_MIN:
1525         {
1526             retVal = Cy_SysPm_SystemSetMinRegulatorCurrent();
1527         }
1528         break;
1529 
1530         case CY_SYSPM_LDO_MODE_DISABLED:
1531         {
1532         #if !((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
1533             /* Disable the LDO, Deep Sleep, nWell, and Retention regulators */
1534             SRSS_PWR_CTL |= (_VAL2FLD(SRSS_PWR_CTL_DPSLP_REG_DIS, 1U) |
1535                              _VAL2FLD(SRSS_PWR_CTL_RET_REG_DIS, 1U) |
1536                              _VAL2FLD(SRSS_PWR_CTL_NWELL_REG_DIS, 1U) |
1537                              _VAL2FLD(SRSS_PWR_CTL_LINREG_DIS, 1U));
1538 
1539             retVal = CY_SYSPM_SUCCESS;
1540         #endif /* !(CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
1541         }
1542         break;
1543 
1544         default:
1545             retVal = CY_SYSPM_FAIL;
1546         break;
1547     }
1548 
1549     return retVal;
1550 }
1551 
1552 
Cy_SysPm_LdoGetMode(void)1553 cy_en_syspm_ldo_mode_t Cy_SysPm_LdoGetMode(void)
1554 {
1555     cy_en_syspm_ldo_mode_t retVal;
1556 
1557     if (!Cy_SysPm_LdoIsEnabled())
1558     {
1559         retVal = CY_SYSPM_LDO_MODE_DISABLED;
1560     }
1561     else if (Cy_SysPm_SystemIsMinRegulatorCurrentSet())
1562     {
1563         retVal = CY_SYSPM_LDO_MODE_MIN;
1564     }
1565     else
1566     {
1567         retVal = CY_SYSPM_LDO_MODE_NORMAL;
1568     }
1569 
1570     return retVal;
1571 }
1572 
1573 
Cy_SysPm_RegisterCallback(cy_stc_syspm_callback_t * handler)1574 bool Cy_SysPm_RegisterCallback(cy_stc_syspm_callback_t* handler)
1575 {
1576     bool retVal = false;
1577 
1578     /* Verify the input parameters. */
1579     if ((handler != NULL) && (handler->callbackParams != NULL) && (handler->callback != NULL))
1580     {
1581         uint32_t callbackRootIdx = (uint32_t) handler->type;
1582 
1583         /* If the callback list is not empty. */
1584         if (pmCallbackRoot[callbackRootIdx] != NULL)
1585         {
1586             cy_stc_syspm_callback_t* curCallback = pmCallbackRoot[callbackRootIdx];
1587             cy_stc_syspm_callback_t* insertPos  = curCallback;
1588 
1589             /* Find the callback after which the new callback is to be
1590              * inserted. Ensure the given callback has not been registered.
1591              */
1592             while ((NULL != curCallback->nextItm) && (curCallback != handler))
1593             {
1594                 curCallback = curCallback->nextItm;
1595                 /* Callbacks with the same order value are stored in the order
1596                  * they are registered.
1597                  */
1598                 if (curCallback->order <= handler->order)
1599                 {
1600                     insertPos = curCallback;
1601                 }
1602             }
1603             /* If the callback has not been registered. */
1604             if (curCallback != handler)
1605             {
1606                 /* If the callback is to be inserted at the beginning of the list. */
1607                 if ((insertPos->prevItm == NULL) && (handler->order < insertPos->order))
1608                 {
1609                     handler->nextItm = insertPos;
1610                     handler->prevItm = NULL;
1611                     handler->nextItm->prevItm = handler;
1612                     pmCallbackRoot[callbackRootIdx] = handler;
1613                 }
1614                 else
1615                 {
1616                     handler->nextItm = insertPos->nextItm;
1617                     handler->prevItm = insertPos;
1618 
1619                     /* If the callback is not inserted at the end of the list. */
1620                     if (handler->nextItm != NULL)
1621                     {
1622                         handler->nextItm->prevItm = handler;
1623                     }
1624                     insertPos->nextItm = handler;
1625                 }
1626                 retVal = true;
1627             }
1628         }
1629         else
1630         {
1631             /* The callback list is empty. */
1632             pmCallbackRoot[callbackRootIdx] = handler;
1633             handler->nextItm = NULL;
1634             handler->prevItm = NULL;
1635             retVal = true;
1636         }
1637     }
1638     return retVal;
1639 }
1640 
1641 
Cy_SysPm_UnregisterCallback(cy_stc_syspm_callback_t const * handler)1642 bool Cy_SysPm_UnregisterCallback(cy_stc_syspm_callback_t const *handler)
1643 {
1644     bool retVal = false;
1645 
1646     if (handler != NULL)
1647     {
1648         uint32_t callbackRootIdx = (uint32_t) handler->type;
1649         cy_stc_syspm_callback_t* curCallback = pmCallbackRoot[callbackRootIdx];
1650 
1651         /* Search requested callback item in the linked list */
1652         while (curCallback != NULL)
1653         {
1654             /* Requested callback is found */
1655             if (curCallback == handler)
1656             {
1657                 retVal = true;
1658                 break;
1659             }
1660 
1661             /* Go to next callback item in the linked list */
1662             curCallback = curCallback->nextItm;
1663         }
1664 
1665         if (retVal)
1666         {
1667             /* Requested callback is first in the list */
1668             if (pmCallbackRoot[callbackRootIdx] == handler)
1669             {
1670                 /* Check whether this the only callback registered */
1671                 if (pmCallbackRoot[callbackRootIdx]->nextItm != NULL)
1672                 {
1673                     pmCallbackRoot[callbackRootIdx] = pmCallbackRoot[callbackRootIdx]->nextItm;
1674                     pmCallbackRoot[callbackRootIdx]->prevItm = NULL;
1675                 }
1676                 else
1677                 {
1678                     /* We had only one callback */
1679                     pmCallbackRoot[callbackRootIdx] = NULL;
1680                 }
1681             }
1682             else
1683             {
1684                 /* Update links of related to unregistered callback items */
1685                 curCallback->prevItm->nextItm = curCallback->nextItm;
1686 
1687                 if (curCallback->nextItm != NULL)
1688                 {
1689                     curCallback->nextItm->prevItm = curCallback->prevItm;
1690                 }
1691             }
1692         }
1693     }
1694 
1695     return retVal;
1696 }
1697 
1698 
Cy_SysPm_ExecuteCallback(cy_en_syspm_callback_type_t type,cy_en_syspm_callback_mode_t mode)1699 cy_en_syspm_status_t Cy_SysPm_ExecuteCallback(cy_en_syspm_callback_type_t type, cy_en_syspm_callback_mode_t mode)
1700 {
1701     CY_ASSERT_L3(CY_SYSPM_IS_CALLBACK_TYPE_VALID(type));
1702     CY_ASSERT_L3(CY_SYSPM_IS_CALLBACK_MODE_VALID(mode));
1703 
1704     static cy_stc_syspm_callback_t* lastExecutedCallback = NULL;
1705     cy_en_syspm_status_t retVal = CY_SYSPM_SUCCESS;
1706     cy_stc_syspm_callback_t* curCallback = pmCallbackRoot[(uint32_t) type];
1707     cy_stc_syspm_callback_params_t curParams;
1708 
1709     if ((mode == CY_SYSPM_BEFORE_TRANSITION) || (mode == CY_SYSPM_CHECK_READY))
1710     {
1711         /* Execute registered callbacks with order from first registered to the
1712         *  last registered. Stop executing if CY_SYSPM_FAIL was returned in
1713         *  CY_SYSPM_CHECK_READY mode
1714         */
1715         while ((curCallback != NULL) && ((retVal != CY_SYSPM_FAIL) || (mode != CY_SYSPM_CHECK_READY)))
1716         {
1717             /* The modes defined in the .skipMode element are not executed */
1718             if (0UL == ((uint32_t) mode & curCallback->skipMode))
1719             {
1720                 /* Update elements for local callback parameter values */
1721                 curParams.base = curCallback->callbackParams->base;
1722                 curParams.context = curCallback->callbackParams->context;
1723 
1724                 retVal = curCallback->callback(&curParams, mode);
1725 
1726                 /* Update callback pointer with value of executed callback.
1727                 * Such update is required to execute further callbacks in
1728                 * backward order after exit from LP mode or to undo
1729                 * configuration after callback returned fail: from last called
1730                 * to first registered.
1731                 */
1732                 lastExecutedCallback = curCallback;
1733             }
1734             curCallback = curCallback->nextItm;
1735         }
1736 
1737         if (mode == CY_SYSPM_CHECK_READY)
1738         {
1739             /* Update the pointer to  the failed callback with the result of the callback execution.
1740             *  If the callback fails, the value of the pointer will be updated
1741             *  with the address of the callback which returned CY_SYSPM_FAIL, else,
1742             *  it will be updated with NULL.
1743             */
1744             if(retVal == CY_SYSPM_FAIL)
1745             {
1746                 failedCallback[(uint32_t) type] = lastExecutedCallback;
1747             }
1748             else
1749             {
1750                 failedCallback[(uint32_t) type] = NULL;
1751             }
1752         }
1753     }
1754     else
1755     {
1756         /* Execute registered callbacks with order from lastCallback or last
1757         * executed to the first registered callback. Such a flow is required if
1758         * a previous callback function returned CY_SYSPM_FAIL or a previous
1759         * callback mode was CY_SYSPM_BEFORE_TRANSITION. Such an order is
1760         * required to undo configurations in correct backward order.
1761         */
1762         if (mode != CY_SYSPM_CHECK_FAIL)
1763         {
1764             while (curCallback->nextItm != NULL)
1765             {
1766                 curCallback = curCallback->nextItm;
1767             }
1768         }
1769         else
1770         {
1771             /* Skip last executed callback that returns CY_SYSPM_FAIL, as this
1772             *  callback already knows that it failed.
1773             */
1774             curCallback = lastExecutedCallback;
1775 
1776             if (curCallback != NULL)
1777             {
1778                 curCallback = curCallback->prevItm;
1779             }
1780         }
1781 
1782         /* Execute callback functions with required type and mode */
1783         while (curCallback != NULL)
1784         {
1785             /* The modes defined in the .skipMode element are not executed */
1786             if (0UL == ((uint32_t) mode & curCallback->skipMode))
1787             {
1788                 /* Update elements for local callback parameter values */
1789                 curParams.base = curCallback->callbackParams->base;
1790                 curParams.context = curCallback->callbackParams->context;
1791 
1792                 retVal = curCallback->callback(&curParams, mode);
1793             }
1794             curCallback = curCallback->prevItm;
1795         }
1796     }
1797 
1798     return retVal;
1799 }
1800 
1801 
Cy_SysPm_GetFailedCallback(cy_en_syspm_callback_type_t type)1802 cy_stc_syspm_callback_t* Cy_SysPm_GetFailedCallback(cy_en_syspm_callback_type_t type)
1803 {
1804     return failedCallback[(uint32_t) type];
1805 }
1806 
1807 
Cy_SysPm_IoUnfreeze(void)1808 void Cy_SysPm_IoUnfreeze(void)
1809 {
1810     uint32_t interruptState;
1811     interruptState = Cy_SysLib_EnterCriticalSection();
1812 
1813 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
1814     CY_PRA_FUNCTION_CALL_VOID_PARAM(CY_PRA_MSG_TYPE_SECURE_ONLY, CY_PRA_PM_FUNC_HIBERNATE, PM_HIBERNATE_IO_UNFREEZE);
1815 #else
1816     /* Preserve the last reset reason and wakeup polarity. Then, unfreeze I/O:
1817      * write PWR_HIBERNATE.FREEZE=0, .UNLOCK=0x3A, .HIBERANTE=0
1818      */
1819     SRSS_PWR_HIBERNATE = (SRSS_PWR_HIBERNATE & HIBERNATE_RETAIN_STATUS_MASK) | HIBERNATE_UNLOCK_VAL;
1820 
1821     /* Lock the Hibernate mode:
1822     * write PWR_HIBERNATE.HIBERNATE=0, UNLOCK=0x00, HIBERANTE=0
1823     */
1824     SRSS_PWR_HIBERNATE &= HIBERNATE_RETAIN_STATUS_MASK;
1825 #endif /* ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
1826 
1827     /* Read register to make sure it is settled */
1828     (void) SRSS_PWR_HIBERNATE;
1829 
1830     Cy_SysLib_ExitCriticalSection(interruptState);
1831 }
1832 
1833 
Cy_SysPm_WriteVoltageBitForFlash(cy_en_syspm_flash_voltage_bit_t value)1834 cy_en_syspm_status_t Cy_SysPm_WriteVoltageBitForFlash(cy_en_syspm_flash_voltage_bit_t value)
1835 {
1836     CY_ASSERT_L3(CY_SYSPM_IS_BIT_FOR_FLASH_VALID(value));
1837 
1838     cy_en_syspm_status_t retVal = CY_SYSPM_CANCELED;
1839 
1840 #if !((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
1841     uint16_t curDeviceRevision = Cy_SysLib_GetDeviceRevision();
1842     uint16_t curDevice = Cy_SysLib_GetDevice();
1843 
1844     /* Check the current protection context value. We can have a direct register
1845     *  update if protection context is = 0 */
1846     if ((Cy_Prot_GetActivePC(ACTIVE_BUS_MASTER) == 0U) && (curDevice == CY_SYSLIB_DEVICE_PSOC6ABLE2) &&
1847                                                           (curDeviceRevision <= SYSPM_DEVICE_PSOC6ABLE2_REV_0B))
1848     {
1849         FLASHC_FM_CTL_ANA_CTL0 =
1850         _CLR_SET_FLD32U((FLASHC_FM_CTL_ANA_CTL0), FLASHC_FM_CTL_ANA_CTL0_VCC_SEL, value);
1851 
1852         retVal = CY_SYSPM_SUCCESS;
1853     }
1854 
1855     /* Update the flash voltage bit using a syscall. This can be done on devices
1856     *  that support modifying registers via syscall.
1857     */
1858     if (((curDevice == CY_SYSLIB_DEVICE_PSOC6ABLE2) && (curDeviceRevision > SYSPM_DEVICE_PSOC6ABLE2_REV_0B)) ||
1859                                                        (curDevice != CY_SYSLIB_DEVICE_PSOC6ABLE2))
1860     {
1861         uint32_t syscallCode;
1862         IPC_STRUCT_Type *ipcSyscallBase = Cy_IPC_Drv_GetIpcBaseAddress(CY_IPC_CHAN_SYSCALL);
1863 
1864         /* Set required syscall code */
1865         if (curDevice == CY_SYSLIB_DEVICE_PSOC6ABLE2)
1866         {
1867             syscallCode = (CY_SYSPM_FLASH_VOLTAGE_BIT_LP != value) ?
1868             FLASH_VOLTAGE_BIT_ULP_PSOC6ABLE2_OPCODE : FLASH_VOLTAGE_BIT_LP_PSOC6ABLE2_OPCODE;
1869         }
1870         else
1871         {
1872             syscallCode = (CY_SYSPM_FLASH_VOLTAGE_BIT_LP != value) ?
1873             FLASH_VOLTAGE_BIT_ULP_OPCODE : FLASH_VOLTAGE_BIT_LP_OPCODE;
1874         }
1875 
1876         /* Tries to acquire the IPC structure and pass the arguments to SROM API */
1877         if (Cy_IPC_Drv_SendMsgWord(ipcSyscallBase, SYSPM_IPC_NOTIFY_STRUCT0, syscallCode) == CY_IPC_DRV_SUCCESS)
1878         {
1879             /* Checks whether the IPC structure is not locked */
1880             while (Cy_IPC_Drv_IsLockAcquired(ipcSyscallBase))
1881             {
1882                 /* Polls whether the IPC is released */
1883             }
1884 
1885             /* Check the return status of a syscall */
1886             uint32_t syscallStatus = Cy_IPC_Drv_ReadDataValue(ipcSyscallBase);
1887 
1888             if (SYSCALL_STATUS_SUCCESS == (syscallStatus & SYSCALL_STATUS_MASK))
1889             {
1890                 retVal = CY_SYSPM_SUCCESS;
1891             }
1892         }
1893     }
1894 #else
1895     (void)value;
1896 #endif /* !((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
1897 
1898     return retVal;
1899 }
1900 
1901 
1902 #if !((CY_CPU_CORTEX_M4) && (defined (CY_DEVICE_SECURE)))
Cy_SysPm_SaveRegisters(cy_stc_syspm_backup_regs_t * regs)1903 void Cy_SysPm_SaveRegisters(cy_stc_syspm_backup_regs_t *regs)
1904 {
1905     CY_ASSERT_L1(NULL != regs);
1906 
1907     /* Save the registers before Deep Sleep */
1908     regs->CY_SYSPM_CM0_CLOCK_CTL_REG = CPUSS_CM0_CLOCK_CTL;
1909     regs->CY_SYSPM_CM4_CLOCK_CTL_REG = CPUSS_CM4_CLOCK_CTL;
1910 
1911 #if (CPUSS_UDB_PRESENT != 0)
1912     if ((0U != cy_device->udbPresent) && (0UL != (PERI_GR_SL_CTL(MMIO_UDB_SLAVE_NR) & PERI_UDB_SLAVE_ENABLED)))
1913     {
1914         regs->CY_SYSPM_UDB_UDBIF_BANK_CTL_REG = UDB_UDBIF_BANK_CTL;
1915 
1916         regs->CY_SYSPM_UDB_BCTL_MDCLK_EN_REG = UDB_BCTL_MDCLK_EN;
1917         regs->CY_SYSPM_UDB_BCTL_MBCLK_EN_REG = UDB_BCTL_MBCLK_EN;
1918         regs->CY_SYSPM_UDB_BCTL_BOTSEL_L_REG = UDB_BCTL_BOTSEL_L;
1919         regs->CY_SYSPM_UDB_BCTL_BOTSEL_U_REG = UDB_BCTL_BOTSEL_U;
1920         regs->CY_SYSPM_UDB_BCTL_QCLK_EN0_REG = UDB_BCTL_QCLK_EN_0;
1921         regs->CY_SYSPM_UDB_BCTL_QCLK_EN1_REG = UDB_BCTL_QCLK_EN_1;
1922         regs->CY_SYSPM_UDB_BCTL_QCLK_EN2_REG = UDB_BCTL_QCLK_EN_2;
1923     }
1924 #endif /* CPUSS_UDB_PRESENT */
1925 }
1926 
1927 
Cy_SysPm_RestoreRegisters(cy_stc_syspm_backup_regs_t const * regs)1928 void Cy_SysPm_RestoreRegisters(cy_stc_syspm_backup_regs_t const *regs)
1929 {
1930     CY_ASSERT_L1(NULL != regs);
1931 
1932     /* Restore the registers after Deep Sleep */
1933     CPUSS_CM0_CLOCK_CTL = regs->CY_SYSPM_CM0_CLOCK_CTL_REG;
1934     CPUSS_CM4_CLOCK_CTL = regs->CY_SYSPM_CM4_CLOCK_CTL_REG;
1935 
1936 #if (CPUSS_UDB_PRESENT != 0)
1937     if ((0U != cy_device->udbPresent) && (0UL != (PERI_GR_SL_CTL(MMIO_UDB_SLAVE_NR) & PERI_UDB_SLAVE_ENABLED)))
1938     {
1939         UDB_BCTL_MDCLK_EN  = regs->CY_SYSPM_UDB_BCTL_MDCLK_EN_REG;
1940         UDB_BCTL_MBCLK_EN  = regs->CY_SYSPM_UDB_BCTL_MBCLK_EN_REG;
1941         UDB_BCTL_BOTSEL_L  = regs->CY_SYSPM_UDB_BCTL_BOTSEL_L_REG;
1942         UDB_BCTL_BOTSEL_U  = regs->CY_SYSPM_UDB_BCTL_BOTSEL_U_REG;
1943         UDB_BCTL_QCLK_EN_0 = regs->CY_SYSPM_UDB_BCTL_QCLK_EN0_REG;
1944         UDB_BCTL_QCLK_EN_1 = regs->CY_SYSPM_UDB_BCTL_QCLK_EN1_REG;
1945         UDB_BCTL_QCLK_EN_2 = regs->CY_SYSPM_UDB_BCTL_QCLK_EN2_REG;
1946 
1947         UDB_UDBIF_BANK_CTL = regs->CY_SYSPM_UDB_UDBIF_BANK_CTL_REG;
1948     }
1949 #endif /* CPUSS_UDB_PRESENT */
1950 }
1951 #endif /* !((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
1952 
1953 
1954 /*******************************************************************************
1955 * Function Name: EnterDeepSleepRam
1956 ****************************************************************************//**
1957 *
1958 * The internal function that prepares the system for Deep Sleep and
1959 * restores the system after a wakeup from Deep Sleep.
1960 *
1961 * \param waitFor
1962 * Selects wait for action. See \ref cy_en_syspm_waitfor_t.
1963 *
1964 * \return
1965 * - true - System Deep Sleep was occurred.
1966 * - false - System Deep Sleep was not occurred.
1967 *
1968 *******************************************************************************/
1969 CY_SECTION_RAMFUNC_BEGIN
1970 #if !defined (__ICCARM__)
1971     CY_NOINLINE
1972 #endif
EnterDeepSleepRam(cy_en_syspm_waitfor_t waitFor)1973 static void EnterDeepSleepRam(cy_en_syspm_waitfor_t waitFor)
1974 {
1975 #if !((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
1976 
1977     /* Store the address of the Deep Sleep indicator into the RAM */
1978     volatile uint32_t *delayDoneFlag = DELAY_FLAG_REGISTER_ADDR;
1979 #endif /* !((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
1980 
1981 #if (CY_CPU_CORTEX_M4)
1982 
1983     /* Store the address of the CM4 power status register */
1984     volatile uint32_t *cpussCm4PwrCtlAddr = &CPUSS_CM4_PWR_CTL;
1985 
1986     /* Repeat the WFI/WFE instruction if a wake up was not intended.
1987     *  Cypress ID #272909
1988     */
1989     do
1990     {
1991 #endif /* (CY_CPU_CORTEX_M4) */
1992 
1993         /* The CPU enters Deep Sleep mode upon execution of WFI/WFE */
1994         SCB_SCR |= SCB_SCR_SLEEPDEEP_Msk;
1995 
1996         if(waitFor != CY_SYSPM_WAIT_FOR_EVENT)
1997         {
1998             __WFI();
1999         }
2000         else
2001         {
2002             __WFE();
2003 
2004         #if (CY_CPU_CORTEX_M4)
2005             /* Call the WFE instruction twice to clear the Event register
2006             *  of the CM4 CPU. Cypress ID #279077
2007             */
2008             if(wasEventSent)
2009             {
2010                 __WFE();
2011             }
2012             wasEventSent = true;
2013         #endif /* (CY_CPU_CORTEX_M4) */
2014         }
2015 
2016 #if (CY_CPU_CORTEX_M4)
2017     } while (_FLD2VAL(CPUSS_CM4_PWR_CTL_PWR_MODE, (*cpussCm4PwrCtlAddr)) == CM4_PWR_STS_RETAINED);
2018 
2019     #if defined(CY_DEVICE_SECURE)
2020         CY_PRA_CM0_WAKEUP();
2021     #endif /* defined(CY_DEVICE_SECURE) */
2022 #endif /* (CY_CPU_CORTEX_M4) */
2023 
2024 #if !((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
2025     /* Set 10 uS delay only under condition that the FLASHC_BIST_DATA[0] is
2026     *  cleared. Cypress ID #288510
2027     */
2028     if (*delayDoneFlag == NEED_DELAY)
2029     {
2030         uint32_t ddftSlowCtl;
2031         uint32_t clkOutputSlow;
2032         uint32_t ddftFastCtl;
2033 
2034     #if defined(CY_DEVICE_SECURE)
2035         Cy_PRA_CloseSrssMain2();
2036     #endif /* defined(CY_DEVICE_SECURE) */
2037 
2038         /* Save timer configuration */
2039         ddftSlowCtl   = SRSS_TST_DDFT_SLOW_CTL_REG;
2040         clkOutputSlow = SRSS_CLK_OUTPUT_SLOW;
2041         ddftFastCtl   = SRSS_TST_DDFT_FAST_CTL_REG;
2042 
2043         /* Configure the counter to be sourced by IMO */
2044         SRSS_TST_DDFT_SLOW_CTL_REG = SRSS_TST_DDFT_SLOW_CTL_MASK;
2045         SRSS_CLK_OUTPUT_SLOW       = CLK_OUTPUT_SLOW_MASK;
2046         SRSS_TST_DDFT_FAST_CTL_REG = TST_DDFT_FAST_CTL_MASK;
2047 
2048         /* Load the down-counter to count the 10 us */
2049         SRSS_CLK_CAL_CNT1 = IMO_10US_DELAY;
2050 
2051         while (0U == (SRSS_CLK_CAL_CNT1 & SRSS_CLK_CAL_CNT1_CAL_COUNTER_DONE_Msk))
2052         {
2053             /* Wait until the counter stops counting */
2054         }
2055 
2056         /* Indicate that delay was done */
2057         *delayDoneFlag = DELAY_DONE;
2058 
2059         /* Restore timer configuration */
2060         SRSS_TST_DDFT_SLOW_CTL_REG = ddftSlowCtl;
2061         SRSS_CLK_OUTPUT_SLOW       = clkOutputSlow;
2062         SRSS_TST_DDFT_FAST_CTL_REG = ddftFastCtl;
2063 
2064     #if defined(CY_DEVICE_SECURE)
2065         Cy_PRA_OpenSrssMain2();
2066     #endif /* defined(CY_DEVICE_SECURE) */
2067     }
2068 #endif /* !((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
2069 }
2070 CY_SECTION_RAMFUNC_END
2071 
Cy_SysPm_SetSRAMMacroPwrMode(cy_en_syspm_sram_index_t sramNum,uint32_t sramMacroNum,cy_en_syspm_sram_pwr_mode_t sramPwrMode)2072 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)
2073 {
2074 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
2075     cy_stc_pra_sram_power_mode_config_t pwrModeConfig;
2076 #endif /* ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
2077     cy_en_syspm_status_t status = CY_SYSPM_BAD_PARAM;
2078 
2079     CY_ASSERT_L1( sramNum < CPUSS_SRAM_COUNT );
2080 
2081 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
2082     pwrModeConfig.sramNum = sramNum;
2083     pwrModeConfig.sramMacroNum = sramMacroNum;
2084     pwrModeConfig.sramPwrMode = sramPwrMode;
2085 
2086     status = (cy_en_syspm_status_t)CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_SECURE_ONLY, CY_PRA_PM_FUNC_SRAM_MACRO_PWR_MODE, &pwrModeConfig);
2087 
2088 #else
2089 
2090     if(sramNum == CY_SYSPM_SRAM0_MEMORY)
2091     {
2092         CY_ASSERT_L1( sramMacroNum < CPUSS_RAMC0_MACRO_NR );
2093         if (sramMacroNum < CPUSS_RAMC0_MACRO_NR)
2094         {
2095             CPUSS_RAM0_PWR_CTL(sramMacroNum) = _VAL2FLD(CPUSS_V2_RAM0_PWR_MACRO_CTL_VECTKEYSTAT, CY_SYSPM_PWR_MACRO_CTL_WRITE_KEY) |
2096                                                 _VAL2FLD(CPUSS_V2_RAM0_PWR_MACRO_CTL_PWR_MODE, sramPwrMode);
2097             status = CY_SYSPM_SUCCESS;
2098         }
2099     }
2100     else if(sramNum == CY_SYSPM_SRAM1_MEMORY)
2101     {
2102         CY_ASSERT_L1( CPUSS_RAMC1_PRESENT );
2103         CY_ASSERT_L1( sramMacroNum == 0UL );
2104 
2105         CPUSS_RAM1_PWR_CTL = _VAL2FLD(CPUSS_V2_RAM1_PWR_CTL_VECTKEYSTAT, CY_SYSPM_PWR_MACRO_CTL_WRITE_KEY) |
2106                                     _VAL2FLD(CPUSS_V2_RAM1_PWR_CTL_PWR_MODE, sramPwrMode);
2107         status = CY_SYSPM_SUCCESS;
2108     }
2109     else if(sramNum == CY_SYSPM_SRAM2_MEMORY)
2110     {
2111         CY_ASSERT_L1( CPUSS_RAMC2_PRESENT );
2112         CY_ASSERT_L1( sramMacroNum == 0UL );
2113 
2114         CPUSS_RAM2_PWR_CTL = _VAL2FLD(CPUSS_V2_RAM2_PWR_CTL_VECTKEYSTAT, CY_SYSPM_PWR_MACRO_CTL_WRITE_KEY) |
2115                                     _VAL2FLD(CPUSS_V2_RAM2_PWR_CTL_PWR_MODE, sramPwrMode);
2116         status = CY_SYSPM_SUCCESS;
2117     }
2118     else
2119     {
2120         /* Invalid SRAM Number */
2121     }
2122 #endif /* ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
2123     return status;
2124 }
2125 
Cy_SysPm_GetSRAMMacroPwrMode(cy_en_syspm_sram_index_t sramNum,uint32_t sramMacroNum)2126 cy_en_syspm_sram_pwr_mode_t Cy_SysPm_GetSRAMMacroPwrMode(cy_en_syspm_sram_index_t sramNum, uint32_t sramMacroNum)
2127 {
2128     uint32_t retVal = (uint32_t)CY_SYSPM_SRAM_PWR_MODE_INVALID;
2129 
2130     CY_ASSERT_L1( sramNum < CPUSS_SRAM_COUNT );
2131 
2132     if(sramNum == CY_SYSPM_SRAM0_MEMORY)
2133     {
2134         CY_ASSERT_L1( sramMacroNum < CPUSS_RAMC0_MACRO_NR );
2135         if (sramMacroNum < CPUSS_RAMC0_MACRO_NR)
2136         {
2137             retVal = _FLD2VAL(CPUSS_V2_RAM0_PWR_MACRO_CTL_PWR_MODE, CPUSS_RAM0_PWR_CTL(sramMacroNum));
2138         }
2139     }
2140     else if(sramNum == CY_SYSPM_SRAM1_MEMORY)
2141     {
2142         CY_ASSERT_L1( sramMacroNum == 0UL );
2143         retVal = _FLD2VAL(CPUSS_V2_RAM1_PWR_CTL_PWR_MODE, CPUSS_RAM1_PWR_CTL);
2144     }
2145     else if(sramNum == CY_SYSPM_SRAM2_MEMORY)
2146     {
2147         CY_ASSERT_L1( sramMacroNum == 0UL );
2148         retVal = _FLD2VAL(CPUSS_V2_RAM2_PWR_CTL_PWR_MODE, CPUSS_RAM2_PWR_CTL);
2149     }
2150     else
2151     {
2152         /* Invalid SRAM Number */
2153     }
2154     return (cy_en_syspm_sram_pwr_mode_t)retVal;
2155 }
2156 
Cy_SysPm_SetSRAMPwrMode(cy_en_syspm_sram_index_t sramNum,cy_en_syspm_sram_pwr_mode_t sramPwrMode)2157 cy_en_syspm_status_t Cy_SysPm_SetSRAMPwrMode(cy_en_syspm_sram_index_t sramNum, cy_en_syspm_sram_pwr_mode_t sramPwrMode)
2158 {
2159 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
2160     cy_stc_pra_sram_power_mode_config_t pwrModeConfig;
2161 #else
2162     uint32 idx;
2163 #endif /* ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
2164     cy_en_syspm_status_t status = CY_SYSPM_BAD_PARAM;
2165     CY_ASSERT_L1( sramNum < CPUSS_SRAM_COUNT );
2166 
2167 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
2168     pwrModeConfig.sramNum = sramNum;
2169     pwrModeConfig.sramPwrMode = sramPwrMode;
2170 
2171     status = (cy_en_syspm_status_t)CY_PRA_FUNCTION_CALL_RETURN_PARAM(CY_PRA_MSG_TYPE_SECURE_ONLY, CY_PRA_PM_FUNC_SRAM_PWR_MODE, &pwrModeConfig);
2172 #else
2173     if(sramNum == CY_SYSPM_SRAM0_MEMORY)
2174     {
2175         for(idx = 0UL; idx < CPUSS_RAMC0_MACRO_NR; idx++)
2176         {
2177             CPUSS_RAM0_PWR_CTL(idx) = _VAL2FLD(CPUSS_V2_RAM0_PWR_MACRO_CTL_VECTKEYSTAT, CY_SYSPM_PWR_MACRO_CTL_WRITE_KEY) |
2178                                         _VAL2FLD(CPUSS_V2_RAM0_PWR_MACRO_CTL_PWR_MODE, sramPwrMode);
2179         }
2180         status = CY_SYSPM_SUCCESS;
2181     }
2182     else if(sramNum == CY_SYSPM_SRAM1_MEMORY)
2183     {
2184         CY_ASSERT_L1( CPUSS_RAMC1_PRESENT );
2185         CPUSS_RAM1_PWR_CTL = _VAL2FLD(CPUSS_V2_RAM1_PWR_CTL_VECTKEYSTAT, CY_SYSPM_PWR_MACRO_CTL_WRITE_KEY) |
2186                                         _VAL2FLD(CPUSS_V2_RAM1_PWR_CTL_PWR_MODE, sramPwrMode);
2187         status = CY_SYSPM_SUCCESS;
2188 
2189     }
2190     else if(sramNum == CY_SYSPM_SRAM2_MEMORY)
2191     {
2192         CY_ASSERT_L1( CPUSS_RAMC2_PRESENT );
2193         CPUSS_RAM2_PWR_CTL = _VAL2FLD(CPUSS_V2_RAM2_PWR_CTL_VECTKEYSTAT, CY_SYSPM_PWR_MACRO_CTL_WRITE_KEY) |
2194                                         _VAL2FLD(CPUSS_V2_RAM2_PWR_CTL_PWR_MODE, sramPwrMode);
2195         status = CY_SYSPM_SUCCESS;
2196 
2197     }
2198     else
2199     {
2200         /* Invalid SRAM Number */
2201     }
2202 #endif /* ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
2203     return status;
2204 }
2205 
2206 #if !((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
2207 /*******************************************************************************
2208 * Function Name: SetReadMarginTrimUlp
2209 ****************************************************************************//**
2210 *
2211 * This is the internal function that updates the read-margin trim values for the
2212 * RAM and ROM. The trim update is done during transition of regulator voltage
2213 * from higher to a lower one.
2214 *
2215 *******************************************************************************/
SetReadMarginTrimUlp(void)2216 static void SetReadMarginTrimUlp(void)
2217 {
2218     /* Update read-write margin value for the ULP mode. Cypress ID#297292 */
2219     if (Cy_SysLib_GetDevice() == CY_SYSLIB_DEVICE_PSOC6ABLE2)
2220     {
2221         CPUSS_TRIM_RAM_CTL = (CPUSS_TRIM_RAM_CTL & ((uint32_t) ~CPUSS_TRIM_RAM_CTL_RM_Msk)) |
2222                              (CPUSS_TRIM_RAM_ULP & CPUSS_TRIM_RAM_CTL_RM_Msk);
2223 
2224         CPUSS_TRIM_ROM_CTL = (CPUSS_TRIM_ROM_CTL & ((uint32_t) ~CPUSS_TRIM_ROM_CTL_RM_Msk)) |
2225                              (CPUSS_TRIM_ROM_ULP & CPUSS_TRIM_ROM_CTL_RM_Msk);
2226     }
2227     else
2228     {
2229         CPUSS_TRIM_RAM_CTL = (SFLASH_CPUSS_TRIM_RAM_CTL_HALF_ULP & ((uint32_t) ~CPUSS_TRIM_RAM_CTL_RA_MASK)) |
2230                              (CPUSS_TRIM_RAM_CTL & CPUSS_TRIM_RAM_CTL_RA_MASK);
2231 
2232         CPUSS_TRIM_ROM_CTL = SFLASH_CPUSS_TRIM_ROM_CTL_HALF_ULP;
2233     }
2234 }
2235 
2236 
2237 /*******************************************************************************
2238 * Function Name: SetReadMarginTrimLp
2239 ****************************************************************************//**
2240 *
2241 * The internal function that updates the read-margin trim values for the
2242 * RAM and ROM. The trim update is done during transition of regulator voltage
2243 * from a lower to a higher one.
2244 *
2245 *******************************************************************************/
SetReadMarginTrimLp(void)2246 static void SetReadMarginTrimLp(void)
2247 {
2248     /* Update read-write margin value for the LP mode. Cypress ID#297292 */
2249     if (Cy_SysLib_GetDevice() == CY_SYSLIB_DEVICE_PSOC6ABLE2)
2250     {
2251         CPUSS_TRIM_RAM_CTL = (CPUSS_TRIM_RAM_CTL & ((uint32_t) ~CPUSS_TRIM_RAM_CTL_RM_Msk)) |
2252                              (CPUSS_TRIM_RAM_LP & CPUSS_TRIM_RAM_CTL_RM_Msk);
2253 
2254         CPUSS_TRIM_ROM_CTL = (CPUSS_TRIM_ROM_CTL & ((uint32_t) ~CPUSS_TRIM_ROM_CTL_RM_Msk)) |
2255                              (CPUSS_TRIM_ROM_LP & CPUSS_TRIM_ROM_CTL_RM_Msk);
2256     }
2257     else
2258     {
2259         CPUSS_TRIM_RAM_CTL = (SFLASH_CPUSS_TRIM_RAM_CTL_LP & ((uint32_t) ~CPUSS_TRIM_RAM_CTL_RA_MASK)) |
2260                              (CPUSS_TRIM_RAM_CTL & CPUSS_TRIM_RAM_CTL_RA_MASK);
2261 
2262         CPUSS_TRIM_ROM_CTL =  SFLASH_CPUSS_TRIM_ROM_CTL_LP;
2263     }
2264 }
2265 
2266 
2267 /*******************************************************************************
2268 * Function Name: SetWriteAssistTrimUlp
2269 ****************************************************************************//**
2270 *
2271 * The internal function that updates the write assistant trim value for the
2272 * RAM. The trim update is done during transition of regulator voltage
2273 * from higher to a lower.
2274 *
2275 *******************************************************************************/
SetWriteAssistTrimUlp(void)2276 static void SetWriteAssistTrimUlp(void)
2277 {
2278     /* Update write assist value for the LP mode. Cypress ID#297292 */
2279     if (Cy_SysLib_GetDevice() == CY_SYSLIB_DEVICE_PSOC6ABLE2)
2280     {
2281         CPUSS_TRIM_RAM_CTL = (CPUSS_TRIM_RAM_CTL & ((uint32_t) ~CPUSS_TRIM_RAM_CTL_WA_Msk)) |
2282                              (CPUSS_TRIM_RAM_ULP & CPUSS_TRIM_RAM_CTL_WA_Msk);
2283     }
2284     else
2285     {
2286         CPUSS_TRIM_RAM_CTL = (SFLASH_CPUSS_TRIM_RAM_CTL_ULP & ((uint32_t) ~CPUSS_TRIM_RAM_CTL_RA_MASK)) |
2287                              (CPUSS_TRIM_RAM_CTL & CPUSS_TRIM_RAM_CTL_RA_MASK);
2288     }
2289 }
2290 
2291 
2292 /*******************************************************************************
2293 * Function Name: SetWriteAssistTrimLp
2294 ****************************************************************************//**
2295 *
2296 * The internal function that updates the write assistant trim value for the
2297 * RAM. The trim update is done during transition of regulator voltage
2298 * from lower to a higher one.
2299 *
2300 *******************************************************************************/
SetWriteAssistTrimLp(void)2301 static void SetWriteAssistTrimLp(void)
2302 {
2303     /* Update write assist value for the LP mode. Cypress ID#297292 */
2304     if (Cy_SysLib_GetDevice() == CY_SYSLIB_DEVICE_PSOC6ABLE2)
2305     {
2306         CPUSS_TRIM_RAM_CTL = (CPUSS_TRIM_RAM_CTL & ((uint32_t) ~CPUSS_TRIM_RAM_CTL_WA_Msk)) |
2307                              (CPUSS_TRIM_RAM_LP & CPUSS_TRIM_RAM_CTL_WA_Msk);
2308     }
2309     else
2310     {
2311         CPUSS_TRIM_RAM_CTL = (SFLASH_CPUSS_TRIM_RAM_CTL_HALF_LP & ((uint32_t) ~CPUSS_TRIM_RAM_CTL_RA_MASK)) |
2312                              (CPUSS_TRIM_RAM_CTL & CPUSS_TRIM_RAM_CTL_RA_MASK);
2313 
2314         CPUSS_TRIM_ROM_CTL = SFLASH_CPUSS_TRIM_ROM_CTL_HALF_LP;
2315     }
2316 }
2317 
2318 
2319 /*******************************************************************************
2320 * Function Name: IsVoltageChangePossible
2321 ****************************************************************************//**
2322 *
2323 * The internal function that checks wherever it is possible to change the core
2324 * voltage. The voltage change is possible only when the protection context is
2325 * set to zero (PC = 0), or the device supports modifying registers via syscall.
2326 *
2327 *******************************************************************************/
IsVoltageChangePossible(void)2328 static bool IsVoltageChangePossible(void)
2329 {
2330     bool retVal = false;
2331     uint32_t trimRamCheckVal = (CPUSS_TRIM_RAM_CTL & CPUSS_TRIM_RAM_CTL_WC_MASK);
2332 
2333     if (Cy_SysLib_GetDevice() == CY_SYSLIB_DEVICE_PSOC6ABLE2)
2334     {
2335         uint32_t curProtContext = Cy_Prot_GetActivePC(ACTIVE_BUS_MASTER);
2336 
2337         retVal = ((Cy_SysLib_GetDeviceRevision() > SYSPM_DEVICE_PSOC6ABLE2_REV_0B) || (curProtContext == 0U));
2338     }
2339     else
2340     {
2341         CPUSS_TRIM_RAM_CTL &= ~CPUSS_TRIM_RAM_CTL_WC_MASK;
2342         CPUSS_TRIM_RAM_CTL |= ((~trimRamCheckVal) & CPUSS_TRIM_RAM_CTL_WC_MASK);
2343 
2344         retVal = (trimRamCheckVal != (CPUSS_TRIM_RAM_CTL & CPUSS_TRIM_RAM_CTL_WC_MASK));
2345     }
2346 
2347     return retVal;
2348 }
2349 #endif /* !((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
2350 
2351 
2352 
Cy_SysPm_Cm4IsActive(void)2353 bool Cy_SysPm_Cm4IsActive(void)
2354 {
2355     return ((Cy_SysPm_ReadStatus() & CY_SYSPM_STATUS_CM4_ACTIVE) != 0U);
2356 }
2357 
2358 
Cy_SysPm_Cm4IsSleep(void)2359 bool Cy_SysPm_Cm4IsSleep(void)
2360 {
2361     return ((Cy_SysPm_ReadStatus() & CY_SYSPM_STATUS_CM4_SLEEP) != 0U);
2362 }
2363 
2364 
Cy_SysPm_Cm4IsDeepSleep(void)2365 bool Cy_SysPm_Cm4IsDeepSleep(void)
2366 {
2367     return ((Cy_SysPm_ReadStatus() & CY_SYSPM_STATUS_CM4_DEEPSLEEP) != 0U);
2368 }
2369 
2370 #if (__CORTEX_M == 0) || (defined (__CM0P_PRESENT) && (__CM0P_PRESENT == 1))
Cy_SysPm_Cm0IsActive(void)2371 bool Cy_SysPm_Cm0IsActive(void)
2372 {
2373     return ((Cy_SysPm_ReadStatus() & CY_SYSPM_STATUS_CM0_ACTIVE) != 0U);
2374 }
2375 
Cy_SysPm_Cm0IsSleep(void)2376 bool Cy_SysPm_Cm0IsSleep(void)
2377 {
2378     return((Cy_SysPm_ReadStatus() & CY_SYSPM_STATUS_CM0_SLEEP) != 0U);
2379 }
2380 
2381 
Cy_SysPm_Cm0IsDeepSleep(void)2382 bool Cy_SysPm_Cm0IsDeepSleep(void)
2383 {
2384     return((Cy_SysPm_ReadStatus() & CY_SYSPM_STATUS_CM0_DEEPSLEEP) != 0U);
2385 }
2386 #endif /* (__CORTEX_M == 0) || (defined (__CM0P_PRESENT) && (__CM0P_PRESENT == 1)) */
2387 
Cy_SysPm_IsSystemLp(void)2388 bool Cy_SysPm_IsSystemLp(void)
2389 {
2390     return((Cy_SysPm_ReadStatus() & CY_SYSPM_STATUS_SYSTEM_LP) != 0U);
2391 }
2392 
2393 
Cy_SysPm_IsSystemUlp(void)2394 bool Cy_SysPm_IsSystemUlp(void)
2395 {
2396     return((Cy_SysPm_ReadStatus() & CY_SYSPM_STATUS_SYSTEM_ULP) != 0U);
2397 }
2398 
2399 
Cy_SysPm_CpuSendWakeupEvent(void)2400 void Cy_SysPm_CpuSendWakeupEvent(void)
2401 {
2402     __SEV();
2403 }
2404 
2405 
Cy_SysPm_SystemIsMinRegulatorCurrentSet(void)2406 bool Cy_SysPm_SystemIsMinRegulatorCurrentSet(void)
2407 {
2408     uint32_t regMask = Cy_SysPm_LdoIsEnabled() ? CY_SYSPM_PWR_CIRCUITS_LPMODE_ACTIVE_LDO_MASK : CY_SYSPM_PWR_CIRCUITS_LPMODE_ACTIVE_BUCK_MASK;
2409 
2410     return ((SRSS_PWR_CTL & regMask) == regMask);
2411 }
2412 
2413 
Cy_SysPm_BuckIsEnabled(void)2414 bool Cy_SysPm_BuckIsEnabled(void)
2415 {
2416     return (0U != _FLD2VAL(SRSS_PWR_BUCK_CTL_BUCK_EN, SRSS_PWR_BUCK_CTL));
2417 }
2418 
2419 
Cy_SysPm_BuckGetVoltage1(void)2420 cy_en_syspm_buck_voltage1_t Cy_SysPm_BuckGetVoltage1(void)
2421 {
2422     uint32_t retVal;
2423     retVal = _FLD2VAL(SRSS_PWR_BUCK_CTL_BUCK_OUT1_SEL, SRSS_PWR_BUCK_CTL);
2424 
2425     return ((cy_en_syspm_buck_voltage1_t) retVal);
2426 }
2427 
2428 
Cy_SysPm_BuckGetVoltage2(void)2429 cy_en_syspm_buck_voltage2_t Cy_SysPm_BuckGetVoltage2(void)
2430 {
2431     uint32_t retVal = 0UL;
2432 
2433     if (0U != cy_device->sysPmSimoPresent)
2434     {
2435         retVal = _FLD2VAL(SRSS_PWR_BUCK_CTL2_BUCK_OUT2_SEL, SRSS_PWR_BUCK_CTL2);
2436     }
2437 
2438     return ((cy_en_syspm_buck_voltage2_t) retVal);
2439 }
2440 
2441 
Cy_SysPm_BuckDisableVoltage2(void)2442 void Cy_SysPm_BuckDisableVoltage2(void)
2443 {
2444 #if ((CY_CPU_CORTEX_M4) && (defined (CY_DEVICE_SECURE)))
2445     CY_PRA_FUNCTION_CALL_VOID_VOID(CY_PRA_MSG_TYPE_SECURE_ONLY,
2446                                    CY_PRA_PM_FUNC_BUCK_DISABLE_VOLTAGE2);
2447 #else
2448     if (0U != cy_device->sysPmSimoPresent)
2449     {
2450         /* Disable the Vbuck2 output */
2451         SRSS_PWR_BUCK_CTL2 &= (uint32_t) ~_VAL2FLD(SRSS_PWR_BUCK_CTL2_BUCK_OUT2_EN, 1U);
2452     }
2453 #endif /* ((CY_CPU_CORTEX_M4) && (defined (CY_DEVICE_SECURE))) */
2454 }
2455 
2456 
Cy_SysPm_BuckSetVoltage2HwControl(bool hwControl)2457 void Cy_SysPm_BuckSetVoltage2HwControl(bool hwControl)
2458 {
2459 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
2460     CY_PRA_FUNCTION_CALL_VOID_PARAM(CY_PRA_MSG_TYPE_SECURE_ONLY,
2461                                     CY_PRA_PM_FUNC_BUCK_VOLTAGE2_HW_CTRL,
2462                                     hwControl);
2463 #else
2464     bool isBuckEnabled = Cy_SysPm_BuckIsEnabled();
2465 
2466     if ((0U != cy_device->sysPmSimoPresent) && isBuckEnabled)
2467     {
2468         if(hwControl)
2469         {
2470             SRSS_PWR_BUCK_CTL2 |= _VAL2FLD(SRSS_PWR_BUCK_CTL2_BUCK_OUT2_HW_SEL, 1U);
2471         }
2472         else
2473         {
2474             SRSS_PWR_BUCK_CTL2 &= (uint32_t) ~_VAL2FLD(SRSS_PWR_BUCK_CTL2_BUCK_OUT2_HW_SEL, 1U);
2475         }
2476     }
2477 #endif /* ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
2478 }
2479 
2480 
Cy_SysPm_BuckIsVoltage2HwControlled(void)2481 bool Cy_SysPm_BuckIsVoltage2HwControlled(void)
2482 {
2483     bool retVal = false;
2484 
2485     if (0U != cy_device->sysPmSimoPresent)
2486     {
2487         retVal = (0U != _FLD2VAL(SRSS_PWR_BUCK_CTL2_BUCK_OUT2_HW_SEL, SRSS_PWR_BUCK_CTL2));
2488     }
2489 
2490     return retVal;
2491 }
2492 
2493 
Cy_SysPm_LdoGetVoltage(void)2494 cy_en_syspm_ldo_voltage_t Cy_SysPm_LdoGetVoltage(void)
2495 {
2496     uint32_t curVoltage;
2497 
2498     curVoltage = _FLD2VAL(SRSS_PWR_TRIM_PWRSYS_CTL_ACT_REG_TRIM, SRSS_PWR_TRIM_PWRSYS_CTL);
2499 
2500     return ((curVoltage == (SFLASH_LDO_0P9V_TRIM)) ? CY_SYSPM_LDO_VOLTAGE_ULP : CY_SYSPM_LDO_VOLTAGE_LP);
2501 }
2502 
2503 
Cy_SysPm_LdoIsEnabled(void)2504 bool Cy_SysPm_LdoIsEnabled(void)
2505 {
2506     return ((0U != _FLD2VAL(SRSS_PWR_CTL_LINREG_DIS, SRSS_PWR_CTL)) ? false : true);
2507 }
2508 
2509 
Cy_SysPm_IoIsFrozen(void)2510 bool Cy_SysPm_IoIsFrozen(void)
2511 {
2512     return (0U != _FLD2VAL(SRSS_PWR_HIBERNATE_FREEZE, SRSS_PWR_HIBERNATE));
2513 }
2514 
2515 
Cy_SysPm_PmicEnable(void)2516 void Cy_SysPm_PmicEnable(void)
2517 {
2518     if (CY_SYSPM_PMIC_UNLOCK_KEY == _FLD2VAL(BACKUP_PMIC_CTL_UNLOCK, BACKUP_PMIC_CTL))
2519     {
2520         BACKUP_PMIC_CTL =
2521         _VAL2FLD(BACKUP_PMIC_CTL_UNLOCK, CY_SYSPM_PMIC_UNLOCK_KEY) |
2522         _VAL2FLD(BACKUP_PMIC_CTL_PMIC_EN_OUTEN, 1U) |
2523         _VAL2FLD(BACKUP_PMIC_CTL_PMIC_EN, 1U);
2524     }
2525 }
2526 
2527 
Cy_SysPm_PmicDisable(cy_en_syspm_pmic_wakeup_polarity_t polarity)2528 void Cy_SysPm_PmicDisable(cy_en_syspm_pmic_wakeup_polarity_t polarity)
2529 {
2530     CY_ASSERT_L3(CY_SYSPM_IS_POLARITY_VALID(polarity));
2531 
2532     if (CY_SYSPM_PMIC_UNLOCK_KEY == _FLD2VAL(BACKUP_PMIC_CTL_UNLOCK, BACKUP_PMIC_CTL))
2533     {
2534         BACKUP_PMIC_CTL =
2535         (_VAL2FLD(BACKUP_PMIC_CTL_UNLOCK, CY_SYSPM_PMIC_UNLOCK_KEY) |
2536          _CLR_SET_FLD32U(BACKUP_PMIC_CTL, BACKUP_PMIC_CTL_POLARITY, (uint32_t) polarity)) &
2537         ((uint32_t) ~ _VAL2FLD(BACKUP_PMIC_CTL_PMIC_EN, 1U));
2538     }
2539 }
2540 
2541 
Cy_SysPm_PmicAlwaysEnable(void)2542 void Cy_SysPm_PmicAlwaysEnable(void)
2543 {
2544     BACKUP_PMIC_CTL |= _VAL2FLD(BACKUP_PMIC_CTL_PMIC_ALWAYSEN, 1U);
2545 }
2546 
2547 
Cy_SysPm_PmicEnableOutput(void)2548 void Cy_SysPm_PmicEnableOutput(void)
2549 {
2550     if (CY_SYSPM_PMIC_UNLOCK_KEY == _FLD2VAL(BACKUP_PMIC_CTL_UNLOCK, BACKUP_PMIC_CTL))
2551     {
2552         BACKUP_PMIC_CTL |=
2553         _VAL2FLD(BACKUP_PMIC_CTL_UNLOCK, CY_SYSPM_PMIC_UNLOCK_KEY) | _VAL2FLD(BACKUP_PMIC_CTL_PMIC_EN_OUTEN, 1U);
2554     }
2555 }
2556 
2557 
Cy_SysPm_PmicDisableOutput(void)2558 void Cy_SysPm_PmicDisableOutput(void)
2559 {
2560     if (CY_SYSPM_PMIC_UNLOCK_KEY == _FLD2VAL(BACKUP_PMIC_CTL_UNLOCK, BACKUP_PMIC_CTL))
2561     {
2562         BACKUP_PMIC_CTL =
2563         (BACKUP_PMIC_CTL | _VAL2FLD(BACKUP_PMIC_CTL_UNLOCK, CY_SYSPM_PMIC_UNLOCK_KEY)) &
2564         ((uint32_t) ~ _VAL2FLD(BACKUP_PMIC_CTL_PMIC_EN_OUTEN, 1U));
2565     }
2566 }
2567 
2568 
Cy_SysPm_PmicLock(void)2569 void Cy_SysPm_PmicLock(void)
2570 {
2571     BACKUP_PMIC_CTL = _CLR_SET_FLD32U(BACKUP_PMIC_CTL, BACKUP_PMIC_CTL_UNLOCK, 0U);
2572 }
2573 
2574 
Cy_SysPm_PmicUnlock(void)2575 void Cy_SysPm_PmicUnlock(void)
2576 {
2577     BACKUP_PMIC_CTL = _CLR_SET_FLD32U(BACKUP_PMIC_CTL, BACKUP_PMIC_CTL_UNLOCK, CY_SYSPM_PMIC_UNLOCK_KEY);
2578 }
2579 
2580 
Cy_SysPm_PmicIsEnabled(void)2581 bool Cy_SysPm_PmicIsEnabled(void)
2582 {
2583     return (0U != _FLD2VAL(BACKUP_PMIC_CTL_PMIC_EN, BACKUP_PMIC_CTL));
2584 }
2585 
2586 
Cy_SysPm_PmicIsOutputEnabled(void)2587 bool Cy_SysPm_PmicIsOutputEnabled(void)
2588 {
2589     return (0U != _FLD2VAL(BACKUP_PMIC_CTL_PMIC_EN_OUTEN, BACKUP_PMIC_CTL));
2590 }
2591 
2592 
Cy_SysPm_PmicIsLocked(void)2593 bool Cy_SysPm_PmicIsLocked(void)
2594 {
2595     return ((_FLD2VAL(BACKUP_PMIC_CTL_UNLOCK, BACKUP_PMIC_CTL) == CY_SYSPM_PMIC_UNLOCK_KEY) ? false : true);
2596 }
2597 
2598 
Cy_SysPm_BackupSetSupply(cy_en_syspm_vddbackup_control_t vddBackControl)2599 void Cy_SysPm_BackupSetSupply(cy_en_syspm_vddbackup_control_t vddBackControl)
2600 {
2601     CY_ASSERT_L3(CY_SYSPM_IS_VDDBACKUP_VALID(vddBackControl));
2602 
2603     BACKUP_CTL = _CLR_SET_FLD32U((BACKUP_CTL), BACKUP_CTL_VDDBAK_CTL, (uint32_t) vddBackControl);
2604 }
2605 
2606 
Cy_SysPm_BackupGetSupply(void)2607 cy_en_syspm_vddbackup_control_t Cy_SysPm_BackupGetSupply(void)
2608 {
2609     uint32_t retVal;
2610     retVal = _FLD2VAL(BACKUP_CTL_VDDBAK_CTL, BACKUP_CTL);
2611 
2612     return ((cy_en_syspm_vddbackup_control_t) retVal);
2613 }
2614 
2615 
Cy_SysPm_BackupEnableVoltageMeasurement(void)2616 void Cy_SysPm_BackupEnableVoltageMeasurement(void)
2617 {
2618     BACKUP_CTL |= BACKUP_CTL_VBACKUP_MEAS_Msk;
2619 }
2620 
2621 
Cy_SysPm_BackupDisableVoltageMeasurement(void)2622 void Cy_SysPm_BackupDisableVoltageMeasurement(void)
2623 {
2624     BACKUP_CTL &= ((uint32_t) ~BACKUP_CTL_VBACKUP_MEAS_Msk);
2625 }
2626 
2627 
Cy_SysPm_BackupSuperCapCharge(cy_en_syspm_sc_charge_key_t key)2628 void Cy_SysPm_BackupSuperCapCharge(cy_en_syspm_sc_charge_key_t key)
2629 {
2630     CY_ASSERT_L3(CY_SYSPM_IS_SC_CHARGE_KEY_VALID(key));
2631 
2632     if(key == CY_SYSPM_SC_CHARGE_ENABLE)
2633     {
2634         BACKUP_CTL = _CLR_SET_FLD32U((BACKUP_CTL), BACKUP_CTL_EN_CHARGE_KEY, (uint32_t) CY_SYSPM_SC_CHARGE_ENABLE);
2635     }
2636     else
2637     {
2638         BACKUP_CTL &= ((uint32_t) ~BACKUP_CTL_EN_CHARGE_KEY_Msk);
2639     }
2640 }
2641 
2642 #if defined (CY_DEVICE_SECURE)
2643 CY_MISRA_BLOCK_END('MISRA C-2012 Rule 17.2')
2644 CY_MISRA_BLOCK_END('MISRA C-2012 Rule 18.6')
2645 #endif
2646 
2647 #endif
2648 /* [] END OF FILE */
2649