| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825 |
- /*
- * @File name : driver_lowpwr.c
- * @Author : Bluetrum IOT Team
- * @Date : 2023-02-15
- * @Version : v2.0
- *
- * Copyright (c) by Bluetrum, All Rights Reserved.
- */
- #include "driver_gpio.h"
- #include "driver_saradc.h"
- #include "driver_lowpwr.h"
- extern void io_sleep(void);
- extern void io_resume(void);
- extern u32 __comm_vma;
- static lowpwr_sfr_backup_t sfr_backup;
- static uint32_t wkupedg_bak = 0;
- AT(.com_sleep.lv2_get_wksrc)
- uint32_t lowpwr_sleep_get_io_wksrc(void)
- {
- return wkupedg_bak;
- }
- AT(.com_sleep.lv2_clr_wksrc)
- void lowpwr_sleep_clr_io_wksrc(void)
- {
- wkupedg_bak = 0;
- }
- u32 lowpwr_get_wakeup_source(void)
- {
- u32 reason = RTCCON9;
- if(reason){
- if(reason & WK_LP_KEYSCAN){
- printf("KEY_SCAN_WK\n");
- }
- if(reason & WK_LP_GPIO){
- printf("GPIO_WK\n");
- }
- if(reason & WK_LP_TOUCH){
- printf("TOUCH_WK\n");
- }
- if(reason & WK_LP_INBOX){
- printf("INBOX_WK\n");
- }
- if(reason & WK_LP_VUSB){
- printf("VUSB_WK\n");
- }
- if(reason & WK_LP_WK0){
- printf("WKO_WK\n");
- }
- if(reason & WK_LP_RTC_1S){
- printf("RTC1S_WK\n");
- }
- if(reason & WK_LP_ALARM){
- printf("ALMWKP_WK\n");
- }
- RTCCON9 = 0x1fff; //Clr wakeup pending
- RTCCON10 = 0xffff;
- }
- return reason;
- }
- void lowpwr_wakeup_disable(void)
- {
- RTCCON9 = 0x1fff; //Clr wakeup pending
- RTCCON10 = 0xffff;
- RTCCON3 &= 0xFF;
- WKUPCPND = 0xff << 16; //clear wakeup pending
- WKUPEDG = 0;
- WKUPCON = 0;
- PORTINTEDG = 0;
- PORTINTEN = 0;
- }
- void lowpwr_clr_wakeup_pending(void)
- {
- WKUPCPND = 0xff << 16; //clear wakeup pending
- RTCCON9 = 0x1fff; //Clr wakeup pending
- RTCCON10 = 0xffff;
- }
- AT(.com_periph.lowpwr.sleep)
- bool lowpwr_is_wakeup_pending(u32 ignore_src)
- {
- u32 wk_pending = 0x1fff;
- if(ignore_src){
- wk_pending &= ~ignore_src;
- }
- return (RTCCON9 & wk_pending);
- }
- void lowpwr_wk0_wakeup_config(lowpwr_wakeup_typedef *config)
- {
- if (config->lp_type == LP_TYPE_SLEEP) {
- wk0_edge_capture_config(config->edge);
- WKUPCON |= BIT(17); //wakeup sleep mode enable
- RTCCON3 |= BIT(17);
- } else if(config->lp_type == LP_TYPE_POWOFF) {
- if (config->edge == WK_EDGE_FALLING) {
- wko_io_config(1, 0, 1);
- RTCCON1 &= ~BIT(6); //wk pin low level wakeup
- } else {
- wko_io_config(0, 1, 1);
- RTCCON1 |= BIT(6); //wk pin high level wakeup
- }
- RTCCON3 |= BIT(10);
- }
- }
- void lowpwr_gpio_wakeup_config(lowpwr_wakeup_typedef *config)
- {
- if((config->gpiox == GPIOA_REG) || (config->gpiox == GPIOB_REG)){
- gpio_edge_cap_typedef gpio_cfg;
- gpio_cfg.edge = config->edge;
- gpio_cfg.gpio_pin = config->gpio_pin;
- gpio_cfg.gpiox = config->gpiox;
- gpio_cfg.gpio_pupd = config->gpio_pupd;
- gpio_edge_capture_config(&gpio_cfg);
- RTCCON3 |= BIT(17);
- WKUPCON |= BIT(17); //wakeup sleep mode enable
- WKUPCPND = 0xff << 16; //clear wakeup pending
- }
- }
- void lowpwr_wakeup_config_do(lowpwr_wakeup_typedef *config)
- {
- if(config){
- if(!(config->source & WK_LP_TOUCH)){
- RTCCON0 &= ~BIT(4); //disable touch key
- }
- if(config->source & WK_LP_WK0){
- lowpwr_wk0_wakeup_config(config);
- }
- if(config->source & WK_LP_TOUCH){
- RTCCON0 |= BIT(4);
- RTCCON1 |= BIT(8);
- RTCCON1 |= BIT(9); //VDDTK enable for touch key logic
- RTCCON3 |= BIT(14); // Touch key long press wakeup enable
- }
- if(config->source & WK_LP_BT){
- RTCCON3 |= BIT(13);
- }
- if(config->source & WK_LP_ALARM){
- RTCCON0 |= BIT(19);
- RTCCON3 |= BIT(8);
- }
- if(config->source & WK_LP_RTC_1S){
- RTCCON3 |= BIT(9);
- }
- if(config->source & WK_LP_VUSB){
- RTCCON3 |= BIT(11);
- }
- if(config->source & WK_LP_KEYSCAN){
- RTCCON3 |= BIT(16);
- }
- if(config->source & WK_LP_INBOX){
- RTCCON3 |= BIT(12);
- }
- if(config->source & WK_LP_GPIO){
- lowpwr_gpio_wakeup_config(config);
- }
- }
- }
- void lowpwr_wakeup_config(lowpwr_wakeup_typedef *config)
- {
- if(config){
- RTCCON3 &= 0xFF;
- lowpwr_wakeup_config_do(config);
- }
- }
- void lowpwr_wakeup_config_2(lowpwr_wakeup_typedef *config)
- {
- if(config){
- lowpwr_wakeup_config_do(config);
- }
- }
- void lowpwr_wakeup_source_enable(WK_LP_SRC_SEL wk_src)
- {
- if(wk_src & WK_LP_WK0){
- RTCCON3 |= BIT(17);
- }
- if(wk_src & WK_LP_TOUCH){
- RTCCON3 |= BIT(14);
- }
- if(wk_src & WK_LP_BT){
- RTCCON3 |= BIT(13);
- }
- if(wk_src & WK_LP_ALARM){
- RTCCON3 |= BIT(8);
- }
- if(wk_src & WK_LP_RTC_1S){
- RTCCON3 |= BIT(9);
- }
- if(wk_src & WK_LP_VUSB){
- RTCCON3 |= BIT(11);
- }
- if(wk_src & WK_LP_KEYSCAN){
- RTCCON3 |= BIT(16);
- }
- if(wk_src & WK_LP_INBOX){
- RTCCON3 |= BIT(12);
- }
- if(wk_src & WK_LP_GPIO){
- RTCCON3 |= BIT(17);
- }
- }
- void lowpwr_wakeup_source_disable(WK_LP_SRC_SEL wk_src)
- {
- if (wk_src == WK_LP_SRC_ALL) {
- RTCCON3 &= 0xFF;
- return;
- }
- if(wk_src & WK_LP_WK0){
- RTCCON3 &= ~BIT(17);
- }
- if(wk_src & WK_LP_TOUCH){
- RTCCON3 &= ~BIT(14); // Touch key long press wakeup enable
- }
- if(wk_src & WK_LP_BT){
- RTCCON3 &= ~BIT(13);
- }
- if(wk_src & WK_LP_ALARM){
- RTCCON3 &= ~BIT(8);
- }
- if(wk_src & WK_LP_RTC_1S){
- RTCCON3 &= ~BIT(9);
- }
- if(wk_src & WK_LP_VUSB){
- RTCCON3 &= ~BIT(11);
- }
- if(wk_src & WK_LP_KEYSCAN){
- RTCCON3 &= ~BIT(16);
- }
- if(wk_src & WK_LP_INBOX){
- RTCCON3 &= ~BIT(12);
- }
- if(wk_src & WK_LP_GPIO){
- RTCCON3 &= ~BIT(17);
- }
- }
- ALIGNED(512)
- void lowpwr_pwroff_mode1_do(void)
- {
- u32 rtccon3;
- saradc_deinit(); //disable saradc
- PICCONCLR = BIT(0); //disable global interrupt
- NMICON = 0;
- RTCCON3 &= ~BIT(17); //disable gpio wakeup
- RTCCON9 = 0x1fff; //Clr wakeup pending
- if(RTCCON3 & BIT(14)){ //Touch need rc2m clk
- RTCCON0 |= BIT(19); //RC2M_RTC enable
- asm("nop");asm("nop");asm("nop");
- RTCCON0 = (RTCCON0 & ~(0x03 << 12)) | (0x02 << 12); //CLK2M in Touch select SNF_RC_RTC
- }else{
- RTCCON0 &= ~BIT(19); //RC2M_RTC disable
- }
- RTCCON4 &= ~BIT(17); //FGS
- RTCCON4 &= ~BIT(18); //FGBUF
- RTCCON4 &= ~BIT(15); //VIO_PD not work
- 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
- CLKCON0 &= ~0xc; //sys_clk switch to RC
- asm("nop");
- asm("nop");
- asm("nop");
- XOSCCON = 0;
- PLL0CON = 0;
- rtccon3 = RTCCON3 & ~(0xFF);
- rtccon3 |= BIT(5) | BIT(6); //core power down enable
- WDT_DIS();
- RTCCON |= BIT(5); //RTC wake up power down mode reset system enable
- RTCCON3 = rtccon3;
- LPMCON |= BIT(0); //sleep mode
- LPMCON |= BIT(1); //idle mode
- asm("nop");asm("nop");asm("nop");
- while(1);
- }
- //in pwroff_mode2_final, can't use subfunction
- AT(.com_text.pwroff.mode2)
- static void pwroff_mode2_final(void)
- {
- u32 rtccon3 = RTCCON3;
- u32 rtccon0 = RTCCON0;
- RTCCON12 = (RTCCON12 & ~0xf) | 0xa | (0x3<<6) | (0x3<<4); //disable WKO reset, RTC WDT, GPIO reset
- RTCCON4 &= ~(BIT(17) | BIT(18)); //FGS, FGBUF
- if(RTCCON3 & (BIT(8) | BIT(14) | BIT(16))){ //wakeup source need rc2m clk
- RTCCON0 |= BIT(19); //RC2M_RTC enable
- }else{
- RTCCON0 &= ~BIT(19); //RC2M_RTC disable
- }
- PWRCON1 = (PWRCON1 & ~(0XF<<14)) | (0X0<<14); //DI_SW DISABLE
- RTCCON8 &= ~BIT(29);
- RTCCON4 |= BIT(11); //VDDIO_AON voltage
- RTCCON3 |= BIT(7); //enable vddio aon ldo
- 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
- rtccon0 = RTCCON0;
- if(RTCCON3 & BIT(14)){
- rtccon0 = (rtccon0 & ~(0x03 << 12)) | (0x02 << 12); //CLK2M in Touch select SNF_RC_RTC
- }
- if(RTCCON3 & BIT(16)){
- rtccon0 = (rtccon0 & ~(0x03 << 14)) | (0x02 << 14); //CLK2M in Keyscan select SNF_RC_RTC
- }
- RTCCON0 = rtccon0;
- RTCCON5 &= ~(1<<12); //CLEAR LP FLAG
- WKUPCPND = 0xFF<<16;
- CLKCON0 &= ~0xc; //sys_clk switch to RC
- asm("nop");
- asm("nop");
- asm("nop");
- XOSCCON = 0;
- PLL0CON = 0;
- // when switch power, reduce lp_top power, disable ram0/1 clock
- CLKGAT0 &= ~((3<<2) | BIT(15)); // sram0/1 & LP disable clock
- RTCCON5 &= ~(1<<11); // dis sram if
- RTCCON5 |= (BIT(15) | BIT(16)); //RAM0 RAM1 shutdown
- //RTCCON5 |= BIT(13); //RAM0/1 light sleep
- //RTCCON5 |= BIT(14); //RAM0/1 deep sleep
- // pmu power down
- LVDCON &= ~(BIT(3) | BIT(5)); //disable LVD reset
- rtccon3 = RTCCON3 & ~BIT(5); //disable C2RL
- rtccon3 |= (BIT(4) | BIT(3)); //PD CORE2, disable all analog model except IO
- rtccon3 &= ~0x7; //disable VDDCORE & VDDIO & VDDBT LDO
- //disable WDT
- WDT_DIS();
- RTCCON |= BIT(5); //RTC wake up power down mode reset system enable
- RTCCON3 = rtccon3;
- LPMCON |= BIT(0); //sleep mode
- LPMCON |= BIT(1); //idle mode
- while(1);
- }
- AT(.com_text.lp_port_init)
- void lp_port_init(void)
- {
- //config IO low power state
- //when RTCCON5 bit12=0, will select LPGPIO; otherwise, select GPIO
- //save IO
- if(pmu_vddio_to_flash()){
- GPIOGDE = BIT(2);
- GPIOGPU = BIT(2);
- }else{
- GPIOGDE = 0;
- GPIOGPU = 0;
- }
- CLKGAT0 |= BIT(15); //lp_clk enable
- io_sleep();
- }
- AT(.com_text.pwroff_mode2)
- void lowpwr_pwroff_mode2_do(void)
- {
- u8 *src, *dst;
- u32 i;
- void (*p_func)(void);
- p_func = (void (*)(void))CACHE_ADDR;
- saradc_deinit();
- PICCONCLR = BIT(0); //disable global interrupt
- NMICON = 0;
- RTCCON9 = 0x1fff; //Clr wakeup pending
- RTCCON10 = 0xffff;
- PWRCON1 &= ~(0xf<<14); //disable flash power gate
- PWRCON1 |= BIT(18);
- //copy pwroff_mode2_final to cache ram
- dst = (u8*) CACHE_ADDR;
- src = (u8*) (&pwroff_mode2_final);
- for(i = 0; i < 0x300; i++){
- *dst++ = *src++;
- }
- lp_port_init();
- //jmp to run lp_sniff_final()
- p_func();
- }
- AT(.com_sleep.sleep.lv1)
- WEAK void lowpwr_sleep_lv1_proc(void)
- {
- u32 pwrcon2 = PWRCON2;
- u32 pwrcon0 = PWRCON0;
- u32 lpmcon = LPMCON;
- PWRCON2 = (PWRCON2 & ~(0xf<<0)) | (0x0<<0); // vddbt set 0.85v
- PLL0CON |= BIT(1);
- PLL0CON = (PLL0CON & ~(0x1)); // disable vdd12 from AVDD
- XOSCCON &= ~(BIT(5) | 0xb<<24); // disable XOSC48M clkout
- // vddio AON
- RTCCON3 |= BIT(7);
- PWRCON0 = (PWRCON0 & ~(0XF<<5)) | 4<<5;
- delay_us(5);
- RTCCON3 &= ~BIT(1);
- //LPMCON = (LPMCON & ~(0X1F << 16)) | (0x0<<16); // sniff vddcore set 0.7v
- WDT_DIS();
- LPMCON |= BIT(2); // system sleep
- asm("nop");asm("nop");
- asm("nop");asm("nop");
- PWRCON1 |= BIT(7); // enable vddbt climit
- PWRCON2 = pwrcon2;
- delay_us(10); // disable vddbt climit
- PWRCON1 &= ~BIT(7);
- LPMCON = lpmcon; // resume vddcore
- // vddio AON exit
- RTCCON3 |= BIT(1);
- PWRCON0 = pwrcon0;
- delay_us(1);
- RTCCON3 &= ~BIT(7);
- XOSCCON |= BIT(5) | 0xb<<24; // resume XOSC clkout
- WDT_EN();
- }
- AT(.com_sleep.lv2)
- WEAK void lowpwr_sleep_sfr_user_save(void)
- {
- }
- AT(.com_sleep.lv2)
- WEAK void lowpwr_sleep_sfr_user_resume(void)
- {
- }
- AT(.com_sleep.lv2_do)
- void lp_sleep_lv2_do(void)
- {
- u32 rtccon3 = RTCCON3;
- // 1. disable clock
- CLKGAT0 &= ~(BIT(15) | BIT(3) | BIT(2)); //lp clk, sram0/1 disable clock
- //RTCCON4 &= ~(0x3<<22); //VRTC24 to 1.7V
- // 2. disable interface
- // disable if, then deep sleep memory, can not do in 1 cycle
- RTCCON5 &= ~(1<<11); // dis sram if
- //RTCCON5 = (RTCCON5 & ~(0x7<<13)) | (1<<13);
- RTCCON5 |= (2<<13); // 1xx : shutdown
- // 01x : deep sleep
- // 001 : light sleep
- // 000 : normal
- RTCCON5 |= (1<<17); // set lp_flag
- RTCCON5 |= BIT(0);
- // pmu power down ...
- rtccon3 &= ~(1<<5); // VDDCORE and VLCORE
- rtccon3 |= ((1<<3) | (1<<4)); // VLCORE LDO enable, RI_PD_CORE2 from rtc
- rtccon3 &= ~(0x7<<0); // VDDBT/VDDIO/VDDCORE LDO disable
- RTCCON |= BIT(5); //RTC wake up power down mode reset system enable
- RTCCON3 = rtccon3;
- // RTCCON3 |= (1<<6); // PD CORE
- LPMCON |= BIT(0);
- LPMCON |= BIT(1); //idle mode
- asm("nop");
- asm("nop");
- asm("nop");
- while(1);
- }
- AT(.com_sleep.lv2_proc)
- void lp_sleep_lv2_proc(void)
- {
- u32 rtccon0 = RTCCON0;
- u32 *dst = (u32 *)0x70000;
- u32 *src = (u32 *)&lp_sleep_lv2_do;
- for(uint i=0; i<512/4; i++) {
- *dst++ = *src++;
- }
- // 1, save IO
- CLKGAT0 |= (1<<15); // LP_CLK Enable
- io_sleep();
- WKUPCPND = 0xFF<<16;
- wkupedg_bak = 0;
- sfr_backup.gpioa_fen = GPIOAFEN;
- sfr_backup.gpiob_fen = GPIOBFEN;
- sfr_backup.gpioa_fdiren = GPIOAFDIREN;
- sfr_backup.gpiob_fdiren = GPIOBFDIREN;
- sfr_backup.gpioa_drv = GPIOADRV;
- sfr_backup.gpiob_drv = GPIOBDRV;
- RTCCON9 = 0x1fff; //Clr wakeup pending
- RTCCON10 = 0xffff;
- WDT_DIS();
- RTCCON12 = (RTCCON12 & ~0xf) | 0xa | (0x3<<6) | (0x3<<4); //disable WKO reset, RTC WDT, GPIO reset
- // 2, analog disable
- RTCCON4 &= ~(BIT(17) | BIT(18)); //FGS,FGBUF
- RTCCON8 &= ~BIT(29);
- RTCCON3 |= BIT(7); //enable vddio aon ldo
- 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
- // PG OFF
- PWRCON1 |= BIT(9) | BIT(18); // SD/FS PG PD
- PWRCON1 = PWRCON1 & ~((0x3f << 10)) ; // PG off
- // ... other analog pd
- if(RTCCON3 & BIT(14)){
- rtccon0 = (rtccon0 & ~(0x03 << 12)) | (0x02 << 12); //CLK2M in Touch select SNF_RC_RTC
- }
- if(RTCCON3 & BIT(16)){
- rtccon0 = (rtccon0 & ~(0x03 << 14)) | (0x02 << 14); //CLK2M in Keyscan select SNF_RC_RTC
- }
- rtccon0 = (rtccon0 & ~(0x7<<22)) | (1<<22); //sys reset delay
- RTCCON0 = rtccon0;
- // 3, select sniff rc clock and disable pll,xosc
- CLKCON0 = (CLKCON0 & ~(3<<2)) | (0<<2); // sel rc2m
- asm("nop");
- asm("nop");
- asm("nop");
- // 4, PLL, XOSC, CLK2M_BT off
- PLL0CON = 0;
- PLL0CON1 = 0;
- XOSCCON = 0;
- //RTCCON3 |= BIT(3) | BIT(5); //enable RL2VLC & C2VLC
- //PWRCON0 = (PWRCON0 & ~0x1f) | 0x8; //VDDCORE is 0.9V
- asm("j 0x70000");
- };
- AT(.com_sleep.lv2_wakeup)
- void lp_wakeup_lv2_proc(void)
- {
- bool gpio_pending = true;
- RTCCON4 &= ~BIT(6); //VDDBT to VCORE dis
- RTCCON4 |= BIT(5) ; //VCORE from VDDIO
- PICADR = (u32)&__comm_vma;
- if(!(sfr_backup.rtccon5 & BIT(0))){
- PWRCON1 = (PWRCON1 & ~(0X3<<2)) | (0X1<<2); // DI_CLIMIT_S 109:85:366mA
- RTCCON5 &= ~BIT(0);
- }
- PWRCON0 |= BIT(20); //pmu normal
- wkupedg_bak = WKUPEDG;
- //pending is generated due to burrs after the gpio is wakeup from sleep. In this case, manually clear pending
- if(!(RTCCON9 & WK_LP_GPIO) && !(WKUPEDG & 0xff0000)){
- gpio_pending = false;
- }
- //resume IO
- io_resume();
- if (gpio_pending == false) {
- WKUPCPND = 0xFF<<16;
- }
- GPIOAFEN = sfr_backup.gpioa_fen;
- GPIOBFEN = sfr_backup.gpiob_fen;
- GPIOAFDIREN = sfr_backup.gpioa_fdiren;
- GPIOBFDIREN = sfr_backup.gpiob_fdiren;
- GPIOADRV = sfr_backup.gpioa_drv;
- GPIOBDRV = sfr_backup.gpiob_drv;
- // 2, analog init
- RTCCON3 |= BIT(0); //VDDDBT
- PWRCON0 = (PWRCON0 & ~0x1f) | pmu_get_vddcore(); //VDDCORE is 1.15V
- asm("nop");
- PLL0CON |= BIT(12); //DI_EN_LDO
- delay(10);
- RSTCON0 = sfr_backup.rstcon0; //pllsdm reset release
- delay(25); //delay 100us, by rc
- // 3, PLL,XOSC,CLK2M_BT, on
- XOSCCON = sfr_backup.xosccon;
- PLL0CON = sfr_backup.pll0con;
- PLL0CON1 = sfr_backup.pll0con1;
- delay(700); //delay 1ms - 2ms for xosc to work
- CLKDIVCON0 = sfr_backup.clkdivcon0;
- // 4, resume CLK
- CLKCON1 = sfr_backup.clkcon1; //xosc_mux_clk select xosc24m
- asm("nop");
- asm("nop");
- asm("nop");
- CLKCON0 = sfr_backup.clkcon0; //sysclk select xosc_mux_clk
- asm("nop");
- asm("nop");
- LVDCON &= ~BIT(30); //Enable reset pending
- }
- AT(.com_sleep.lv2_proc)
- WEAK void lowpwr_sleep_lv2_proc(void)
- {
- sfr_backup.piccon = PICCON;
- sfr_backup.picen = PICEN;
- sfr_backup.picpr = PICPR;
- sfr_backup.nmicon = NMICON;
- sfr_backup.clkgat0 = CLKGAT0;
- sfr_backup.clkgat1 = CLKGAT1;
- sfr_backup.clkgat2 = CLKGAT2;
- sfr_backup.pwrcon0 = PWRCON0 & ~BIT(20);
- sfr_backup.pwrcon1 = PWRCON1;
- sfr_backup.pwrcon2 = PWRCON2;
- sfr_backup.clkcon0 = CLKCON0;
- sfr_backup.clkcon1 = CLKCON1;
- sfr_backup.clkdivcon0 = CLKDIVCON0;
- sfr_backup.xosccon = XOSCCON;
- sfr_backup.pll0con = PLL0CON;
- sfr_backup.pll0con1 = PLL0CON1;
- sfr_backup.rstcon0 = RSTCON0;
- sfr_backup.rtccon = RTCCON;
- sfr_backup.rtccon5 = RTCCON5;
- lowpwr_sleep_sfr_save();
- lowpwr_sleep_sfr_user_save();
- u32 gpiogde = GPIOGDE;
- u32 gpiogpu = GPIOGPU;
- if(pmu_vddio_to_flash()){
- GPIOGDE = BIT(2); //SPICS
- GPIOGPU = BIT(2);
- }else{
- GPIOGDE = 0;
- GPIOGPU = 0;
- PWRCON1 &= ~(0XF<<14); //DI_SW DISABLE
- }
- sfr_backup.rtccon0 = RTCCON0;
- sfr_backup.rtccon12 = RTCCON12;
- if(RTCCON3 & (BIT(8) | BIT(9) | BIT(13) | BIT(14) | BIT(16))){ //wakeup source need rc2m clk
- RTCCON0 |= BIT(19); //RC2M_RTC enable
- }else{
- RTCCON0 &= ~BIT(19); //RC2M_RTC disable
- }
- lp_sleep(lp_sleep_lv2_proc, lp_wakeup_lv2_proc);
- RTCCON4 |= BIT(5) | BIT(6); //VCORE from VDDBT & VDDIO
- RTCCON12 = sfr_backup.rtccon12;
- RTCCON0 = sfr_backup.rtccon0;
- asm("nop");
- asm("nop");
- PWRCON1 = sfr_backup.pwrcon1 | BIT(7);
- PWRCON2 = sfr_backup.pwrcon2;
- PWRCON0 = sfr_backup.pwrcon0 | BIT(20);
- CLKGAT0 = sfr_backup.clkgat0;
- CLKGAT1 = sfr_backup.clkgat1;
- CLKGAT2 = sfr_backup.clkgat2;
- lowpwr_sleep_sfr_resume();
- lowpwr_sleep_sfr_user_resume();
- GPIOGDE = gpiogde;
- GPIOGPU = gpiogpu;
- RTCCON = sfr_backup.rtccon;
- PICCON = sfr_backup.piccon;
- PICPR = sfr_backup.picpr;
- PICEN = sfr_backup.picen;
- NMICON = sfr_backup.nmicon;
- if(sfr_backup.rtccon5 & BIT(0)){
- RTCCON4 &= ~BIT(6); //LDO Mode,VCORE disable VDDBT, from VDDIO
- }else{
- RTCCON4 &= ~BIT(5); //Buck Mode,VCORE disable VDDIO, from VDDBT
- }
- PWRCON1 &= ~BIT(7);
- }
- AT(.com_sleep.sleep)
- void lowpwr_sleep_proc(u8 lpclk_type)
- {
- if (lpclk_type == CLK_RCDIV) {
- lowpwr_sleep_lv2_proc();
- } else {
- lowpwr_sleep_lv1_proc();
- }
- }
|