From ae079c1fc5d990ba55714d4b3a51b19f96edaec4 Mon Sep 17 00:00:00 2001 From: WXK <287788329@qq.com> Date: 星期四, 24 四月 2025 16:01:43 +0800 Subject: [PATCH] 改为中断来低电平触发发送当前扫描数据,3s内扫描不到的会退出,串口来55 AA 75 70 64 61 74 65,进入升级模式 --- 01_SDK/modules/hal/panchip/panplat/pan1070/bsp/device/Source/pan_lp.c | 614 ++++++++++++++++++++++++++++++++++++++++++------------- 1 files changed, 462 insertions(+), 152 deletions(-) diff --git a/01_SDK/modules/hal/panchip/panplat/pan1070/bsp/device/Source/pan_lp.c b/01_SDK/modules/hal/panchip/panplat/pan1070/bsp/device/Source/pan_lp.c index 688ead5..a1d92e1 100644 --- a/01_SDK/modules/hal/panchip/panplat/pan1070/bsp/device/Source/pan_lp.c +++ b/01_SDK/modules/hal/panchip/panplat/pan1070/bsp/device/Source/pan_lp.c @@ -1,11 +1,15 @@ #include "PanSeries.h" #include "pan_lp.h" #include "pan_clk.h" +#include "comm_prf.h" + +extern const uint32_t PanFlashLineMode; +extern const bool PanFlashEnhanceEnable; /** -* @brief This function enable gpio p56 wake up +* @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 +* @param[in] WkEdge: wake up edge select,0-->low,1-->high * @return none */ void LP_SetExternalWake(ANA_T *ana,uint8_t WkEdge) @@ -21,7 +25,7 @@ * @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 +* @param[in] idx: channel index of sleeptimer, can be 0, 1, 2 * @return none */ void LP_SetSleepTime(ANA_T *ana,uint32_t u32ClkCnt,uint8_t idx) @@ -29,6 +33,15 @@ ((__IO uint32_t *)(&(ana)->LP_SPACING_TIME0))[idx] = u32ClkCnt; } +/** +* @brief This function get current 32K timer counter +* @param[in] ana: where ana is analog module +* @return Current 32K timer counter +*/ +uint32_t LP_GetSlptmrCurrCount(ANA_T *ana) +{ + return ana->LP_SLPTMR; +} /** * @brief This function set delay time used for standby_m0 mode for wait LPLDOH ready @@ -73,7 +86,6 @@ * * @return none */ - void LP_SetSleepMode(ANA_T *ana,uint8_t mode) { uint32_t tmp_reg; @@ -84,174 +96,472 @@ ana->LP_FL_CTRL_3V = tmp_reg; } +__STATIC_FORCEINLINE void PHY_FifoFlush(void) +{ + PRI_RF_WRITE_REG_VALUE(PRI_RF, PHY1, PHY_DRV_CFG_BUF_FLUSH, 0x1); + PRI_RF_WRITE_REG_VALUE(PRI_RF, PHY1, PHY_DRV_CFG_BUF_FLUSH, 0x0); - /** + PRI_RF_WRITE_REG_VALUE(PRI_RF, PHY1, PHY_DRV_RSP_BUF_FLUSH, 0x1); + PRI_RF_WRITE_REG_VALUE(PRI_RF, PHY1, PHY_DRV_RSP_BUF_FLUSH, 0x0); +} + +uint32_t PHY_WriteCfgFifoBatchCopy(const uint32_t *command, const uint32_t cmd_len, uint32_t *ptr_rsp_value) +{ + volatile uint32_t reg = 0; + uint32_t time_out = 0, cmd_idx = 0; + uint32_t rsp_len = 0; + + if (0 == cmd_len) + { + goto fun_ext; + } + + /* Flush the PHY Driver FIFO */ + PHY_FifoFlush(); + + /* Trigger the FIFO */ + PRI_RF_WRITE_REG_VALUE(PRI_RF, PHY1, PHY_DRV_CFG_TRG, 0x1); + + do + { + do + { + /* check that the FIFO is empty */ + reg = PRI_RF_READ_REG_VALUE(PRI_RF, PHY1, PHY_DRV_CFG_BUF_FULL); + } while (reg == 1); + + /* Write the commands to FIFO */ + PRI_RF_WRITE_REG_VALUE(PRI_RF, PHY3, PHY_DRV_CFG_BUF_DIN, command[cmd_idx++]); + + /* check that the Response buff is full */ + reg = PRI_RF_READ_REG_VALUE(PRI_RF, PHY1, PHY_DRV_RSP_BUF_EMPTY); + if ((ptr_rsp_value != NULL) && (reg == 0)) + { + /* read the response from FIFO */ + ptr_rsp_value[rsp_len++] = PRI_RF_READ_REG_VALUE(PRI_RF, PHY4, PHY_DRV_RSP_BUF_DOUT); + } + } while (cmd_idx < cmd_len); + + do + { + time_out++; + reg = PRI_RF_READ_REG_VALUE(PRI_RF, INTR1, IC_PHY_DRV_CFG_DONE); + } while (reg == 0); + + /* check that the Response buff is full */ + reg = PRI_RF_READ_REG_VALUE(PRI_RF, PHY1, PHY_DRV_RSP_BUF_EMPTY); + + while ((ptr_rsp_value != NULL) && (reg == 0)) + { + /* read the response from FIFO */ + ptr_rsp_value[rsp_len++] = PRI_RF_READ_REG_VALUE(PRI_RF, PHY4, PHY_DRV_RSP_BUF_DOUT); + /* check that the Response buff is full */ + reg = PRI_RF_READ_REG_VALUE(PRI_RF, PHY1, PHY_DRV_RSP_BUF_EMPTY); + } + + /* Clear the interrupt */ + PRI_RF_WRITE_REG_VALUE(PRI_RF, INTCLR, IC_PHY_DRV_CFG_DONE_CLR, 1); + PRI_RF_WRITE_REG_VALUE(PRI_RF, INTCLR, IC_PHY_DRV_CFG_DONE_CLR, 0); + PRI_RF_WRITE_REG_VALUE(PRI_RF, PHY1, PHY_DRV_CFG_TRG, 0x0); + +fun_ext: + + return rsp_len; +} + +uint32_t PHY_SingleRegRead(uint32_t reg_addr) +{ + uint32_t reg; + uint32_t val; + uint32_t cmd[] = { + 0x00000013 | (reg_addr << 8), + }; + + // Backup AHB Clock Register and enable LL Clock + reg = CLK->AHB_CLK_CTRL; + CLK->AHB_CLK_CTRL |= CLK_AHBCLK_BLE32M_EN_Msk | CLK_AHBCLK_BLE32K_EN_Msk; + + // Enable LL module for later phy operation + LLHWC_WRITE_MASK32_REG(REG_FILE_OFST, CTRL_MEM_SOFT_RST_N, CTRL_MEM_SOFT_RST_N_MSK, CTRL_MEM_SOFT_RST_N_SHFT, 0); + LLHWC_WRITE_MASK32_REG(REG_FILE_OFST, CTRL_MEM_SOFT_RST_N, CTRL_MEM_SOFT_RST_N_MSK, CTRL_MEM_SOFT_RST_N_SHFT, 1); + LLHWC_WRITE_MASK32_REG(REG_FILE_OFST, CTRL_PWR_MOD, CTRL_PWR_MOD_MSK, CTRL_PWR_MOD_SHFT, 1); + + // Start to read phy register + PHY_WriteCfgFifoBatchCopy(cmd, sizeof(cmd) >> 2, &val); + + // Restore AHB Clock Register + CLK->AHB_CLK_CTRL = reg; + + return val; +} + +void PHY_SingleRegWrite(uint32_t reg_addr, uint32_t reg_val) +{ + uint32_t reg; + uint32_t cmd[] = { + 0x00000012 | (reg_addr << 8) | (reg_val << 16), + }; + + // Backup AHB Clock Register and enable LL Clock + reg = CLK->AHB_CLK_CTRL; + CLK->AHB_CLK_CTRL |= CLK_AHBCLK_BLE32M_EN_Msk | CLK_AHBCLK_BLE32K_EN_Msk; + + // Enable LL module for later phy operation + LLHWC_WRITE_MASK32_REG(REG_FILE_OFST, CTRL_MEM_SOFT_RST_N, CTRL_MEM_SOFT_RST_N_MSK, CTRL_MEM_SOFT_RST_N_SHFT, 0); + LLHWC_WRITE_MASK32_REG(REG_FILE_OFST, CTRL_MEM_SOFT_RST_N, CTRL_MEM_SOFT_RST_N_MSK, CTRL_MEM_SOFT_RST_N_SHFT, 1); + LLHWC_WRITE_MASK32_REG(REG_FILE_OFST, CTRL_PWR_MOD, CTRL_PWR_MOD_MSK, CTRL_PWR_MOD_SHFT, 1); + + // Start to write phy register + PHY_WriteCfgFifoBatchCopy(cmd, sizeof(cmd) >> 2, NULL); + + // Restore AHB Clock Register + CLK->AHB_CLK_CTRL = 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 +* @param[in] ana: Select analog module +* @param[in] enterCyclically: Enable ARM Sleep-On-Exit Feature or not * @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) +void LP_EnterSleepMode(ANA_T *ana, bool enterCyclically) { - 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; - } + LP_EnableInt(ana, ENABLE); - // 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; + /* Enable proper 32k clock in low power mode */ + 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_FL_CTRL_3V = ((PowerCtrl & 0x1f) << 24u) | (ana->LP_FL_CTRL_3V & 0xe0FFFFFF); + LP_SetSleepMode(ana, LP_MODE_SEL_SLEEP_MODE); + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; - // 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 (enterCyclically) { + SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk; + } else { + SCB->SCR &= ~SCB_SCR_SLEEPONEXIT_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(); + __WFI(); } - -void LP_SetStandbyMode0Config(void) +void LP_EnterDeepSleepMode(ANA_T *ana, bool enterCyclically, uint8_t powerCtrl, uint8_t dpMode) { - 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 + uint32_t nvicInt; - SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; - __WFI(); + ana->LP_INT_CTRL |= ANAC_INT_LP_INT_EN_Msk | ANAC_INT_SLEEP_TMR_INT_EN_Msk | ANAC_INT_SLEEP_TMR_WK_EN_Msk; + + if (dpMode == 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 (dpMode == 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 (dpMode == 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 LPDOH mode 2 to save power + // NOTE: This option is now configured in SystemHwParamLoader() flow due to ft version. +#if 0 + ana->LP_LP_LDO_3V |= ANAC_LPLDO_H_MODE_SEL_Msk_3v; +#endif + +#if CONFIG_KEEP_FLASH_POWER_IN_LP_MODE + // Keep flash power in Deepsleep mode +#if CONFIG_FLASH_LDO_EN + ana->LP_FL_CTRL_3V |= ANAC_FL_FLASH_LP_EN_Msk; + ana->LP_FL_CTRL_3V &= ~ANAC_FL_FLASH_BP_EN_Msk; +#else + ana->LP_FL_CTRL_3V &= ~ANAC_FL_FLASH_LP_EN_Msk; + ana->LP_FL_CTRL_3V |= ANAC_FL_FLASH_BP_EN_Msk; +#endif /* CONFIG_FLASH_LDO_EN */ + // Configure rdp wait cnt for auto dp use + FMC_SetRdpWaitCount(FLCTL, 0x400); +#else + // Power down flash in Deepsleep mode + ana->LP_FL_CTRL_3V &= ~ANAC_FL_FLASH_LP_EN_Msk; + ana->LP_FL_CTRL_3V &= ~ANAC_FL_FLASH_BP_EN_Msk; +#endif /* CONFIG_KEEP_FLASH_POWER_IN_LP_MODE */ + + /* Enable flash auto-dp no matter flash power-down or not in deepsleep mode */ + FMC_EnableAutoDp(FLCTL); + + /* Enable proper 32k clock in low power mode */ + 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; + } + + // Configure power of SRAM + ana->LP_FL_CTRL_3V = ((powerCtrl & 0x1f) << 24u) | (ana->LP_FL_CTRL_3V & 0xe0FFFFFF); + + // Configure LP delay + ana->LP_DLY_CTRL_3V &= ~0x3ff; + ana->LP_DLY_CTRL_3V |= 0x7; + + // Mask all interrupts + __disable_irq(); + + // Set LP irq to lowest priority + NVIC_SetPriority(LP_IRQn, 3); + + /* Store and Clear NVIC Interrupt Enable Register */ + nvicInt = NVIC->ISER[0U]; + NVIC->ICER[0U] = 0xFFFFFFFF; + /* Enable LP IRQ to make sure related ISR would trigger after wake up */ + NVIC_EnableIRQ(LP_IRQn); + + // Ensure next wfi enter deepsleep mode + LP_SetSleepMode(ana, LP_MODE_SEL_DEEPSLEEP_MODE); + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + // 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 (enterCyclically) { + SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk; + } else { + SCB->SCR &= ~SCB_SCR_SLEEPONEXIT_Msk; + } + + __WFI(); + + // Ensure next wfi enter sleep mode + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + LP_SetSleepMode(ana, LP_MODE_SEL_SLEEP_MODE); + + /* Disable flash auto-dp after deepsleep wakeup */ + FMC_DisableAutoDp(FLCTL); + +#if ((!CONFIG_KEEP_FLASH_POWER_IN_LP_MODE) && (CONFIG_FLASH_LINE_MODE == FLASH_X4_MODE)) + /* Set en_burst_wrap in FMC */ + FLCTL->X_FL_X_MODE |= (0x1 << 16); + /* Re-issue burst_wrap command to flash if is X4 mode */ + FLCTL->X_FL_CTL = (0 << 8) | (0x05 << 0); + FLCTL->X_FL_WD[0] = CMD_BURST_READ; + FLCTL->X_FL_WD[4] = BURST_READ_MODE_32 << 5; + FLCTL->X_FL_TRIG = CMD_TRIG; + while (FLCTL->X_FL_TRIG) { + __NOP(); + } +#endif + + /* Restore NVIC Interrupt Enable Register [xxx:107 must]*/ + NVIC->ISER[0U] = nvicInt; } -void LP_SetStandbyMode0BodLvrConfig(void) +__ASM static void LP_WfiWithCoreRegsBackupAndResume(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(); + push {r0-r7} /* Backup r0 ~ r7 */ + mov r0, r8 + mov r1, r9 + mov r2, r10 + mov r3, r11 + mov r4, r12 + mov r5, lr + push {r0-r5} /* Backup r8 ~ r12 and lr */ + wfi /* Trigger hw to enter low power mode */ + pop {r0-r5} /* Restore r8 ~ r12 and lr */ + mov r8, r0 + mov r9, r1 + mov r10, r2 + mov r11, r3 + mov r12, r4 + mov lr, r5 + pop {r0-r7} /* Restore r0 ~ r7 */ + bx lr /* Function return */ } -void LP_SetStandbyMode1Config(ANA_T *ana, - uint32_t wkMode, - uint8_t PowerCtrl, - uint32_t slpTimer, - uint8_t spaceIdx, - uint8_t stdy_mode) +void LP_EnterStandbyMode1(ANA_T *ana, uint8_t powerCtrl, bool wakeupWithoutReset) { - 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; - } + ana->LP_INT_CTRL |= ANAC_INT_LP_INT_EN_Msk | ANAC_INT_SLEEP_TMR_INT_EN_Msk | ANAC_INT_SLEEP_TMR_WK_EN_Msk; - // 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)) {} + /* StandbyM1 Power Mode 1, use both LPLDOH and LPLDOL */ + 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); - 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(); + /* LPDOH switch to mode 2 for better power consumption performance */ + ana->LP_LP_LDO_3V |= ANAC_LPLDO_H_MODE_SEL_Msk_3v; + + /* Power down Flash in lp mode discard the dedicated Flash LDO enabled or not */ + ana->LP_FL_CTRL_3V = (ana->LP_FL_CTRL_3V & ~(0x3 << 12u)) | (0x0 << 12u); + + /* Enable proper 32k clock in low power mode */ + 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; + } + + /* Configure retention SRAM modules in low power mode */ + ana->LP_FL_CTRL_3V = ((powerCtrl & 0x1f) << 24u) | (ana->LP_FL_CTRL_3V & 0xe0FFFFFF); + + /* Set digital delay with 32k tick unit */ + ana->LP_DLY_CTRL_3V &= ~0x3ff; + ana->LP_DLY_CTRL_3V |= 7; + + /* Insure we are going to enter hw standby mode 1 */ + LP_SetSleepMode(ana, LP_MODE_SEL_STANDBY_M1_MODE); + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + // Mask all interrupts + __disable_irq(); + + /* Trigger 3v sync */ + ana->LP_REG_SYNC |= ANAC_LP_REG_SYNC_3V_Msk | ANAC_LP_REG_SYNC_3V_TRG_Msk; + + /* Clear all lowpower related int flags if any */ + ana->LP_INT_CTRL = ana->LP_INT_CTRL; +#if 0 + /* Reset all hw peripheral modules except eFuse and GPIO */ + CLK->IPRST0 = 0x1CC; + CLK->IPRST0 = 0x0; + CLK->IPRST1 = 0x17FFF; + CLK->IPRST1 = 0x0; +#endif + /* Disable all IRQs and clear all pending IRQs on NVIC */ + NVIC->ICER[0U] = 0xFFFFFFFF; + NVIC->ICPR[0U] = 0xFFFFFFFF; + + /* Wait until 3v sync done */ + while (ana->LP_REG_SYNC & (ANAC_LP_REG_SYNC_3V_TRG_Msk)) { + __NOP(); + } + + if (!wakeupWithoutReset) { + + /* Reset CPU Vector Remap register to avoid issue after waking up */ + ana->CPU_ADDR_REMAP_CTRL = 0; + + /* Trigger hw to enter low power mode */ + __WFI(); + + /* + * ======== (Now SoC is expected in HW Standby Mode 1 and would never return back here) ========= + */ + } else { + /* + * Enable CPU core regs retention in standby mode 1 + * The CPU core registers PC, MSP, PSP and CONTROL would automatically + * be saved and restored by hardware in SoC standby mode 1. + */ + ana->LP_FL_CTRL_3V |= ANAC_FL_CPU_RETENTION_EN_Msk; + + /* Backup the FMC remap register in case we configure it in bootloader */ + uint32_t fmc_remap_bkp = FLCTL->X_FL_REMAP_ADDR; + + /* + * 1. Backup CPU core registers which are not auto-saved by hardware + * 2. Enter SoC Standby Mode 1 (WFI) + * 3. Restore previous backup CPU core registers + */ + LP_WfiWithCoreRegsBackupAndResume(); + + /* Restore FMC remap register after waking up */ + FLCTL->X_FL_REMAP_ADDR = fmc_remap_bkp; + + // Disable CPU core regs retention after wakeup + ANA->LP_FL_CTRL_3V &= ~ANAC_FL_CPU_RETENTION_EN_Msk; + + /* Reset SoC lp mode to sleep mode (1.2v area, do not need 3v sync) */ + ana->LP_FL_CTRL_3V = (ana->LP_FL_CTRL_3V & ~ANAC_FL_SLEEP_MODE_SEL_Msk) + | (LP_MODE_SEL_SLEEP_MODE << ANAC_FL_SLEEP_MODE_SEL_Pos); + + /* Restore fmc and flash status */ + FMC_SetFlashMode(FLCTL, PanFlashEnhanceEnable, PanFlashEnhanceEnable); + /* Reinit I-Cache */ + InitIcache(FLCTL, PanFlashEnhanceEnable); + /* + * Clear StandbyM1 int flag (write 1 to clear) in this register, but still + * retain all other ctrl/status flags. + */ + ana->LP_INT_CTRL = (ana->LP_INT_CTRL | ANAC_INT_STANDBY_M1_FLAG_Msk) + & ~(ANAC_INT_SLEEP_TMR0_Msk | ANAC_INT_SLEEP_TMR1_Msk | ANAC_INT_SLEEP_TMR2_Msk + | ANAC_INT_DP_FLAG_Msk | ANAC_INT_STANDBY_M0_FLAG_Msk | ANAC_INT_SRAM_RET_FLAG_Msk); + } +} + +void LP_EnterStandbyMode0(ANA_T *ana, bool enableClk32k) +{ + /* Mask all IRQs when we are on the way to enter standby mode */ + __disable_irq(); + + if (enableClk32k) { + /* Enable proper 32k clock in low power mode */ + 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; + } + } else { + // Disable 32K Clock Source to save power + ANA->LP_FL_CTRL_3V &= ~ANAC_FL_RC32K_EN_Msk_3v; + ANA->LP_FL_CTRL_3V &= ~ANAC_FL_XTAL32K_EN_Msk_3v; + } + + /* Set digital delay with 32k tick unit */ + ANA->LP_DLY_CTRL_3V &= ~0x3ff; + ANA->LP_DLY_CTRL_3V |= 7; + + /* Insure we are going to enter hw standby mode 1 */ + LP_SetSleepMode(ANA, LP_MODE_SEL_STANDBY_M0_MODE); + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + + /* Trigger 3v sync */ + ANA->LP_REG_SYNC |= ANAC_LP_REG_SYNC_3V_Msk | ANAC_LP_REG_SYNC_3V_TRG_Msk; + + /* Disable SLPTMR interrupt and wakeup in lp mode (Only enable LP interrupt) */ + ANA->LP_INT_CTRL = ANAC_INT_LP_INT_EN_Msk; + // Clear configured time of sleep timers + ANA->LP_SPACING_TIME0 = 0; + ANA->LP_SPACING_TIME1 = 0; + ANA->LP_SPACING_TIME2 = 0; + + /* Clear all lowpower related int flags if any */ + ANA->LP_INT_CTRL = ANA->LP_INT_CTRL; +#if 0 + /* Reset all hw peripheral modules except eFuse and GPIO */ + CLK->IPRST0 = 0x1CC; + CLK->IPRST0 = 0x0; + CLK->IPRST1 = 0x17FFF; + CLK->IPRST1 = 0x0; +#endif + /* Disable all IRQs and clear all pending IRQs on NVIC */ + NVIC->ICER[0U] = 0xFFFFFFFF; + NVIC->ICPR[0U] = 0xFFFFFFFF; + + /* Wait until 3v sync done */ + while (ANA->LP_REG_SYNC & (ANAC_LP_REG_SYNC_3V_TRG_Msk)) { + __NOP(); + } + + /* Trigger hw to enter low power mode */ + __WFI(); + + /* + * ======== (Now SoC is expected in HW Standby Mode 0 and would never return back here) ========= + */ } -- Gitblit v1.9.3