diff --git a/drivers/bl702_driver/hal_drv/inc/hal_pm.h b/drivers/bl702_driver/hal_drv/inc/hal_pm.h index 5f4bd1fd..24b892d7 100644 --- a/drivers/bl702_driver/hal_drv/inc/hal_pm.h +++ b/drivers/bl702_driver/hal_drv/inc/hal_pm.h @@ -24,7 +24,7 @@ #define __HAL_PM__H__ #ifdef __cplusplus -extern "C"{ +extern "C" { #endif #include "hal_common.h" @@ -38,7 +38,7 @@ enum pm_pds_sleep_level { PM_PDS_LEVEL_5, /*do not recommend to use*/ PM_PDS_LEVEL_6, /*do not recommend to use*/ PM_PDS_LEVEL_7, /*do not recommend to use*/ - PM_PDS_LEVEL_31, + PM_PDS_LEVEL_31 = 31, }; enum pm_hbn_sleep_level { @@ -57,16 +57,15 @@ enum pm_event_type { PM_HBN_ACOMP1_WAKEUP_EVENT, }; -void pm_pds_mode_enter(enum pm_pds_sleep_level pds_level, uint8_t sleep_time); +void pm_pds_mode_enter(enum pm_pds_sleep_level pds_level, uint32_t sleep_time); void pm_hbn_mode_enter(enum pm_hbn_sleep_level hbn_level, uint8_t sleep_time); -void pm_hbn_set_wakeup_callback(void (*wakeup_callback)(void)); +void pm_set_wakeup_callback(void (*wakeup_callback)(void)); void pm_hbn_enter_again(bool reset); void pm_hbn_out0_irq_register(void); void pm_hbn_out1_irq_register(void); void pm_irq_callback(enum pm_event_type event); -uint32_t hal_pds_enter_with_time_compensation(uint32_t pdsLevel, uint32_t pdsSleepCycles); #ifdef __cplusplus } #endif -#endif +#endif \ No newline at end of file diff --git a/drivers/bl702_driver/hal_drv/inc/hal_pm_util.h b/drivers/bl702_driver/hal_drv/inc/hal_pm_util.h new file mode 100644 index 00000000..1fd923bc --- /dev/null +++ b/drivers/bl702_driver/hal_drv/inc/hal_pm_util.h @@ -0,0 +1,35 @@ +/** + * @file hal_pm_util.h + * @brief + * + * Copyright (c) 2021 Bouffalolab team + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + */ +#ifndef __HAL_PM_UTIL_H__ +#define __HAL_PM_UTIL_H__ + +#include "hal_common.h" + +#define ATTR_PDS_RAM_SECTION __attribute__((section(".pds_ram_code"))) +#define ATTR_PDS_RAM_CONST_SECTION __attribute__((section(".pds_ram_data"))) + +uint32_t hal_pds_enter_with_time_compensation(uint32_t pdsLevel, uint32_t pdsSleepCycles); +void pm_set_tcm_recovery_callback(void (*tcm_recovery_cb)(void)); +void pm_set_board_recovery_callback(void (*board_recovery_cb)(void)); + +#endif \ No newline at end of file diff --git a/drivers/bl702_driver/hal_drv/src/hal_pm.c b/drivers/bl702_driver/hal_drv/src/hal_pm.c index 64db3328..f165514e 100644 --- a/drivers/bl702_driver/hal_drv/src/hal_pm.c +++ b/drivers/bl702_driver/hal_drv/src/hal_pm.c @@ -26,8 +26,19 @@ #include "hal_clock.h" #include "hal_rtc.h" #include "hal_flash.h" -#include "hal_common.h" +/* Cache Way Disable, will get from l1c register */ +uint8_t cacheWayDisable = 0; + +/* PSRAM IO Configuration, will get from glb register */ +uint32_t psramIoCfg = 0; + +/* Flash offset value, will get from sf_ctrl register */ +uint32_t flash_offset = 0; + +SPI_Flash_Cfg_Type *flash_cfg; + +#define PM_PDS_GPIO_IE_PUPD 0 #define PM_PDS_FLASH_POWER_OFF 1 #define PM_PDS_DLL_POWER_OFF 1 #define PM_PDS_PLL_POWER_OFF 1 @@ -845,6 +856,19 @@ static ATTR_TCM_SECTION void PDS_Update_Flash_Ctrl_Setting(uint8_t fastClock) SF_Ctrl_Set_Clock_Delay(fastClock); } + +ATTR_TCM_SECTION void pm_pds_enter_done(bool store_flag) +{ + if (store_flag) { + __asm__ __volatile__( + "la a2, __ld_pds_bak_addr\n\t" + "sw ra, 0(a2)\n\t"); + } + + BL702_Delay_MS(1); + + __WFI(); /* if(.wfiMask==0){CPU won't power down until PDS module had seen __wfi} */ +} /** * @brief power management in pds(power down sleep) mode * @@ -861,13 +885,29 @@ static ATTR_TCM_SECTION void PDS_Update_Flash_Ctrl_Setting(uint8_t fastClock) * PDS7 ON ON ON OFF OFF OFF * PDS31 ON OFF OFF OFF OFF OFF */ -ATTR_TCM_SECTION void pm_pds_mode_enter(enum pm_pds_sleep_level pds_level, uint8_t sleep_time) +ATTR_TCM_SECTION void pm_pds_mode_enter(enum pm_pds_sleep_level pds_level, uint32_t sleep_time) { + bool store_flag = 0; PDS_DEFAULT_LV_CFG_Type *pPdsCfg = NULL; uint32_t tmpVal; - SPI_Flash_Cfg_Type *flash_cfg; uint32_t flash_cfg_len; + if (HBN_STATUS_ENTER_FLAG == BL_RD_REG(HBN_BASE, HBN_RSV0)) { + store_flag = 1; + + // Get cache way disable setting + cacheWayDisable = (*(volatile uint32_t *)(L1C_BASE + 0x00) >> 8) & 0x0F; + + // Get psram io configuration + psramIoCfg = *(volatile uint32_t *)(GLB_BASE + 0x88); + + // Get flash offset + flash_offset = BL_RD_REG(SF_CTRL_BASE, SF_CTRL_SF_ID0_OFFSET); + + } else { + store_flag = 0; + } + /* To make it simple and safe*/ cpu_global_irq_disable(); @@ -954,7 +994,7 @@ ATTR_TCM_SECTION void pm_pds_mode_enter(enum pm_pds_sleep_level pds_level, uint8 /* pds31 : ldo11rt_iload_sel=1 */ if ((pds_level >= 0) && (pds_level <= 7)) { HBN_Set_Ldo11rt_Drive_Strength(HBN_LDO11RT_DRIVE_STRENGTH_25_250UA); - } else if (pds_level == 31) { + } else if (pds_level == PM_PDS_LEVEL_31) { HBN_Set_Ldo11rt_Drive_Strength(HBN_LDO11RT_DRIVE_STRENGTH_10_100UA); } else { /* pdsLevel error */ @@ -963,14 +1003,52 @@ ATTR_TCM_SECTION void pm_pds_mode_enter(enum pm_pds_sleep_level pds_level, uint8 pPdsCfg->pdsCtl.pdsLdoVol = PM_PDS_LDO_LEVEL_DEFAULT; pPdsCfg->pdsCtl.pdsLdoVselEn = 1; +#if PM_PDS_GPIO_IE_PUPD == 0 + pPdsCfg->pdsCtl.gpioIePuPd = 0; +#endif + #if PM_PDS_RF_POWER_OFF == 0 pPdsCfg->pdsCtl.pdsCtlRfSel = 0; #endif /* config ldo11soc_sstart_delay_aon =2 , cr_pds_pd_ldo11=0 to speedup ldo11soc_rdy_aon */ AON_Set_LDO11_SOC_Sstart_Delay(0x2); - PDS_Default_Level_Config(pPdsCfg, sleep_time * 32768); - __WFI(); /* if(.wfiMask==0){CPU won't power down until PDS module had seen __wfi} */ + PDS_Default_Level_Config(pPdsCfg, sleep_time); + if (store_flag) { + __asm__ __volatile__( + "csrr a0, mtvec\n\t" + "csrr a1, mstatus\n\t" + "la a2, __ld_pds_bak_addr\n\t" + "sw sp, 1*4(a2)\n\t" + "sw tp, 2*4(a2)\n\t" + "sw t0, 3*4(a2)\n\t" + "sw t1, 4*4(a2)\n\t" + "sw t2, 5*4(a2)\n\t" + "sw fp, 6*4(a2)\n\t" + "sw s1, 7*4(a2)\n\t" + "sw a0, 8*4(a2)\n\t" + "sw a1, 9*4(a2)\n\t" + "sw a3, 10*4(a2)\n\t" + "sw a4, 11*4(a2)\n\t" + "sw a5, 12*4(a2)\n\t" + "sw a6, 13*4(a2)\n\t" + "sw a7, 14*4(a2)\n\t" + "sw s2, 15*4(a2)\n\t" + "sw s3, 16*4(a2)\n\t" + "sw s4, 17*4(a2)\n\t" + "sw s5, 18*4(a2)\n\t" + "sw s6, 19*4(a2)\n\t" + "sw s7, 20*4(a2)\n\t" + "sw s8, 21*4(a2)\n\t" + "sw s9, 22*4(a2)\n\t" + "sw s10, 23*4(a2)\n\t" + "sw s11, 24*4(a2)\n\t" + "sw t3, 25*4(a2)\n\t" + "sw t4, 26*4(a2)\n\t" + "sw t5, 27*4(a2)\n\t" + "sw t6, 28*4(a2)\n\t"); + } + pm_pds_enter_done(store_flag); #if PM_PDS_PLL_POWER_OFF GLB_Set_System_CLK(XTAL_TYPE, BSP_ROOT_CLOCK_SOURCE); @@ -978,15 +1056,26 @@ ATTR_TCM_SECTION void pm_pds_mode_enter(enum pm_pds_sleep_level pds_level, uint8 #endif #if PM_PDS_FLASH_POWER_OFF - HBN_Set_Pad_23_28_Pullnone(); - /* Init flash gpio */ - SF_Cfg_Init_Flash_Gpio(0, 1); + if (pds_level < PM_PDS_LEVEL_4) { + HBN_Set_Pad_23_28_Pullnone(); + /* Init flash gpio */ + SF_Cfg_Init_Flash_Gpio(0, 1); - SF_Ctrl_Set_Owner(SF_CTRL_OWNER_SAHB); - SFlash_Restore_From_Powerdown(flash_cfg, 0); + SF_Ctrl_Set_Owner(SF_CTRL_OWNER_SAHB); + SFlash_Restore_From_Powerdown(flash_cfg, 0); + } #endif cpu_global_irq_enable(); + + if (store_flag) { + // Get cache way disable setting + *(volatile uint32_t *)(L1C_BASE + 0x00) &= ~(0x0F < 8); + *(volatile uint32_t *)(L1C_BASE + 0x00) |= cacheWayDisable; + + // Get psram io configuration + *(volatile uint32_t *)(GLB_BASE + 0x88) = psramIoCfg; + } } /** * @brief @@ -1080,9 +1169,11 @@ ATTR_TCM_SECTION void pm_hbn_mode_enter(enum pm_hbn_sleep_level hbn_level, uint8 } } -void pm_hbn_set_wakeup_callback(void (*wakeup_callback)(void)) +void pm_set_wakeup_callback(void (*wakeup_callback)(void)) { BL_WR_REG(HBN_BASE, HBN_RSV1, (uint32_t)wakeup_callback); + /* Set HBN flag */ + BL_WR_REG(HBN_BASE, HBN_RSV0, HBN_STATUS_ENTER_FLAG); } ATTR_HBN_RAM_SECTION void pm_hbn_enter_again(bool reset) @@ -1167,35 +1258,3 @@ void HBN_OUT1_IRQ(void) __WEAK void pm_irq_callback(enum pm_event_type event) { } -/** - * @brief hal_pds_enter_with_time_compensation - * - * @param pdsLevel pds level support 0~3,31 - * @param pdsSleepCycles if user set sleep time, pdsSleepCycles cannot be less than 32768, pdsSleepCycles is a multiple of 32768 preferably. - * @return uint32_t actual sleep time(ms) - * - * @note If necessary,please application layer call vTaskStepTick, - */ -uint32_t hal_pds_enter_with_time_compensation(uint32_t pdsLevel, uint32_t pdsSleepCycles) -{ - uint32_t rtcLowBeforeSleep = 0, rtcHighBeforeSleep = 0; - uint32_t rtcLowAfterSleep = 0, rtcHighAfterSleep = 0; - uint32_t actualSleepDuration_32768cycles = 0; - uint32_t actualSleepDuration_ms = 0; - - HBN_Get_RTC_Timer_Val(&rtcLowBeforeSleep, &rtcHighBeforeSleep); - - pm_pds_mode_enter(pdsLevel, pdsSleepCycles / 32768); - - HBN_Get_RTC_Timer_Val(&rtcLowAfterSleep, &rtcHighAfterSleep); - - CHECK_PARAM((rtcHighAfterSleep - rtcHighBeforeSleep) <= 1); // make sure sleep less than 1 hour (2^32 us > 1 hour) - - actualSleepDuration_32768cycles = (rtcLowAfterSleep - rtcLowBeforeSleep); - - actualSleepDuration_ms = (actualSleepDuration_32768cycles >> 5) - (actualSleepDuration_32768cycles >> 11) - (actualSleepDuration_32768cycles >> 12); - - // vTaskStepTick(actualSleepDuration_ms); - - return actualSleepDuration_ms; -} diff --git a/drivers/bl702_driver/hal_drv/src/hal_pm_util.c b/drivers/bl702_driver/hal_drv/src/hal_pm_util.c new file mode 100644 index 00000000..45c9d6cc --- /dev/null +++ b/drivers/bl702_driver/hal_drv/src/hal_pm_util.c @@ -0,0 +1,291 @@ +/** + * @file hal_pm_util.c + * @brief + * + * Copyright (c) 2021 Bouffalolab team + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + */ + +#include "bl702_romdriver.h" +#include "bl702_sf_ctrl.h" +#include "hal_pm.h" +#include "hal_pm_util.h" + +/* Cache Way Disable, will get from l1c register */ +extern uint8_t cacheWayDisable; + +/* PSRAM IO Configuration, will get from glb register */ +extern uint32_t psramIoCfg; + +/* Flash offset value, will get from sf_ctrl register */ +extern uint32_t flash_offset; + +extern SPI_Flash_Cfg_Type *flash_cfg; + +void ATTR_PDS_RAM_SECTION pm_pds_fastboot_entry(void); + +void (*tcm_recovery)(void) = NULL; +void (*board_recovery)(void) = NULL; + +/** + * @brief hal_pds_enter_with_time_compensation + * + * @param pdsLevel pds level support 0~3,31 + * @param pdsSleepCycles user set sleep time, clock of pds_time is 32768hz + * @return uint32_t actual sleep time(ms) + * + * @note If necessary,please application layer call vTaskStepTick, + */ +uint32_t hal_pds_enter_with_time_compensation(uint32_t pdsLevel, uint32_t pdsSleepCycles) +{ + uint32_t rtcLowBeforeSleep = 0, rtcHighBeforeSleep = 0; + uint32_t rtcLowAfterSleep = 0, rtcHighAfterSleep = 0; + uint32_t actualSleepDuration_32768cycles = 0; + uint32_t actualSleepDuration_ms = 0; + + if (pdsLevel >= 4 && HBN_Get_Status_Flag() != HBN_STATUS_ENTER_FLAG) { + pm_set_wakeup_callback(pm_pds_fastboot_entry); + } + HBN_Get_RTC_Timer_Val(&rtcLowBeforeSleep, &rtcHighBeforeSleep); + + pm_pds_mode_enter(pdsLevel, pdsSleepCycles); + + HBN_Get_RTC_Timer_Val(&rtcLowAfterSleep, &rtcHighAfterSleep); + + CHECK_PARAM((rtcHighAfterSleep - rtcHighBeforeSleep) <= 1); // make sure sleep less than 1 hour (2^32 us > 1 hour) + + actualSleepDuration_32768cycles = (rtcLowAfterSleep - rtcLowBeforeSleep); + + actualSleepDuration_ms = (actualSleepDuration_32768cycles >> 5) - (actualSleepDuration_32768cycles >> 11) - (actualSleepDuration_32768cycles >> 12); + + // vTaskStepTick(actualSleepDuration_ms); + + return actualSleepDuration_ms; +} +/** + * @brief get delay value of spi flash init + * + * @param delay_index + * @return uint8_t + */ +static uint8_t ATTR_PDS_RAM_SECTION bflb_spi_flash_get_delay_val(uint8_t delay_index) +{ + switch (delay_index) { + case 0: + return 0x00; + case 1: + return 0x80; + case 2: + return 0xc0; + case 3: + return 0xe0; + case 4: + return 0xf0; + case 5: + return 0xf8; + case 6: + return 0xfc; + case 7: + return 0xfe; + default: + return 0x00; + } +} +/** + * @brief config spi flash + * + * @param pFlashCfg flash parameter + */ +static void ATTR_PDS_RAM_SECTION bflb_spi_flash_set_sf_ctrl(SPI_Flash_Cfg_Type *pFlashCfg) +{ + SF_Ctrl_Cfg_Type sfCtrlCfg; + uint8_t delay_index; + + sfCtrlCfg.owner = SF_CTRL_OWNER_SAHB; + + /* bit0-3 for clk delay */ + sfCtrlCfg.clkDelay = (pFlashCfg->clkDelay & 0x0f); + /* bit0 for clk invert */ + sfCtrlCfg.clkInvert = pFlashCfg->clkInvert & 0x01; + /* bit1 for rx clk invert */ + sfCtrlCfg.rxClkInvert = (pFlashCfg->clkInvert >> 1) & 0x01; + /* bit4-6 for do delay */ + delay_index = (pFlashCfg->clkDelay >> 4) & 0x07; + sfCtrlCfg.doDelay = bflb_spi_flash_get_delay_val(delay_index); + /* bit2-4 for di delay */ + delay_index = (pFlashCfg->clkInvert >> 2) & 0x07; + sfCtrlCfg.diDelay = bflb_spi_flash_get_delay_val(delay_index); + /* bit5-7 for oe delay */ + delay_index = (pFlashCfg->clkInvert >> 5) & 0x07; + sfCtrlCfg.oeDelay = bflb_spi_flash_get_delay_val(delay_index); + + RomDriver_SFlash_Init(&sfCtrlCfg); +} + +/** + * @brief + * + * @param media_boot + * @return int32_t + */ +int32_t ATTR_PDS_RAM_SECTION pm_spi_flash_init(uint8_t media_boot) +{ + uint32_t stat; + uint32_t jdecId = 0; + uint32_t flash_read_try = 0; + + /*use fclk as flash clok */ + RomDriver_GLB_Set_SF_CLK(1, GLB_SFLASH_CLK_BCLK, 0); // 32M + + bflb_spi_flash_set_sf_ctrl(flash_cfg); + + /* Wake flash up from power down */ + RomDriver_SFlash_Releae_Powerdown(flash_cfg); + //ARCH_Delay_US(15*((pFlashCfg->pdDelay&0x7)+1)); + RomDriver_BL702_Delay_US(120); + + do { + if (flash_read_try > 4) { + // bflb_bootrom_printd("Flash read id TO\r\n"); + break; + } else if (flash_read_try > 0) { + RomDriver_BL702_Delay_US(500); + } + + // bflb_bootrom_printd("reset flash\r\n"); + /* Exit form continous read for accepting command */ + RomDriver_SFlash_Reset_Continue_Read(flash_cfg); + /* Send software reset command(80bv has no this command)to deburst wrap for ISSI like */ + RomDriver_SFlash_Software_Reset(flash_cfg); + /* Disable burst may be removed(except for 80BV) and only work with winbond,but just for make sure */ + RomDriver_SFlash_Write_Enable(flash_cfg); + /* For disable command that is setting register instaed of send command, we need write enable */ + RomDriver_SFlash_DisableBurstWrap(flash_cfg); + + stat = RomDriver_SFlash_SetSPIMode(SF_CTRL_SPI_MODE); + if (SUCCESS != stat) { + // bflb_bootrom_printe("enter spi mode fail %d\r\n", stat); + // return BFLB_BOOTROM_FLASH_INIT_ERROR; + return -1; + } + + RomDriver_SFlash_GetJedecId(flash_cfg, (uint8_t *)&jdecId); + + /* Dummy disable burstwrap for make sure */ + RomDriver_SFlash_Write_Enable(flash_cfg); + /* For disable command that is setting register instead of send command, we need write enable */ + RomDriver_SFlash_DisableBurstWrap(flash_cfg); + + jdecId = jdecId & 0xffffff; + // bflb_bootrom_printd("ID =%08x\r\n", jdecId); + flash_read_try++; + } while ((jdecId & 0x00ffff) == 0 || (jdecId & 0xffff00) == 0 || (jdecId & 0x00ffff) == 0xffff || (jdecId & 0xffff00) == 0xffff00); + + /*clear offset setting*/ + + // reset image offset + BL_WR_REG(SF_CTRL_BASE, SF_CTRL_SF_ID0_OFFSET, flash_offset); + + /* set read mode */ + if ((flash_cfg->ioMode & 0x0f) == SF_CTRL_QO_MODE || (flash_cfg->ioMode & 0x0f) == SF_CTRL_QIO_MODE) { + stat = RomDriver_SFlash_Qspi_Enable(flash_cfg); + } + + if (media_boot) { + RomDriver_L1C_Set_Wrap(DISABLE); + + RomDriver_SFlash_Cache_Read_Enable(flash_cfg, flash_cfg->ioMode & 0xf, 0, 0x00); + } + + return jdecId; +} + +// can be placed in flash, here placed in pds section to reduce fast boot time +static void ATTR_PDS_RAM_SECTION pm_pds_restore_cpu_reg(void) +{ + __asm__ __volatile__( + "la a2, __ld_pds_bak_addr\n\t" + "lw ra, 0(a2)\n\t" + "lw sp, 1*4(a2)\n\t" + "lw tp, 2*4(a2)\n\t" + "lw t0, 3*4(a2)\n\t" + "lw t1, 4*4(a2)\n\t" + "lw t2, 5*4(a2)\n\t" + "lw fp, 6*4(a2)\n\t" + "lw s1, 7*4(a2)\n\t" + "lw a0, 8*4(a2)\n\t" + "lw a1, 9*4(a2)\n\t" + "lw a3, 10*4(a2)\n\t" + "lw a4, 11*4(a2)\n\t" + "lw a5, 12*4(a2)\n\t" + "lw a6, 13*4(a2)\n\t" + "lw a7, 14*4(a2)\n\t" + "lw s2, 15*4(a2)\n\t" + "lw s3, 16*4(a2)\n\t" + "lw s4, 17*4(a2)\n\t" + "lw s5, 18*4(a2)\n\t" + "lw s6, 19*4(a2)\n\t" + "lw s7, 20*4(a2)\n\t" + "lw s8, 21*4(a2)\n\t" + "lw s9, 22*4(a2)\n\t" + "lw s10, 23*4(a2)\n\t" + "lw s11, 24*4(a2)\n\t" + "lw t3, 25*4(a2)\n\t" + "lw t4, 26*4(a2)\n\t" + "lw t5, 27*4(a2)\n\t" + "lw t6, 28*4(a2)\n\t" + "csrw mtvec, a0\n\t" + "csrw mstatus,a1\n\t" + "ret\n\t"); +} + +// must be placed in pds section +void ATTR_PDS_RAM_SECTION pm_pds_fastboot_entry(void) +{ + // reload gp register + __asm__ __volatile__( + ".option push\n\t" + ".option norelax\n\t" + "la gp, __global_pointer$\n\t" + ".option pop\n\t"); + + // recovery flash pad and param + RomDriver_SF_Cfg_Init_Flash_Gpio(0, 1); + pm_spi_flash_init(1); + + // Restore tcm code + if (tcm_recovery) + tcm_recovery(); + + // Recovery gpio and clock + if (board_recovery) + board_recovery(); + + // Restore cpu registers + pm_pds_restore_cpu_reg(); +} + +void pm_set_tcm_recovery_callback(void (*tcm_recovery_cb)(void)) +{ + tcm_recovery = tcm_recovery_cb; +} + +void pm_set_board_recovery_callback(void (*board_recovery_cb)(void)) +{ + board_recovery = board_recovery_cb; +} \ No newline at end of file diff --git a/examples/pm/hbn_mode_wakeup/main.c b/examples/pm/hbn_mode_wakeup/main.c index 9bf31138..2f2df736 100644 --- a/examples/pm/hbn_mode_wakeup/main.c +++ b/examples/pm/hbn_mode_wakeup/main.c @@ -123,7 +123,7 @@ int hbn_run_in_wakeup_addr(int argc, char *argv[]) /*cpu will wakeup when you set gpio9-gpio12 with GPIO_FUN_WAKEUP * rtc can not wakeup level2 **/ - pm_hbn_set_wakeup_callback(led_blink); /*cpu will run in wakeup callback not reset when it awakes*/ + pm_set_wakeup_callback(led_blink); /*cpu will run in wakeup callback not reset when it awakes*/ pm_hbn_mode_enter(PM_HBN_LEVEL_0, 0); return 0;