func_lowpwr.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. #include "include.h"
  2. #include "driver_lowpwr.h"
  3. #include "driver_gpio.h"
  4. #include "ble_user_service.h"
  5. #include "bsp_io_key.h"
  6. #if SLEEP_SFR_SAVE
  7. /*
  8. Users save the registers that need to be backed up.
  9. Registers that are not backed up will lose their values after they enter deep sleep
  10. */
  11. #define LOWPWR_SFR_USER_SAVE
  12. #ifdef LOWPWR_SFR_USER_SAVE
  13. typedef struct {
  14. u32 funcomcon[6];
  15. u32 uart0baud;
  16. u16 uart0con;
  17. } lowpwr_sfr_user_backup_t;
  18. lowpwr_sfr_user_backup_t sfr_user_backup;
  19. AT(.com_sleep.lv2)
  20. void lowpwr_sleep_sfr_user_save(void)
  21. {
  22. sfr_user_backup.funcomcon[0] = FUNCOMCON0;
  23. sfr_user_backup.funcomcon[1] = FUNCOMCON1;
  24. sfr_user_backup.funcomcon[2] = FUNCOMCON4;
  25. sfr_user_backup.funcomcon[3] = FUNCOMCON5;
  26. sfr_user_backup.funcomcon[4] = FUNCOMCON6;
  27. sfr_user_backup.funcomcon[5] = FUNCIMCON0;
  28. sfr_user_backup.uart0baud = UART0BAUD;
  29. sfr_user_backup.uart0con = UART0CON;
  30. }
  31. AT(.com_sleep.lv2)
  32. void lowpwr_sleep_sfr_user_resume(void)
  33. {
  34. FUNCOMCON0 = sfr_user_backup.funcomcon[0];
  35. FUNCOMCON1 = sfr_user_backup.funcomcon[1];
  36. FUNCOMCON4 = sfr_user_backup.funcomcon[2];
  37. FUNCOMCON5 = sfr_user_backup.funcomcon[3];
  38. FUNCOMCON6 = sfr_user_backup.funcomcon[4];
  39. FUNCIMCON0 = sfr_user_backup.funcomcon[5];
  40. UART0BAUD = sfr_user_backup.uart0baud;
  41. UART0CON = sfr_user_backup.uart0con;
  42. UART0CPND = BIT(17) | BIT(16); //CLR Pending
  43. }
  44. #endif
  45. #endif
  46. AT(.com_text.sleep_tick)
  47. void lowpwr_tout_ticks(void)
  48. {
  49. #if SYS_SLEEP_LEVEL
  50. if(sys_cb.sleep_delay != -1L && sys_cb.sleep_delay > 0) {
  51. sys_cb.sleep_delay--;
  52. }
  53. #endif
  54. #if SYS_OFF_TIME
  55. if(sys_cb.pwroff_delay != -1L && sys_cb.pwroff_delay > 0) {
  56. sys_cb.pwroff_delay--;
  57. }
  58. #endif
  59. }
  60. #if SYS_SLEEP_LEVEL
  61. AT(.com_sleep.sleep)
  62. void sys_sleep_cb(u8 lpclk_type)
  63. {
  64. //注意!!!!!!!!!!!!!!!!!
  65. //此函数只能调用com_sleep或com_text函数
  66. //此处关掉影响功耗的模块
  67. lowpwr_sleep_proc(lpclk_type); //enter sleep
  68. //唤醒后,恢复模块功能
  69. }
  70. void sleep_pwrdown_timer_cb(uint32_t handle)
  71. {
  72. #if 1/* TRACE_EN */
  73. GPIO_PORT_GET(BSP_UART_DEBUG_EN)->de |= GPIO_PIN_GET(BSP_UART_DEBUG_EN);
  74. printf("sleep pwrdown timeout\n");
  75. #endif
  76. func_pwroff();
  77. }
  78. void lowpwr_sleep_wakeup_config(void)
  79. {
  80. lowpwr_wakeup_typedef config;
  81. lowpwr_wakeup_disable();
  82. config.source = WK_LP_WK0 | WK_LP_BT;
  83. #if BSP_CHARGE_EN || FUNC_USBD_EN
  84. config.source |= WK_LP_VUSB;
  85. #endif
  86. #if BSP_IOKEY_EN
  87. config.source |= WK_LP_GPIO;
  88. config.gpiox = NULL;
  89. config.gpio_pin = 0;
  90. #endif
  91. config.edge = WK_EDGE_FALLING;
  92. config.lp_type = LP_TYPE_SLEEP;
  93. lowpwr_wakeup_config_2(&config);
  94. #if BSP_IOKEY_EN
  95. for (u8 i = 0; i < IO_KEY_COL_TABLE_SIZE; i++) {
  96. config.gpiox = key_io_table_column[i].gpiox;
  97. config.gpio_pin = key_io_table_column[i].gpio_pin;
  98. config.gpio_pupd = GPIO_PUPD_PU10K; // same with init in bsp_io_key.c
  99. lowpwr_gpio_wakeup_config(&config);
  100. }
  101. #if IO_KEY_SCAN_MODE
  102. config.edge = WK_EDGE_RISING;
  103. for (u8 i = 0; i < IO_KEY_ROW_TABLE_SIZE; i++) {
  104. config.gpiox = key_io_table_row[i].gpiox;
  105. config.gpio_pin = key_io_table_row[i].gpio_pin;
  106. config.gpio_pupd = GPIO_PUPD_PD10K;
  107. lowpwr_gpio_wakeup_config(&config);
  108. }
  109. #endif // IO_KEY_SCAN_MODE
  110. #endif // BSP_IOKEY_EN
  111. }
  112. AT(.text.lowpwr.sleep)
  113. static void sfunc_sleep(void)
  114. {
  115. uint32_t sysclk;
  116. u8 pg_de;
  117. u16 pa_de, pb_de;
  118. printf("%s\n", __func__);
  119. ble_enter_sleep_proc();
  120. delay_5ms(1);
  121. bt_enter_sleep();
  122. sys_set_tmr_enable(0, 0);
  123. sysclk = sys_clk_get();
  124. sys_clk_set(SYS_24M);
  125. #if SYS_OFF_TIME
  126. bt_timer_mem_t sleep_pwrdown_timer;
  127. bt_timer_handle_t sleep_pwrdown_timer_handle;
  128. bt_alarm_timer_mem_extend(&sleep_pwrdown_timer, sizeof(sleep_pwrdown_timer));
  129. bt_alarm_timer_acquire(&sleep_pwrdown_timer_handle, 100 * sys_cb.pwroff_delay, 0, sleep_pwrdown_timer_cb);
  130. bt_alarm_timer_start(sleep_pwrdown_timer_handle);
  131. printf("wk and pwr after: %ds\n", 100 * sys_cb.pwroff_delay / 1000);
  132. #endif
  133. //io analog input
  134. pa_de = GPIOADE;
  135. pb_de = GPIOBDE;
  136. pg_de = GPIOGDE;
  137. GPIOADE = 0;
  138. GPIOBDE = 0;
  139. GPIOGDE = 0x3F; //MCP FLASH
  140. lowpwr_wakeup_disable();
  141. lowpwr_sleep_wakeup_config();
  142. sys_cb.sleep_sta = 1;
  143. while (bt_is_sleep()) {
  144. WDT_CLR();
  145. bt_sleep_proc();
  146. #if SYS_OFF_TIME
  147. {
  148. if (func_cb.sta == FUNC_PWROFF) {
  149. break;
  150. }
  151. if (0/* Condition: reset pwr timer */) {
  152. bt_alarm_timer_modify_interval(sleep_pwrdown_timer_handle, 6666, 0);
  153. }
  154. }
  155. #endif
  156. if (lowpwr_is_wakeup_pending(WK_LP_BT)) {
  157. break;
  158. }
  159. #if BSP_IOKEY_EN
  160. if(gpio_is_edge_pending()){
  161. break;
  162. }
  163. #endif
  164. if(ble_proc_pending()){
  165. break;
  166. }
  167. }
  168. sys_cb.sleep_sta = 0;
  169. #if SYS_OFF_TIME
  170. bt_alarm_timer_mem_free(&sleep_pwrdown_timer, sizeof(sleep_pwrdown_timer));
  171. #endif
  172. sys_clk_set(sysclk);
  173. //Reinitialize all peripherals, because all register configurations are lost after low power
  174. bsp_periph_init();
  175. printf("wakeup\n");
  176. GPIOADE = pa_de;
  177. GPIOBDE = pb_de;
  178. GPIOGDE = pg_de;
  179. lowpwr_wakeup_disable();
  180. sys_set_tmr_enable(1, 1);
  181. bt_exit_sleep();
  182. ble_exit_sleep_proc();
  183. printf("sleep_exit\n");
  184. }
  185. AT(.text.app.proc.sleep)
  186. bool sleep_process(is_sleep_func is_sleep)
  187. {
  188. if (is_sleep()) {
  189. if (sys_cb.sleep_delay == -1L) {
  190. return false;
  191. }
  192. if(sys_cb.sleep_delay == 0) {
  193. sfunc_sleep();
  194. lowpwr_sleep_delay_reset();
  195. lowpwr_pwroff_delay_reset();
  196. return true;
  197. }
  198. } else {
  199. lowpwr_sleep_delay_reset();
  200. }
  201. return false;
  202. }
  203. #endif
  204. void lowpwr_pwroff_wakeup_config(void)
  205. {
  206. lowpwr_wakeup_typedef config;
  207. lowpwr_wakeup_disable();
  208. config.source = WK_LP_WK0;
  209. #if BSP_CHARGE_EN || FUNC_USBD_EN
  210. config.source |= WK_LP_VUSB;
  211. #endif
  212. #if BSP_IOKEY_EN
  213. config.source |= WK_LP_GPIO;
  214. config.gpiox = NULL;
  215. config.gpio_pin = 0;
  216. #endif
  217. config.edge = WK_EDGE_FALLING;
  218. config.lp_type = LP_TYPE_POWOFF;
  219. lowpwr_wakeup_config_2(&config);
  220. #if BSP_IOKEY_EN
  221. for (u8 i = 0; i < IO_KEY_COL_TABLE_SIZE; i++) {
  222. config.gpiox = key_io_table_column[i].gpiox;
  223. config.gpio_pin = key_io_table_column[i].gpio_pin;
  224. config.gpio_pupd = GPIO_PUPD_PU10K; // same with init in bsp_io_key.c
  225. lowpwr_gpio_wakeup_config(&config);
  226. }
  227. #if IO_KEY_SCAN_MODE
  228. config.edge = WK_EDGE_RISING;
  229. for (u8 i = 0; i < IO_KEY_ROW_TABLE_SIZE; i++) {
  230. config.gpiox = key_io_table_row[i].gpiox;
  231. config.gpio_pin = key_io_table_row[i].gpio_pin;
  232. config.gpio_pupd = GPIO_PUPD_PD10K;
  233. lowpwr_gpio_wakeup_config(&config);
  234. }
  235. #endif // IO_KEY_SCAN_MODE
  236. #endif // BSP_IOKEY_EN
  237. }
  238. void sfunc_pwroff(void)
  239. {
  240. GPIOADE = 0;
  241. GPIOBDE = 0;
  242. lowpwr_pwroff_wakeup_config();
  243. pwroff_do();
  244. }
  245. AT(.text.lowpwr.pwroff)
  246. void func_pwroff(void)
  247. {
  248. printf("%s\n", __func__);
  249. if (SOFT_POWER_ON_OFF) {
  250. sfunc_pwroff();
  251. }
  252. }