1 /*
2  * Copyright (C) 2022-2024, Xiaohua Semiconductor Co., Ltd.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2023-06-12     CDT          first version
9  */
10 
11 
12 #ifndef __DRV_PM_H__
13 #define __DRV_PM_H__
14 
15 /*******************************************************************************
16  * Include files
17  ******************************************************************************/
18 #include <drv_config.h>
19 
20 /* C binding of definitions if building with C++ compiler */
21 #ifdef __cplusplus
22 extern "C"
23 {
24 #endif
25 /*******************************************************************************
26  *  @defgroup sleep_mode_map
27  *  @brief The mapping of rtt pm sleep mode to hc32 low power mode
28  * --------------------------------------------------
29  * rtt pm sleep mode |  hc32 low power mode
30  * ------------------|-------------------------------
31  *    idle           |    sleep
32  *    deep           |    stop
33  *    standby        |    power down mode 1 or 2, selection @ref PM_SLEEP_STANDBY_CFG
34  *    shutdown mode  |    power down mode 3 or 4, selection @ref PM_SLEEP_SHUTDOWN_CFG
35  ******************************************************************************/
36 
37 /*******************************************************************************
38  * Global type definitions ('typedef')
39  ******************************************************************************/
40 typedef void (* run_mode_init_func)(uint8_t run_mode);
41 
42 /**
43  * @brief  run mode config @ref PM_RUN_MODE_CFG
44  */
45 struct pm_run_mode_config
46 {
47     run_mode_init_func sys_clk_cfg;
48 };
49 
50 /**
51  * @brief  sleep idle config @ref PM_SLEEP_IDLE_CFG
52  */
53 struct pm_sleep_mode_idle_config
54 {
55     uint8_t pwc_sleep_type;              /*!< WFI/WFE selection and SEVONPEND configuration
56                                             @ref PWC_Sleep_Type */
57 };
58 
59 
60 /**
61  * @brief  sleep deep config @ref PM_SLEEP_DEEP_CFG
62  */
63 struct pm_sleep_mode_deep_config
64 {
65     stc_pwc_stop_mode_config_t cfg;
66     uint8_t pwc_stop_type;              /*!< WFI/WFE selection and SEVONPEND configuration
67                                             @ref PWC_Stop_Type */
68 };
69 
70 
71 /**
72  * @brief  sleep standby config @ref PM_SLEEP_STANDBY_CFG
73  */
74 struct pm_sleep_mode_standby_config
75 {
76     stc_pwc_pd_mode_config_t cfg;       /*!< cfg.u8Mode could only be PWC_PD_MD1 or  PWC_PD_MD2,
77                                             @ref PWC_PDMode_Sel, @ref  sleep_mode_map */
78 };
79 
80 /**
81  * @brief  sleep shutdown config @ref PM_SLEEP_SHUTDOWN_CFG
82  */
83 struct pm_sleep_mode_shutdown_config
84 {
85     stc_pwc_pd_mode_config_t cfg;       /*!< cfg.u8Mode could only be PWC_PD_MD3 or  PWC_PD_MD4,
86                                               @ref PWC_PDMode_Sel, @ref sleep_mode_map */
87 };
88 
89 /*******************************************************************************
90  * Global pre-processor symbols/macros ('#define')
91  ******************************************************************************/
92 #if defined(HC32F4A0) || defined(HC32F4A8)
93 #define PM_CHECK_EFM()                  ((EFM_GetStatus(EFM_FLAG_RDY) == SET) && (EFM_GetStatus(EFM_FLAG_RDY1) == SET))
94 #elif defined(HC32F460) || defined (HC32F448) || defined (HC32F472)
95 #define PM_CHECK_EFM()                  ((EFM_GetStatus(EFM_FLAG_RDY) == SET))
96 #endif
97 #define PM_CHECK_XTAL()                 ((CM_CMU->XTALSTDCR & CLK_XTALSTD_ON) == 0)
98 #define PM_CHECK_DMA()                                              \
99 (                                       (DMA_GetTransStatus(CM_DMA1, DMA_STAT_TRANS_DMA) == RESET) && \
100                                         (DMA_GetTransStatus(CM_DMA2, DMA_STAT_TRANS_DMA) == RESET))
101 #define PM_CHECK_SWDT()                                             \
102 (                                       ((CM_ICG->ICG0 & ICG_SWDT_RST_START) != ICG_SWDT_RST_START) || \
103                                         ((CM_ICG->ICG0 & ICG_SWDT_LPM_CNT_STOP) == ICG_SWDT_LPM_CNT_STOP))
104 #define PM_CHECK_PVD()                                              \
105 (                                       ((CM_PWC->PVDCR1 & (PWC_PVDCR1_PVD1IRE | PWC_PVDCR1_PVD1IRS)) != (PWC_PVDCR1_PVD1IRE | PWC_PVDCR1_PVD1IRS)) && \
106                                         ((CM_PWC->PVDCR1 & (PWC_PVDCR1_PVD2IRE | PWC_PVDCR1_PVD2IRS)) != (PWC_PVDCR1_PVD2IRE | PWC_PVDCR1_PVD2IRS)))
107 #define PM_SLEEP_SHUTDOWN_CHECK()                                   \
108 (                                       PM_CHECK_EFM() &&           \
109                                         PM_CHECK_XTAL() &&          \
110                                         PM_CHECK_SWDT() &&          \
111                                         PM_CHECK_PVD())
112 #define PM_SLEEP_DEEP_CHECK()                                       \
113 (                                       PM_CHECK_EFM() &&           \
114                                         PM_CHECK_XTAL() &&          \
115                                         PM_CHECK_DMA())
116 /*
117 * please make sure the state of the peripherals meet the requirements of entering the specified sleep mode,
118 * otherwise system may not entering the right sleep mode or something unexpected may happen.
119 * PM_SLEEP_CHECK is a demo of requirements and may not be comprehensive,
120 * please refer user manual to know all the requirements in detail.
121 */
122 #define PM_SLEEP_CHECK(mode)                                        \
123 (                                       (mode ==  PM_SLEEP_MODE_STANDBY && PM_SLEEP_SHUTDOWN_CHECK()) || \
124 (                                       (mode ==  PM_SLEEP_MODE_SHUTDOWN && PM_SLEEP_SHUTDOWN_CHECK()) || \
125                                         (mode ==  PM_SLEEP_MODE_DEEP && PM_SLEEP_DEEP_CHECK())|| \
126                                         (mode <=  PM_SLEEP_MODE_IDLE)))
127 
128 /**
129  * @defgroup PWC_Sleep_Type PWC sleep mode type.
130  * @{
131  */
132 #ifndef PWC_SLEEP_WFI
133 #define PWC_SLEEP_WFI                   (0x00U)                 /*!< Enter sleep mode by WFI, and wake-up by interrupt handle. */
134 #endif
135 #ifndef PWC_SLEEP_WFE_INT
136 #define PWC_SLEEP_WFE_INT               (0x01U)                 /*!< Enter sleep mode by WFE, and wake-up by interrupt request(SEVONPEND=1). */
137 #endif
138 #ifndef PWC_SLEEP_WFE_EVT
139 #define PWC_SLEEP_WFE_EVT               (0x02U)                 /*!< Enter sleep mode by WFE, and wake-up by event(SEVONPEND=0). */
140 #endif
141 /**
142  * @}
143  */
144 
145 /*******************************************************************************
146  * Global function prototypes (definition in C source)
147  ******************************************************************************/
148 
149 
150 #ifdef __cplusplus
151 }
152 #endif
153 
154 #endif /* __DRV_PM_H__ */
155 
156 /*******************************************************************************
157  * EOF (not truncated)
158  ******************************************************************************/
159