• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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