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