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