#include "PanSeries.h" #include "pan_lp.h" #include "pan_clk.h" /** * @brief This function enable gpio p56 wake up * @param[in] ana: where ana is analog module * @param[in] WkEdge: wake up edge select,0-->low,1-->high * @return none */ void LP_SetExternalWake(ANA_T *ana,uint8_t WkEdge) { if(WkEdge){ ana->LP_FL_CTRL_3V |= ANAC_FL_EXT_WAKEUP_SEL_Msk_3v; }else{ ana->LP_FL_CTRL_3V &= ~ANAC_FL_EXT_WAKEUP_SEL_Msk_3v; } } /** * @brief This function set sleep time * @param[in] ana: where ana is analog module * @param[in] u32ClkCnt: where u32ClkCnt is 32k clock cnt num * @param[in] idx: where idx is 0,1, 2 * @return none */ void LP_SetSleepTime(ANA_T *ana,uint32_t u32ClkCnt,uint8_t idx) { ((__IO uint32_t *)(&(ana)->LP_SPACING_TIME0))[idx] = u32ClkCnt; } /** * @brief This function set delay time used for standby_m0 mode for wait LPLDOH ready * @param[in] ana: where ana is analog module * @param[in] u8Clk32Cnt: where u8Clk32Cnt is 32k clock period cnt * @return none */ void LP_SetLpldohDelay(ANA_T *ana,uint16_t u16Clk32Cnt) { uint32_t tmp_reg; tmp_reg = ana->LP_DLY_CTRL_3V; tmp_reg &= ~(ANAC_LPLDOH_DLY_TIME_Msk_3v); tmp_reg |= (u16Clk32Cnt << ANAC_LPLDOH_DLY_TIME_Pos_3v); ana->LP_DLY_CTRL_3V = tmp_reg; } /** * @brief This function set delay time used for fast clock ready * @param[in] ana: where ana is analog module * @param[in] u8Clk32Cnt: where u8Clk32Cnt is 32k clock period cnt * @return none */ void LP_SetWakeDelay(ANA_T *ana,uint16_t u16Clk32Cnt) { uint32_t tmp_reg; tmp_reg = ana->LP_DLY_CTRL_3V; tmp_reg &= ~(ANAC_32KCLK_DLY_TIME_Msk); tmp_reg |= (u16Clk32Cnt << ANAC_32KCLK_DLY_TIME_Pos); ana->LP_DLY_CTRL_3V = tmp_reg; } /** * @brief This function set delay time used for fast clock ready * @param[in] ana: where ana is analog module * @param[in] mode: where mode is sleep mode select * LP_MODE_SEL_SLEEP_MODE * LP_MODE_SEL_DEEPSLEEP_MODE * LP_MODE_SEL_STANDBY_M1_MODE * LP_MODE_SEL_STANDBY_M0_MODE * * @return none */ void LP_SetSleepMode(ANA_T *ana,uint8_t mode) { uint32_t tmp_reg; tmp_reg = ana->LP_FL_CTRL_3V; tmp_reg &= ~(ANAC_FL_SLEEP_MODE_SEL_Msk); tmp_reg |= (mode << ANAC_FL_SLEEP_MODE_SEL_Pos); ana->LP_FL_CTRL_3V = tmp_reg; } /** * @brief This function set sleep mode config * @param[in] ana: where ana is analog module * @param[in] u8ExtWkDis: where u8ExtWkDis determine whether to wake up by GPIO * 0:gpio can wake up * 1:gpio can notwake up * @return none */ void LP_SetSleepModeConfig(ANA_T *ana,uint32_t wkMode,bool enterCyclically) { LP_EnableInt(ana,ENABLE); LP_SetSleepMode(ana, LP_MODE_SEL_SLEEP_MODE); if((LP_WKUP_MODE_SEL_EXT_GPIO != wkMode)&&(LP_WKUP_MODE_SEL_GPIO != wkMode)){ ana->LP_FL_CTRL_3V |= ANAC_FL_RC32K_EN_Msk_3v; ana->LP_FL_CTRL_3V |= ANAC_FL_SLEEP_CNT_EN_Msk; } else { ana->LP_FL_CTRL_3V &= ~ANAC_FL_SLEEP_CNT_EN_Msk; ana->LP_FL_CTRL_3V &= ~ANAC_FL_RC32K_EN_Msk_3v; } #ifdef SYNC_3V_REG_MANUALLY CLK_Wait3vSyncReady(); #endif SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; if(enterCyclically) SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk; else SCB->SCR &= ~SCB_SCR_SLEEPONEXIT_Msk; __WFI(); #ifdef SYNC_3V_REG_MANUALLY CLK_Wait3vSyncReady(); #endif } void LP_SetDeepSleepConfig(ANA_T *ana, uint32_t wkMode, bool enterCyclically, uint8_t PowerCtrl, uint8_t dp_mode) { LP_EnableInt(ana,ENABLE); if (dp_mode == LP_DEEPSLEEP_MODE1){ ana->LP_LP_LDO_3V |= ANAC_LPLDO_H_EN_Msk_3v; ana->LP_LP_LDO_3V |= ANAC_LPLDO_L_EN_Msk; ana->LP_FL_CTRL_3V |= ANAC_LDO_POWER_CTL_Msk | ANAC_FL_LDO_ISOLATE_EN_Msk; ana->LP_FL_CTRL_3V &= ~ANAC_LDOL_POWER_CTL_Msk; } else if (dp_mode == LP_DEEPSLEEP_MODE2){ ana->LP_LP_LDO_3V |= ANAC_LPLDO_H_EN_Msk_3v; ana->LP_LP_LDO_3V &= ~ANAC_LPLDO_L_EN_Msk; ana->LP_FL_CTRL_3V |= ANAC_LDOL_POWER_CTL_Msk | ANAC_LDO_POWER_CTL_Msk; ana->LP_FL_CTRL_3V &= ~ANAC_FL_LDO_ISOLATE_EN_Msk; } else if (dp_mode == LP_DEEPSLEEP_MODE3){ ana->LP_LP_LDO_3V &= ~ANAC_LPLDO_H_EN_Msk_3v; ana->LP_LP_LDO_3V |= ANAC_LPLDO_L_EN_Msk; ana->LP_FL_CTRL_3V |= ANAC_LDOL_POWER_CTL_Msk | ANAC_LDO_POWER_CTL_Msk; ana->LP_FL_CTRL_3V &= ~ANAC_FL_LDO_ISOLATE_EN_Msk; } // Enable flash power in lp mode (Also need to enable flash AutoDp to save power) // ana->LP_FL_CTRL_3V |= ANAC_FL_FLASH_BP_EN_Msk; LP_SetSleepMode(ana, LP_MODE_SEL_DEEPSLEEP_MODE); if((LP_WKUP_MODE_SEL_EXT_GPIO != wkMode)&&(LP_WKUP_MODE_SEL_GPIO != wkMode)){ if (CLK->CLK_TOP_CTRL_3V & CLK_TOPCTL_32K_CLK_SEL_Msk_3v) { ana->LP_FL_CTRL_3V |= ANAC_FL_XTAL32K_EN_Msk_3v; ana->LP_FL_CTRL_3V &= ~ANAC_FL_RC32K_EN_Msk_3v; } else { ana->LP_FL_CTRL_3V &= ~ANAC_FL_XTAL32K_EN_Msk_3v; ana->LP_FL_CTRL_3V |= ANAC_FL_RC32K_EN_Msk_3v; } ana->LP_INT_CTRL |= ANAC_INT_SLEEP_TMR_WK_EN_Msk; } else { ana->LP_FL_CTRL_3V &= ~ANAC_FL_RC32K_EN_Msk_3v; } ana->LP_FL_CTRL_3V = ((PowerCtrl & 0x1f) << 24u) | (ana->LP_FL_CTRL_3V & 0xe0FFFFFF); // Wait 3v sync ready manually ANA->LP_REG_SYNC |= ANAC_LP_REG_SYNC_3V_Msk | ANAC_LP_REG_SYNC_3V_TRG_Msk; while(ANA->LP_REG_SYNC & (ANAC_LP_REG_SYNC_3V_TRG_Msk)) {} SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; if(enterCyclically) SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk; else SCB->SCR &= ~SCB_SCR_SLEEPONEXIT_Msk; ANA->LP_INT_CTRL |= ANAC_INT_SLEEP_TMR_INT_EN_Msk; __WFI(); } void LP_SetStandbyMode0Config(void) { LP_SetSleepMode(ANA, LP_MODE_SEL_STANDBY_M0_MODE); LP_EnableInt(ANA,ENABLE); ANA->LP_FL_CTRL_3V &= ~ANAC_FL_XTAL32K_EN_Msk_3v; ANA->LP_FL_CTRL_3V &= ~ANAC_FL_RC32K_EN_Msk_3v; #ifdef SYNC_3V_REG_MANUALLY CLK_Wait3vSyncReady(); #endif SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; __WFI(); } void LP_SetStandbyMode0BodLvrConfig(void) { LP_SetSleepMode(ANA, LP_MODE_SEL_STANDBY_M0_MODE); LP_EnableInt(ANA,ENABLE); //bod/lvr wakeup need ANA->LP_FL_CTRL_3V |= ANAC_FL_XTAL32K_EN_Msk_3v; ANA->LP_FL_CTRL_3V |= ANAC_FL_RC32K_EN_Msk_3v; #ifdef SYNC_3V_REG_MANUALLY CLK_Wait3vSyncReady(); #endif SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; __WFI(); } void LP_SetStandbyMode1Config(ANA_T *ana, uint32_t wkMode, uint8_t PowerCtrl, uint32_t slpTimer, uint8_t spaceIdx, uint8_t stdy_mode) { LP_SetSleepMode(ana, LP_MODE_SEL_STANDBY_M1_MODE); LP_EnableInt(ana,ENABLE); if (stdy_mode == LP_STANDBY_M1_MODE1){ ana->LP_LP_LDO_3V |= ANAC_LPLDO_H_EN_Msk_3v; ana->LP_LP_LDO_3V |= ANAC_LPLDO_L_EN_Msk; ana->LP_FL_CTRL_3V |= ANAC_FL_LDO_ISOLATE_EN_Msk; ana->LP_FL_CTRL_3V &= ~(ANAC_LDOL_POWER_CTL_Msk | ANAC_LDO_POWER_CTL_Msk); } else if (stdy_mode == LP_STANDBY_M1_MODE2){ ana->LP_LP_LDO_3V |= ANAC_LPLDO_H_EN_Msk_3v; ana->LP_LP_LDO_3V &= ~ANAC_LPLDO_L_EN_Msk; ana->LP_FL_CTRL_3V |= ANAC_LDOL_POWER_CTL_Msk | ANAC_FL_LDO_ISOLATE_EN_Msk; ana->LP_FL_CTRL_3V &= ~(ANAC_LDO_POWER_CTL_Msk); } else if (stdy_mode == LP_STANDBY_M1_MODE3){ ana->LP_LP_LDO_3V &= ~ANAC_LPLDO_H_EN_Msk_3v; ana->LP_LP_LDO_3V |= ANAC_LPLDO_L_EN_Msk; ana->LP_FL_CTRL_3V |= ANAC_LDOL_POWER_CTL_Msk | ANAC_FL_LDO_ISOLATE_EN_Msk; ana->LP_FL_CTRL_3V &= ~(ANAC_LDO_POWER_CTL_Msk); } ana->LP_FL_CTRL_3V = ((PowerCtrl & 0x1f) << 24u) | (ana->LP_FL_CTRL_3V & 0xe0FFFFFF); if((LP_WKUP_MODE_SEL_EXT_GPIO != wkMode)&&(LP_WKUP_MODE_SEL_GPIO != wkMode)){ if (CLK->CLK_TOP_CTRL_3V & CLK_TOPCTL_32K_CLK_SEL_Msk_3v) { ana->LP_FL_CTRL_3V |= ANAC_FL_XTAL32K_EN_Msk_3v; ana->LP_FL_CTRL_3V &= ~ANAC_FL_RC32K_EN_Msk_3v; } else { ana->LP_FL_CTRL_3V &= ~ANAC_FL_XTAL32K_EN_Msk_3v; ana->LP_FL_CTRL_3V |= ANAC_FL_RC32K_EN_Msk_3v; } ana->LP_INT_CTRL |= ANAC_INT_SLEEP_TMR_WK_EN_Msk; } else { ana->LP_FL_CTRL_3V &= ~ANAC_FL_RC32K_EN_Msk_3v; ana->LP_FL_CTRL_3V &= ~ANAC_FL_XTAL32K_EN_Msk_3v; } // Wait 3v sync ready manually ANA->LP_REG_SYNC |= ANAC_LP_REG_SYNC_3V_Msk | ANAC_LP_REG_SYNC_3V_TRG_Msk; while(ANA->LP_REG_SYNC & (ANAC_LP_REG_SYNC_3V_TRG_Msk)) {} if((LP_WKUP_MODE_SEL_EXT_GPIO != wkMode)&&(LP_WKUP_MODE_SEL_GPIO != wkMode)){ LP_SetSleepTime(ana,slpTimer,spaceIdx); } SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; __WFI(); }