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