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