123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467 |
- /**
- * @file pwrmgr.c
- * @author chipsea
- * @brief
- * @version 0.1
- * @date 2020-11-30
- * @copyright Copyright (c) 2020, CHIPSEA Co., Ltd.
- * @note
- */
- #include "sdk_config.h"
- #include "rom_sym_def.h"
- #include "types.h"
- #include "ll_sleep.h"
- #include "cst92f2x.h"
- #include "string.h"
- #include "pwrmgr.h"
- #include "error.h"
- #include "gpio.h"
- #include "log.h"
- #include "clock.h"
- #include "jump_function.h"
- #include "rf_phy_driver.h"
- #if(CFG_SLEEP_MODE == PWR_MODE_NO_SLEEP)
- static uint8_t mPwrMode = PWR_MODE_NO_SLEEP;
- #elif(CFG_SLEEP_MODE == PWR_MODE_SLEEP)
- static uint8_t mPwrMode = PWR_MODE_SLEEP;
- #elif(CFG_SLEEP_MODE == PWR_MODE_PWROFF_NO_SLEEP)
- static uint8_t mPwrMode = PWR_MODE_PWROFF_NO_SLEEP;
- #else
- #error "CFG_SLEEP_MODE define incorrect"
- #endif
- //#define CFG_FLASH_ENABLE_DEEP_SLEEP
- #ifdef CFG_FLASH_ENABLE_DEEP_SLEEP
- #warning "CONFIG FLASH ENABLE DEEP SLEEP !!!"
- #endif
- typedef struct _pwrmgr_Context_t{
- MODULE_e moudle_id;
- bool lock;
- pwrmgr_Hdl_t sleep_handler;
- pwrmgr_Hdl_t wakeup_handler;
- }pwrmgr_Ctx_t;
- static pwrmgr_Ctx_t mCtx[HAL_PWRMGR_TASK_MAX_NUM];
- static uint32_t sramRet_config;
- static uint32_t s_config_swClk0 = DEF_CLKG_CONFIG_0;
-
- uint32_t s_config_swClk1 = DEF_CLKG_CONFIG_1;
- uint32_t s_gpio_wakeup_src_group1,s_gpio_wakeup_src_group2;
- int hal_pwrmgr_init(void)
- {
- memset(&mCtx, 0, sizeof(mCtx));
- switch(mPwrMode){
- case PWR_MODE_NO_SLEEP:
- case PWR_MODE_PWROFF_NO_SLEEP:
- disableSleep();
- break;
- case PWR_MODE_SLEEP:
- enableSleep();
- break;
- }
- return ERR_NONE;
- }
- int hal_pwrmgr_clk_gate_config(MODULE_e module)
- {
- if (module < MOD_CP_CPU)
- {
- s_config_swClk0 |= BIT(module);
- }
- else if (module < MOD_PCLK_CACHE)
- {
- s_config_swClk1 |= BIT(module - MOD_CP_CPU);
- }
- return ERR_NONE;
- }
- bool hal_pwrmgr_is_lock(MODULE_e mod)
- {
- int i;
- int ret = FALSE;
- if(mPwrMode == PWR_MODE_NO_SLEEP || mPwrMode == PWR_MODE_PWROFF_NO_SLEEP ){
- return TRUE;
- }
-
- HAL_ENTER_CRITICAL_SECTION();
- for(i = 0; i< HAL_PWRMGR_TASK_MAX_NUM; i++){
- if(mCtx[i].moudle_id == MOD_NONE)
- break;
- if(mCtx[i].moudle_id == mod){
- if(mCtx[i].lock == TRUE)
- ret = TRUE;
- break;
- }
- }
- HAL_EXIT_CRITICAL_SECTION();
- return ret;
- }
- int hal_pwrmgr_lock(MODULE_e mod)
- {
- int i;
- int ret = ERR_NOT_REGISTED;
- if(mPwrMode == PWR_MODE_NO_SLEEP || mPwrMode == PWR_MODE_PWROFF_NO_SLEEP ){
- disableSleep();
- return ERR_NONE;
- }
-
- HAL_ENTER_CRITICAL_SECTION();
- for(i = 0; i< HAL_PWRMGR_TASK_MAX_NUM; i++){
- if(mCtx[i].moudle_id == MOD_NONE)
- break;
- if(mCtx[i].moudle_id == mod){
- mCtx[i].lock = TRUE;
- disableSleep();
- //LOG("LOCK\n");
- ret = ERR_NONE;
- break;
- }
- }
- HAL_EXIT_CRITICAL_SECTION();
- return ret;
- }
- int hal_pwrmgr_unlock(MODULE_e mod)
- {
- int i, cnt = 0;
-
- if(mPwrMode == PWR_MODE_NO_SLEEP || mPwrMode == PWR_MODE_PWROFF_NO_SLEEP ){
- disableSleep();
- return ERR_NONE;
- }
- HAL_ENTER_CRITICAL_SECTION();
- for(i = 0; i< HAL_PWRMGR_TASK_MAX_NUM; i++){
- if(mCtx[i].moudle_id == MOD_NONE)
- break;
- if(mCtx[i].moudle_id == mod){
- mCtx[i].lock = FALSE;
- }
- if(mCtx[i].lock)
- cnt ++;
- }
- if(cnt == 0)
- enableSleep();
- else
- disableSleep();
- HAL_EXIT_CRITICAL_SECTION();
-
- //LOG("sleep mode:%d\n", isSleepAllow());
-
- return ERR_NONE;
- }
- ErrCode_t hal_pwrmgr_register(MODULE_e mod, pwrmgr_Hdl_t sleepHandle, pwrmgr_Hdl_t wakeupHandle)
- {
- int i;
- pwrmgr_Ctx_t* pctx = NULL;
- for(i = 0; i< HAL_PWRMGR_TASK_MAX_NUM; i++){
- if(mCtx[i].moudle_id == mod)
- return ERR_INVALID_STATE;
- if(mCtx[i].moudle_id == MOD_NONE){
- pctx = &mCtx[i];
- break;
- }
- }
- if(pctx == NULL)
- return ERR_NO_MEM;
- pctx->lock = FALSE;
- pctx->moudle_id = mod;
- pctx->sleep_handler = sleepHandle;
- pctx->wakeup_handler = wakeupHandle;
- return ERR_NONE;
- }
- int hal_pwrmgr_unregister(MODULE_e mod)
- {
- int i;
- pwrmgr_Ctx_t* pctx = NULL;
- for(i = 0; i< HAL_PWRMGR_TASK_MAX_NUM; i++){
- if(mCtx[i].moudle_id == mod){
- pctx = &mCtx[i];
- break;
- }
- if(mCtx[i].moudle_id == MOD_NONE){
- return ERR_NOT_REGISTED;
- }
- }
- if(pctx == NULL)
- return ERR_NOT_REGISTED;
- HAL_ENTER_CRITICAL_SECTION();
- memcpy(pctx, pctx+1, sizeof(pwrmgr_Ctx_t)*(HAL_PWRMGR_TASK_MAX_NUM-i-1));
- HAL_EXIT_CRITICAL_SECTION();
- return ERR_NONE;
- }
- int __attribute__((used)) hal_pwrmgr_wakeup_process(void)
- {
- int i;
- #ifdef CFG_FLASH_ENABLE_DEEP_SLEEP
- extern void spif_release_deep_sleep(void);
- spif_release_deep_sleep();
- WaitRTCCount(8);
- #endif
-
- AP_PCR->SW_CLK = s_config_swClk0;
- AP_PCR->SW_CLK1 = s_config_swClk1|0x01;//force set M0 CPU
- s_gpio_wakeup_src_group1 = AP_AON->GPIO_WAKEUP_SRC[0];
- s_gpio_wakeup_src_group2 = AP_AON->GPIO_WAKEUP_SRC[1];
-
- //restore BB TIMER IRQ_PRIO
- NVIC_SetPriority((IRQn_Type)BB_IRQn, IRQ_PRIO_REALTIME);
- NVIC_SetPriority((IRQn_Type)TIM1_IRQn, IRQ_PRIO_HIGH); //ll_EVT
- NVIC_SetPriority((IRQn_Type)TIM2_IRQn, IRQ_PRIO_HIGH); //OSAL_TICK
- NVIC_SetPriority((IRQn_Type)TIM4_IRQn, IRQ_PRIO_HIGH); //LL_EXA_ADV
- for(i = 0; i< HAL_PWRMGR_TASK_MAX_NUM; i++){
- if(mCtx[i].moudle_id == MOD_NONE){
- return ERR_NOT_REGISTED;
- }
- if(mCtx[i].wakeup_handler)
- mCtx[i].wakeup_handler();
- }
- return ERR_NONE;
- }
- int __attribute__((used)) hal_pwrmgr_sleep_process(void)
- {
- int i;
- hal_pwrmgr_RAM_retention_set();
- //LOG("Sleep\n");
- for(i = 0; i< HAL_PWRMGR_TASK_MAX_NUM; i++){
- if(mCtx[i].moudle_id == MOD_NONE){
- //return ERR_NOT_REGISTED;
- //found last module
- break;
- }
- if(mCtx[i].sleep_handler)
- mCtx[i].sleep_handler();
- }
- #ifdef CFG_FLASH_ENABLE_DEEP_SLEEP
- extern void spif_set_deep_sleep(void);
- spif_set_deep_sleep();
- #endif
-
- return ERR_NONE;
- }
- /**************************************************************************************
- * @fn hal_pwrmgr_RAM_retention
- *
- * @brief This function process for enable retention sram
- *
- * input parameters
- *
- * @param uint32_t sram: sram bit map
- *
- * output parameters
- *
- * @param None.
- *
- * @return refer error.h.
- **************************************************************************************/
- int hal_pwrmgr_RAM_retention(uint32_t sram)
- {
- if(sram & 0xffffffe0)
- {
- sramRet_config = 0x00;
- return ERR_INVALID_PARAM;
- }
- sramRet_config = sram;
- return ERR_NONE;
- }
- int hal_pwrmgr_RAM_retention_clr(void)
- {
- subWriteReg(0x4000f01c,21,17,0x00);
- return ERR_NONE;
- }
- int hal_pwrmgr_RAM_retention_set(void)
- {
- subWriteReg(0x4000f01c,21,17,sramRet_config);
- return ERR_NONE;
- }
- int hal_pwrmgr_LowCurrentLdo_enable(void)
- {
- subWriteReg(0x4000f014,26,26, 1);
- return ERR_NONE;
- }
- int hal_pwrmgr_LowCurrentLdo_disable(void)
- {
- subWriteReg(0x4000f014,26,26, 0);
- return ERR_NONE;
- }
- extern void gpio_wakeup_set(GpioPin_t pin, gpio_polarity_e type);
- extern void gpio_pull_set(GpioPin_t pin, gpio_pupd_e type);
- extern void GpioSleepHandler(void);
- __attribute__((section("_section_standby_code_"))) void hal_pwrmgr_poweroff(pwroff_cfg_t* pcfg, uint8_t wakeup_pin_num)
- {
- HAL_ENTER_CRITICAL_SECTION();
- subWriteReg(0x4000f01c,6,6,0x00); //disable software control
-
- GpioSleepHandler();
-
- for(uint8_t i=0; i<wakeup_pin_num; i++)
- {
- if(pcfg[i].type==POL_FALLING)
- gpio_pull_set(pcfg[i].pin ,GPIO_PULL_UP_S);
- else
- gpio_pull_set(pcfg[i].pin,GPIO_PULL_DOWN);
- gpio_wakeup_set(pcfg[i].pin, pcfg[i].type);
- }
-
- /**
- * config reset casue as RSTC_OFF_MODE
- * reset path walkaround dwc
- */
- AON_CLEAR_XTAL_TRACKING_AND_CALIB;
- AP_AON->SLEEP_R[0] = 2;
- // write_reg(0x4000f000,0x5a5aa5a5);
- enter_sleep_off_mode(SYSTEM_OFF_MODE);
- while(1);
- }
- __attribute__((section("_section_standby_code_"))) void hal_pwrmgr_enter_sleep_rtc_reset(uint32_t sleepRtcTick)
- {
- HAL_ENTER_CRITICAL_SECTION();
- subWriteReg(0x4000f01c,6,6,0x00); //disable software control
- config_RTC(sleepRtcTick);
- // clear sram0 and sram1 retention
- // hal_pwrmgr_RAM_retention_clr();
- subWriteReg(0x4000f01c,21,17,0x04);
- /**
- config reset casue as RSTC_WARM_NDWC
- reset path walkaround dwc
- */
- AON_CLEAR_XTAL_TRACKING_AND_CALIB;
- AP_AON->SLEEP_R[0]=4;
- enter_sleep_off_mode(SYSTEM_SLEEP_MODE);
- while(1) {};
- }
- #define STANDBY_WAIT_MS(a) WaitRTCCount((a)<<5) // 32us * 32 around 1ms
- __attribute__((section("_section_standby_code_"))) pwroff_cfg_t s_pwroff_cfg[WAKEUP_PIN_MAX];
- __attribute__((section("_section_standby_code_"))) __attribute__((used)) uint8 pwroff_register_number=0;
- __attribute__((section("_section_standby_code_"))) void wakeupProcess_standby(void)
- {
- subWriteReg(0x4000f014,29,27,0x07);
- STANDBY_WAIT_MS(5);
- #ifdef CFG_FLASH_ENABLE_DEEP_SLEEP
- extern void spif_release_deep_sleep(void);
- spif_release_deep_sleep();
- STANDBY_WAIT_MS(15);
- #endif
- uint32_t volatile cnt=0;
- uint8_t volatile find_flag=0;
- uint8 pin_n=0;
- extern bool gpio_read(GpioPin_t pin);
-
- for(pin_n=0; pin_n<pwroff_register_number; pin_n++)
- {
- if((s_pwroff_cfg[pin_n].pin == P2) || (s_pwroff_cfg[pin_n].pin == P3))
- {
- HalGpioPin2Pin3Control(s_pwroff_cfg[pin_n].pin,1);
- }
- }
- for(pin_n=0; pin_n<pwroff_register_number; pin_n++)
- {
- if(gpio_read(s_pwroff_cfg[pin_n].pin)==s_pwroff_cfg[pin_n].type)
- {
- find_flag=1;
- break;
- }
- }
- while(1)
- {
- if(gpio_read(s_pwroff_cfg[pin_n].pin)==s_pwroff_cfg[pin_n].type&&find_flag==1)
- {
- cnt++;
- STANDBY_WAIT_MS(32);
- if(cnt>(s_pwroff_cfg[pin_n].on_time>>5))
- {
- write_reg(0x4000f030, 0x01);
- break;
- }
- }
- else
- hal_pwrmgr_enter_standby(&s_pwroff_cfg[0],pwroff_register_number);
- }
- JUMP_FUNCTION(WAKEUP_PROCESS) = 0;
- wakeupProcess0();
- // set_sleep_flag(0);
- // HAL_ENTER_CRITICAL_SECTION();
- // AP_PCR->SW_RESET1 = 0;
- // while(1);
- }
- extern void gpio_wakeup_set(GpioPin_t pin, gpio_polarity_e type);
- extern void gpio_pull_set(GpioPin_t pin, gpio_pupd_e type);
- __attribute__((section("_section_standby_code_"))) void hal_pwrmgr_enter_standby(pwroff_cfg_t* pcfg,uint8_t wakeup_pin_num)
- {
- HAL_ENTER_CRITICAL_SECTION();
- subWriteReg(0x4000f01c,6,6,0x00); //disable software control,Hardware automatically controls power on/off of 32M RCOSC, 32K RCOSC, 32K XOSC, Bandgap, DIGLDO, LCLDO, RTC, LPCMP.
- uint8_t i = 0;
- if(wakeup_pin_num>WAKEUP_PIN_MAX)
- {
- wakeup_pin_num=WAKEUP_PIN_MAX;
- }
- GpioSleepHandler();
- pwroff_register_number = wakeup_pin_num;
- for(i = 0; i < wakeup_pin_num; i++)
- {
- if(pcfg[i].type==POL_FALLING)
- gpio_pull_set(pcfg[i].pin,GPIO_PULL_UP_S);
- else
- gpio_pull_set(pcfg[i].pin,GPIO_PULL_DOWN);
- gpio_wakeup_set(pcfg[i].pin, pcfg[i].type);
- osal_memcpy(&s_pwroff_cfg[i],&(pcfg[i]),sizeof(pwroff_cfg_t));
- }
- JUMP_FUNCTION(WAKEUP_PROCESS)= (uint32_t)&wakeupProcess_standby;
- #ifdef CFG_FLASH_ENABLE_DEEP_SLEEP
- extern void spif_set_deep_sleep(void);
- spif_set_deep_sleep();
- WaitRTCCount(50);
- #endif
- subWriteReg(0x4000f014,29,27,0);
- set_sleep_flag(1);
- AP_AON->SLEEP_R[0] = 2;
- subWriteReg(0x4000f01c,21,17,sramRet_config);
- enter_sleep_off_mode(SYSTEM_SLEEP_MODE);
- while(1);
- }
|