driver_lowpwr.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825
  1. /*
  2. * @File name : driver_lowpwr.c
  3. * @Author : Bluetrum IOT Team
  4. * @Date : 2023-02-15
  5. * @Version : v2.0
  6. *
  7. * Copyright (c) by Bluetrum, All Rights Reserved.
  8. */
  9. #include "driver_gpio.h"
  10. #include "driver_saradc.h"
  11. #include "driver_lowpwr.h"
  12. extern void io_sleep(void);
  13. extern void io_resume(void);
  14. extern u32 __comm_vma;
  15. static lowpwr_sfr_backup_t sfr_backup;
  16. static uint32_t wkupedg_bak = 0;
  17. AT(.com_sleep.lv2_get_wksrc)
  18. uint32_t lowpwr_sleep_get_io_wksrc(void)
  19. {
  20. return wkupedg_bak;
  21. }
  22. AT(.com_sleep.lv2_clr_wksrc)
  23. void lowpwr_sleep_clr_io_wksrc(void)
  24. {
  25. wkupedg_bak = 0;
  26. }
  27. u32 lowpwr_get_wakeup_source(void)
  28. {
  29. u32 reason = RTCCON9;
  30. if(reason){
  31. if(reason & WK_LP_KEYSCAN){
  32. printf("KEY_SCAN_WK\n");
  33. }
  34. if(reason & WK_LP_GPIO){
  35. printf("GPIO_WK\n");
  36. }
  37. if(reason & WK_LP_TOUCH){
  38. printf("TOUCH_WK\n");
  39. }
  40. if(reason & WK_LP_INBOX){
  41. printf("INBOX_WK\n");
  42. }
  43. if(reason & WK_LP_VUSB){
  44. printf("VUSB_WK\n");
  45. }
  46. if(reason & WK_LP_WK0){
  47. printf("WKO_WK\n");
  48. }
  49. if(reason & WK_LP_RTC_1S){
  50. printf("RTC1S_WK\n");
  51. }
  52. if(reason & WK_LP_ALARM){
  53. printf("ALMWKP_WK\n");
  54. }
  55. RTCCON9 = 0x1fff; //Clr wakeup pending
  56. RTCCON10 = 0xffff;
  57. }
  58. return reason;
  59. }
  60. void lowpwr_wakeup_disable(void)
  61. {
  62. RTCCON9 = 0x1fff; //Clr wakeup pending
  63. RTCCON10 = 0xffff;
  64. RTCCON3 &= 0xFF;
  65. WKUPCPND = 0xff << 16; //clear wakeup pending
  66. WKUPEDG = 0;
  67. WKUPCON = 0;
  68. PORTINTEDG = 0;
  69. PORTINTEN = 0;
  70. }
  71. void lowpwr_clr_wakeup_pending(void)
  72. {
  73. WKUPCPND = 0xff << 16; //clear wakeup pending
  74. RTCCON9 = 0x1fff; //Clr wakeup pending
  75. RTCCON10 = 0xffff;
  76. }
  77. AT(.com_periph.lowpwr.sleep)
  78. bool lowpwr_is_wakeup_pending(u32 ignore_src)
  79. {
  80. u32 wk_pending = 0x1fff;
  81. if(ignore_src){
  82. wk_pending &= ~ignore_src;
  83. }
  84. return (RTCCON9 & wk_pending);
  85. }
  86. void lowpwr_wk0_wakeup_config(lowpwr_wakeup_typedef *config)
  87. {
  88. if (config->lp_type == LP_TYPE_SLEEP) {
  89. wk0_edge_capture_config(config->edge);
  90. WKUPCON |= BIT(17); //wakeup sleep mode enable
  91. RTCCON3 |= BIT(17);
  92. } else if(config->lp_type == LP_TYPE_POWOFF) {
  93. if (config->edge == WK_EDGE_FALLING) {
  94. wko_io_config(1, 0, 1);
  95. RTCCON1 &= ~BIT(6); //wk pin low level wakeup
  96. } else {
  97. wko_io_config(0, 1, 1);
  98. RTCCON1 |= BIT(6); //wk pin high level wakeup
  99. }
  100. RTCCON3 |= BIT(10);
  101. }
  102. }
  103. void lowpwr_gpio_wakeup_config(lowpwr_wakeup_typedef *config)
  104. {
  105. if((config->gpiox == GPIOA_REG) || (config->gpiox == GPIOB_REG)){
  106. gpio_edge_cap_typedef gpio_cfg;
  107. gpio_cfg.edge = config->edge;
  108. gpio_cfg.gpio_pin = config->gpio_pin;
  109. gpio_cfg.gpiox = config->gpiox;
  110. gpio_cfg.gpio_pupd = config->gpio_pupd;
  111. gpio_edge_capture_config(&gpio_cfg);
  112. RTCCON3 |= BIT(17);
  113. WKUPCON |= BIT(17); //wakeup sleep mode enable
  114. WKUPCPND = 0xff << 16; //clear wakeup pending
  115. }
  116. }
  117. void lowpwr_wakeup_config_do(lowpwr_wakeup_typedef *config)
  118. {
  119. if(config){
  120. if(!(config->source & WK_LP_TOUCH)){
  121. RTCCON0 &= ~BIT(4); //disable touch key
  122. }
  123. if(config->source & WK_LP_WK0){
  124. lowpwr_wk0_wakeup_config(config);
  125. }
  126. if(config->source & WK_LP_TOUCH){
  127. RTCCON0 |= BIT(4);
  128. RTCCON1 |= BIT(8);
  129. RTCCON1 |= BIT(9); //VDDTK enable for touch key logic
  130. RTCCON3 |= BIT(14); // Touch key long press wakeup enable
  131. }
  132. if(config->source & WK_LP_BT){
  133. RTCCON3 |= BIT(13);
  134. }
  135. if(config->source & WK_LP_ALARM){
  136. RTCCON0 |= BIT(19);
  137. RTCCON3 |= BIT(8);
  138. }
  139. if(config->source & WK_LP_RTC_1S){
  140. RTCCON3 |= BIT(9);
  141. }
  142. if(config->source & WK_LP_VUSB){
  143. RTCCON3 |= BIT(11);
  144. }
  145. if(config->source & WK_LP_KEYSCAN){
  146. RTCCON3 |= BIT(16);
  147. }
  148. if(config->source & WK_LP_INBOX){
  149. RTCCON3 |= BIT(12);
  150. }
  151. if(config->source & WK_LP_GPIO){
  152. lowpwr_gpio_wakeup_config(config);
  153. }
  154. }
  155. }
  156. void lowpwr_wakeup_config(lowpwr_wakeup_typedef *config)
  157. {
  158. if(config){
  159. RTCCON3 &= 0xFF;
  160. lowpwr_wakeup_config_do(config);
  161. }
  162. }
  163. void lowpwr_wakeup_config_2(lowpwr_wakeup_typedef *config)
  164. {
  165. if(config){
  166. lowpwr_wakeup_config_do(config);
  167. }
  168. }
  169. void lowpwr_wakeup_source_enable(WK_LP_SRC_SEL wk_src)
  170. {
  171. if(wk_src & WK_LP_WK0){
  172. RTCCON3 |= BIT(17);
  173. }
  174. if(wk_src & WK_LP_TOUCH){
  175. RTCCON3 |= BIT(14);
  176. }
  177. if(wk_src & WK_LP_BT){
  178. RTCCON3 |= BIT(13);
  179. }
  180. if(wk_src & WK_LP_ALARM){
  181. RTCCON3 |= BIT(8);
  182. }
  183. if(wk_src & WK_LP_RTC_1S){
  184. RTCCON3 |= BIT(9);
  185. }
  186. if(wk_src & WK_LP_VUSB){
  187. RTCCON3 |= BIT(11);
  188. }
  189. if(wk_src & WK_LP_KEYSCAN){
  190. RTCCON3 |= BIT(16);
  191. }
  192. if(wk_src & WK_LP_INBOX){
  193. RTCCON3 |= BIT(12);
  194. }
  195. if(wk_src & WK_LP_GPIO){
  196. RTCCON3 |= BIT(17);
  197. }
  198. }
  199. void lowpwr_wakeup_source_disable(WK_LP_SRC_SEL wk_src)
  200. {
  201. if (wk_src == WK_LP_SRC_ALL) {
  202. RTCCON3 &= 0xFF;
  203. return;
  204. }
  205. if(wk_src & WK_LP_WK0){
  206. RTCCON3 &= ~BIT(17);
  207. }
  208. if(wk_src & WK_LP_TOUCH){
  209. RTCCON3 &= ~BIT(14); // Touch key long press wakeup enable
  210. }
  211. if(wk_src & WK_LP_BT){
  212. RTCCON3 &= ~BIT(13);
  213. }
  214. if(wk_src & WK_LP_ALARM){
  215. RTCCON3 &= ~BIT(8);
  216. }
  217. if(wk_src & WK_LP_RTC_1S){
  218. RTCCON3 &= ~BIT(9);
  219. }
  220. if(wk_src & WK_LP_VUSB){
  221. RTCCON3 &= ~BIT(11);
  222. }
  223. if(wk_src & WK_LP_KEYSCAN){
  224. RTCCON3 &= ~BIT(16);
  225. }
  226. if(wk_src & WK_LP_INBOX){
  227. RTCCON3 &= ~BIT(12);
  228. }
  229. if(wk_src & WK_LP_GPIO){
  230. RTCCON3 &= ~BIT(17);
  231. }
  232. }
  233. ALIGNED(512)
  234. void lowpwr_pwroff_mode1_do(void)
  235. {
  236. u32 rtccon3;
  237. saradc_deinit(); //disable saradc
  238. PICCONCLR = BIT(0); //disable global interrupt
  239. NMICON = 0;
  240. RTCCON3 &= ~BIT(17); //disable gpio wakeup
  241. RTCCON9 = 0x1fff; //Clr wakeup pending
  242. if(RTCCON3 & BIT(14)){ //Touch need rc2m clk
  243. RTCCON0 |= BIT(19); //RC2M_RTC enable
  244. asm("nop");asm("nop");asm("nop");
  245. RTCCON0 = (RTCCON0 & ~(0x03 << 12)) | (0x02 << 12); //CLK2M in Touch select SNF_RC_RTC
  246. }else{
  247. RTCCON0 &= ~BIT(19); //RC2M_RTC disable
  248. }
  249. RTCCON4 &= ~BIT(17); //FGS
  250. RTCCON4 &= ~BIT(18); //FGBUF
  251. RTCCON4 &= ~BIT(15); //VIO_PD not work
  252. RTCCON4 = (RTCCON4 & ~(0x3f<<24)) | (5<<24) | (6<<27); //no sfr access, bit26~bit24, VRTC11 is 1.025V; sfr access, bit29~27, VRTC11 is 1.09V
  253. CLKCON0 &= ~0xc; //sys_clk switch to RC
  254. asm("nop");
  255. asm("nop");
  256. asm("nop");
  257. XOSCCON = 0;
  258. PLL0CON = 0;
  259. rtccon3 = RTCCON3 & ~(0xFF);
  260. rtccon3 |= BIT(5) | BIT(6); //core power down enable
  261. WDT_DIS();
  262. RTCCON |= BIT(5); //RTC wake up power down mode reset system enable
  263. RTCCON3 = rtccon3;
  264. LPMCON |= BIT(0); //sleep mode
  265. LPMCON |= BIT(1); //idle mode
  266. asm("nop");asm("nop");asm("nop");
  267. while(1);
  268. }
  269. //in pwroff_mode2_final, can't use subfunction
  270. AT(.com_text.pwroff.mode2)
  271. static void pwroff_mode2_final(void)
  272. {
  273. u32 rtccon3 = RTCCON3;
  274. u32 rtccon0 = RTCCON0;
  275. RTCCON12 = (RTCCON12 & ~0xf) | 0xa | (0x3<<6) | (0x3<<4); //disable WKO reset, RTC WDT, GPIO reset
  276. RTCCON4 &= ~(BIT(17) | BIT(18)); //FGS, FGBUF
  277. if(RTCCON3 & (BIT(8) | BIT(14) | BIT(16))){ //wakeup source need rc2m clk
  278. RTCCON0 |= BIT(19); //RC2M_RTC enable
  279. }else{
  280. RTCCON0 &= ~BIT(19); //RC2M_RTC disable
  281. }
  282. PWRCON1 = (PWRCON1 & ~(0XF<<14)) | (0X0<<14); //DI_SW DISABLE
  283. RTCCON8 &= ~BIT(29);
  284. RTCCON4 |= BIT(11); //VDDIO_AON voltage
  285. RTCCON3 |= BIT(7); //enable vddio aon ldo
  286. RTCCON4 = (RTCCON4 & ~(0x3f<<24)) | (5<<24) | (6<<27); //no sfr access, bit26~bit24, VRTC11 is 1.025V; sfr access, bit29~27, VRTC11 is 1.09V
  287. rtccon0 = RTCCON0;
  288. if(RTCCON3 & BIT(14)){
  289. rtccon0 = (rtccon0 & ~(0x03 << 12)) | (0x02 << 12); //CLK2M in Touch select SNF_RC_RTC
  290. }
  291. if(RTCCON3 & BIT(16)){
  292. rtccon0 = (rtccon0 & ~(0x03 << 14)) | (0x02 << 14); //CLK2M in Keyscan select SNF_RC_RTC
  293. }
  294. RTCCON0 = rtccon0;
  295. RTCCON5 &= ~(1<<12); //CLEAR LP FLAG
  296. WKUPCPND = 0xFF<<16;
  297. CLKCON0 &= ~0xc; //sys_clk switch to RC
  298. asm("nop");
  299. asm("nop");
  300. asm("nop");
  301. XOSCCON = 0;
  302. PLL0CON = 0;
  303. // when switch power, reduce lp_top power, disable ram0/1 clock
  304. CLKGAT0 &= ~((3<<2) | BIT(15)); // sram0/1 & LP disable clock
  305. RTCCON5 &= ~(1<<11); // dis sram if
  306. RTCCON5 |= (BIT(15) | BIT(16)); //RAM0 RAM1 shutdown
  307. //RTCCON5 |= BIT(13); //RAM0/1 light sleep
  308. //RTCCON5 |= BIT(14); //RAM0/1 deep sleep
  309. // pmu power down
  310. LVDCON &= ~(BIT(3) | BIT(5)); //disable LVD reset
  311. rtccon3 = RTCCON3 & ~BIT(5); //disable C2RL
  312. rtccon3 |= (BIT(4) | BIT(3)); //PD CORE2, disable all analog model except IO
  313. rtccon3 &= ~0x7; //disable VDDCORE & VDDIO & VDDBT LDO
  314. //disable WDT
  315. WDT_DIS();
  316. RTCCON |= BIT(5); //RTC wake up power down mode reset system enable
  317. RTCCON3 = rtccon3;
  318. LPMCON |= BIT(0); //sleep mode
  319. LPMCON |= BIT(1); //idle mode
  320. while(1);
  321. }
  322. AT(.com_text.lp_port_init)
  323. void lp_port_init(void)
  324. {
  325. //config IO low power state
  326. //when RTCCON5 bit12=0, will select LPGPIO; otherwise, select GPIO
  327. //save IO
  328. if(pmu_vddio_to_flash()){
  329. GPIOGDE = BIT(2);
  330. GPIOGPU = BIT(2);
  331. }else{
  332. GPIOGDE = 0;
  333. GPIOGPU = 0;
  334. }
  335. CLKGAT0 |= BIT(15); //lp_clk enable
  336. io_sleep();
  337. }
  338. AT(.com_text.pwroff_mode2)
  339. void lowpwr_pwroff_mode2_do(void)
  340. {
  341. u8 *src, *dst;
  342. u32 i;
  343. void (*p_func)(void);
  344. p_func = (void (*)(void))CACHE_ADDR;
  345. saradc_deinit();
  346. PICCONCLR = BIT(0); //disable global interrupt
  347. NMICON = 0;
  348. RTCCON9 = 0x1fff; //Clr wakeup pending
  349. RTCCON10 = 0xffff;
  350. PWRCON1 &= ~(0xf<<14); //disable flash power gate
  351. PWRCON1 |= BIT(18);
  352. //copy pwroff_mode2_final to cache ram
  353. dst = (u8*) CACHE_ADDR;
  354. src = (u8*) (&pwroff_mode2_final);
  355. for(i = 0; i < 0x300; i++){
  356. *dst++ = *src++;
  357. }
  358. lp_port_init();
  359. //jmp to run lp_sniff_final()
  360. p_func();
  361. }
  362. AT(.com_sleep.sleep.lv1)
  363. WEAK void lowpwr_sleep_lv1_proc(void)
  364. {
  365. u32 pwrcon2 = PWRCON2;
  366. u32 pwrcon0 = PWRCON0;
  367. u32 lpmcon = LPMCON;
  368. PWRCON2 = (PWRCON2 & ~(0xf<<0)) | (0x0<<0); // vddbt set 0.85v
  369. PLL0CON |= BIT(1);
  370. PLL0CON = (PLL0CON & ~(0x1)); // disable vdd12 from AVDD
  371. XOSCCON &= ~(BIT(5) | 0xb<<24); // disable XOSC48M clkout
  372. // vddio AON
  373. RTCCON3 |= BIT(7);
  374. PWRCON0 = (PWRCON0 & ~(0XF<<5)) | 4<<5;
  375. delay_us(5);
  376. RTCCON3 &= ~BIT(1);
  377. //LPMCON = (LPMCON & ~(0X1F << 16)) | (0x0<<16); // sniff vddcore set 0.7v
  378. WDT_DIS();
  379. LPMCON |= BIT(2); // system sleep
  380. asm("nop");asm("nop");
  381. asm("nop");asm("nop");
  382. PWRCON1 |= BIT(7); // enable vddbt climit
  383. PWRCON2 = pwrcon2;
  384. delay_us(10); // disable vddbt climit
  385. PWRCON1 &= ~BIT(7);
  386. LPMCON = lpmcon; // resume vddcore
  387. // vddio AON exit
  388. RTCCON3 |= BIT(1);
  389. PWRCON0 = pwrcon0;
  390. delay_us(1);
  391. RTCCON3 &= ~BIT(7);
  392. XOSCCON |= BIT(5) | 0xb<<24; // resume XOSC clkout
  393. WDT_EN();
  394. }
  395. AT(.com_sleep.lv2)
  396. WEAK void lowpwr_sleep_sfr_user_save(void)
  397. {
  398. }
  399. AT(.com_sleep.lv2)
  400. WEAK void lowpwr_sleep_sfr_user_resume(void)
  401. {
  402. }
  403. AT(.com_sleep.lv2_do)
  404. void lp_sleep_lv2_do(void)
  405. {
  406. u32 rtccon3 = RTCCON3;
  407. // 1. disable clock
  408. CLKGAT0 &= ~(BIT(15) | BIT(3) | BIT(2)); //lp clk, sram0/1 disable clock
  409. //RTCCON4 &= ~(0x3<<22); //VRTC24 to 1.7V
  410. // 2. disable interface
  411. // disable if, then deep sleep memory, can not do in 1 cycle
  412. RTCCON5 &= ~(1<<11); // dis sram if
  413. //RTCCON5 = (RTCCON5 & ~(0x7<<13)) | (1<<13);
  414. RTCCON5 |= (2<<13); // 1xx : shutdown
  415. // 01x : deep sleep
  416. // 001 : light sleep
  417. // 000 : normal
  418. RTCCON5 |= (1<<17); // set lp_flag
  419. RTCCON5 |= BIT(0);
  420. // pmu power down ...
  421. rtccon3 &= ~(1<<5); // VDDCORE and VLCORE
  422. rtccon3 |= ((1<<3) | (1<<4)); // VLCORE LDO enable, RI_PD_CORE2 from rtc
  423. rtccon3 &= ~(0x7<<0); // VDDBT/VDDIO/VDDCORE LDO disable
  424. RTCCON |= BIT(5); //RTC wake up power down mode reset system enable
  425. RTCCON3 = rtccon3;
  426. // RTCCON3 |= (1<<6); // PD CORE
  427. LPMCON |= BIT(0);
  428. LPMCON |= BIT(1); //idle mode
  429. asm("nop");
  430. asm("nop");
  431. asm("nop");
  432. while(1);
  433. }
  434. AT(.com_sleep.lv2_proc)
  435. void lp_sleep_lv2_proc(void)
  436. {
  437. u32 rtccon0 = RTCCON0;
  438. u32 *dst = (u32 *)0x70000;
  439. u32 *src = (u32 *)&lp_sleep_lv2_do;
  440. for(uint i=0; i<512/4; i++) {
  441. *dst++ = *src++;
  442. }
  443. // 1, save IO
  444. CLKGAT0 |= (1<<15); // LP_CLK Enable
  445. io_sleep();
  446. WKUPCPND = 0xFF<<16;
  447. wkupedg_bak = 0;
  448. sfr_backup.gpioa_fen = GPIOAFEN;
  449. sfr_backup.gpiob_fen = GPIOBFEN;
  450. sfr_backup.gpioa_fdiren = GPIOAFDIREN;
  451. sfr_backup.gpiob_fdiren = GPIOBFDIREN;
  452. sfr_backup.gpioa_drv = GPIOADRV;
  453. sfr_backup.gpiob_drv = GPIOBDRV;
  454. RTCCON9 = 0x1fff; //Clr wakeup pending
  455. RTCCON10 = 0xffff;
  456. WDT_DIS();
  457. RTCCON12 = (RTCCON12 & ~0xf) | 0xa | (0x3<<6) | (0x3<<4); //disable WKO reset, RTC WDT, GPIO reset
  458. // 2, analog disable
  459. RTCCON4 &= ~(BIT(17) | BIT(18)); //FGS,FGBUF
  460. RTCCON8 &= ~BIT(29);
  461. RTCCON3 |= BIT(7); //enable vddio aon ldo
  462. RTCCON4 = (RTCCON4 & ~(0x3f<<24)) | (6<<24) | (6<<27); //no sfr access, bit26~bit24, VRTC11 is 0.83V; sfr access, bit29~27, VRTC11 is 1.1V
  463. // PG OFF
  464. PWRCON1 |= BIT(9) | BIT(18); // SD/FS PG PD
  465. PWRCON1 = PWRCON1 & ~((0x3f << 10)) ; // PG off
  466. // ... other analog pd
  467. if(RTCCON3 & BIT(14)){
  468. rtccon0 = (rtccon0 & ~(0x03 << 12)) | (0x02 << 12); //CLK2M in Touch select SNF_RC_RTC
  469. }
  470. if(RTCCON3 & BIT(16)){
  471. rtccon0 = (rtccon0 & ~(0x03 << 14)) | (0x02 << 14); //CLK2M in Keyscan select SNF_RC_RTC
  472. }
  473. rtccon0 = (rtccon0 & ~(0x7<<22)) | (1<<22); //sys reset delay
  474. RTCCON0 = rtccon0;
  475. // 3, select sniff rc clock and disable pll,xosc
  476. CLKCON0 = (CLKCON0 & ~(3<<2)) | (0<<2); // sel rc2m
  477. asm("nop");
  478. asm("nop");
  479. asm("nop");
  480. // 4, PLL, XOSC, CLK2M_BT off
  481. PLL0CON = 0;
  482. PLL0CON1 = 0;
  483. XOSCCON = 0;
  484. //RTCCON3 |= BIT(3) | BIT(5); //enable RL2VLC & C2VLC
  485. //PWRCON0 = (PWRCON0 & ~0x1f) | 0x8; //VDDCORE is 0.9V
  486. asm("j 0x70000");
  487. };
  488. AT(.com_sleep.lv2_wakeup)
  489. void lp_wakeup_lv2_proc(void)
  490. {
  491. bool gpio_pending = true;
  492. RTCCON4 &= ~BIT(6); //VDDBT to VCORE dis
  493. RTCCON4 |= BIT(5) ; //VCORE from VDDIO
  494. PICADR = (u32)&__comm_vma;
  495. if(!(sfr_backup.rtccon5 & BIT(0))){
  496. PWRCON1 = (PWRCON1 & ~(0X3<<2)) | (0X1<<2); // DI_CLIMIT_S 109:85:366mA
  497. RTCCON5 &= ~BIT(0);
  498. }
  499. PWRCON0 |= BIT(20); //pmu normal
  500. wkupedg_bak = WKUPEDG;
  501. //pending is generated due to burrs after the gpio is wakeup from sleep. In this case, manually clear pending
  502. if(!(RTCCON9 & WK_LP_GPIO) && !(WKUPEDG & 0xff0000)){
  503. gpio_pending = false;
  504. }
  505. //resume IO
  506. io_resume();
  507. if (gpio_pending == false) {
  508. WKUPCPND = 0xFF<<16;
  509. }
  510. GPIOAFEN = sfr_backup.gpioa_fen;
  511. GPIOBFEN = sfr_backup.gpiob_fen;
  512. GPIOAFDIREN = sfr_backup.gpioa_fdiren;
  513. GPIOBFDIREN = sfr_backup.gpiob_fdiren;
  514. GPIOADRV = sfr_backup.gpioa_drv;
  515. GPIOBDRV = sfr_backup.gpiob_drv;
  516. // 2, analog init
  517. RTCCON3 |= BIT(0); //VDDDBT
  518. PWRCON0 = (PWRCON0 & ~0x1f) | pmu_get_vddcore(); //VDDCORE is 1.15V
  519. asm("nop");
  520. PLL0CON |= BIT(12); //DI_EN_LDO
  521. delay(10);
  522. RSTCON0 = sfr_backup.rstcon0; //pllsdm reset release
  523. delay(25); //delay 100us, by rc
  524. // 3, PLL,XOSC,CLK2M_BT, on
  525. XOSCCON = sfr_backup.xosccon;
  526. PLL0CON = sfr_backup.pll0con;
  527. PLL0CON1 = sfr_backup.pll0con1;
  528. delay(700); //delay 1ms - 2ms for xosc to work
  529. CLKDIVCON0 = sfr_backup.clkdivcon0;
  530. // 4, resume CLK
  531. CLKCON1 = sfr_backup.clkcon1; //xosc_mux_clk select xosc24m
  532. asm("nop");
  533. asm("nop");
  534. asm("nop");
  535. CLKCON0 = sfr_backup.clkcon0; //sysclk select xosc_mux_clk
  536. asm("nop");
  537. asm("nop");
  538. LVDCON &= ~BIT(30); //Enable reset pending
  539. }
  540. AT(.com_sleep.lv2_proc)
  541. WEAK void lowpwr_sleep_lv2_proc(void)
  542. {
  543. sfr_backup.piccon = PICCON;
  544. sfr_backup.picen = PICEN;
  545. sfr_backup.picpr = PICPR;
  546. sfr_backup.nmicon = NMICON;
  547. sfr_backup.clkgat0 = CLKGAT0;
  548. sfr_backup.clkgat1 = CLKGAT1;
  549. sfr_backup.clkgat2 = CLKGAT2;
  550. sfr_backup.pwrcon0 = PWRCON0 & ~BIT(20);
  551. sfr_backup.pwrcon1 = PWRCON1;
  552. sfr_backup.pwrcon2 = PWRCON2;
  553. sfr_backup.clkcon0 = CLKCON0;
  554. sfr_backup.clkcon1 = CLKCON1;
  555. sfr_backup.clkdivcon0 = CLKDIVCON0;
  556. sfr_backup.xosccon = XOSCCON;
  557. sfr_backup.pll0con = PLL0CON;
  558. sfr_backup.pll0con1 = PLL0CON1;
  559. sfr_backup.rstcon0 = RSTCON0;
  560. sfr_backup.rtccon = RTCCON;
  561. sfr_backup.rtccon5 = RTCCON5;
  562. lowpwr_sleep_sfr_save();
  563. lowpwr_sleep_sfr_user_save();
  564. u32 gpiogde = GPIOGDE;
  565. u32 gpiogpu = GPIOGPU;
  566. if(pmu_vddio_to_flash()){
  567. GPIOGDE = BIT(2); //SPICS
  568. GPIOGPU = BIT(2);
  569. }else{
  570. GPIOGDE = 0;
  571. GPIOGPU = 0;
  572. PWRCON1 &= ~(0XF<<14); //DI_SW DISABLE
  573. }
  574. sfr_backup.rtccon0 = RTCCON0;
  575. sfr_backup.rtccon12 = RTCCON12;
  576. if(RTCCON3 & (BIT(8) | BIT(9) | BIT(13) | BIT(14) | BIT(16))){ //wakeup source need rc2m clk
  577. RTCCON0 |= BIT(19); //RC2M_RTC enable
  578. }else{
  579. RTCCON0 &= ~BIT(19); //RC2M_RTC disable
  580. }
  581. lp_sleep(lp_sleep_lv2_proc, lp_wakeup_lv2_proc);
  582. RTCCON4 |= BIT(5) | BIT(6); //VCORE from VDDBT & VDDIO
  583. RTCCON12 = sfr_backup.rtccon12;
  584. RTCCON0 = sfr_backup.rtccon0;
  585. asm("nop");
  586. asm("nop");
  587. PWRCON1 = sfr_backup.pwrcon1 | BIT(7);
  588. PWRCON2 = sfr_backup.pwrcon2;
  589. PWRCON0 = sfr_backup.pwrcon0 | BIT(20);
  590. CLKGAT0 = sfr_backup.clkgat0;
  591. CLKGAT1 = sfr_backup.clkgat1;
  592. CLKGAT2 = sfr_backup.clkgat2;
  593. lowpwr_sleep_sfr_resume();
  594. lowpwr_sleep_sfr_user_resume();
  595. GPIOGDE = gpiogde;
  596. GPIOGPU = gpiogpu;
  597. RTCCON = sfr_backup.rtccon;
  598. PICCON = sfr_backup.piccon;
  599. PICPR = sfr_backup.picpr;
  600. PICEN = sfr_backup.picen;
  601. NMICON = sfr_backup.nmicon;
  602. if(sfr_backup.rtccon5 & BIT(0)){
  603. RTCCON4 &= ~BIT(6); //LDO Mode,VCORE disable VDDBT, from VDDIO
  604. }else{
  605. RTCCON4 &= ~BIT(5); //Buck Mode,VCORE disable VDDIO, from VDDBT
  606. }
  607. PWRCON1 &= ~BIT(7);
  608. }
  609. AT(.com_sleep.sleep)
  610. void lowpwr_sleep_proc(u8 lpclk_type)
  611. {
  612. if (lpclk_type == CLK_RCDIV) {
  613. lowpwr_sleep_lv2_proc();
  614. } else {
  615. lowpwr_sleep_lv1_proc();
  616. }
  617. }