1 /***************************************************************************//**
2 * \file cy_syspm.c
3 * \version 5.94
4 *
5 * This driver provides the source code for API power management.
6 *
7 ********************************************************************************
8 * \copyright
9 * Copyright (c) (2016-2023), Cypress Semiconductor Corporation (an Infineon company) or
10 * an affiliate of Cypress Semiconductor Corporation.
11 * SPDX-License-Identifier: Apache-2.0
12 *
13 * Licensed under the Apache License, Version 2.0 (the "License");
14 * you may not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 *     http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS,
21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
24 *******************************************************************************/
25 
26 #include "cy_device.h"
27 
28 #if defined (CY_IP_MXS40SRSS) && (CY_IP_MXS40SRSS_VERSION < 3)
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 ((0U != cy_device->udbPresent) && (0UL != (PERI_GR_SL_CTL(MMIO_UDB_SLAVE_NR) & PERI_UDB_SLAVE_ENABLED)))
1912     {
1913         regs->CY_SYSPM_UDB_UDBIF_BANK_CTL_REG = UDB_UDBIF_BANK_CTL;
1914 
1915         regs->CY_SYSPM_UDB_BCTL_MDCLK_EN_REG = UDB_BCTL_MDCLK_EN;
1916         regs->CY_SYSPM_UDB_BCTL_MBCLK_EN_REG = UDB_BCTL_MBCLK_EN;
1917         regs->CY_SYSPM_UDB_BCTL_BOTSEL_L_REG = UDB_BCTL_BOTSEL_L;
1918         regs->CY_SYSPM_UDB_BCTL_BOTSEL_U_REG = UDB_BCTL_BOTSEL_U;
1919         regs->CY_SYSPM_UDB_BCTL_QCLK_EN0_REG = UDB_BCTL_QCLK_EN_0;
1920         regs->CY_SYSPM_UDB_BCTL_QCLK_EN1_REG = UDB_BCTL_QCLK_EN_1;
1921         regs->CY_SYSPM_UDB_BCTL_QCLK_EN2_REG = UDB_BCTL_QCLK_EN_2;
1922     }
1923 }
1924 
1925 
Cy_SysPm_RestoreRegisters(cy_stc_syspm_backup_regs_t const * regs)1926 void Cy_SysPm_RestoreRegisters(cy_stc_syspm_backup_regs_t const *regs)
1927 {
1928     CY_ASSERT_L1(NULL != regs);
1929 
1930     /* Restore the registers after Deep Sleep */
1931     CPUSS_CM0_CLOCK_CTL = regs->CY_SYSPM_CM0_CLOCK_CTL_REG;
1932     CPUSS_CM4_CLOCK_CTL = regs->CY_SYSPM_CM4_CLOCK_CTL_REG;
1933 
1934     if ((0U != cy_device->udbPresent) && (0UL != (PERI_GR_SL_CTL(MMIO_UDB_SLAVE_NR) & PERI_UDB_SLAVE_ENABLED)))
1935     {
1936         UDB_BCTL_MDCLK_EN  = regs->CY_SYSPM_UDB_BCTL_MDCLK_EN_REG;
1937         UDB_BCTL_MBCLK_EN  = regs->CY_SYSPM_UDB_BCTL_MBCLK_EN_REG;
1938         UDB_BCTL_BOTSEL_L  = regs->CY_SYSPM_UDB_BCTL_BOTSEL_L_REG;
1939         UDB_BCTL_BOTSEL_U  = regs->CY_SYSPM_UDB_BCTL_BOTSEL_U_REG;
1940         UDB_BCTL_QCLK_EN_0 = regs->CY_SYSPM_UDB_BCTL_QCLK_EN0_REG;
1941         UDB_BCTL_QCLK_EN_1 = regs->CY_SYSPM_UDB_BCTL_QCLK_EN1_REG;
1942         UDB_BCTL_QCLK_EN_2 = regs->CY_SYSPM_UDB_BCTL_QCLK_EN2_REG;
1943 
1944         UDB_UDBIF_BANK_CTL = regs->CY_SYSPM_UDB_UDBIF_BANK_CTL_REG;
1945     }
1946 }
1947 #endif /* !((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
1948 
1949 
1950 /*******************************************************************************
1951 * Function Name: EnterDeepSleepRam
1952 ****************************************************************************//**
1953 *
1954 * The internal function that prepares the system for Deep Sleep and
1955 * restores the system after a wakeup from Deep Sleep.
1956 *
1957 * \param waitFor
1958 * Selects wait for action. See \ref cy_en_syspm_waitfor_t.
1959 *
1960 * \return
1961 * - true - System Deep Sleep was occurred.
1962 * - false - System Deep Sleep was not occurred.
1963 *
1964 *******************************************************************************/
1965 CY_SECTION_RAMFUNC_BEGIN
1966 #if !defined (__ICCARM__)
1967     CY_NOINLINE
1968 #endif
EnterDeepSleepRam(cy_en_syspm_waitfor_t waitFor)1969 static void EnterDeepSleepRam(cy_en_syspm_waitfor_t waitFor)
1970 {
1971 #if !((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
1972 
1973     /* Store the address of the Deep Sleep indicator into the RAM */
1974     volatile uint32_t *delayDoneFlag = DELAY_FLAG_REGISTER_ADDR;
1975 #endif /* !((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
1976 
1977 #if (CY_CPU_CORTEX_M4)
1978 
1979     /* Store the address of the CM4 power status register */
1980     volatile uint32_t *cpussCm4PwrCtlAddr = &CPUSS_CM4_PWR_CTL;
1981 
1982     /* Repeat the WFI/WFE instruction if a wake up was not intended.
1983     *  Cypress ID #272909
1984     */
1985     do
1986     {
1987 #endif /* (CY_CPU_CORTEX_M4) */
1988 
1989         /* The CPU enters Deep Sleep mode upon execution of WFI/WFE */
1990         SCB_SCR |= SCB_SCR_SLEEPDEEP_Msk;
1991 
1992         if(waitFor != CY_SYSPM_WAIT_FOR_EVENT)
1993         {
1994             __WFI();
1995         }
1996         else
1997         {
1998             __WFE();
1999 
2000         #if (CY_CPU_CORTEX_M4)
2001             /* Call the WFE instruction twice to clear the Event register
2002             *  of the CM4 CPU. Cypress ID #279077
2003             */
2004             if(wasEventSent)
2005             {
2006                 __WFE();
2007             }
2008             wasEventSent = true;
2009         #endif /* (CY_CPU_CORTEX_M4) */
2010         }
2011 
2012 #if (CY_CPU_CORTEX_M4)
2013     } while (_FLD2VAL(CPUSS_CM4_PWR_CTL_PWR_MODE, (*cpussCm4PwrCtlAddr)) == CM4_PWR_STS_RETAINED);
2014 
2015     #if defined(CY_DEVICE_SECURE)
2016         CY_PRA_CM0_WAKEUP();
2017     #endif /* defined(CY_DEVICE_SECURE) */
2018 #endif /* (CY_CPU_CORTEX_M4) */
2019 
2020 #if !((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
2021     /* Set 10 uS delay only under condition that the FLASHC_BIST_DATA[0] is
2022     *  cleared. Cypress ID #288510
2023     */
2024     if (*delayDoneFlag == NEED_DELAY)
2025     {
2026         uint32_t ddftSlowCtl;
2027         uint32_t clkOutputSlow;
2028         uint32_t ddftFastCtl;
2029 
2030     #if defined(CY_DEVICE_SECURE)
2031         Cy_PRA_CloseSrssMain2();
2032     #endif /* defined(CY_DEVICE_SECURE) */
2033 
2034         /* Save timer configuration */
2035         ddftSlowCtl   = SRSS_TST_DDFT_SLOW_CTL_REG;
2036         clkOutputSlow = SRSS_CLK_OUTPUT_SLOW;
2037         ddftFastCtl   = SRSS_TST_DDFT_FAST_CTL_REG;
2038 
2039         /* Configure the counter to be sourced by IMO */
2040         SRSS_TST_DDFT_SLOW_CTL_REG = SRSS_TST_DDFT_SLOW_CTL_MASK;
2041         SRSS_CLK_OUTPUT_SLOW       = CLK_OUTPUT_SLOW_MASK;
2042         SRSS_TST_DDFT_FAST_CTL_REG = TST_DDFT_FAST_CTL_MASK;
2043 
2044         /* Load the down-counter to count the 10 us */
2045         SRSS_CLK_CAL_CNT1 = IMO_10US_DELAY;
2046 
2047         while (0U == (SRSS_CLK_CAL_CNT1 & SRSS_CLK_CAL_CNT1_CAL_COUNTER_DONE_Msk))
2048         {
2049             /* Wait until the counter stops counting */
2050         }
2051 
2052         /* Indicate that delay was done */
2053         *delayDoneFlag = DELAY_DONE;
2054 
2055         /* Restore timer configuration */
2056         SRSS_TST_DDFT_SLOW_CTL_REG = ddftSlowCtl;
2057         SRSS_CLK_OUTPUT_SLOW       = clkOutputSlow;
2058         SRSS_TST_DDFT_FAST_CTL_REG = ddftFastCtl;
2059 
2060     #if defined(CY_DEVICE_SECURE)
2061         Cy_PRA_OpenSrssMain2();
2062     #endif /* defined(CY_DEVICE_SECURE) */
2063     }
2064 #endif /* !((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
2065 }
2066 CY_SECTION_RAMFUNC_END
2067 
Cy_SysPm_SetSRAMMacroPwrMode(cy_en_syspm_sram_index_t sramNum,uint32_t sramMacroNum,cy_en_syspm_sram_pwr_mode_t sramPwrMode)2068 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)
2069 {
2070 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
2071     cy_stc_pra_sram_power_mode_config_t pwrModeConfig;
2072 #endif /* ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
2073     cy_en_syspm_status_t status = CY_SYSPM_BAD_PARAM;
2074 
2075     CY_ASSERT_L1( sramNum < CPUSS_SRAM_COUNT );
2076 
2077 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
2078     pwrModeConfig.sramNum = sramNum;
2079     pwrModeConfig.sramMacroNum = sramMacroNum;
2080     pwrModeConfig.sramPwrMode = sramPwrMode;
2081 
2082     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);
2083 
2084 #else
2085 
2086     if(sramNum == CY_SYSPM_SRAM0_MEMORY)
2087     {
2088         CY_ASSERT_L1( sramMacroNum < CPUSS_RAMC0_MACRO_NR );
2089         if (sramMacroNum < CPUSS_RAMC0_MACRO_NR)
2090         {
2091             CPUSS_RAM0_PWR_CTL(sramMacroNum) = _VAL2FLD(CPUSS_V2_RAM0_PWR_MACRO_CTL_VECTKEYSTAT, CY_SYSPM_PWR_MACRO_CTL_WRITE_KEY) |
2092                                                 _VAL2FLD(CPUSS_V2_RAM0_PWR_MACRO_CTL_PWR_MODE, sramPwrMode);
2093             status = CY_SYSPM_SUCCESS;
2094         }
2095     }
2096     else if(sramNum == CY_SYSPM_SRAM1_MEMORY)
2097     {
2098         CY_ASSERT_L1( CPUSS_RAMC1_PRESENT );
2099         CY_ASSERT_L1( sramMacroNum == 0UL );
2100 
2101         CPUSS_RAM1_PWR_CTL = _VAL2FLD(CPUSS_V2_RAM1_PWR_CTL_VECTKEYSTAT, CY_SYSPM_PWR_MACRO_CTL_WRITE_KEY) |
2102                                     _VAL2FLD(CPUSS_V2_RAM1_PWR_CTL_PWR_MODE, sramPwrMode);
2103         status = CY_SYSPM_SUCCESS;
2104     }
2105     else if(sramNum == CY_SYSPM_SRAM2_MEMORY)
2106     {
2107         CY_ASSERT_L1( CPUSS_RAMC2_PRESENT );
2108         CY_ASSERT_L1( sramMacroNum == 0UL );
2109 
2110         CPUSS_RAM2_PWR_CTL = _VAL2FLD(CPUSS_V2_RAM2_PWR_CTL_VECTKEYSTAT, CY_SYSPM_PWR_MACRO_CTL_WRITE_KEY) |
2111                                     _VAL2FLD(CPUSS_V2_RAM2_PWR_CTL_PWR_MODE, sramPwrMode);
2112         status = CY_SYSPM_SUCCESS;
2113     }
2114     else
2115     {
2116         /* Invalid SRAM Number */
2117     }
2118 #endif /* ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
2119     return status;
2120 }
2121 
Cy_SysPm_GetSRAMMacroPwrMode(cy_en_syspm_sram_index_t sramNum,uint32_t sramMacroNum)2122 cy_en_syspm_sram_pwr_mode_t Cy_SysPm_GetSRAMMacroPwrMode(cy_en_syspm_sram_index_t sramNum, uint32_t sramMacroNum)
2123 {
2124     uint32_t retVal = (uint32_t)CY_SYSPM_SRAM_PWR_MODE_INVALID;
2125 
2126     CY_ASSERT_L1( sramNum < CPUSS_SRAM_COUNT );
2127 
2128     if(sramNum == CY_SYSPM_SRAM0_MEMORY)
2129     {
2130         CY_ASSERT_L1( sramMacroNum < CPUSS_RAMC0_MACRO_NR );
2131         if (sramMacroNum < CPUSS_RAMC0_MACRO_NR)
2132         {
2133             retVal = _FLD2VAL(CPUSS_V2_RAM0_PWR_MACRO_CTL_PWR_MODE, CPUSS_RAM0_PWR_CTL(sramMacroNum));
2134         }
2135     }
2136     else if(sramNum == CY_SYSPM_SRAM1_MEMORY)
2137     {
2138         CY_ASSERT_L1( sramMacroNum == 0UL );
2139         retVal = _FLD2VAL(CPUSS_V2_RAM1_PWR_CTL_PWR_MODE, CPUSS_RAM1_PWR_CTL);
2140     }
2141     else if(sramNum == CY_SYSPM_SRAM2_MEMORY)
2142     {
2143         CY_ASSERT_L1( sramMacroNum == 0UL );
2144         retVal = _FLD2VAL(CPUSS_V2_RAM2_PWR_CTL_PWR_MODE, CPUSS_RAM2_PWR_CTL);
2145     }
2146     else
2147     {
2148         /* Invalid SRAM Number */
2149     }
2150     return (cy_en_syspm_sram_pwr_mode_t)retVal;
2151 }
2152 
Cy_SysPm_SetSRAMPwrMode(cy_en_syspm_sram_index_t sramNum,cy_en_syspm_sram_pwr_mode_t sramPwrMode)2153 cy_en_syspm_status_t Cy_SysPm_SetSRAMPwrMode(cy_en_syspm_sram_index_t sramNum, cy_en_syspm_sram_pwr_mode_t sramPwrMode)
2154 {
2155 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
2156     cy_stc_pra_sram_power_mode_config_t pwrModeConfig;
2157 #else
2158     uint32 idx;
2159 #endif /* ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
2160     cy_en_syspm_status_t status = CY_SYSPM_BAD_PARAM;
2161     CY_ASSERT_L1( sramNum < CPUSS_SRAM_COUNT );
2162 
2163 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
2164     pwrModeConfig.sramNum = sramNum;
2165     pwrModeConfig.sramPwrMode = sramPwrMode;
2166 
2167     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);
2168 #else
2169     if(sramNum == CY_SYSPM_SRAM0_MEMORY)
2170     {
2171         for(idx = 0UL; idx < CPUSS_RAMC0_MACRO_NR; idx++)
2172         {
2173             CPUSS_RAM0_PWR_CTL(idx) = _VAL2FLD(CPUSS_V2_RAM0_PWR_MACRO_CTL_VECTKEYSTAT, CY_SYSPM_PWR_MACRO_CTL_WRITE_KEY) |
2174                                         _VAL2FLD(CPUSS_V2_RAM0_PWR_MACRO_CTL_PWR_MODE, sramPwrMode);
2175         }
2176         status = CY_SYSPM_SUCCESS;
2177     }
2178     else if(sramNum == CY_SYSPM_SRAM1_MEMORY)
2179     {
2180         CY_ASSERT_L1( CPUSS_RAMC1_PRESENT );
2181         CPUSS_RAM1_PWR_CTL = _VAL2FLD(CPUSS_V2_RAM1_PWR_CTL_VECTKEYSTAT, CY_SYSPM_PWR_MACRO_CTL_WRITE_KEY) |
2182                                         _VAL2FLD(CPUSS_V2_RAM1_PWR_CTL_PWR_MODE, sramPwrMode);
2183         status = CY_SYSPM_SUCCESS;
2184 
2185     }
2186     else if(sramNum == CY_SYSPM_SRAM2_MEMORY)
2187     {
2188         CY_ASSERT_L1( CPUSS_RAMC2_PRESENT );
2189         CPUSS_RAM2_PWR_CTL = _VAL2FLD(CPUSS_V2_RAM2_PWR_CTL_VECTKEYSTAT, CY_SYSPM_PWR_MACRO_CTL_WRITE_KEY) |
2190                                         _VAL2FLD(CPUSS_V2_RAM2_PWR_CTL_PWR_MODE, sramPwrMode);
2191         status = CY_SYSPM_SUCCESS;
2192 
2193     }
2194     else
2195     {
2196         /* Invalid SRAM Number */
2197     }
2198 #endif /* ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
2199     return status;
2200 }
2201 
2202 #if !((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
2203 /*******************************************************************************
2204 * Function Name: SetReadMarginTrimUlp
2205 ****************************************************************************//**
2206 *
2207 * This is the internal function that updates the read-margin trim values for the
2208 * RAM and ROM. The trim update is done during transition of regulator voltage
2209 * from higher to a lower one.
2210 *
2211 *******************************************************************************/
SetReadMarginTrimUlp(void)2212 static void SetReadMarginTrimUlp(void)
2213 {
2214     /* Update read-write margin value for the ULP mode. Cypress ID#297292 */
2215     if (Cy_SysLib_GetDevice() == CY_SYSLIB_DEVICE_PSOC6ABLE2)
2216     {
2217         CPUSS_TRIM_RAM_CTL = (CPUSS_TRIM_RAM_CTL & ((uint32_t) ~CPUSS_TRIM_RAM_CTL_RM_Msk)) |
2218                              (CPUSS_TRIM_RAM_ULP & CPUSS_TRIM_RAM_CTL_RM_Msk);
2219 
2220         CPUSS_TRIM_ROM_CTL = (CPUSS_TRIM_ROM_CTL & ((uint32_t) ~CPUSS_TRIM_ROM_CTL_RM_Msk)) |
2221                              (CPUSS_TRIM_ROM_ULP & CPUSS_TRIM_ROM_CTL_RM_Msk);
2222     }
2223     else
2224     {
2225         CPUSS_TRIM_RAM_CTL = (SFLASH_CPUSS_TRIM_RAM_CTL_HALF_ULP & ((uint32_t) ~CPUSS_TRIM_RAM_CTL_RA_MASK)) |
2226                              (CPUSS_TRIM_RAM_CTL & CPUSS_TRIM_RAM_CTL_RA_MASK);
2227 
2228         CPUSS_TRIM_ROM_CTL = SFLASH_CPUSS_TRIM_ROM_CTL_HALF_ULP;
2229     }
2230 }
2231 
2232 
2233 /*******************************************************************************
2234 * Function Name: SetReadMarginTrimLp
2235 ****************************************************************************//**
2236 *
2237 * The internal function that updates the read-margin trim values for the
2238 * RAM and ROM. The trim update is done during transition of regulator voltage
2239 * from a lower to a higher one.
2240 *
2241 *******************************************************************************/
SetReadMarginTrimLp(void)2242 static void SetReadMarginTrimLp(void)
2243 {
2244     /* Update read-write margin value for the LP mode. Cypress ID#297292 */
2245     if (Cy_SysLib_GetDevice() == CY_SYSLIB_DEVICE_PSOC6ABLE2)
2246     {
2247         CPUSS_TRIM_RAM_CTL = (CPUSS_TRIM_RAM_CTL & ((uint32_t) ~CPUSS_TRIM_RAM_CTL_RM_Msk)) |
2248                              (CPUSS_TRIM_RAM_LP & CPUSS_TRIM_RAM_CTL_RM_Msk);
2249 
2250         CPUSS_TRIM_ROM_CTL = (CPUSS_TRIM_ROM_CTL & ((uint32_t) ~CPUSS_TRIM_ROM_CTL_RM_Msk)) |
2251                              (CPUSS_TRIM_ROM_LP & CPUSS_TRIM_ROM_CTL_RM_Msk);
2252     }
2253     else
2254     {
2255         CPUSS_TRIM_RAM_CTL = (SFLASH_CPUSS_TRIM_RAM_CTL_LP & ((uint32_t) ~CPUSS_TRIM_RAM_CTL_RA_MASK)) |
2256                              (CPUSS_TRIM_RAM_CTL & CPUSS_TRIM_RAM_CTL_RA_MASK);
2257 
2258         CPUSS_TRIM_ROM_CTL =  SFLASH_CPUSS_TRIM_ROM_CTL_LP;
2259     }
2260 }
2261 
2262 
2263 /*******************************************************************************
2264 * Function Name: SetWriteAssistTrimUlp
2265 ****************************************************************************//**
2266 *
2267 * The internal function that updates the write assistant trim value for the
2268 * RAM. The trim update is done during transition of regulator voltage
2269 * from higher to a lower.
2270 *
2271 *******************************************************************************/
SetWriteAssistTrimUlp(void)2272 static void SetWriteAssistTrimUlp(void)
2273 {
2274     /* Update write assist value for the LP mode. Cypress ID#297292 */
2275     if (Cy_SysLib_GetDevice() == CY_SYSLIB_DEVICE_PSOC6ABLE2)
2276     {
2277         CPUSS_TRIM_RAM_CTL = (CPUSS_TRIM_RAM_CTL & ((uint32_t) ~CPUSS_TRIM_RAM_CTL_WA_Msk)) |
2278                              (CPUSS_TRIM_RAM_ULP & CPUSS_TRIM_RAM_CTL_WA_Msk);
2279     }
2280     else
2281     {
2282         CPUSS_TRIM_RAM_CTL = (SFLASH_CPUSS_TRIM_RAM_CTL_ULP & ((uint32_t) ~CPUSS_TRIM_RAM_CTL_RA_MASK)) |
2283                              (CPUSS_TRIM_RAM_CTL & CPUSS_TRIM_RAM_CTL_RA_MASK);
2284     }
2285 }
2286 
2287 
2288 /*******************************************************************************
2289 * Function Name: SetWriteAssistTrimLp
2290 ****************************************************************************//**
2291 *
2292 * The internal function that updates the write assistant trim value for the
2293 * RAM. The trim update is done during transition of regulator voltage
2294 * from lower to a higher one.
2295 *
2296 *******************************************************************************/
SetWriteAssistTrimLp(void)2297 static void SetWriteAssistTrimLp(void)
2298 {
2299     /* Update write assist value for the LP mode. Cypress ID#297292 */
2300     if (Cy_SysLib_GetDevice() == CY_SYSLIB_DEVICE_PSOC6ABLE2)
2301     {
2302         CPUSS_TRIM_RAM_CTL = (CPUSS_TRIM_RAM_CTL & ((uint32_t) ~CPUSS_TRIM_RAM_CTL_WA_Msk)) |
2303                              (CPUSS_TRIM_RAM_LP & CPUSS_TRIM_RAM_CTL_WA_Msk);
2304     }
2305     else
2306     {
2307         CPUSS_TRIM_RAM_CTL = (SFLASH_CPUSS_TRIM_RAM_CTL_HALF_LP & ((uint32_t) ~CPUSS_TRIM_RAM_CTL_RA_MASK)) |
2308                              (CPUSS_TRIM_RAM_CTL & CPUSS_TRIM_RAM_CTL_RA_MASK);
2309 
2310         CPUSS_TRIM_ROM_CTL = SFLASH_CPUSS_TRIM_ROM_CTL_HALF_LP;
2311     }
2312 }
2313 
2314 
2315 /*******************************************************************************
2316 * Function Name: IsVoltageChangePossible
2317 ****************************************************************************//**
2318 *
2319 * The internal function that checks wherever it is possible to change the core
2320 * voltage. The voltage change is possible only when the protection context is
2321 * set to zero (PC = 0), or the device supports modifying registers via syscall.
2322 *
2323 *******************************************************************************/
IsVoltageChangePossible(void)2324 static bool IsVoltageChangePossible(void)
2325 {
2326     bool retVal = false;
2327     uint32_t trimRamCheckVal = (CPUSS_TRIM_RAM_CTL & CPUSS_TRIM_RAM_CTL_WC_MASK);
2328 
2329 
2330     if (Cy_SysLib_GetDevice() == CY_SYSLIB_DEVICE_PSOC6ABLE2)
2331     {
2332         uint32_t curProtContext = Cy_Prot_GetActivePC(ACTIVE_BUS_MASTER);
2333 
2334         retVal = ((Cy_SysLib_GetDeviceRevision() > SYSPM_DEVICE_PSOC6ABLE2_REV_0B) || (curProtContext == 0U));
2335     }
2336     else
2337     {
2338         CPUSS_TRIM_RAM_CTL &= ~CPUSS_TRIM_RAM_CTL_WC_MASK;
2339         CPUSS_TRIM_RAM_CTL |= ((~trimRamCheckVal) & CPUSS_TRIM_RAM_CTL_WC_MASK);
2340 
2341         retVal = (trimRamCheckVal != (CPUSS_TRIM_RAM_CTL & CPUSS_TRIM_RAM_CTL_WC_MASK));
2342     }
2343 
2344     return retVal;
2345 }
2346 #endif /* !((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
2347 
2348 
2349 
Cy_SysPm_Cm4IsActive(void)2350 bool Cy_SysPm_Cm4IsActive(void)
2351 {
2352     return ((Cy_SysPm_ReadStatus() & CY_SYSPM_STATUS_CM4_ACTIVE) != 0U);
2353 }
2354 
2355 
Cy_SysPm_Cm4IsSleep(void)2356 bool Cy_SysPm_Cm4IsSleep(void)
2357 {
2358     return ((Cy_SysPm_ReadStatus() & CY_SYSPM_STATUS_CM4_SLEEP) != 0U);
2359 }
2360 
2361 
Cy_SysPm_Cm4IsDeepSleep(void)2362 bool Cy_SysPm_Cm4IsDeepSleep(void)
2363 {
2364     return ((Cy_SysPm_ReadStatus() & CY_SYSPM_STATUS_CM4_DEEPSLEEP) != 0U);
2365 }
2366 
2367 #if (__CORTEX_M == 0) || (defined (__CM0P_PRESENT) && (__CM0P_PRESENT == 1))
Cy_SysPm_Cm0IsActive(void)2368 bool Cy_SysPm_Cm0IsActive(void)
2369 {
2370     return ((Cy_SysPm_ReadStatus() & CY_SYSPM_STATUS_CM0_ACTIVE) != 0U);
2371 }
2372 
Cy_SysPm_Cm0IsSleep(void)2373 bool Cy_SysPm_Cm0IsSleep(void)
2374 {
2375     return((Cy_SysPm_ReadStatus() & CY_SYSPM_STATUS_CM0_SLEEP) != 0U);
2376 }
2377 
2378 
Cy_SysPm_Cm0IsDeepSleep(void)2379 bool Cy_SysPm_Cm0IsDeepSleep(void)
2380 {
2381     return((Cy_SysPm_ReadStatus() & CY_SYSPM_STATUS_CM0_DEEPSLEEP) != 0U);
2382 }
2383 #endif /* (__CORTEX_M == 0) || (defined (__CM0P_PRESENT) && (__CM0P_PRESENT == 1)) */
2384 
Cy_SysPm_IsSystemLp(void)2385 bool Cy_SysPm_IsSystemLp(void)
2386 {
2387     return((Cy_SysPm_ReadStatus() & CY_SYSPM_STATUS_SYSTEM_LP) != 0U);
2388 }
2389 
2390 
Cy_SysPm_IsSystemUlp(void)2391 bool Cy_SysPm_IsSystemUlp(void)
2392 {
2393     return((Cy_SysPm_ReadStatus() & CY_SYSPM_STATUS_SYSTEM_ULP) != 0U);
2394 }
2395 
2396 
Cy_SysPm_CpuSendWakeupEvent(void)2397 void Cy_SysPm_CpuSendWakeupEvent(void)
2398 {
2399     __SEV();
2400 }
2401 
2402 
Cy_SysPm_SystemIsMinRegulatorCurrentSet(void)2403 bool Cy_SysPm_SystemIsMinRegulatorCurrentSet(void)
2404 {
2405     uint32_t regMask = Cy_SysPm_LdoIsEnabled() ? CY_SYSPM_PWR_CIRCUITS_LPMODE_ACTIVE_LDO_MASK : CY_SYSPM_PWR_CIRCUITS_LPMODE_ACTIVE_BUCK_MASK;
2406 
2407     return ((SRSS_PWR_CTL & regMask) == regMask);
2408 }
2409 
2410 
Cy_SysPm_BuckIsEnabled(void)2411 bool Cy_SysPm_BuckIsEnabled(void)
2412 {
2413     return (0U != _FLD2VAL(SRSS_PWR_BUCK_CTL_BUCK_EN, SRSS_PWR_BUCK_CTL));
2414 }
2415 
2416 
Cy_SysPm_BuckGetVoltage1(void)2417 cy_en_syspm_buck_voltage1_t Cy_SysPm_BuckGetVoltage1(void)
2418 {
2419     uint32_t retVal;
2420     retVal = _FLD2VAL(SRSS_PWR_BUCK_CTL_BUCK_OUT1_SEL, SRSS_PWR_BUCK_CTL);
2421 
2422     return ((cy_en_syspm_buck_voltage1_t) retVal);
2423 }
2424 
2425 
Cy_SysPm_BuckGetVoltage2(void)2426 cy_en_syspm_buck_voltage2_t Cy_SysPm_BuckGetVoltage2(void)
2427 {
2428     uint32_t retVal = 0UL;
2429 
2430     if (0U != cy_device->sysPmSimoPresent)
2431     {
2432         retVal = _FLD2VAL(SRSS_PWR_BUCK_CTL2_BUCK_OUT2_SEL, SRSS_PWR_BUCK_CTL2);
2433     }
2434 
2435     return ((cy_en_syspm_buck_voltage2_t) retVal);
2436 }
2437 
2438 
Cy_SysPm_BuckDisableVoltage2(void)2439 void Cy_SysPm_BuckDisableVoltage2(void)
2440 {
2441 #if ((CY_CPU_CORTEX_M4) && (defined (CY_DEVICE_SECURE)))
2442     CY_PRA_FUNCTION_CALL_VOID_VOID(CY_PRA_MSG_TYPE_SECURE_ONLY,
2443                                    CY_PRA_PM_FUNC_BUCK_DISABLE_VOLTAGE2);
2444 #else
2445     if (0U != cy_device->sysPmSimoPresent)
2446     {
2447         /* Disable the Vbuck2 output */
2448         SRSS_PWR_BUCK_CTL2 &= (uint32_t) ~_VAL2FLD(SRSS_PWR_BUCK_CTL2_BUCK_OUT2_EN, 1U);
2449     }
2450 #endif /* ((CY_CPU_CORTEX_M4) && (defined (CY_DEVICE_SECURE))) */
2451 }
2452 
2453 
Cy_SysPm_BuckSetVoltage2HwControl(bool hwControl)2454 void Cy_SysPm_BuckSetVoltage2HwControl(bool hwControl)
2455 {
2456 #if ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE)))
2457     CY_PRA_FUNCTION_CALL_VOID_PARAM(CY_PRA_MSG_TYPE_SECURE_ONLY,
2458                                     CY_PRA_PM_FUNC_BUCK_VOLTAGE2_HW_CTRL,
2459                                     hwControl);
2460 #else
2461     bool isBuckEnabled = Cy_SysPm_BuckIsEnabled();
2462 
2463     if ((0U != cy_device->sysPmSimoPresent) && isBuckEnabled)
2464     {
2465         if(hwControl)
2466         {
2467             SRSS_PWR_BUCK_CTL2 |= _VAL2FLD(SRSS_PWR_BUCK_CTL2_BUCK_OUT2_HW_SEL, 1U);
2468         }
2469         else
2470         {
2471             SRSS_PWR_BUCK_CTL2 &= (uint32_t) ~_VAL2FLD(SRSS_PWR_BUCK_CTL2_BUCK_OUT2_HW_SEL, 1U);
2472         }
2473     }
2474 #endif /* ((CY_CPU_CORTEX_M4) && (defined(CY_DEVICE_SECURE))) */
2475 }
2476 
2477 
Cy_SysPm_BuckIsVoltage2HwControlled(void)2478 bool Cy_SysPm_BuckIsVoltage2HwControlled(void)
2479 {
2480     bool retVal = false;
2481 
2482     if (0U != cy_device->sysPmSimoPresent)
2483     {
2484         retVal = (0U != _FLD2VAL(SRSS_PWR_BUCK_CTL2_BUCK_OUT2_HW_SEL, SRSS_PWR_BUCK_CTL2));
2485     }
2486 
2487     return retVal;
2488 }
2489 
2490 
Cy_SysPm_LdoGetVoltage(void)2491 cy_en_syspm_ldo_voltage_t Cy_SysPm_LdoGetVoltage(void)
2492 {
2493     uint32_t curVoltage;
2494 
2495     curVoltage = _FLD2VAL(SRSS_PWR_TRIM_PWRSYS_CTL_ACT_REG_TRIM, SRSS_PWR_TRIM_PWRSYS_CTL);
2496 
2497     return ((curVoltage == (SFLASH_LDO_0P9V_TRIM)) ? CY_SYSPM_LDO_VOLTAGE_ULP : CY_SYSPM_LDO_VOLTAGE_LP);
2498 }
2499 
2500 
Cy_SysPm_LdoIsEnabled(void)2501 bool Cy_SysPm_LdoIsEnabled(void)
2502 {
2503     return ((0U != _FLD2VAL(SRSS_PWR_CTL_LINREG_DIS, SRSS_PWR_CTL)) ? false : true);
2504 }
2505 
2506 
Cy_SysPm_IoIsFrozen(void)2507 bool Cy_SysPm_IoIsFrozen(void)
2508 {
2509     return (0U != _FLD2VAL(SRSS_PWR_HIBERNATE_FREEZE, SRSS_PWR_HIBERNATE));
2510 }
2511 
2512 
Cy_SysPm_PmicEnable(void)2513 void Cy_SysPm_PmicEnable(void)
2514 {
2515     if (CY_SYSPM_PMIC_UNLOCK_KEY == _FLD2VAL(BACKUP_PMIC_CTL_UNLOCK, BACKUP_PMIC_CTL))
2516     {
2517         BACKUP_PMIC_CTL =
2518         _VAL2FLD(BACKUP_PMIC_CTL_UNLOCK, CY_SYSPM_PMIC_UNLOCK_KEY) |
2519         _VAL2FLD(BACKUP_PMIC_CTL_PMIC_EN_OUTEN, 1U) |
2520         _VAL2FLD(BACKUP_PMIC_CTL_PMIC_EN, 1U);
2521     }
2522 }
2523 
2524 
Cy_SysPm_PmicDisable(cy_en_syspm_pmic_wakeup_polarity_t polarity)2525 void Cy_SysPm_PmicDisable(cy_en_syspm_pmic_wakeup_polarity_t polarity)
2526 {
2527     CY_ASSERT_L3(CY_SYSPM_IS_POLARITY_VALID(polarity));
2528 
2529     if (CY_SYSPM_PMIC_UNLOCK_KEY == _FLD2VAL(BACKUP_PMIC_CTL_UNLOCK, BACKUP_PMIC_CTL))
2530     {
2531         BACKUP_PMIC_CTL =
2532         (_VAL2FLD(BACKUP_PMIC_CTL_UNLOCK, CY_SYSPM_PMIC_UNLOCK_KEY) |
2533          _CLR_SET_FLD32U(BACKUP_PMIC_CTL, BACKUP_PMIC_CTL_POLARITY, (uint32_t) polarity)) &
2534         ((uint32_t) ~ _VAL2FLD(BACKUP_PMIC_CTL_PMIC_EN, 1U));
2535     }
2536 }
2537 
2538 
Cy_SysPm_PmicAlwaysEnable(void)2539 void Cy_SysPm_PmicAlwaysEnable(void)
2540 {
2541     BACKUP_PMIC_CTL |= _VAL2FLD(BACKUP_PMIC_CTL_PMIC_ALWAYSEN, 1U);
2542 }
2543 
2544 
Cy_SysPm_PmicEnableOutput(void)2545 void Cy_SysPm_PmicEnableOutput(void)
2546 {
2547     if (CY_SYSPM_PMIC_UNLOCK_KEY == _FLD2VAL(BACKUP_PMIC_CTL_UNLOCK, BACKUP_PMIC_CTL))
2548     {
2549         BACKUP_PMIC_CTL |=
2550         _VAL2FLD(BACKUP_PMIC_CTL_UNLOCK, CY_SYSPM_PMIC_UNLOCK_KEY) | _VAL2FLD(BACKUP_PMIC_CTL_PMIC_EN_OUTEN, 1U);
2551     }
2552 }
2553 
2554 
Cy_SysPm_PmicDisableOutput(void)2555 void Cy_SysPm_PmicDisableOutput(void)
2556 {
2557     if (CY_SYSPM_PMIC_UNLOCK_KEY == _FLD2VAL(BACKUP_PMIC_CTL_UNLOCK, BACKUP_PMIC_CTL))
2558     {
2559         BACKUP_PMIC_CTL =
2560         (BACKUP_PMIC_CTL | _VAL2FLD(BACKUP_PMIC_CTL_UNLOCK, CY_SYSPM_PMIC_UNLOCK_KEY)) &
2561         ((uint32_t) ~ _VAL2FLD(BACKUP_PMIC_CTL_PMIC_EN_OUTEN, 1U));
2562     }
2563 }
2564 
2565 
Cy_SysPm_PmicLock(void)2566 void Cy_SysPm_PmicLock(void)
2567 {
2568     BACKUP_PMIC_CTL = _CLR_SET_FLD32U(BACKUP_PMIC_CTL, BACKUP_PMIC_CTL_UNLOCK, 0U);
2569 }
2570 
2571 
Cy_SysPm_PmicUnlock(void)2572 void Cy_SysPm_PmicUnlock(void)
2573 {
2574     BACKUP_PMIC_CTL = _CLR_SET_FLD32U(BACKUP_PMIC_CTL, BACKUP_PMIC_CTL_UNLOCK, CY_SYSPM_PMIC_UNLOCK_KEY);
2575 }
2576 
2577 
Cy_SysPm_PmicIsEnabled(void)2578 bool Cy_SysPm_PmicIsEnabled(void)
2579 {
2580     return (0U != _FLD2VAL(BACKUP_PMIC_CTL_PMIC_EN, BACKUP_PMIC_CTL));
2581 }
2582 
2583 
Cy_SysPm_PmicIsOutputEnabled(void)2584 bool Cy_SysPm_PmicIsOutputEnabled(void)
2585 {
2586     return (0U != _FLD2VAL(BACKUP_PMIC_CTL_PMIC_EN_OUTEN, BACKUP_PMIC_CTL));
2587 }
2588 
2589 
Cy_SysPm_PmicIsLocked(void)2590 bool Cy_SysPm_PmicIsLocked(void)
2591 {
2592     return ((_FLD2VAL(BACKUP_PMIC_CTL_UNLOCK, BACKUP_PMIC_CTL) == CY_SYSPM_PMIC_UNLOCK_KEY) ? false : true);
2593 }
2594 
2595 
Cy_SysPm_BackupSetSupply(cy_en_syspm_vddbackup_control_t vddBackControl)2596 void Cy_SysPm_BackupSetSupply(cy_en_syspm_vddbackup_control_t vddBackControl)
2597 {
2598     CY_ASSERT_L3(CY_SYSPM_IS_VDDBACKUP_VALID(vddBackControl));
2599 
2600     BACKUP_CTL = _CLR_SET_FLD32U((BACKUP_CTL), BACKUP_CTL_VDDBAK_CTL, (uint32_t) vddBackControl);
2601 }
2602 
2603 
Cy_SysPm_BackupGetSupply(void)2604 cy_en_syspm_vddbackup_control_t Cy_SysPm_BackupGetSupply(void)
2605 {
2606     uint32_t retVal;
2607     retVal = _FLD2VAL(BACKUP_CTL_VDDBAK_CTL, BACKUP_CTL);
2608 
2609     return ((cy_en_syspm_vddbackup_control_t) retVal);
2610 }
2611 
2612 
Cy_SysPm_BackupEnableVoltageMeasurement(void)2613 void Cy_SysPm_BackupEnableVoltageMeasurement(void)
2614 {
2615     BACKUP_CTL |= BACKUP_CTL_VBACKUP_MEAS_Msk;
2616 }
2617 
2618 
Cy_SysPm_BackupDisableVoltageMeasurement(void)2619 void Cy_SysPm_BackupDisableVoltageMeasurement(void)
2620 {
2621     BACKUP_CTL &= ((uint32_t) ~BACKUP_CTL_VBACKUP_MEAS_Msk);
2622 }
2623 
2624 
Cy_SysPm_BackupSuperCapCharge(cy_en_syspm_sc_charge_key_t key)2625 void Cy_SysPm_BackupSuperCapCharge(cy_en_syspm_sc_charge_key_t key)
2626 {
2627     CY_ASSERT_L3(CY_SYSPM_IS_SC_CHARGE_KEY_VALID(key));
2628 
2629     if(key == CY_SYSPM_SC_CHARGE_ENABLE)
2630     {
2631         BACKUP_CTL = _CLR_SET_FLD32U((BACKUP_CTL), BACKUP_CTL_EN_CHARGE_KEY, (uint32_t) CY_SYSPM_SC_CHARGE_ENABLE);
2632     }
2633     else
2634     {
2635         BACKUP_CTL &= ((uint32_t) ~BACKUP_CTL_EN_CHARGE_KEY_Msk);
2636     }
2637 }
2638 
2639 #if defined (CY_DEVICE_SECURE)
2640 CY_MISRA_BLOCK_END('MISRA C-2012 Rule 17.2')
2641 CY_MISRA_BLOCK_END('MISRA C-2012 Rule 18.6')
2642 #endif
2643 
2644 #endif
2645 /* [] END OF FILE */
2646