1 /***************************************************************************//**
2 * \file cy_syspm_v2.c
3 * \version 5.94
4 *
5 * This driver provides the source code for API power management.
6 *
7 ********************************************************************************
8 * \copyright
9 * Copyright (c) (2016-2023), Cypress Semiconductor Corporation (an Infineon company) or
10 * an affiliate of Cypress Semiconductor Corporation.
11 * SPDX-License-Identifier: Apache-2.0
12 *
13 * Licensed under the Apache License, Version 2.0 (the "License");
14 * you may not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS,
21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
24 *******************************************************************************/
25
26 #include "cy_device.h"
27 #include "cy_sysclk.h"
28
29 #if defined (CY_IP_MXS40SSRSS)
30
31 #include "cy_syspm.h"
32 #if defined (CY_IP_MXS40SSRSS)
33 #include "cy_syspm_ppu.h"
34 #endif
35
36
37 /*******************************************************************************
38 * Internal Functions
39 *******************************************************************************/
40 __WEAK void Cy_SysPm_Dsramoff_Entry(void);
41
42 #ifdef ENABLE_MEM_VOLTAGE_TRIMS
43 /* RAM and ROM Voltage TRIM functions */
44 static void SetMemoryVoltageTrims(cy_en_syspm_sdr_voltage_t voltage);
45 static bool IsVoltageChangePossible(void);
46 #endif /* ENABLE_MEM_VOLTAGE_TRIMS */
47
48 /*******************************************************************************
49 * Internal Defines
50 *******************************************************************************/
51
52 /* The define for number of callback roots */
53 #define CALLBACK_ROOT_NR (7U)
54
55 /* The mask to unlock the Hibernate power mode */
56 #define HIBERNATE_UNLOCK_VAL ((uint32_t) 0x3Au << SRSS_PWR_HIBERNATE_UNLOCK_Pos)
57
58 /* The mask to set the Hibernate power mode */
59 #define SET_HIBERNATE_MODE ((HIBERNATE_UNLOCK_VAL |\
60 SRSS_PWR_HIBERNATE_FREEZE_Msk |\
61 SRSS_PWR_HIBERNATE_HIBERNATE_Msk))
62
63 /* The mask to retain the Hibernate power mode status */
64 #define HIBERNATE_RETAIN_STATUS_MASK ((SRSS_PWR_HIBERNATE_TOKEN_Msk |\
65 SRSS_PWR_HIBERNATE_MASK_HIBALARM_Msk |\
66 SRSS_PWR_HIBERNATE_MASK_HIBWDT_Msk |\
67 SRSS_PWR_HIBERNATE_POLARITY_HIBPIN_Msk |\
68 SRSS_PWR_HIBERNATE_MASK_HIBPIN_Msk))
69
70 /** The mask for the Hibernate wakeup sources */
71 #define HIBERNATE_WAKEUP_MASK ((SRSS_PWR_HIB_WAKE_CTL_HIB_WAKE_SRC_Msk |\
72 SRSS_PWR_HIB_WAKE_CTL_HIB_WAKE_CSV_BAK_Msk |\
73 SRSS_PWR_HIB_WAKE_CTL_HIB_WAKE_RTC_Msk |\
74 SRSS_PWR_HIB_WAKE_CTL_HIB_WAKE_WDT_Msk))
75
76 /** The define to update the token to indicate the transition into Hibernate */
77 #define HIBERNATE_TOKEN ((uint32_t) 0x1BU << SRSS_PWR_HIBERNATE_TOKEN_Pos)
78
79 /* The wait time for transition into the minimum regulator current mode
80 */
81 #define SET_MIN_CURRENT_MODE_DELAY_US (1U)
82
83 /* The wait delay time that occurs before the active reference is settled.
84 * Intermediate delay is used in transition into the normal regulator current
85 * mode
86 */
87 #define ACT_REF_SETTLE_DELAY_US (6U)
88
89 /* The wait delay time that occurs after the active reference is settled.
90 * Final delay is used in transition into the normal regulator current mode
91 */
92 #define SET_NORMAL_CURRENT_MODE_DELAY_US (1U)
93
94 /* The internal define of the tries number in the
95 * Cy_SysPm_SystemSetMinRegulatorCurrent() function
96 */
97 #define WAIT_DELAY_TRIES (100U)
98
99 /* The internal define of the tries number in the
100 * Cy_SysPm_SystemSetMinRegulatorCurrent() function
101 */
102 #define CY_SYSPM_CBUCK_BUSY_RETRY_COUNT (100U)
103 #define CY_SYSPM_CBUCK_BUSY_RETRY_DELAY_MS (1U)
104
105 /* Define for ROM trim for 0.9V */
106 #define CPUSS_TRIM_ROM_VOLT_0_900 (0x00000012U)
107
108 /* Define for ROM trim for 1.0V */
109 #define CPUSS_TRIM_ROM_VOLT_1_000 (0x00000012U)
110
111 /* Define for ROM trim for 1.1V */
112 #define CPUSS_TRIM_ROM_VOLT_1_100 (0x00000013U)
113
114 /* Define for RAM trim for 0.9V */
115 #define CPUSS_TRIM_RAM_VOLT_0_900 (0x00006012U)
116
117 /* Define for RAM trim for 1.0V */
118 #define CPUSS_TRIM_RAM_VOLT_1_000 (0x00005012U)
119
120 /* Define for RAM trim for 1.1V */
121 #define CPUSS_TRIM_RAM_VOLT_1_100 (0x00004013U)
122
123 /* Mask for the RAM write check bits */
124 #define CPUSS_TRIM_RAM_CTL_WC_MASK (0x3UL << 10U)
125
126 /*******************************************************************************
127 * Internal Variables
128 *******************************************************************************/
129
130 /* Array of the callback roots */
131 static cy_stc_syspm_callback_t* pmCallbackRoot[CALLBACK_ROOT_NR] = {(void *)0, (void *)0, (void *)0, (void *)0, (void *)0, (void *)0, (void *)0};
132
133 /* The array of the pointers to failed callback */
134 static cy_stc_syspm_callback_t* failedCallback[CALLBACK_ROOT_NR] = {(void *)0, (void *)0, (void *)0, (void *)0, (void *)0, (void *)0, (void *)0};
135
136
Cy_SysPm_Init(void)137 void Cy_SysPm_Init(void)
138 {
139 if(CY_SYSPM_WARM_BOOT_MODE != Cy_SysPm_GetBootMode())
140 {
141 (void)cy_pd_ppu_init((struct ppu_v1_reg *)CY_PPU_MAIN_BASE); /* Suppress a compiler warning about unused return value */
142 (void)cy_pd_ppu_init((struct ppu_v1_reg *)CY_PPU_CPUSS_BASE); /* Suppress a compiler warning about unused return value */
143 (void)cy_pd_ppu_init((struct ppu_v1_reg *)CY_PPU_SRAM_BASE); /* Suppress a compiler warning about unused return value */
144
145 /* Set Default mode to DEEPSLEEP */
146 (void)Cy_SysPm_SetDeepSleepMode(CY_SYSPM_MODE_DEEPSLEEP);
147 }
148 }
149
Cy_SysPm_CpuEnterSleep(cy_en_syspm_waitfor_t waitFor)150 cy_en_syspm_status_t Cy_SysPm_CpuEnterSleep(cy_en_syspm_waitfor_t waitFor)
151 {
152 uint32_t interruptState;
153 uint32_t cbSleepRootIdx = (uint32_t) CY_SYSPM_SLEEP;
154 cy_en_syspm_status_t retVal = CY_SYSPM_SUCCESS;
155
156 CY_ASSERT_L3(CY_SYSPM_IS_WAIT_FOR_VALID(waitFor));
157
158 /* Call registered callback functions with CY_SYSPM_CHECK_READY parameter */
159 if (pmCallbackRoot[cbSleepRootIdx] != NULL)
160 {
161 retVal = Cy_SysPm_ExecuteCallback(CY_SYSPM_SLEEP, CY_SYSPM_CHECK_READY);
162 }
163
164 /* The CPU can switch into the Sleep power mode only when
165 * all executed registered callback functions with the CY_SYSPM_CHECK_READY
166 * parameter return CY_SYSPM_SUCCESS.
167 */
168 if(retVal == CY_SYSPM_SUCCESS)
169 {
170 /* Call the registered callback functions with
171 * CY_SYSPM_BEFORE_TRANSITION parameter
172 */
173 interruptState = Cy_SysLib_EnterCriticalSection();
174 if (pmCallbackRoot[cbSleepRootIdx] != NULL)
175 {
176 (void) Cy_SysPm_ExecuteCallback(CY_SYSPM_SLEEP, CY_SYSPM_BEFORE_TRANSITION);
177 }
178
179 /* The CPU enters the Sleep power mode upon execution of WFI/WFE */
180 SCB_SCR &= (uint32_t) ~SCB_SCR_SLEEPDEEP_Msk;
181
182 if(waitFor != CY_SYSPM_WAIT_FOR_EVENT)
183 {
184 __WFI();
185 }
186 else
187 {
188 __WFE();
189 }
190 Cy_SysLib_ExitCriticalSection(interruptState);
191
192 /* Call the registered callback functions with the
193 * CY_SYSPM_AFTER_TRANSITION parameter
194 */
195 if (pmCallbackRoot[cbSleepRootIdx] != NULL)
196 {
197 (void) Cy_SysPm_ExecuteCallback(CY_SYSPM_SLEEP, CY_SYSPM_AFTER_TRANSITION);
198 }
199 }
200 else
201 {
202 /* Execute callback functions with the CY_SYSPM_CHECK_FAIL parameter to
203 * undo everything done in the callback with the CY_SYSPM_CHECK_READY
204 * parameter
205 */
206 (void) Cy_SysPm_ExecuteCallback(CY_SYSPM_SLEEP, CY_SYSPM_CHECK_FAIL);
207 retVal = CY_SYSPM_FAIL;
208 }
209 return retVal;
210 }
211
Cy_SysPm_SystemLpActiveEnter(void)212 cy_en_syspm_status_t Cy_SysPm_SystemLpActiveEnter(void)
213 {
214 uint32_t interruptState;
215 uint32_t cbSleepRootIdx = (uint32_t)CY_SYSPM_LPACTIVE_ENTER;
216 cy_en_syspm_status_t retVal = CY_SYSPM_SUCCESS;
217
218 /* Step-1: Wait until PWR_CTL.LPM_READY==1 to indicate low power circuits are ready. */
219 if(!Cy_SysPm_IsLpmReady())
220 {
221 retVal = CY_SYSPM_FAIL;
222 }
223 else
224 {
225 /* Call registered callback functions with CY_SYSPM_CHECK_READY parameter */
226 if (pmCallbackRoot[cbSleepRootIdx] != NULL)
227 {
228 retVal = Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbSleepRootIdx, CY_SYSPM_CHECK_READY);
229 }
230
231 if (retVal == CY_SYSPM_SUCCESS)
232 {
233 /* The CPU can switch into the LPACTIVE power mode only when
234 * all executed registered callback functions with the CY_SYSPM_CHECK_READY
235 * parameter return CY_SYSPM_SUCCESS.
236 */
237 /* Call the registered callback functions with
238 * CY_SYSPM_BEFORE_TRANSITION parameter
239 */
240 interruptState = Cy_SysLib_EnterCriticalSection();
241 if (pmCallbackRoot[cbSleepRootIdx] != NULL)
242 {
243 (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbSleepRootIdx, CY_SYSPM_BEFORE_TRANSITION); /* Suppress a compiler warning about unused return value */
244 }
245
246 //Enabling Low Power Profile
247 /* Step-2: Clock for clk_hf0 is selected as IMO, which runs at 8MHz Nominal. */
248 (void)Cy_SysClk_ClkHfDirectSel(0U, true);
249
250 //Disable FLL if enabled
251 if(Cy_SysClk_FllIsEnabled())
252 {
253 (void)Cy_SysClk_FllDisable(); /* Suppress a compiler warning about unused return value */
254 }
255
256 /* Step-3: If reducing the regulator output voltage for RegSetB, perform the extra requester sequence.
257 * Call API-Cy_SysPm_LdoExtraRequesterConfig before calling this if the voltage needs to be reduced
258 */
259
260 /* Step-4: If lowest power is required; perform the following writes to PWR_CTL2 */
261 retVal = Cy_SysPm_SystemSetMinRegulatorCurrent();
262
263 Cy_SysLib_ExitCriticalSection(interruptState);
264
265 /* Call the registered callback functions with the
266 * CY_SYSPM_AFTER_TRANSITION parameter
267 */
268 if (pmCallbackRoot[cbSleepRootIdx] != NULL)
269 {
270 (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbSleepRootIdx, CY_SYSPM_AFTER_TRANSITION); /* Suppress a compiler warning about unused return value */
271 }
272 }
273 else
274 {
275 /* Execute callback functions with the CY_SYSPM_CHECK_FAIL parameter to
276 * undo everything done in the callback with the CY_SYSPM_CHECK_READY
277 * parameter
278 */
279 (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbSleepRootIdx, CY_SYSPM_CHECK_FAIL); /* Suppress a compiler warning about unused return value */
280 retVal = CY_SYSPM_FAIL;
281 }
282 }
283 return retVal;
284 }
285
Cy_SysPm_SystemLpActiveExit(void)286 cy_en_syspm_status_t Cy_SysPm_SystemLpActiveExit(void)
287 {
288 uint32_t interruptState;
289 uint32_t cbSleepRootIdx = (uint32_t)CY_SYSPM_LPACTIVE_EXIT;
290 cy_en_syspm_status_t retVal = CY_SYSPM_SUCCESS;
291
292 /* Call registered callback functions with CY_SYSPM_CHECK_READY parameter */
293 if (pmCallbackRoot[cbSleepRootIdx] != NULL)
294 {
295 retVal = Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbSleepRootIdx, CY_SYSPM_CHECK_READY);
296 }
297
298 if (retVal == CY_SYSPM_SUCCESS)
299 {
300 /* The CPU can switch into the LPACTIVE power mode only when
301 * all executed registered callback functions with the CY_SYSPM_CHECK_READY
302 * parameter return CY_SYSPM_SUCCESS.
303 */
304 /* Call the registered callback functions with
305 * CY_SYSPM_BEFORE_TRANSITION parameter
306 */
307 interruptState = Cy_SysLib_EnterCriticalSection();
308 if (pmCallbackRoot[cbSleepRootIdx] != NULL)
309 {
310 (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbSleepRootIdx, CY_SYSPM_BEFORE_TRANSITION); /* Suppress a compiler warning about unused return value */
311 }
312
313 /* Step-1: Reverse the writes to PWR_CTL2 which are done in Cy_SysPm_SystemLpActiveEnter*/
314 retVal = Cy_SysPm_SystemSetNormalRegulatorCurrent();
315
316 /* Step-2: If increasing the regulator output voltage for RegSetB, perform the extra requester sequence.
317 * Call API-Cy_SysPm_LdoExtraRequesterConfig before calling this if the voltage needs to be increased
318 */
319
320 /* Step-3: High Frequency clocks could be enabled */
321 (void)Cy_SysClk_FllEnable(0UL);
322 if (CY_SYSCLK_SUCCESS != Cy_SysClk_FllEnable(0UL))
323 {
324 retVal = CY_SYSPM_FAIL;
325 }
326 (void)Cy_SysClk_ClkHfDirectSel(0U, false);
327
328 Cy_SysLib_ExitCriticalSection(interruptState);
329
330 /* Call the registered callback functions with the
331 * CY_SYSPM_AFTER_TRANSITION parameter
332 */
333 if (pmCallbackRoot[cbSleepRootIdx] != NULL)
334 {
335 (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbSleepRootIdx, CY_SYSPM_AFTER_TRANSITION); /* Suppress a compiler warning about unused return value */
336 }
337 }
338 else
339 {
340 /* Execute callback functions with the CY_SYSPM_CHECK_FAIL parameter to
341 * undo everything done in the callback with the CY_SYSPM_CHECK_READY
342 * parameter
343 */
344 (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbSleepRootIdx, CY_SYSPM_CHECK_FAIL); /* Suppress a compiler warning about unused return value */
345 retVal = CY_SYSPM_FAIL;
346 }
347 return retVal;
348 }
349
Cy_SysPm_IsSystemLpActiveEnabled(void)350 bool Cy_SysPm_IsSystemLpActiveEnabled(void)
351 {
352 return (_FLD2BOOL(SRSS_PWR_CTL2_REFV_DIS, SRSS_PWR_CTL2)? true : false);
353 }
354
Cy_SysPm_SetDeepSleepMode(cy_en_syspm_deep_sleep_mode_t deepSleepMode)355 cy_en_syspm_status_t Cy_SysPm_SetDeepSleepMode(cy_en_syspm_deep_sleep_mode_t deepSleepMode)
356 {
357 cy_en_syspm_status_t retVal = CY_SYSPM_FAIL;
358
359 switch(deepSleepMode)
360 {
361 case CY_SYSPM_MODE_DEEPSLEEP:
362 {
363 (void)cy_pd_ppu_set_power_mode((struct ppu_v1_reg *)CY_PPU_MAIN_BASE, (uint32_t)CY_SYSTEM_MAIN_PPU_DEEPSLEEP_MODE); /* Suppress a compiler warning about unused return value */
364 (void)cy_pd_ppu_set_power_mode((struct ppu_v1_reg *)CY_PPU_CPUSS_BASE, (uint32_t)CY_SYSTEM_CPUSS_PPU_DEEPSLEEP_MODE); /* Suppress a compiler warning about unused return value */
365 (void)cy_pd_ppu_set_power_mode((struct ppu_v1_reg *)CY_PPU_SRAM_BASE, (uint32_t)CY_SYSTEM_SRAM_PPU_DEEPSLEEP_MODE); /* Suppress a compiler warning about unused return value */
366 retVal = CY_SYSPM_SUCCESS;
367 }
368 break;
369
370 case CY_SYSPM_MODE_DEEPSLEEP_RAM:
371 {
372 (void)cy_pd_ppu_set_power_mode((struct ppu_v1_reg *)CY_PPU_MAIN_BASE, (uint32_t)CY_SYSTEM_MAIN_PPU_DEEPSLEEP_RAM_MODE); /* Suppress a compiler warning about unused return value */
373 (void)cy_pd_ppu_set_power_mode((struct ppu_v1_reg *)CY_PPU_CPUSS_BASE, (uint32_t)CY_SYSTEM_CPUSS_PPU_DEEPSLEEP_RAM_MODE); /* Suppress a compiler warning about unused return value */
374 (void)cy_pd_ppu_set_power_mode((struct ppu_v1_reg *)CY_PPU_SRAM_BASE, (uint32_t)CY_SYSTEM_SRAM_PPU_DEEPSLEEP_RAM_MODE); /* Suppress a compiler warning about unused return value */
375 retVal = CY_SYSPM_SUCCESS;
376 }
377 break;
378
379 case CY_SYSPM_MODE_DEEPSLEEP_OFF:
380 {
381 (void)cy_pd_ppu_set_power_mode((struct ppu_v1_reg *)CY_PPU_MAIN_BASE, (uint32_t)CY_SYSTEM_MAIN_PPU_DEEPSLEEP_OFF_MODE); /* Suppress a compiler warning about unused return value */
382 (void)cy_pd_ppu_set_power_mode((struct ppu_v1_reg *)CY_PPU_CPUSS_BASE, (uint32_t)CY_SYSTEM_CPUSS_PPU_DEEPSLEEP_OFF_MODE); /* Suppress a compiler warning about unused return value */
383 (void)cy_pd_ppu_set_power_mode((struct ppu_v1_reg *)CY_PPU_SRAM_BASE, (uint32_t)CY_SYSTEM_SRAM_PPU_DEEPSLEEP_OFF_MODE); /* Suppress a compiler warning about unused return value */
384 retVal = CY_SYSPM_SUCCESS;
385 }
386 break;
387
388 default:
389 retVal = CY_SYSPM_BAD_PARAM;
390 break;
391 }
392 return retVal;
393 }
394
Cy_SysPm_GetDeepSleepMode(void)395 cy_en_syspm_deep_sleep_mode_t Cy_SysPm_GetDeepSleepMode(void)
396 {
397 uint32_t mode;
398 cy_en_syspm_deep_sleep_mode_t deepSleepMode;
399
400 mode = (uint32_t)cy_pd_ppu_get_programmed_power_mode((struct ppu_v1_reg *)CY_PPU_MAIN_BASE);
401
402 switch(mode)
403 {
404 case CY_SYSTEM_DEEPSLEEP_PPU_MODES:
405 {
406 deepSleepMode = CY_SYSPM_MODE_DEEPSLEEP;
407 }
408 break;
409
410 case CY_SYSTEM_DEEPSLEEP_RAM_PPU_MODES:
411 {
412 deepSleepMode = CY_SYSPM_MODE_DEEPSLEEP_RAM;
413 }
414 break;
415
416 case CY_SYSTEM_DEEPSLEEP_OFF_PPU_MODES:
417 {
418 deepSleepMode = CY_SYSPM_MODE_DEEPSLEEP_OFF;
419 }
420 break;
421
422 default:
423 {
424 deepSleepMode = CY_SYSPM_MODE_DEEPSLEEP_NONE;
425 }
426 break;
427 }
428
429 CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to cy_en_syspm_deep_sleep_mode_t enum.');
430 return ((cy_en_syspm_deep_sleep_mode_t)deepSleepMode);
431 }
432
Cy_SysPm_GetBootMode(void)433 cy_en_syspm_boot_mode_t Cy_SysPm_GetBootMode(void)
434 {
435 uint32_t resCause, resCause2;
436 cy_en_syspm_boot_mode_t deepSleepWakeMode = CY_SYSPM_POR_BOOT_MODE;
437
438 resCause = SRSS_RES_CAUSE;
439 resCause2 = SRSS_RES_CAUSE2;
440
441 if((resCause == 0UL) || (resCause2 == 0UL))
442 {
443 switch(Cy_SysPm_GetDeepSleepMode())
444 {
445 case CY_SYSPM_MODE_DEEPSLEEP_RAM:
446 {
447 deepSleepWakeMode = CY_SYSPM_WARM_BOOT_MODE;
448 }
449 break;
450
451 case CY_SYSPM_MODE_DEEPSLEEP_OFF:
452 {
453 deepSleepWakeMode = CY_SYSPM_COLD_BOOT_MODE;
454 }
455 break;
456
457 default:
458 {
459 deepSleepWakeMode = CY_SYSPM_POR_BOOT_MODE;
460 }
461 break;
462 }
463
464 }
465
466 return ((cy_en_syspm_boot_mode_t)deepSleepWakeMode);
467 }
468
Cy_SysPm_CpuEnterDeepSleep(cy_en_syspm_waitfor_t waitFor)469 cy_en_syspm_status_t Cy_SysPm_CpuEnterDeepSleep(cy_en_syspm_waitfor_t waitFor)
470 {
471 uint32_t interruptState;
472 uint32_t cbDeepSleepRootIdx = (uint32_t) Cy_SysPm_GetDeepSleepMode();
473 cy_en_syspm_status_t retVal = CY_SYSPM_SUCCESS;
474
475 CY_ASSERT_L3(CY_SYSPM_IS_WAIT_FOR_VALID(waitFor));
476 CY_ASSERT_L3(CY_SYSPM_IS_DEEPSLEEP_MODE_VALID(cbDeepSleepRootIdx));
477
478 //Check if LPM is ready
479 if(!Cy_SysPm_IsLpmReady())
480 {
481 retVal = CY_SYSPM_FAIL;
482 }
483 else
484 {
485 /* Call the registered callback functions with the CY_SYSPM_CHECK_READY
486 * parameter
487 */
488 if (pmCallbackRoot[cbDeepSleepRootIdx] != NULL)
489 {
490 retVal = Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbDeepSleepRootIdx, CY_SYSPM_CHECK_READY);
491 }
492
493 /* The CPU can switch into the Deep Sleep power mode only when
494 * all executed registered callback functions with the CY_SYSPM_CHECK_READY
495 * parameter return CY_SYSPM_SUCCESS
496 */
497 if (retVal == CY_SYSPM_SUCCESS)
498 {
499 /* Call the registered callback functions with the
500 * CY_SYSPM_BEFORE_TRANSITION parameter
501 */
502 interruptState = Cy_SysLib_EnterCriticalSection();
503 if (pmCallbackRoot[cbDeepSleepRootIdx] != NULL)
504 {
505 (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbDeepSleepRootIdx, CY_SYSPM_BEFORE_TRANSITION);
506 }
507 /* The CPU enters Deep Sleep mode upon execution of WFI/WFE
508 * use Cy_SysPm_SetDeepSleepMode to set various deepsleep modes TBD*/
509 SCB_SCR |= SCB_SCR_SLEEPDEEP_Msk;
510
511 if(waitFor != CY_SYSPM_WAIT_FOR_EVENT)
512 {
513 __WFI();
514 }
515 else
516 {
517 __WFE();
518 }
519
520 /* Call the registered callback functions with the CY_SYSPM_AFTER_DS_WFI_TRANSITION
521 * parameter
522 */
523 if (pmCallbackRoot[cbDeepSleepRootIdx] != NULL)
524 {
525 (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbDeepSleepRootIdx, CY_SYSPM_AFTER_DS_WFI_TRANSITION);
526 }
527
528 Cy_SysLib_ExitCriticalSection(interruptState);
529 }
530 if (retVal == CY_SYSPM_SUCCESS)
531 {
532 /* Call the registered callback functions with the CY_SYSPM_AFTER_TRANSITION
533 * parameter
534 */
535 if (pmCallbackRoot[cbDeepSleepRootIdx] != NULL)
536 {
537 (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbDeepSleepRootIdx, CY_SYSPM_AFTER_TRANSITION);
538 }
539 }
540 else
541 {
542 /* Execute callback functions with the CY_SYSPM_CHECK_FAIL parameter to
543 * undo everything done in the callback with the CY_SYSPM_CHECK_READY
544 * parameter
545 */
546 if (pmCallbackRoot[cbDeepSleepRootIdx] != NULL)
547 {
548 (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbDeepSleepRootIdx, CY_SYSPM_CHECK_FAIL);
549 }
550 }
551 }
552 return retVal;
553 }
554
Cy_SysPm_SetupDeepSleepRAM(cy_en_syspm_dsram_checks_t dsramCheck,uint32_t * dsramIntState)555 cy_en_syspm_status_t Cy_SysPm_SetupDeepSleepRAM(cy_en_syspm_dsram_checks_t dsramCheck, uint32_t *dsramIntState)
556 {
557 uint32_t cbDeepSleepRootIdx = (uint32_t) Cy_SysPm_GetDeepSleepMode();
558 cy_en_syspm_status_t retVal = CY_SYSPM_SUCCESS;
559
560 CY_ASSERT_L3(CY_SYSPM_IS_DSRAM_CHECK_VALID(dsramCheck));
561 CY_ASSERT_L3(CY_SYSPM_IS_DEEPSLEEP_MODE_VALID(cbDeepSleepRootIdx));
562
563 //Check if LPM is ready
564 if(!Cy_SysPm_IsLpmReady())
565 {
566 retVal = CY_SYSPM_FAIL;
567 }
568 else
569 {
570 if(dsramCheck == CY_SYSPM_PRE_DSRAM)
571 {
572 /* Clear the Warm Boot Entry status Flag */
573 Cy_SysLib_ClearDSRAMWarmBootEntryStatus();
574
575 /* Call the registered callback functions with the CY_SYSPM_CHECK_READY
576 * parameter
577 */
578 if (pmCallbackRoot[cbDeepSleepRootIdx] != NULL)
579 {
580 retVal = Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbDeepSleepRootIdx, CY_SYSPM_CHECK_READY);
581 }
582
583 /* The CPU can switch into the Deep Sleep power mode only when
584 * all executed registered callback functions with the CY_SYSPM_CHECK_READY
585 * parameter return CY_SYSPM_SUCCESS
586 */
587 if (retVal == CY_SYSPM_SUCCESS)
588 {
589 /* Call the registered callback functions with the
590 * CY_SYSPM_BEFORE_TRANSITION parameter
591 */
592 *dsramIntState = Cy_SysLib_EnterCriticalSection();
593
594 if (pmCallbackRoot[cbDeepSleepRootIdx] != NULL)
595 {
596 (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbDeepSleepRootIdx, CY_SYSPM_BEFORE_TRANSITION);
597 }
598 /* The CPU enters Deep Sleep mode upon execution of WFI/WFE
599 * use Cy_SysPm_SetDeepSleepMode to set various deepsleep modes TBD*/
600 SCB_SCR |= SCB_SCR_SLEEPDEEP_Msk;
601
602 }
603 else
604 {
605 /* Execute callback functions with the CY_SYSPM_CHECK_FAIL parameter to
606 * undo everything done in the callback with the CY_SYSPM_CHECK_READY
607 * parameter
608 */
609 if (pmCallbackRoot[cbDeepSleepRootIdx] != NULL)
610 {
611 (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbDeepSleepRootIdx, CY_SYSPM_CHECK_FAIL);
612 }
613 }
614 }
615 else
616 {
617 /* Call the registered callback functions with the CY_SYSPM_AFTER_DS_WFI_TRANSITION
618 * parameter
619 */
620 if (pmCallbackRoot[cbDeepSleepRootIdx] != NULL)
621 {
622 (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbDeepSleepRootIdx, CY_SYSPM_AFTER_DS_WFI_TRANSITION);
623 }
624
625 Cy_SysLib_ExitCriticalSection(*dsramIntState);
626
627 /* Call the registered callback functions with the CY_SYSPM_AFTER_TRANSITION
628 * parameter
629 */
630 if (pmCallbackRoot[cbDeepSleepRootIdx] != NULL)
631 {
632 (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbDeepSleepRootIdx, CY_SYSPM_AFTER_TRANSITION);
633 }
634 }
635 }
636 return retVal;
637 }
638
Cy_SysPm_SystemEnterHibernate(void)639 cy_en_syspm_status_t Cy_SysPm_SystemEnterHibernate(void)
640 {
641 cy_en_syspm_status_t retVal = CY_SYSPM_SUCCESS;
642 uint32_t cbHibernateRootIdx = (uint32_t) CY_SYSPM_HIBERNATE;
643 /* Call the registered callback functions with the
644 * CY_SYSPM_CHECK_READY parameter
645 */
646 if (pmCallbackRoot[cbHibernateRootIdx] != NULL)
647 {
648 retVal = Cy_SysPm_ExecuteCallback(CY_SYSPM_HIBERNATE, CY_SYSPM_CHECK_READY);
649 }
650
651 /* The system can switch into Hibernate power mode only when
652 * all executed registered callback functions with CY_SYSPM_CHECK_READY
653 * parameter return CY_SYSPM_SUCCESS.
654 */
655 if(retVal == CY_SYSPM_SUCCESS)
656 {
657 /* Call registered callback functions with CY_SYSPM_BEFORE_TRANSITION
658 * parameter
659 */
660 (void) Cy_SysLib_EnterCriticalSection();
661 if (pmCallbackRoot[cbHibernateRootIdx] != NULL)
662 {
663 (void) Cy_SysPm_ExecuteCallback(CY_SYSPM_HIBERNATE, CY_SYSPM_BEFORE_TRANSITION);
664 }
665
666 /* Preserve the token that will be retained through a wakeup sequence.
667 * This could be used by Cy_SysLib_GetResetReason() to differentiate
668 * Wakeup from a general reset event.
669 * Preserve the wakeup source(s) configuration.
670 */
671 SRSS_PWR_HIBERNATE = (SRSS_PWR_HIBERNATE | HIBERNATE_TOKEN);
672
673 /* Clear Previous Wakeup Reasons */
674 Cy_SysPm_ClearHibernateWakeupCause();
675
676 /* Disable overriding by the peripherals the next pin-freeze command */
677 SRSS_PWR_HIBERNATE |= SET_HIBERNATE_MODE;
678
679 /* The second write causes freezing of I/O cells to save the I/O-cell state */
680 SRSS_PWR_HIBERNATE |= SET_HIBERNATE_MODE;
681
682 /* Third write cause system to enter Hibernate */
683 SRSS_PWR_HIBERNATE |= SET_HIBERNATE_MODE;
684
685 /* Read register to make sure it is settled */
686 (void) SRSS_PWR_HIBERNATE;
687
688 /* Wait for transition */
689 __WFI();
690
691 /* The callback function calls with the CY_SYSPM_AFTER_TRANSITION
692 * parameter in the Hibernate power mode are not applicable as system
693 * wake-up was made on system reboot.
694 */
695
696 /* A wakeup from Hibernate is performed by toggling of the wakeup
697 * pins, or WDT matches, or Backup domain alarm expires. This depends on
698 * what item is configured in the Hibernate register. After a wakeup
699 * event, a normal Boot procedure occurs.
700 * There is no need to exit from the critical section.
701 */
702 }
703 else
704 {
705 /* Execute callback functions with the CY_SYSPM_CHECK_FAIL parameter to
706 * undo everything done in the callback with the CY_SYSPM_CHECK_READY
707 * parameter. The return value should be CY_SYSPM_SUCCESS.
708 */
709 (void) Cy_SysPm_ExecuteCallback(CY_SYSPM_HIBERNATE, CY_SYSPM_CHECK_FAIL);
710 retVal = CY_SYSPM_FAIL;
711 }
712 return retVal;
713 }
714
Cy_SysPm_SystemSetMinRegulatorCurrent(void)715 cy_en_syspm_status_t Cy_SysPm_SystemSetMinRegulatorCurrent(void)
716 {
717 cy_en_syspm_status_t retVal = CY_SYSPM_CANCELED;
718
719 /* Check if the power circuits are ready to enter into regulator minimum
720 * current mode
721 */
722 if (Cy_SysPm_IsLpmReady())
723 {
724 SRSS_PWR_CTL2 |= (SRSS_PWR_CTL2_LINREG_LPMODE_Msk |
725 SRSS_PWR_CTL2_PORBOD_LPMODE_Msk |
726 SRSS_PWR_CTL2_BGREF_LPMODE_Msk |
727 SRSS_PWR_CTL2_REFI_LPMODE_Msk);
728
729 /* This wait time allows the circuits to remove their dependence on
730 * the Active mode circuits, such as active Reference
731 */
732 Cy_SysLib_DelayUs(SET_MIN_CURRENT_MODE_DELAY_US);
733
734 /* Disable active reference */
735 SRSS_PWR_CTL2 |= SRSS_PWR_CTL2_REFV_DIS_Msk;
736
737 retVal = CY_SYSPM_SUCCESS;
738 }
739
740 return retVal;
741 }
742
Cy_SysPm_SystemSetNormalRegulatorCurrent(void)743 cy_en_syspm_status_t Cy_SysPm_SystemSetNormalRegulatorCurrent(void)
744 {
745 cy_en_syspm_status_t retVal = CY_SYSPM_TIMEOUT;
746
747 uint32_t timeOut = WAIT_DELAY_TRIES;
748
749 /* Configure the regulator normal current mode for the POR/BOD circuits
750 * and for the Voltage References
751 */
752
753 /* Bring Regulators Power Circuit out of LPMODE */
754 SRSS_PWR_CTL2 &= (uint32_t)~(SRSS_PWR_CTL2_REFV_DIS_Msk |
755 SRSS_PWR_CTL2_LINREG_LPMODE_Msk |
756 SRSS_PWR_CTL2_PORBOD_LPMODE_Msk |
757 SRSS_PWR_CTL2_REFI_LPMODE_Msk);
758
759 /* This wait time allows setting active Reference */
760 Cy_SysLib_DelayUs(ACT_REF_SETTLE_DELAY_US);
761
762 while ((0U == _FLD2VAL(SRSS_PWR_CTL2_REFV_OK, SRSS_PWR_CTL2)) && (0U != timeOut))
763 {
764 timeOut--;
765 }
766
767 if (0U != timeOut)
768 {
769 /* Disable the low-power for Bandgap reference circuit */
770 SRSS_PWR_CTL2 &= (uint32_t) ~SRSS_PWR_CTL2_BGREF_LPMODE_Msk;
771
772 /* Delay to finally set the normal current mode */
773 Cy_SysLib_DelayUs(SET_NORMAL_CURRENT_MODE_DELAY_US);
774
775 retVal= CY_SYSPM_SUCCESS;
776 }
777
778 return retVal;
779 }
780
Cy_SysPm_SystemIsMinRegulatorCurrentSet(void)781 bool Cy_SysPm_SystemIsMinRegulatorCurrentSet(void)
782 {
783 uint32_t regMask = Cy_SysPm_LdoIsEnabled() ? CY_SYSPM_PWR_CIRCUITS_LPMODE_ACTIVE_LDO_MASK : CY_SYSPM_PWR_CIRCUITS_LPMODE_ACTIVE_BUCK_MASK;
784
785 return ((SRSS_PWR_CTL & regMask) == regMask);
786 }
787
Cy_SysPm_LdoSetMode(cy_en_syspm_ldo_mode_t mode)788 cy_en_syspm_status_t Cy_SysPm_LdoSetMode(cy_en_syspm_ldo_mode_t mode)
789 {
790 CY_ASSERT_L3(CY_SYSPM_IS_LDO_MODE_VALID(mode));
791
792 cy_en_syspm_status_t retVal = CY_SYSPM_CANCELED;
793
794 switch (mode)
795 {
796 case CY_SYSPM_LDO_MODE_NORMAL:
797 {
798 retVal = Cy_SysPm_SystemSetNormalRegulatorCurrent();
799 }
800 break;
801
802 case CY_SYSPM_LDO_MODE_MIN:
803 {
804 retVal = Cy_SysPm_SystemSetMinRegulatorCurrent();
805 }
806 break;
807
808 case CY_SYSPM_LDO_MODE_DISABLED:
809 {
810 /* Disable the LDO, Deep Sleep and Retention regulators */
811 SRSS_PWR_CTL2 |= (_VAL2FLD(SRSS_PWR_CTL2_DPSLP_REG_DIS, 1U) |
812 _VAL2FLD(SRSS_PWR_CTL2_RET_REG_DIS, 1U) |
813 _VAL2FLD(SRSS_PWR_CTL2_LINREG_DIS, 1U));
814
815 retVal = CY_SYSPM_SUCCESS;
816 }
817 break;
818
819 default:
820 retVal = CY_SYSPM_FAIL;
821 break;
822 }
823
824 return retVal;
825 }
826
Cy_SysPm_LdoGetMode(void)827 cy_en_syspm_ldo_mode_t Cy_SysPm_LdoGetMode(void)
828 {
829 cy_en_syspm_ldo_mode_t retVal;
830
831 if (!Cy_SysPm_LdoIsEnabled())
832 {
833 retVal = CY_SYSPM_LDO_MODE_DISABLED;
834 }
835 else if (Cy_SysPm_SystemIsMinRegulatorCurrentSet())
836 {
837 retVal = CY_SYSPM_LDO_MODE_MIN;
838 }
839 else
840 {
841 retVal = CY_SYSPM_LDO_MODE_NORMAL;
842 }
843
844 return retVal;
845 }
846
Cy_SysPm_LdoIsEnabled(void)847 bool Cy_SysPm_LdoIsEnabled(void)
848 {
849 return ((0U != _FLD2VAL(SRSS_PWR_CTL2_LINREG_DIS, SRSS_PWR_CTL2)) ? false : true);
850 }
851
852
Cy_SysPm_CpuSleepOnExit(bool enable)853 void Cy_SysPm_CpuSleepOnExit(bool enable)
854 {
855 if(enable)
856 {
857 /* Enable sleep-on-exit feature */
858 SCB_SCR |= SCB_SCR_SLEEPONEXIT_Msk;
859 }
860 else
861 {
862 /* Disable sleep-on-exit feature */
863 SCB_SCR &= (uint32_t) ~(SCB_SCR_SLEEPONEXIT_Msk);
864 }
865 }
866
Cy_SysPm_SetHibernateWakeupSource(uint32_t wakeupSource)867 void Cy_SysPm_SetHibernateWakeupSource(uint32_t wakeupSource)
868 {
869 CY_ASSERT_L3(CY_SYSPM_IS_WAKE_UP_SOURCE_VALID(wakeupSource));
870
871 uint32_t polarityMask = 0U;
872 uint32_t wakeSrcMask = 0U;
873
874 /* LPCOMP0 & LPCOMP1 */
875 if ((0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_LPCOMP0_LOW)) || (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_LPCOMP0_HIGH)))
876 {
877 wakeSrcMask |= CY_SYSPM_HIB_WAKEUP_LPCOMP0_MASK;
878 }
879
880 if ((0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_LPCOMP1_LOW)) || (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_LPCOMP1_HIGH)))
881 {
882 wakeSrcMask |= CY_SYSPM_HIB_WAKEUP_LPCOMP1_MASK;
883 }
884
885 /* PIN0 & PIN1 */
886 if ((0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_PIN0_LOW)) || (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_PIN0_HIGH)))
887 {
888 wakeSrcMask |= CY_SYSPM_HIB_WAKEUP_PIN0_MASK;
889 }
890
891 if ((0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_PIN1_LOW)) || (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_PIN1_HIGH)))
892 {
893 wakeSrcMask |= CY_SYSPM_HIB_WAKEUP_PIN1_MASK;
894 }
895
896 /* RTC */
897 if (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_RTC_ALARM))
898 {
899 wakeSrcMask |= CY_SYSPM_HIB_WAKEUP_RTC_MASK;
900 }
901
902 /* WDT */
903 if (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_WDT))
904 {
905 wakeSrcMask |= CY_SYSPM_HIB_WAKEUP_WDT_MASK;
906 }
907
908 /* Polarity Mask */
909 if (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_LPCOMP0_HIGH))
910 {
911 polarityMask |= CY_SYSPM_HIB_WAKEUP_LPCOMP0_POLARITY_HIGH_MASK;
912 }
913
914 if (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_LPCOMP1_HIGH))
915 {
916 polarityMask |= CY_SYSPM_HIB_WAKEUP_LPCOMP1_POLARITY_HIGH_MASK;
917 }
918
919 if (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_PIN0_HIGH))
920 {
921 polarityMask |= CY_SYSPM_HIB_WAKEUP_PIN0_POLARITY_HIGH_MASK;
922 }
923
924 if (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_PIN1_HIGH))
925 {
926 polarityMask |= CY_SYSPM_HIB_WAKEUP_PIN1_POLARITY_HIGH_MASK;
927 }
928
929 SRSS_PWR_HIB_WAKE_CTL = (SRSS_PWR_HIB_WAKE_CTL | wakeSrcMask);
930 SRSS_PWR_HIB_WAKE_CTL2 = (SRSS_PWR_HIB_WAKE_CTL2 | polarityMask);
931
932 /* Read registers to make sure it is settled */
933 (void) SRSS_PWR_HIB_WAKE_CTL;
934 (void) SRSS_PWR_HIB_WAKE_CTL2;
935
936 }
937
Cy_SysPm_ClearHibernateWakeupSource(uint32_t wakeupSource)938 void Cy_SysPm_ClearHibernateWakeupSource(uint32_t wakeupSource)
939 {
940 CY_ASSERT_L3(CY_SYSPM_IS_WAKE_UP_SOURCE_VALID(wakeupSource));
941
942 uint32_t polarityMask = 0U;
943 uint32_t wakeSrcMask = 0U;
944
945 /* LPCOMP0 & LPCOMP1 */
946 if ((0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_LPCOMP0_LOW)) || (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_LPCOMP0_HIGH)))
947 {
948 wakeSrcMask |= CY_SYSPM_HIB_WAKEUP_LPCOMP0_MASK;
949 }
950
951 if ((0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_LPCOMP1_LOW)) || (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_LPCOMP1_HIGH)))
952 {
953 wakeSrcMask |= CY_SYSPM_HIB_WAKEUP_LPCOMP1_MASK;
954 }
955
956 /* PIN0 & PIN1 */
957 if ((0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_PIN0_LOW)) || (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_PIN0_HIGH)))
958 {
959 wakeSrcMask |= CY_SYSPM_HIB_WAKEUP_PIN0_MASK;
960 }
961
962 if ((0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_PIN1_LOW)) || (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_PIN1_HIGH)))
963 {
964 wakeSrcMask |= CY_SYSPM_HIB_WAKEUP_PIN1_MASK;
965 }
966
967 /* RTC */
968 if (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_RTC_ALARM))
969 {
970 wakeSrcMask |= CY_SYSPM_HIB_WAKEUP_RTC_MASK;
971 }
972
973 /* WDT */
974 if (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_WDT))
975 {
976 wakeSrcMask |= CY_SYSPM_HIB_WAKEUP_WDT_MASK;
977 }
978
979 /* Polarity Mask */
980 if (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_LPCOMP0_HIGH))
981 {
982 polarityMask |= CY_SYSPM_HIB_WAKEUP_LPCOMP0_POLARITY_HIGH_MASK;
983 }
984
985 if (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_LPCOMP1_HIGH))
986 {
987 polarityMask |= CY_SYSPM_HIB_WAKEUP_LPCOMP1_POLARITY_HIGH_MASK;
988 }
989
990 if (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_PIN0_HIGH))
991 {
992 polarityMask |= CY_SYSPM_HIB_WAKEUP_PIN0_POLARITY_HIGH_MASK;
993 }
994
995 if (0U != (wakeupSource & (uint32_t)CY_SYSPM_HIBERNATE_PIN1_HIGH))
996 {
997 polarityMask |= CY_SYSPM_HIB_WAKEUP_PIN1_POLARITY_HIGH_MASK;
998 }
999
1000 SRSS_PWR_HIB_WAKE_CTL = (SRSS_PWR_HIB_WAKE_CTL & (~wakeSrcMask));
1001 SRSS_PWR_HIB_WAKE_CTL2 = (SRSS_PWR_HIB_WAKE_CTL2 & (~polarityMask));
1002
1003 /* Read registers to make sure it is settled */
1004 (void) SRSS_PWR_HIB_WAKE_CTL;
1005 (void) SRSS_PWR_HIB_WAKE_CTL2;
1006 }
1007
Cy_SysPm_GetHibernateWakeupCause(void)1008 cy_en_syspm_hibernate_wakeup_source_t Cy_SysPm_GetHibernateWakeupCause(void)
1009 {
1010 uint32_t wakeupCause;
1011 uint32_t wakeupCausePolarity;
1012
1013 wakeupCause = SRSS_PWR_HIB_WAKE_CAUSE;
1014
1015 wakeupCausePolarity = (wakeupCause & (uint32_t)(CY_SYSPM_HIB_WAKEUP_LPCOMP0_POLARITY_HIGH_MASK |
1016 CY_SYSPM_HIB_WAKEUP_LPCOMP1_POLARITY_HIGH_MASK |
1017 CY_SYSPM_HIB_WAKEUP_PIN0_POLARITY_HIGH_MASK |
1018 CY_SYSPM_HIB_WAKEUP_PIN1_POLARITY_HIGH_MASK ));
1019
1020 switch(wakeupCause)
1021 {
1022 case CY_SYSPM_HIB_WAKEUP_PIN0_POS:
1023 {
1024 if (0U != (wakeupCausePolarity & (uint32_t)CY_SYSPM_HIB_WAKEUP_PIN0_POLARITY_HIGH_MASK))
1025 {
1026 wakeupCause = ((uint32_t)CY_SYSPM_HIBERNATE_PIN0_HIGH);
1027 }
1028 else
1029 {
1030 wakeupCause = ((uint32_t)CY_SYSPM_HIBERNATE_PIN0_LOW);
1031 }
1032 }
1033 break;
1034
1035 case CY_SYSPM_HIB_WAKEUP_PIN1_POS:
1036 {
1037 if (0U != (wakeupCausePolarity & (uint32_t)CY_SYSPM_HIB_WAKEUP_PIN1_POLARITY_HIGH_MASK))
1038 {
1039 wakeupCause = ((uint32_t)CY_SYSPM_HIBERNATE_PIN1_HIGH);
1040 }
1041 else
1042 {
1043 wakeupCause = ((uint32_t)CY_SYSPM_HIBERNATE_PIN1_LOW);
1044 }
1045 }
1046 break;
1047
1048 case CY_SYSPM_HIB_WAKEUP_LPCOMP0_POS:
1049 {
1050 if (0U != (wakeupCausePolarity & (uint32_t)CY_SYSPM_HIB_WAKEUP_LPCOMP0_POLARITY_HIGH_MASK))
1051 {
1052 wakeupCause = ((uint32_t)CY_SYSPM_HIBERNATE_LPCOMP0_HIGH);
1053 }
1054 else
1055 {
1056 wakeupCause = ((uint32_t)CY_SYSPM_HIBERNATE_LPCOMP0_LOW);
1057 }
1058 }
1059 break;
1060
1061 case CY_SYSPM_HIB_WAKEUP_LPCOMP1_POS:
1062 {
1063 if (0U != (wakeupCausePolarity & (uint32_t)CY_SYSPM_HIB_WAKEUP_LPCOMP1_POLARITY_HIGH_MASK))
1064 {
1065 wakeupCause = ((uint32_t)CY_SYSPM_HIBERNATE_LPCOMP1_HIGH);
1066 }
1067 else
1068 {
1069 wakeupCause = ((uint32_t)CY_SYSPM_HIBERNATE_LPCOMP1_LOW);
1070 }
1071 }
1072 break;
1073
1074 case CY_SYSPM_HIB_WAKEUP_RTC_MASK:
1075 {
1076 wakeupCause = ((uint32_t)CY_SYSPM_HIBERNATE_RTC_ALARM);
1077 }
1078 break;
1079
1080 case CY_SYSPM_HIB_WAKEUP_WDT_MASK:
1081 {
1082 wakeupCause = ((uint32_t)CY_SYSPM_HIBERNATE_WDT);
1083 }
1084 break;
1085
1086 default:
1087 CY_ASSERT_L2(false);
1088 break;
1089 }
1090
1091 return (cy_en_syspm_hibernate_wakeup_source_t)wakeupCause;
1092 }
1093
Cy_SysPm_ClearHibernateWakeupCause(void)1094 void Cy_SysPm_ClearHibernateWakeupCause(void)
1095 {
1096 uint32_t temp = SRSS_PWR_HIB_WAKE_CAUSE;
1097 SRSS_PWR_HIB_WAKE_CAUSE = temp;
1098 }
1099
Cy_SysPm_CoreBuckSetVoltage(cy_en_syspm_core_buck_voltage_t voltage)1100 cy_en_syspm_status_t Cy_SysPm_CoreBuckSetVoltage(cy_en_syspm_core_buck_voltage_t voltage)
1101 {
1102 CY_ASSERT_L2(CY_SYSPM_IS_CORE_BUCK_VOLTAGE_VALID(voltage));
1103
1104 CY_REG32_CLR_SET(SRSS_PWR_CBUCK_CTL, SRSS_PWR_CBUCK_CTL_CBUCK_VSEL, voltage);
1105
1106 /* Since voltage is changed , use it for the CBUCK setting decision */
1107 CY_REG32_CLR_SET(SRSS_PWR_CBUCK_CTL2, SRSS_PWR_CBUCK_CTL2_CBUCK_USE_SETTINGS, 1UL);
1108
1109 return Cy_SysPm_CoreBuckStatus();
1110 }
1111
Cy_SysPm_CoreBuckGetVoltage(void)1112 cy_en_syspm_core_buck_voltage_t Cy_SysPm_CoreBuckGetVoltage(void)
1113 {
1114 CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to cy_en_syspm_core_buck_voltage_t enum.');
1115 return (cy_en_syspm_core_buck_voltage_t)(_FLD2VAL(SRSS_PWR_CBUCK_CTL_CBUCK_VSEL, SRSS_PWR_CBUCK_CTL));
1116 }
1117
Cy_SysPm_CoreBuckSetMode(cy_en_syspm_core_buck_mode_t mode)1118 void Cy_SysPm_CoreBuckSetMode(cy_en_syspm_core_buck_mode_t mode)
1119 {
1120 CY_ASSERT_L2(CY_SYSPM_IS_CORE_BUCK_MODE_VALID(mode));
1121
1122 CY_REG32_CLR_SET(SRSS_PWR_CBUCK_CTL, SRSS_PWR_CBUCK_CTL_CBUCK_MODE, mode);
1123 }
1124
Cy_SysPm_CoreBuckGetMode(void)1125 cy_en_syspm_core_buck_mode_t Cy_SysPm_CoreBuckGetMode(void)
1126 {
1127 CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to cy_en_syspm_core_buck_mode_t enum.');
1128 return (cy_en_syspm_core_buck_mode_t)(_FLD2VAL(SRSS_PWR_CBUCK_CTL_CBUCK_MODE, SRSS_PWR_CBUCK_CTL));
1129 }
1130
Cy_SysPm_CoreBuckSetInrushLimit(cy_en_syspm_core_inrush_limit_t inrushLimit)1131 void Cy_SysPm_CoreBuckSetInrushLimit(cy_en_syspm_core_inrush_limit_t inrushLimit)
1132 {
1133 CY_ASSERT_L2(CY_SYSPM_IS_CORE_BUCK_INRUSH_LIMIT_VALID(inrushLimit));
1134
1135 CY_REG32_CLR_SET(SRSS_PWR_CBUCK_CTL3, SRSS_PWR_CBUCK_CTL3_CBUCK_INRUSH_SEL, inrushLimit);
1136 }
1137
Cy_SysPm_CoreBuckGetInrushLimit(void)1138 cy_en_syspm_core_inrush_limit_t Cy_SysPm_CoreBuckGetInrushLimit(void)
1139 {
1140 CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to cy_en_syspm_core_inrush_limit_t enum.');
1141 return (cy_en_syspm_core_inrush_limit_t)(_FLD2VAL(SRSS_PWR_CBUCK_CTL3_CBUCK_INRUSH_SEL, SRSS_PWR_CBUCK_CTL3));
1142 }
1143
Cy_SysPm_CoreBuckConfig(cy_stc_syspm_core_buck_params_t * config)1144 cy_en_syspm_status_t Cy_SysPm_CoreBuckConfig(cy_stc_syspm_core_buck_params_t *config)
1145 {
1146 CY_ASSERT_L2(CY_SYSPM_IS_CORE_BUCK_VOLTAGE_VALID(config->voltageSel));
1147 CY_ASSERT_L2(CY_SYSPM_IS_CORE_BUCK_MODE_VALID(config->mode));
1148 CY_ASSERT_L2(CY_SYSPM_IS_CORE_BUCK_INRUSH_LIMIT_VALID(config->inRushLimitSel));
1149
1150 SRSS_PWR_CBUCK_CTL = _VAL2FLD(SRSS_PWR_CBUCK_CTL_CBUCK_VSEL, config->voltageSel) |
1151 _VAL2FLD(SRSS_PWR_CBUCK_CTL_CBUCK_MODE, config->mode);
1152
1153 SRSS_PWR_CBUCK_CTL2 = _VAL2FLD(SRSS_PWR_CBUCK_CTL2_CBUCK_OVERRIDE, ((config->override) ? 1UL : 0UL)) |
1154 _VAL2FLD(SRSS_PWR_CBUCK_CTL2_CBUCK_COPY_SETTINGS, ((config->copySettings) ? 1UL : 0UL)) |
1155 _VAL2FLD(SRSS_PWR_CBUCK_CTL2_CBUCK_USE_SETTINGS, ((config->useSettings) ? 1UL : 0UL));
1156
1157 SRSS_PWR_CBUCK_CTL3 = _VAL2FLD(SRSS_PWR_CBUCK_CTL3_CBUCK_INRUSH_SEL, config->inRushLimitSel);
1158
1159 /* Check if the CBUCK transition is Successful */
1160 return Cy_SysPm_CoreBuckStatus();
1161 }
1162
Cy_SysPm_CoreBuckStatus(void)1163 cy_en_syspm_status_t Cy_SysPm_CoreBuckStatus(void)
1164 {
1165 cy_en_syspm_status_t retVal = CY_SYSPM_TIMEOUT;
1166 uint32_t syspmCbuckRetry = CY_SYSPM_CBUCK_BUSY_RETRY_COUNT;
1167
1168 while((_FLD2VAL(SRSS_PWR_CBUCK_STATUS_PMU_DONE, SRSS_PWR_CBUCK_STATUS) == 0U) && (syspmCbuckRetry != 0U))
1169 {
1170 syspmCbuckRetry--;
1171 Cy_SysLib_Delay(CY_SYSPM_CBUCK_BUSY_RETRY_DELAY_MS);
1172 }
1173
1174 if(syspmCbuckRetry != 0UL)
1175 {
1176 retVal = CY_SYSPM_SUCCESS;
1177 }
1178
1179 return retVal;
1180 }
1181
1182 #ifdef ENABLE_MEM_VOLTAGE_TRIMS
Cy_SysPm_SdrConfigure(cy_en_syspm_sdr_t sdr,cy_stc_syspm_sdr_params_t * config)1183 void Cy_SysPm_SdrConfigure(cy_en_syspm_sdr_t sdr, cy_stc_syspm_sdr_params_t *config)
1184 {
1185 CY_ASSERT_L2(CY_SYSPM_IS_SDR_NUM_VALID(sdr));
1186 CY_ASSERT_L2(CY_SYSPM_IS_CORE_BUCK_VOLTAGE_VALID(config->coreBuckVoltSel));
1187 CY_ASSERT_L2(CY_SYSPM_IS_CORE_BUCK_MODE_VALID(config->coreBuckMode));
1188 CY_ASSERT_L2(CY_SYSPM_IS_SDR_VOLTAGE_VALID(config->sdrVoltSel));
1189
1190 CY_SYSPM_CORE_BUCK_PAUSE_ENABLE(1U);
1191
1192 if(sdr == CY_SYSPM_SDR_0)
1193 {
1194 cy_en_syspm_sdr_voltage_t currSdr0Volt = Cy_SysPm_SdrGetVoltage(CY_SYSPM_SDR_0);
1195
1196 CY_ASSERT_L2(CY_SYSPM_IS_SDR_VOLTAGE_VALID(config->sdr0DpSlpVoltSel));
1197 CY_ASSERT_L2(CY_SYSPM_IS_CORE_BUCK_VOLTAGE_VALID(config->coreBuckDpSlpVoltSel));
1198 CY_ASSERT_L2(CY_SYSPM_IS_CORE_BUCK_MODE_VALID(config->coreBuckDpSlpMode));
1199
1200 /* High to Low voltage --> TRIM first , Set Voltage next */
1201 if(config->sdrVoltSel < ((uint8_t)currSdr0Volt))
1202 {
1203 if(IsVoltageChangePossible())
1204 {
1205 SetMemoryVoltageTrims((cy_en_syspm_sdr_voltage_t)config->sdrVoltSel);
1206 }
1207
1208 SRSS_PWR_SDR0_CTL = _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_CBUCK_VSEL, config->coreBuckVoltSel) |
1209 _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_CBUCK_MODE, config->coreBuckMode) |
1210 _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_VSEL, config->sdrVoltSel) |
1211 _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_CBUCK_DPSLP_VSEL, config->coreBuckDpSlpVoltSel) |
1212 _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_CBUCK_DPSLP_MODE, config->coreBuckDpSlpMode) |
1213 _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_DPSLP_VSEL, config->sdr0DpSlpVoltSel) |
1214 _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_ALLOW_BYPASS, ((config->sdr0Allowbypass) ? 1UL : 0UL));
1215
1216 }
1217 else if(config->sdrVoltSel > ((uint8_t)currSdr0Volt)) /* Low to High voltage --> Set Voltage first , Trim next */
1218 {
1219 SRSS_PWR_SDR0_CTL = _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_CBUCK_VSEL, config->coreBuckVoltSel) |
1220 _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_CBUCK_MODE, config->coreBuckMode) |
1221 _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_VSEL, config->sdrVoltSel) |
1222 _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_CBUCK_DPSLP_VSEL, config->coreBuckDpSlpVoltSel) |
1223 _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_CBUCK_DPSLP_MODE, config->coreBuckDpSlpMode) |
1224 _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_DPSLP_VSEL, config->sdr0DpSlpVoltSel) |
1225 _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_ALLOW_BYPASS, ((config->sdr0Allowbypass) ? 1UL : 0UL));
1226
1227 if(IsVoltageChangePossible())
1228 {
1229 SetMemoryVoltageTrims((cy_en_syspm_sdr_voltage_t)config->sdrVoltSel);
1230 }
1231 }
1232 else
1233 {
1234 SRSS_PWR_SDR0_CTL = _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_CBUCK_VSEL, config->coreBuckVoltSel) |
1235 _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_CBUCK_MODE, config->coreBuckMode) |
1236 _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_VSEL, config->sdrVoltSel) |
1237 _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_CBUCK_DPSLP_VSEL, config->coreBuckDpSlpVoltSel) |
1238 _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_CBUCK_DPSLP_MODE, config->coreBuckDpSlpMode) |
1239 _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_DPSLP_VSEL, config->sdr0DpSlpVoltSel) |
1240 _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_ALLOW_BYPASS, ((config->sdr0Allowbypass) ? 1UL : 0UL));
1241 }
1242 }
1243 else
1244 {
1245 SRSS_PWR_SDR1_CTL = _VAL2FLD(SRSS_PWR_SDR1_CTL_SDR1_CBUCK_VSEL, config->coreBuckVoltSel) |
1246 _VAL2FLD(SRSS_PWR_SDR1_CTL_SDR1_CBUCK_MODE, config->coreBuckMode) |
1247 _VAL2FLD(SRSS_PWR_SDR1_CTL_SDR1_VSEL, config->sdrVoltSel) |
1248 _VAL2FLD(SRSS_PWR_SDR1_CTL_SDR1_HW_SEL, ((config->sdr1HwControl) ? 1UL : 0UL)) |
1249 _VAL2FLD(SRSS_PWR_SDR1_CTL_SDR1_ENABLE, ((config->sdr1Enable) ? 1UL : 0UL));
1250 }
1251
1252 CY_SYSPM_CORE_BUCK_PAUSE_ENABLE(0U);
1253 }
1254
Cy_SysPm_SdrSetVoltage(cy_en_syspm_sdr_t sdr,cy_en_syspm_sdr_voltage_t voltage)1255 void Cy_SysPm_SdrSetVoltage(cy_en_syspm_sdr_t sdr, cy_en_syspm_sdr_voltage_t voltage)
1256 {
1257 CY_ASSERT_L2(CY_SYSPM_IS_SDR_NUM_VALID(sdr));
1258 CY_ASSERT_L2(CY_SYSPM_IS_SDR_VOLTAGE_VALID(voltage));
1259
1260 CY_SYSPM_CORE_BUCK_PAUSE_ENABLE(1U);
1261
1262 if(sdr == CY_SYSPM_SDR_0)
1263 {
1264 cy_en_syspm_sdr_voltage_t currSdr0Volt = Cy_SysPm_SdrGetVoltage(CY_SYSPM_SDR_0);
1265 /* High to Low voltage --> Set TRIM's first , Set Voltage next */
1266 if(voltage < currSdr0Volt)
1267 {
1268 if(IsVoltageChangePossible())
1269 {
1270 SetMemoryVoltageTrims(voltage);
1271 }
1272
1273 CY_REG32_CLR_SET(SRSS_PWR_SDR0_CTL, SRSS_PWR_SDR0_CTL_SDR0_VSEL, voltage);
1274 }
1275 /* Low to High voltage --> Set Voltage first , Set TRIM's next */
1276 else if (voltage > currSdr0Volt)
1277 {
1278 CY_REG32_CLR_SET(SRSS_PWR_SDR0_CTL, SRSS_PWR_SDR0_CTL_SDR0_VSEL, voltage);
1279
1280 if(IsVoltageChangePossible())
1281 {
1282 SetMemoryVoltageTrims(voltage);
1283 }
1284 }
1285 else
1286 {
1287 }
1288 }
1289 else
1290 {
1291 CY_REG32_CLR_SET(SRSS_PWR_SDR1_CTL, SRSS_PWR_SDR1_CTL_SDR1_VSEL, voltage);
1292 }
1293
1294 CY_SYSPM_CORE_BUCK_PAUSE_ENABLE(0U);
1295 }
1296 #endif /* ENABLE_MEM_VOLTAGE_TRIMS */
1297
Cy_SysPm_SdrGetVoltage(cy_en_syspm_sdr_t sdr)1298 cy_en_syspm_sdr_voltage_t Cy_SysPm_SdrGetVoltage(cy_en_syspm_sdr_t sdr)
1299 {
1300 CY_ASSERT_L2(CY_SYSPM_IS_SDR_NUM_VALID(sdr));
1301
1302 if(sdr == CY_SYSPM_SDR_0)
1303 {
1304 CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to cy_en_syspm_sdr_voltage_t enum.');
1305 return (cy_en_syspm_sdr_voltage_t)(_FLD2VAL(SRSS_PWR_SDR0_CTL_SDR0_VSEL, SRSS_PWR_SDR0_CTL));
1306 }
1307 else
1308 {
1309 CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to cy_en_syspm_sdr_voltage_t enum.');
1310 return (cy_en_syspm_sdr_voltage_t)(_FLD2VAL(SRSS_PWR_SDR1_CTL_SDR1_VSEL, SRSS_PWR_SDR1_CTL));
1311 }
1312 }
1313
Cy_SysPm_SdrEnable(cy_en_syspm_sdr_t sdr,bool enable)1314 void Cy_SysPm_SdrEnable(cy_en_syspm_sdr_t sdr, bool enable)
1315 {
1316 CY_ASSERT_L2(CY_SYSPM_IS_SDR_NUM_VALID(sdr));
1317
1318 if(sdr == CY_SYSPM_SDR_1)
1319 {
1320 CY_REG32_CLR_SET(SRSS_PWR_SDR1_CTL, SRSS_PWR_SDR1_CTL_SDR1_ENABLE, ((enable) ? 1UL : 0UL));
1321 }
1322 }
1323
Cy_SysPm_IsSdrEnabled(cy_en_syspm_sdr_t sdr)1324 bool Cy_SysPm_IsSdrEnabled(cy_en_syspm_sdr_t sdr)
1325 {
1326 CY_ASSERT_L2(CY_SYSPM_IS_SDR_NUM_VALID(sdr));
1327 if(sdr == CY_SYSPM_SDR_0)
1328 {
1329 return (_FLD2BOOL(SRSS_PWR_SDR0_CTL_SDR0_ALLOW_BYPASS, SRSS_PWR_SDR0_CTL)? false : true);
1330 }
1331 else
1332 {
1333 return (_FLD2BOOL(SRSS_PWR_SDR1_CTL_SDR1_ENABLE, SRSS_PWR_SDR1_CTL)? true : false);
1334 }
1335 }
1336
Cy_SysPm_HvLdoConfigure(cy_stc_syspm_hvldo_params_t * config)1337 void Cy_SysPm_HvLdoConfigure(cy_stc_syspm_hvldo_params_t *config)
1338 {
1339 CY_ASSERT_L2(CY_SYSPM_IS_HVLDO_VOLTAGE_VALID(config->voltageSel));
1340
1341 SRSS_PWR_HVLDO0_CTL = _VAL2FLD(SRSS_PWR_HVLDO0_CTL_HVLDO0_VSEL, config->voltageSel) |
1342 _VAL2FLD(SRSS_PWR_HVLDO0_CTL_HVLDO0_HW_SEL, ((config->hwSel) ? 1UL : 0UL)) |
1343 _VAL2FLD(SRSS_PWR_HVLDO0_CTL_HVLDO0_ENABLE, ((config->hvldoEnable) ? 1UL : 0UL));
1344 }
1345
Cy_SysPm_HvLdoEnable(bool enable)1346 void Cy_SysPm_HvLdoEnable(bool enable)
1347 {
1348 CY_REG32_CLR_SET(SRSS_PWR_HVLDO0_CTL, SRSS_PWR_HVLDO0_CTL_HVLDO0_ENABLE, ((enable) ? 1UL : 0UL));
1349 }
1350
Cy_SysPm_IsHvLdoEnabled(void)1351 bool Cy_SysPm_IsHvLdoEnabled(void)
1352 {
1353 return (_FLD2BOOL(SRSS_PWR_HVLDO0_CTL_HVLDO0_ENABLE, SRSS_PWR_HVLDO0_CTL)? true : false);
1354 }
1355
Cy_SysPm_HvLdoSetVoltage(cy_en_syspm_hvldo_voltage_t voltage)1356 void Cy_SysPm_HvLdoSetVoltage(cy_en_syspm_hvldo_voltage_t voltage)
1357 {
1358 CY_ASSERT_L2(CY_SYSPM_IS_HVLDO_VOLTAGE_VALID(voltage));
1359
1360 CY_REG32_CLR_SET(SRSS_PWR_HVLDO0_CTL, SRSS_PWR_HVLDO0_CTL_HVLDO0_VSEL, voltage);
1361 }
1362
Cy_SysPm_HvLdoGetVoltage(void)1363 cy_en_syspm_hvldo_voltage_t Cy_SysPm_HvLdoGetVoltage(void)
1364 {
1365 CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to cy_en_syspm_hvldo_voltage_t enum.');
1366 return (cy_en_syspm_hvldo_voltage_t)(_FLD2VAL(SRSS_PWR_HVLDO0_CTL_HVLDO0_VSEL, SRSS_PWR_HVLDO0_CTL));
1367 }
1368
1369
Cy_SysPm_LdoExtraRequesterConfig(cy_stc_syspm_extraReq_params_t * extraReqConfig)1370 cy_en_syspm_status_t Cy_SysPm_LdoExtraRequesterConfig(cy_stc_syspm_extraReq_params_t *extraReqConfig)
1371 {
1372 cy_en_syspm_status_t retVal = CY_SYSPM_FAIL;
1373
1374 CY_ASSERT_L2(CY_SYSPM_IS_CORE_BUCK_VOLTAGE_VALID(extraReqConfig->coreBuckVoltSel));
1375 CY_ASSERT_L2(CY_SYSPM_IS_CORE_BUCK_VOLTAGE_VALID(extraReqConfig->sdr0Config->coreBuckVoltSel));
1376 CY_ASSERT_L2(CY_SYSPM_IS_CORE_BUCK_MODE_VALID(extraReqConfig->sdr0Config->coreBuckMode));
1377 CY_ASSERT_L2(CY_SYSPM_IS_SDR_VOLTAGE_VALID(extraReqConfig->sdr0Config->sdrVoltSel));
1378 CY_ASSERT_L2(CY_SYSPM_IS_CORE_BUCK_VOLTAGE_VALID(extraReqConfig->sdr1Config->coreBuckVoltSel));
1379 CY_ASSERT_L2(CY_SYSPM_IS_CORE_BUCK_MODE_VALID(extraReqConfig->sdr1Config->coreBuckMode));
1380 CY_ASSERT_L2(CY_SYSPM_IS_SDR_VOLTAGE_VALID(extraReqConfig->sdr1Config->sdrVoltSel));
1381
1382
1383 /* Extra Requester Sequence */
1384
1385 /* 1. Prevent dynamic setting changes by writing PWR_CBUCK_CTL.CBUCK_PAUSE=1. */
1386 CY_SYSPM_CORE_BUCK_PAUSE_ENABLE(1U);
1387
1388 /* 2. Enable PWR_CBUCK_CTL.CBUCK_COPY_SETTINGS */
1389 CY_SYSPM_CORE_BUCK_COPY_SETTINGS_ENABLE(1U);
1390
1391 /* 3. If the intention is to request higher operational state
1392 * (eg. higher CBUCK target voltage or higher CBUCK mode), load the
1393 * desired settings into the extra requester
1394 * (PWR_CBUCK_CTL.CBUCK_VSEL/MODE). Do not reduce any of the
1395 * settings, because the intention is that the eventual
1396 * composite CBUCK mode matches the extra requester
1397 */
1398 (void)Cy_SysPm_CoreBuckSetVoltage((cy_en_syspm_core_buck_voltage_t)extraReqConfig->coreBuckVoltSel);
1399
1400 (void)Cy_SysPm_CoreBuckSetMode((cy_en_syspm_core_buck_mode_t)extraReqConfig->coreBuckMode);
1401
1402 /* 4. Override the normal harmonization logic which internally selects the
1403 * scratch profile using PWR_CBUCK_CTL.CBUCK_OVERRIDE).
1404 */
1405 CY_SYSPM_CORE_BUCK_OVERRRIDE_ENABLE(1U);
1406
1407 /* 5. Wait until the status register indicates the transition is completed.
1408 * See PWR_CBUCK_STATUS.PMU_DONE.
1409 */
1410 retVal = Cy_SysPm_CoreBuckStatus();
1411
1412 if(retVal == CY_SYSPM_SUCCESS)
1413 {
1414 /* 6. Update the desired SDR requester. This is safe to do, because it is
1415 * not the selected profile and there is no transition in progress, so it
1416 * will not have any effect on a CBUCK profile.
1417 */
1418
1419 SRSS_PWR_SDR0_CTL = _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_CBUCK_VSEL, extraReqConfig->sdr0Config->coreBuckVoltSel) |
1420 _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_CBUCK_MODE, extraReqConfig->sdr0Config->coreBuckMode) |
1421 _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_VSEL, extraReqConfig->sdr0Config->sdrVoltSel) |
1422 _VAL2FLD(SRSS_PWR_SDR0_CTL_SDR0_ALLOW_BYPASS, ((extraReqConfig->sdr0Config->sdr0Allowbypass) ? 1UL : 0UL));
1423
1424 SRSS_PWR_SDR1_CTL = _VAL2FLD(SRSS_PWR_SDR1_CTL_SDR1_CBUCK_VSEL, extraReqConfig->sdr1Config->coreBuckVoltSel) |
1425 _VAL2FLD(SRSS_PWR_SDR1_CTL_SDR1_CBUCK_MODE, extraReqConfig->sdr1Config->coreBuckMode) |
1426 _VAL2FLD(SRSS_PWR_SDR1_CTL_SDR1_VSEL, extraReqConfig->sdr1Config->sdrVoltSel) |
1427 _VAL2FLD(SRSS_PWR_SDR1_CTL_SDR1_HW_SEL, ((extraReqConfig->sdr1Config->sdr1HwControl) ? 1UL : 0UL)) |
1428 _VAL2FLD(SRSS_PWR_SDR1_CTL_SDR1_ENABLE, ((extraReqConfig->sdr1Config->sdr1Enable) ? 1UL : 0UL));
1429
1430 }
1431
1432 /* 7. Remove overrides by clearing CBUCK_OVERRIDE and CBUCK_PAUSE */
1433 CY_SYSPM_CORE_BUCK_OVERRRIDE_ENABLE(0U);
1434 CY_SYSPM_CORE_BUCK_PAUSE_ENABLE(0U);
1435
1436 /* 8. Wait until the status register indicates the transition is
1437 * completed. See PWR_CBUCK_STATUS.PMU_DONE.
1438 */
1439 retVal = Cy_SysPm_CoreBuckStatus();
1440
1441 return retVal;
1442 }
1443
1444
Cy_SysPm_RegisterCallback(cy_stc_syspm_callback_t * handler)1445 bool Cy_SysPm_RegisterCallback(cy_stc_syspm_callback_t* handler)
1446 {
1447 bool retVal = false;
1448
1449 /* Verify the input parameters. */
1450 if ((handler != NULL) && (handler->callbackParams != NULL) && (handler->callback != NULL))
1451 {
1452 uint32_t callbackRootIdx = (uint32_t) handler->type;
1453
1454 /* If the callback list is not empty. */
1455 if (pmCallbackRoot[callbackRootIdx] != NULL)
1456 {
1457 cy_stc_syspm_callback_t* curCallback = pmCallbackRoot[callbackRootIdx];
1458 cy_stc_syspm_callback_t* insertPos = curCallback;
1459
1460 /* Find the callback after which the new callback is to be
1461 * inserted. Ensure the given callback has not been registered.
1462 */
1463 while ((NULL != curCallback->nextItm) && (curCallback != handler))
1464 {
1465 curCallback = curCallback->nextItm;
1466 /* Callbacks with the same order value are stored in the order
1467 * they are registered.
1468 */
1469 if (curCallback->order <= handler->order)
1470 {
1471 insertPos = curCallback;
1472 }
1473 }
1474 /* If the callback has not been registered. */
1475 if (curCallback != handler)
1476 {
1477 /* If the callback is to be inserted at the beginning of the list. */
1478 if ((insertPos->prevItm == NULL) && (handler->order < insertPos->order))
1479 {
1480 handler->nextItm = insertPos;
1481 handler->prevItm = NULL;
1482 handler->nextItm->prevItm = handler;
1483 pmCallbackRoot[callbackRootIdx] = handler;
1484 }
1485 else
1486 {
1487 handler->nextItm = insertPos->nextItm;
1488 handler->prevItm = insertPos;
1489
1490 /* If the callback is not inserted at the end of the list. */
1491 if (handler->nextItm != NULL)
1492 {
1493 handler->nextItm->prevItm = handler;
1494 }
1495 insertPos->nextItm = handler;
1496 }
1497 retVal = true;
1498 }
1499 }
1500 else
1501 {
1502 /* The callback list is empty. */
1503 pmCallbackRoot[callbackRootIdx] = handler;
1504 handler->nextItm = NULL;
1505 handler->prevItm = NULL;
1506 retVal = true;
1507 }
1508 }
1509 return retVal;
1510 }
1511
Cy_SysPm_UnregisterCallback(cy_stc_syspm_callback_t const * handler)1512 bool Cy_SysPm_UnregisterCallback(cy_stc_syspm_callback_t const *handler)
1513 {
1514 bool retVal = false;
1515
1516 if (handler != NULL)
1517 {
1518 uint32_t callbackRootIdx = (uint32_t) handler->type;
1519 cy_stc_syspm_callback_t* curCallback = pmCallbackRoot[callbackRootIdx];
1520
1521 /* Search requested callback item in the linked list */
1522 while (curCallback != NULL)
1523 {
1524 /* Requested callback is found */
1525 if (curCallback == handler)
1526 {
1527 retVal = true;
1528 break;
1529 }
1530
1531 /* Go to next callback item in the linked list */
1532 curCallback = curCallback->nextItm;
1533 }
1534
1535 if (retVal)
1536 {
1537 /* Requested callback is first in the list */
1538 if (pmCallbackRoot[callbackRootIdx] == handler)
1539 {
1540 /* Check whether this the only callback registered */
1541 if (pmCallbackRoot[callbackRootIdx]->nextItm != NULL)
1542 {
1543 pmCallbackRoot[callbackRootIdx] = pmCallbackRoot[callbackRootIdx]->nextItm;
1544 pmCallbackRoot[callbackRootIdx]->prevItm = NULL;
1545 }
1546 else
1547 {
1548 /* We had only one callback */
1549 pmCallbackRoot[callbackRootIdx] = NULL;
1550 }
1551 }
1552 else
1553 {
1554 /* Update links of related to unregistered callback items */
1555 curCallback->prevItm->nextItm = curCallback->nextItm;
1556
1557 if (curCallback->nextItm != NULL)
1558 {
1559 curCallback->nextItm->prevItm = curCallback->prevItm;
1560 }
1561 }
1562 }
1563 }
1564
1565 return retVal;
1566 }
1567
Cy_SysPm_ExecuteCallback(cy_en_syspm_callback_type_t type,cy_en_syspm_callback_mode_t mode)1568 cy_en_syspm_status_t Cy_SysPm_ExecuteCallback(cy_en_syspm_callback_type_t type, cy_en_syspm_callback_mode_t mode)
1569 {
1570 CY_ASSERT_L3(CY_SYSPM_IS_CALLBACK_TYPE_VALID(type));
1571 CY_ASSERT_L3(CY_SYSPM_IS_CALLBACK_MODE_VALID(mode));
1572
1573 static cy_stc_syspm_callback_t* lastExecutedCallback = NULL;
1574 cy_en_syspm_status_t retVal = CY_SYSPM_SUCCESS;
1575 cy_stc_syspm_callback_t* curCallback = pmCallbackRoot[(uint32_t) type];
1576 cy_stc_syspm_callback_params_t curParams;
1577
1578 if ((mode == CY_SYSPM_BEFORE_TRANSITION) || (mode == CY_SYSPM_CHECK_READY))
1579 {
1580 /* Execute registered callbacks with order from first registered to the
1581 * last registered. Stop executing if CY_SYSPM_FAIL was returned in
1582 * CY_SYSPM_CHECK_READY mode
1583 */
1584 while ((curCallback != NULL) && ((retVal != CY_SYSPM_FAIL) || (mode != CY_SYSPM_CHECK_READY)))
1585 {
1586 /* The modes defined in the .skipMode element are not executed */
1587 if (0UL == ((uint32_t) mode & curCallback->skipMode))
1588 {
1589 /* Update elements for local callback parameter values */
1590 curParams.base = curCallback->callbackParams->base;
1591 curParams.context = curCallback->callbackParams->context;
1592
1593 retVal = curCallback->callback(&curParams, mode);
1594
1595 /* Update callback pointer with value of executed callback.
1596 * Such update is required to execute further callbacks in
1597 * backward order after exit from LP mode or to undo
1598 * configuration after callback returned fail: from last called
1599 * to first registered.
1600 */
1601 lastExecutedCallback = curCallback;
1602 }
1603 curCallback = curCallback->nextItm;
1604 }
1605
1606 if (mode == CY_SYSPM_CHECK_READY)
1607 {
1608 /* Update the pointer to the failed callback with the result of the callback execution.
1609 * If the callback fails, the value of the pointer will be updated
1610 * with the address of the callback which returned CY_SYSPM_FAIL, else,
1611 * it will be updated with NULL.
1612 */
1613 if(retVal == CY_SYSPM_FAIL)
1614 {
1615 failedCallback[(uint32_t) type] = lastExecutedCallback;
1616 }
1617 else
1618 {
1619 failedCallback[(uint32_t) type] = NULL;
1620 }
1621 }
1622 }
1623 else
1624 {
1625 /* Execute registered callbacks with order from lastCallback or last
1626 * executed to the first registered callback. Such a flow is required if
1627 * a previous callback function returned CY_SYSPM_FAIL or a previous
1628 * callback mode was CY_SYSPM_BEFORE_TRANSITION. Such an order is
1629 * required to undo configurations in correct backward order.
1630 */
1631 if (mode != CY_SYSPM_CHECK_FAIL)
1632 {
1633 while (curCallback->nextItm != NULL)
1634 {
1635 curCallback = curCallback->nextItm;
1636 }
1637 }
1638 else
1639 {
1640 /* Skip last executed callback that returns CY_SYSPM_FAIL, as this
1641 * callback already knows that it failed.
1642 */
1643 curCallback = lastExecutedCallback;
1644
1645 if (curCallback != NULL)
1646 {
1647 curCallback = curCallback->prevItm;
1648 }
1649 }
1650
1651 /* Execute callback functions with required type and mode */
1652 while (curCallback != NULL)
1653 {
1654 /* The modes defined in the .skipMode element are not executed */
1655 if (0UL == ((uint32_t) mode & curCallback->skipMode))
1656 {
1657 /* Update elements for local callback parameter values */
1658 curParams.base = curCallback->callbackParams->base;
1659 curParams.context = curCallback->callbackParams->context;
1660
1661 retVal = curCallback->callback(&curParams, mode);
1662 }
1663 curCallback = curCallback->prevItm;
1664 }
1665 }
1666
1667 return retVal;
1668 }
1669
Cy_SysPm_GetFailedCallback(cy_en_syspm_callback_type_t type)1670 cy_stc_syspm_callback_t* Cy_SysPm_GetFailedCallback(cy_en_syspm_callback_type_t type)
1671 {
1672 return failedCallback[(uint32_t) type];
1673 }
1674
Cy_SysPm_IoUnfreeze(void)1675 void Cy_SysPm_IoUnfreeze(void)
1676 {
1677 uint32_t interruptState;
1678 interruptState = Cy_SysLib_EnterCriticalSection();
1679
1680 /* Preserve the last reset reason and wakeup polarity. Then, unfreeze I/O:
1681 * write PWR_HIBERNATE.FREEZE=0, .UNLOCK=0x3A, .HIBERANTE=0
1682 */
1683 SRSS_PWR_HIBERNATE = (SRSS_PWR_HIBERNATE & HIBERNATE_RETAIN_STATUS_MASK) | HIBERNATE_UNLOCK_VAL;
1684
1685 /* Lock the Hibernate mode:
1686 * write PWR_HIBERNATE.HIBERNATE=0, UNLOCK=0x00, HIBERANTE=0
1687 */
1688 SRSS_PWR_HIBERNATE &= HIBERNATE_RETAIN_STATUS_MASK;
1689
1690 /* Read register to make sure it is settled */
1691 (void) SRSS_PWR_HIBERNATE;
1692
1693 Cy_SysLib_ExitCriticalSection(interruptState);
1694 }
1695
Cy_SysPm_IoIsFrozen(void)1696 bool Cy_SysPm_IoIsFrozen(void)
1697 {
1698 return (0U != _FLD2VAL(SRSS_PWR_HIBERNATE_FREEZE, SRSS_PWR_HIBERNATE));
1699 }
1700
Cy_SysPm_DeepSleepIoUnfreeze(void)1701 void Cy_SysPm_DeepSleepIoUnfreeze(void)
1702 {
1703 uint32_t interruptState;
1704 interruptState = Cy_SysLib_EnterCriticalSection();
1705
1706 /* Unfreeze IO's which are frozen during DEEPSLEEP-RAM/OFF
1707 * Entry
1708 */
1709 SRSS_PWR_CTL2 |= SRSS_PWR_CTL2_FREEZE_DPSLP_Msk;
1710
1711 Cy_SysLib_ExitCriticalSection(interruptState);
1712 }
1713
Cy_SysPm_DeepSleepIoIsFrozen(void)1714 bool Cy_SysPm_DeepSleepIoIsFrozen(void)
1715 {
1716 return (0U != _FLD2VAL(SRSS_PWR_CTL2_FREEZE_DPSLP, SRSS_PWR_CTL2));
1717 }
1718
1719
Cy_SysPm_CpuSendWakeupEvent(void)1720 void Cy_SysPm_CpuSendWakeupEvent(void)
1721 {
1722 __SEV();
1723 }
1724
Cy_SysPm_IsLpmReady(void)1725 bool Cy_SysPm_IsLpmReady(void)
1726 {
1727 return (_FLD2BOOL(SRSS_PWR_CTL_LPM_READY, SRSS_PWR_CTL)? true : false);
1728 }
1729
Cy_SysPm_BackupSetSupply(cy_en_syspm_vddbackup_control_t vddBackControl)1730 void Cy_SysPm_BackupSetSupply(cy_en_syspm_vddbackup_control_t vddBackControl)
1731 {
1732 CY_ASSERT_L3(CY_SYSPM_IS_VDDBACKUP_VALID(vddBackControl));
1733
1734 BACKUP_CTL = _CLR_SET_FLD32U((BACKUP_CTL), BACKUP_CTL_VDDBAK_CTL, (uint32_t) vddBackControl);
1735 }
1736
1737
Cy_SysPm_BackupGetSupply(void)1738 cy_en_syspm_vddbackup_control_t Cy_SysPm_BackupGetSupply(void)
1739 {
1740 uint32_t retVal;
1741 retVal = _FLD2VAL(BACKUP_CTL_VDDBAK_CTL, BACKUP_CTL);
1742
1743 return ((cy_en_syspm_vddbackup_control_t) retVal);
1744 }
1745
1746
Cy_SysPm_BackupEnableVoltageMeasurement(void)1747 void Cy_SysPm_BackupEnableVoltageMeasurement(void)
1748 {
1749 BACKUP_CTL |= BACKUP_CTL_VBACKUP_MEAS_Msk;
1750 }
1751
1752
Cy_SysPm_BackupDisableVoltageMeasurement(void)1753 void Cy_SysPm_BackupDisableVoltageMeasurement(void)
1754 {
1755 BACKUP_CTL &= ((uint32_t) ~BACKUP_CTL_VBACKUP_MEAS_Msk);
1756 }
1757
1758
Cy_SysPm_BackupSuperCapCharge(cy_en_syspm_sc_charge_key_t key)1759 void Cy_SysPm_BackupSuperCapCharge(cy_en_syspm_sc_charge_key_t key)
1760 {
1761 CY_ASSERT_L3(CY_SYSPM_IS_SC_CHARGE_KEY_VALID(key));
1762
1763 if(key == CY_SYSPM_SC_CHARGE_ENABLE)
1764 {
1765 BACKUP_CTL = _CLR_SET_FLD32U((BACKUP_CTL), BACKUP_CTL_EN_CHARGE_KEY, (uint32_t) CY_SYSPM_SC_CHARGE_ENABLE);
1766 }
1767 else
1768 {
1769 BACKUP_CTL &= ((uint32_t) ~BACKUP_CTL_EN_CHARGE_KEY_Msk);
1770 }
1771 }
1772
Cy_SysPm_BackupWordStore(uint32_t wordIndex,uint32_t * wordSrcPointer,uint32_t wordSize)1773 void Cy_SysPm_BackupWordStore(uint32_t wordIndex, uint32_t *wordSrcPointer, uint32_t wordSize)
1774 {
1775 CY_ASSERT_L3(CY_SYSPM_IS_WORD_INDEX_VALID(wordIndex));
1776 CY_ASSERT_L3(CY_SYSPM_IS_WORD_SIZE_VALID(wordSize + wordIndex));
1777
1778 while(wordSize != 0UL)
1779 {
1780 if(wordIndex < CY_SRSS_BACKUP_BREG1_START_POS)
1781 {
1782 BACKUP_BREG_SET0[wordIndex] = *wordSrcPointer;
1783 }
1784 else if(wordIndex < CY_SRSS_BACKUP_BREG2_START_POS)
1785 {
1786 BACKUP_BREG_SET1[wordIndex - CY_SRSS_BACKUP_BREG1_START_POS] = *wordSrcPointer;
1787 }
1788 else if(wordIndex < CY_SRSS_BACKUP_BREG3_START_POS)
1789 {
1790 BACKUP_BREG_SET2[wordIndex - CY_SRSS_BACKUP_BREG2_START_POS] = *wordSrcPointer;
1791 }
1792 else
1793 {
1794 BACKUP_BREG_SET3[wordIndex - CY_SRSS_BACKUP_BREG3_START_POS] = *wordSrcPointer;
1795 }
1796
1797 wordIndex++;
1798 wordSrcPointer++;
1799 wordSize--;
1800 }
1801 }
1802
Cy_SysPm_BackupWordReStore(uint32_t wordIndex,uint32_t * wordDstPointer,uint32_t wordSize)1803 void Cy_SysPm_BackupWordReStore(uint32_t wordIndex, uint32_t *wordDstPointer, uint32_t wordSize)
1804 {
1805 CY_ASSERT_L3(CY_SYSPM_IS_WORD_INDEX_VALID(wordIndex));
1806 CY_ASSERT_L3(CY_SYSPM_IS_WORD_SIZE_VALID(wordSize + wordIndex));
1807
1808 while(wordSize != 0UL)
1809 {
1810
1811 if(wordIndex < CY_SRSS_BACKUP_BREG1_START_POS)
1812 {
1813 *wordDstPointer = BACKUP_BREG_SET0[wordIndex];
1814 }
1815 else if(wordIndex < CY_SRSS_BACKUP_BREG2_START_POS)
1816 {
1817 *wordDstPointer = BACKUP_BREG_SET1[wordIndex - CY_SRSS_BACKUP_BREG1_START_POS];
1818 }
1819 else if(wordIndex < CY_SRSS_BACKUP_BREG3_START_POS)
1820 {
1821 *wordDstPointer = BACKUP_BREG_SET2[wordIndex - CY_SRSS_BACKUP_BREG2_START_POS];
1822 }
1823 else
1824 {
1825 *wordDstPointer = BACKUP_BREG_SET3[wordIndex - CY_SRSS_BACKUP_BREG3_START_POS];
1826 }
1827
1828 wordIndex++;
1829 wordDstPointer++;
1830 wordSize--;
1831 }
1832 }
1833
1834 /* This API is an inline version of Cy_SysPm_SetSRAMMacroPwrMode */
Cy_SysPm_SetSRAMMacroPwrModeInline(cy_en_syspm_sram_index_t sramNum,uint32_t sramMacroNum,cy_en_syspm_sram_pwr_mode_t sramPwrMode)1835 __STATIC_FORCEINLINE cy_en_syspm_status_t Cy_SysPm_SetSRAMMacroPwrModeInline(cy_en_syspm_sram_index_t sramNum, uint32_t sramMacroNum, cy_en_syspm_sram_pwr_mode_t sramPwrMode)
1836 {
1837 CY_ASSERT_L3(sramNum == CY_SYSPM_SRAM0_MEMORY);
1838 CY_ASSERT_L3((sramPwrMode == CY_SYSPM_SRAM_PWR_MODE_ON) || (sramPwrMode == CY_SYSPM_SRAM_PWR_MODE_OFF));
1839 CY_ASSERT_L3(sramMacroNum < CY_CPUSS_RAMC0_MACRO_NR);
1840
1841 CY_UNUSED_PARAM(sramNum);
1842
1843 /* Unlock PWR MACRO Control */
1844 /* Clear bit 0(CLR0)*/
1845 MXSRAMC_PWR_MACRO_CTL_LOCK = MXSRAMC_PWR_MACRO_CTL_LOCK_CLR0;
1846 /* Clear bit 1(CLR1)*/
1847 MXSRAMC_PWR_MACRO_CTL_LOCK = MXSRAMC_PWR_MACRO_CTL_LOCK_CLR1;
1848
1849 if(sramPwrMode == CY_SYSPM_SRAM_PWR_MODE_ON)
1850 {
1851 /* Enable the Macro Number */
1852 MXSRAMC_PWR_MACRO_CTL &= ~(0x1UL << (uint32_t)sramMacroNum);
1853 }
1854 else
1855 {
1856 /* Disable the Macro Number */
1857 MXSRAMC_PWR_MACRO_CTL |= (0x1UL << (uint32_t)sramMacroNum);
1858 }
1859 /* Wait for the PWR_DONE status */
1860 while(!_FLD2BOOL(RAMC_STATUS_PWR_DONE, MXSRAMC_STATUS)){}
1861
1862 /* Lock PWR MACRO Control(Set SET01) */
1863 MXSRAMC_PWR_MACRO_CTL_LOCK = MXSRAMC_PWR_MACRO_CTL_LOCK_SET01;
1864
1865 return CY_SYSPM_SUCCESS;
1866 }
1867
Cy_SysPm_SetSRAMMacroPwrMode(cy_en_syspm_sram_index_t sramNum,uint32_t sramMacroNum,cy_en_syspm_sram_pwr_mode_t sramPwrMode)1868 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)
1869 {
1870 return Cy_SysPm_SetSRAMMacroPwrModeInline(sramNum, sramMacroNum, sramPwrMode);
1871 }
1872
Cy_SysPm_GetSRAMMacroPwrMode(cy_en_syspm_sram_index_t sramNum,uint32_t sramMacroNum)1873 cy_en_syspm_sram_pwr_mode_t Cy_SysPm_GetSRAMMacroPwrMode(cy_en_syspm_sram_index_t sramNum, uint32_t sramMacroNum)
1874 {
1875 cy_en_syspm_sram_pwr_mode_t value;
1876
1877 CY_ASSERT_L3(sramNum == CY_SYSPM_SRAM0_MEMORY);
1878 CY_ASSERT_L3(sramMacroNum < CY_CPUSS_RAMC0_MACRO_NR);
1879
1880 CY_UNUSED_PARAM(sramNum);
1881
1882 /* Unlock PWR MACRO Control */
1883 /* Clear bit 0(CLR0)*/
1884 MXSRAMC_PWR_MACRO_CTL_LOCK = MXSRAMC_PWR_MACRO_CTL_LOCK_CLR0;
1885 /* Clear bit 1(CLR1)*/
1886 MXSRAMC_PWR_MACRO_CTL_LOCK = MXSRAMC_PWR_MACRO_CTL_LOCK_CLR1;
1887
1888 value = ((MXSRAMC_PWR_MACRO_CTL & (0x1UL << (uint32_t)sramMacroNum)) != 0UL) ? CY_SYSPM_SRAM_PWR_MODE_OFF:CY_SYSPM_SRAM_PWR_MODE_ON;
1889
1890 /* Lock PWR MACRO Control(Set SET01) */
1891 MXSRAMC_PWR_MACRO_CTL_LOCK = MXSRAMC_PWR_MACRO_CTL_LOCK_SET01;
1892
1893 return value;
1894
1895 }
1896
1897
Cy_SysPm_SetSRAMPwrMode(cy_en_syspm_sram_index_t sramNum,cy_en_syspm_sram_pwr_mode_t sramPwrMode)1898 cy_en_syspm_status_t Cy_SysPm_SetSRAMPwrMode(cy_en_syspm_sram_index_t sramNum, cy_en_syspm_sram_pwr_mode_t sramPwrMode)
1899 {
1900 CY_ASSERT_L3(sramNum == CY_SYSPM_SRAM0_MEMORY);
1901 CY_ASSERT_L3((sramPwrMode == CY_SYSPM_SRAM_PWR_MODE_ON) || (sramPwrMode == CY_SYSPM_SRAM_PWR_MODE_OFF));
1902
1903 CY_UNUSED_PARAM(sramNum);
1904
1905 (void)Cy_SysPm_SetSRAMMacroPwrMode(CY_SYSPM_SRAM0_MEMORY, (uint32_t)CY_SYSPM_SRAM0_MACRO_0, sramPwrMode);
1906 (void)Cy_SysPm_SetSRAMMacroPwrMode(CY_SYSPM_SRAM0_MEMORY, (uint32_t)CY_SYSPM_SRAM0_MACRO_1, sramPwrMode);
1907
1908 return CY_SYSPM_SUCCESS;
1909 }
1910
1911 /*This reset handler will be implemented as part of HCI ROM app*/
Cy_SysPm_Dsramoff_Entry(void)1912 __WEAK void Cy_SysPm_Dsramoff_Entry(void)
1913 {
1914 while(true) {}
1915 }
1916
Cy_SysPm_CpuEnterRAMOffDeepSleep(void)1917 cy_en_syspm_status_t Cy_SysPm_CpuEnterRAMOffDeepSleep(void)
1918 {
1919 uint32_t interruptState;
1920 uint32_t cbDeepSleepRootIdx = (uint32_t) Cy_SysPm_GetDeepSleepMode();
1921 cy_en_syspm_status_t retVal = CY_SYSPM_SUCCESS;
1922
1923 CY_ASSERT_L3(CY_SYSPM_IS_DEEPSLEEP_MODE_VALID(cbDeepSleepRootIdx));
1924
1925 //Check if LPM is ready
1926 if(!Cy_SysPm_IsLpmReady())
1927 {
1928 retVal = CY_SYSPM_FAIL;
1929 }
1930 else
1931 {
1932 //TBD Check if PDCM Dependencies are set properly
1933
1934 /* Call the registered callback functions with the CY_SYSPM_CHECK_READY
1935 * parameter
1936 */
1937 if (pmCallbackRoot[cbDeepSleepRootIdx] != NULL)
1938 {
1939 retVal = Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbDeepSleepRootIdx, CY_SYSPM_CHECK_READY);
1940 }
1941
1942 /* The CPU can switch into the Deep Sleep power mode only when
1943 * all executed registered callback functions with the CY_SYSPM_CHECK_READY
1944 * parameter return CY_SYSPM_SUCCESS
1945 */
1946 if (retVal == CY_SYSPM_SUCCESS)
1947 {
1948 /* Call the registered callback functions with the
1949 * CY_SYSPM_BEFORE_TRANSITION parameter
1950 */
1951 interruptState = Cy_SysLib_EnterCriticalSection();
1952 if (pmCallbackRoot[cbDeepSleepRootIdx] != NULL)
1953 {
1954 (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbDeepSleepRootIdx, CY_SYSPM_BEFORE_TRANSITION);
1955 }
1956 /* The CPU enters Deep Sleep mode upon execution of WFI/WFE
1957 * use Cy_SysPm_SetDeepSleepMode to set various deepsleep modes TBD*/
1958 SCB_SCR |= SCB_SCR_SLEEPDEEP_Msk;
1959
1960 /* Disable SRAM Macros to save power */
1961 (void)Cy_SysPm_SetSRAMMacroPwrModeInline(CY_SYSPM_SRAM0_MEMORY, (uint32_t)CY_SYSPM_SRAM0_MACRO_0, CY_SYSPM_SRAM_PWR_MODE_OFF);
1962
1963 __WFI();
1964
1965 /* Enable SRAM Macros as DEEPSLEEP_RAM might have failed if we reach this point */
1966 (void)Cy_SysPm_SetSRAMMacroPwrModeInline(CY_SYSPM_SRAM0_MEMORY, (uint32_t)CY_SYSPM_SRAM0_MACRO_0, CY_SYSPM_SRAM_PWR_MODE_ON);
1967
1968 /* Jump to HCI ROM app Reset handler */
1969 Cy_SysPm_Dsramoff_Entry();
1970
1971 Cy_SysLib_ExitCriticalSection(interruptState);
1972 }
1973 else
1974 {
1975 /* Execute callback functions with the CY_SYSPM_CHECK_FAIL parameter to
1976 * undo everything done in the callback with the CY_SYSPM_CHECK_READY
1977 * parameter
1978 */
1979 if (pmCallbackRoot[cbDeepSleepRootIdx] != NULL)
1980 {
1981 (void) Cy_SysPm_ExecuteCallback((cy_en_syspm_callback_type_t)cbDeepSleepRootIdx, CY_SYSPM_CHECK_FAIL);
1982 }
1983 }
1984 }
1985 return retVal;
1986 }
1987
Cy_SysPm_TriggerSoftReset(void)1988 void Cy_SysPm_TriggerSoftReset(void)
1989 {
1990 SRSS_RES_SOFT_CTL = SRSS_RES_SOFT_CTL_TRIGGER_SOFT_Msk;
1991 }
1992
1993 #ifdef ENABLE_MEM_VOLTAGE_TRIMS
1994 /*******************************************************************************
1995 * Function Name: SetMemoryVoltageTrims
1996 ****************************************************************************//**
1997 *
1998 * This is the internal function that updates the trim values for the
1999 * RAM and ROM. The trim update is done during transition of regulator voltage
2000 * from higher to a lower one.
2001 *
2002 *******************************************************************************/
SetMemoryVoltageTrims(cy_en_syspm_sdr_voltage_t voltage)2003 static void SetMemoryVoltageTrims(cy_en_syspm_sdr_voltage_t voltage)
2004 {
2005 uint32_t ramVoltgeTrim = CPUSS_TRIM_RAM_CTL;
2006 uint32_t romVoltgeTrim = CPUSS_TRIM_ROM_CTL;
2007
2008 CY_ASSERT_L3(CY_SYSPM_IS_SDR_TRIM_VOLTAGE_VALID(voltage));
2009
2010 switch(voltage)
2011 {
2012 case CY_SYSPM_SDR_VOLTAGE_0_900V:
2013 {
2014 ramVoltgeTrim = CPUSS_TRIM_RAM_VOLT_0_900;
2015 romVoltgeTrim = CPUSS_TRIM_ROM_VOLT_0_900;
2016 }
2017 break;
2018
2019 case CY_SYSPM_SDR_VOLTAGE_1_000V:
2020 {
2021 ramVoltgeTrim = CPUSS_TRIM_RAM_VOLT_1_000;
2022 romVoltgeTrim = CPUSS_TRIM_ROM_VOLT_1_000;
2023 }
2024 break;
2025
2026 case CY_SYSPM_SDR_VOLTAGE_1_100V:
2027 {
2028 ramVoltgeTrim = CPUSS_TRIM_RAM_VOLT_1_100;
2029 romVoltgeTrim = CPUSS_TRIM_ROM_VOLT_1_100;
2030 }
2031 break;
2032
2033 default:
2034 {
2035 CY_ASSERT_L2(false);
2036 }
2037 break;
2038 }
2039
2040 CPUSS_TRIM_RAM_CTL = ramVoltgeTrim;
2041 CPUSS_TRIM_ROM_CTL = romVoltgeTrim;
2042
2043 }
2044
2045
2046 /*******************************************************************************
2047 * Function Name: IsVoltageChangePossible
2048 ****************************************************************************//**
2049 *
2050 * The internal function that checks wherever it is possible to change the core
2051 * voltage. The voltage change is possible only when the protection context is
2052 * set to zero (PC = 0), or the device supports modifying registers via syscall.
2053 *
2054 *******************************************************************************/
IsVoltageChangePossible(void)2055 static bool IsVoltageChangePossible(void)
2056 {
2057
2058 bool retVal = false;
2059
2060 #if (CY_SYSLIB_GET_SILICON_REV_ID != CY_SYSLIB_20829A0_SILICON_REV)
2061 {
2062 uint32_t trimRamCheckVal = (CPUSS_TRIM_RAM_CTL & CPUSS_TRIM_RAM_CTL_WC_MASK);
2063
2064 CPUSS_TRIM_RAM_CTL &= ~CPUSS_TRIM_RAM_CTL_WC_MASK;
2065 CPUSS_TRIM_RAM_CTL |= ((~trimRamCheckVal) & CPUSS_TRIM_RAM_CTL_WC_MASK);
2066
2067 retVal = (trimRamCheckVal != (CPUSS_TRIM_RAM_CTL & CPUSS_TRIM_RAM_CTL_WC_MASK));
2068 }
2069 #endif
2070 return retVal;
2071 }
2072 #endif /* ENABLE_MEM_VOLTAGE_TRIMS */
2073
2074 #endif
2075 /* [] END OF FILE */
2076