1 /******************************************************************************
2 * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
3 * All rights reserved.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************/
18
19 #ifndef DRIVERS_B91_DRIVER_EXT_EXT_PM_H_
20 #define DRIVERS_B91_DRIVER_EXT_EXT_PM_H_
21
22 #include "../pm.h"
23 #include "types.h"
24
25 #ifndef PM_32k_RC_CALIBRATION_ALGORITHM_EN
26 #define PM_32k_RC_CALIBRATION_ALGORITHM_EN 1
27 #endif
28
29 /**
30 * @brief available wake-up source for customer
31 */
32 typedef enum {
33 // not available wake-up source for customer
34 PM_TIM_RECOVER_START = BIT(14),
35 PM_TIM_RECOVER_END = BIT(15),
36 } pm_tim_recover_wakeup_src_e;
37
38 typedef pm_sleep_mode_e SleepMode_TypeDef;
39 typedef pm_sleep_wakeup_src_e SleepWakeupSrc_TypeDef;
40
41 typedef int (*suspend_handler_t)(void);
42 typedef void (*check_32k_clk_handler_t)(void);
43 typedef unsigned int (*pm_get_32k_clk_handler_t)(void);
44 typedef int (*cpu_pm_handler_t)(SleepMode_TypeDef sleep_mode, SleepWakeupSrc_TypeDef wakeup_src,
45 unsigned int wakeup_tick);
46 typedef unsigned int (*pm_tim_recover_handler_t)(unsigned int);
47
48 extern cpu_pm_handler_t cpu_sleep_wakeup;
49 extern suspend_handler_t func_before_suspend;
50 extern check_32k_clk_handler_t pm_check_32k_clk_stable;
51 extern pm_get_32k_clk_handler_t pm_get_32k_tick;
52 extern pm_tim_recover_handler_t pm_tim_recover;
53
54 /**
55 * @brief gpio wakeup level definition
56 */
57 typedef enum {
58 Level_Low = 0,
59 Level_High = 1,
60 } pm_gpio_wakeup_Level_e;
61
62 /**
63 * @brief deepsleep wakeup by external xtal
64 */
65 typedef struct {
66 unsigned char ext_cap_en; // 24xtal cap
67 unsigned char pad32k_en;
68 unsigned char pm_enter_en;
69 unsigned char rsvd;
70 } misc_para_t;
71
72 extern _attribute_aligned_(4) misc_para_t blt_miscParam;
73
74 #define SYS_NEED_REINIT_EXT32K BIT(1)
75 #define WAKEUP_STATUS_TIMER_CORE (WAKEUP_STATUS_TIMER | WAKEUP_STATUS_CORE)
76 #define WAKEUP_STATUS_TIMER_PAD (WAKEUP_STATUS_TIMER | WAKEUP_STATUS_PAD)
77
78 void bls_pm_registerFuncBeforeSuspend(suspend_handler_t func);
79
80 /**
81 * @brief analog register below can store infomation when MCU in deepsleep mode
82 * store your information in these ana_regs before deepsleep by calling analog_write function
83 * when MCU wakeup from deepsleep, read the information by by calling analog_read function
84 * Reset these analog registers only by power cycle
85 */
86 #define DEEP_ANA_REG0 0x39 // initial value =0x00
87 #define DEEP_ANA_REG1 0x3a // initial value =0x00
88 #define DEEP_ANA_REG2 0x3b // initial value =0x00
89 #define DEEP_ANA_REG3 0x3c // initial value =0x00
90 #define DEEP_ANA_REG4 0x3d // initial value =0x00
91 #define DEEP_ANA_REG5 0x3e // initial value =0x00
92 #define DEEP_ANA_REG6 0x3f // initial value =0x0f
93
94 /**
95 * @brief these analog register can store data in deepsleep mode or deepsleep with SRAM retention mode.
96 * Reset these analog registers by watchdog, chip reset, RESET Pin, power cycle
97 */
98
99 #define DEEP_ANA_REG7 0x38 // initial value =0xff
100
101 // ana3e system used, user can not use
102 #define SYS_DEEP_ANA_REG PM_ANA_REG_POWER_ON_CLR_BUF0
103
104 /**
105 * @brief This function serves to set the working mode of MCU based on 32k crystal,e.g. suspend mode,
106 * deepsleep mode, deepsleep with SRAM retention mode and shutdown mode.
107 * @param[in] sleep_mode - sleep mode type select.
108 * @param[in] wakeup_src - wake up source select.
109 * @param[in] wakeup_tick - the time of short sleep, which means MCU can sleep for less than 5 minutes.
110 * @return indicate whether the cpu is wake up successful.
111 */
112 int cpu_sleep_wakeup_32k_rc(SleepMode_TypeDef sleep_mode, SleepWakeupSrc_TypeDef wakeup_src, unsigned int wakeup_tick);
113
114 /**
115 * @brief This function serves to set the working mode of MCU based on 32k crystal,e.g.
116 * suspend mode, deepsleep mode, deepsleep with SRAM retention mode and shutdown mode.
117 * @param[in] sleep_mode - sleep mode type select.
118 * @param[in] wakeup_src - wake up source select.
119 * @param[in] wakeup_tick - the time of short sleep, which means MCU can sleep for less than 5 minutes.
120 * @return indicate whether the cpu is wake up successful.
121 */
122 int cpu_sleep_wakeup_32k_xtal(SleepMode_TypeDef sleep_mode, SleepWakeupSrc_TypeDef wakeup_src,
123 unsigned int wakeup_tick);
124
125 void pm_sleep_start(void);
126
127 /**
128 * @brief This function serves to reboot chip.
129 * @param none.
130 * @return none.
131 */
132
133 void start_reboot(void);
134
135 /**
136 * @brief This function serves to recover system timer from tick of internal 32k RC.
137 * @param none.
138 * @return none.
139 */
140 unsigned int pm_tim_recover_32k_rc(unsigned int now_tick_32k);
141
142 /**
143 * @brief This function serves to recover system timer from tick of external 32k crystal.
144 * @param none.
145 * @return none.
146 */
147 unsigned int pm_tim_recover_32k_xtal(unsigned int now_tick_32k);
148
149 /**
150 * @brief This function serves to get the 32k tick.
151 * @param none
152 * @return tick of 32k .
153 */
154 extern unsigned int get_32k_tick(void);
155
156 unsigned int clock_get_digital_32k_tick(void);
157
158 /**
159 * @brief This function serves to determine whether wake up source is internal 32k RC.
160 * @param[in] none.
161 * @return none.
162 */
blc_pm_select_internal_32k_crystal(void)163 static inline void blc_pm_select_internal_32k_crystal(void)
164 {
165 cpu_sleep_wakeup = cpu_sleep_wakeup_32k_rc;
166 pm_tim_recover = pm_tim_recover_32k_rc;
167
168 blt_miscParam.pm_enter_en = 1; // allow enter pm, 32k rc does not need to wait for 32k clk to be stable
169 }
170
171 extern void check_32k_clk_stable(void);
172
173 /**
174 * @brief This function serves to determine whether wake up source is external 32k RC.
175 * @param[in] none.
176 * @return none.
177 */
blc_pm_select_external_32k_crystal(void)178 static inline void blc_pm_select_external_32k_crystal(void)
179 {
180 cpu_sleep_wakeup = cpu_sleep_wakeup_32k_xtal;
181 pm_check_32k_clk_stable = check_32k_clk_stable;
182 pm_tim_recover = pm_tim_recover_32k_xtal;
183 pm_get_32k_tick = get_32k_tick;
184 blt_miscParam.pad32k_en = 1; // set '1': 32k clk src use external 32k crystal
185 }
186
187 /**
188 * @brief This function servers to wake up the cpu from sleep mode.
189 * @param[in] sleep_mode - sleep mode type select.
190 * @param[in] wakeup_src - wake up source select.
191 * @param[in] wakeup_tick - the time of sleep,unit is 31.25us,1ms = 32.
192 * @return indicate whether the cpu is wake up successful.
193 */
194 int cpu_long_sleep_wakeup_32k_rc(SleepMode_TypeDef sleep_mode, SleepWakeupSrc_TypeDef wakeup_src,
195 unsigned int wakeup_tick);
196
197 /**
198 * @brief This function serves to determine whether mcu is waked up from deep retention.
199 * @param[in] none.
200 * @return 1- yes , 0- no.
201 */
pm_is_MCU_deepRetentionWakeup(void)202 static inline int pm_is_MCU_deepRetentionWakeup(void)
203 {
204 return (g_pm_status_info.mcu_status & MCU_STATUS_DEEPRET_BACK);
205 }
206
207 /**
208 * @brief This function serves to determine whether mcu is waked up by pad.
209 * @param[in] none.
210 * @return 1- yes , 0- no.
211 */
pm_is_deepPadWakeup(void)212 static inline int pm_is_deepPadWakeup(void)
213 {
214 return g_pm_status_info.is_pad_wakeup;
215 }
216
217 /**
218 * @brief This function serves to get the status of mcu.
219 * @param[in] none.
220 * @return mcu_status.
221 */
pm_get_mcu_status(void)222 static inline int pm_get_mcu_status(void)
223 {
224 return g_pm_status_info.mcu_status;
225 }
226
227 #define cpu_set_gpio_wakeup pm_set_gpio_wakeup
228
pm_get_latest_offset_cal_time(void)229 static inline unsigned int pm_get_latest_offset_cal_time(void)
230 {
231 return pmcd.offset_cal_tick;
232 }
233
234 /********************************** Internal APIs (not for user)***************************************************/
235 extern unsigned char tl_24mrc_cal;
236 extern unsigned int g_pm_tick_32k_calib;
237 extern unsigned int g_pm_tick_cur;
238 extern unsigned int g_pm_tick_32k_cur;
239 extern unsigned char g_pm_long_suspend;
240 extern unsigned int g_pm_multi_addr;
241
242 extern unsigned int g_sleep_32k_rc_cnt;
243 extern unsigned int g_sleep_stimer_tick;
244
245 extern unsigned int ota_program_bootAddr;
246 extern unsigned int ota_program_offset;
247
248 #define PM_MIN_SLEEP_US 1500 // eagle
249
250 #endif /* DRIVERS_B91_DRIVER_EXT_EXT_PM_H_ */
251