From 5102fff8a13c0319d8125a51d3d2354e7aacdcea Mon Sep 17 00:00:00 2001 From: chen <15335560115@163.com> Date: 星期四, 31 七月 2025 16:40:06 +0800 Subject: [PATCH] 修改为2HZ发poll包,修改second task从原来2s一次为1s一次 --- keil/include/drivers/mk_power.c | 286 +++++++++++++++++++++++++++++--------------------------- 1 files changed, 148 insertions(+), 138 deletions(-) diff --git a/keil/include/drivers/mk_power.c b/keil/include/drivers/mk_power.c index d5f84b8..48bc6c6 100644 --- a/keil/include/drivers/mk_power.c +++ b/keil/include/drivers/mk_power.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019-2023 Beijing Hanwei Innovation Technology Ltd. Co. and + * Copyright (c) 2019-2025 Beijing Hanwei Innovation Technology Ltd. Co. and * its subsidiaries and affiliates (collectly called MKSEMI). * * All rights reserved. @@ -47,13 +47,12 @@ #include "mk_gpio.h" #include "mk_reset.h" #include "mk_misc.h" -#ifdef WSF_EN -#include "wsf_timer.h" -#endif #ifdef UWB_EN #include "mk_uwb.h" -#include "mk_sleep_timer.h" +#include "mk_timer_list.h" #endif + +#include "board.h" /* UCI SPI full-duplex handshake interface */ #ifndef UCI_INTF_SPI_FD_HS @@ -77,24 +76,33 @@ #include "mk_i2c.h" #endif -#ifndef LOW_POWER_CLOCK_PPM -#define LOW_POWER_CLOCK_PPM (50) -#endif - #ifndef SYS_CLK_SOURCE #define SYS_CLK_SOURCE CLOCK_62P4M_XTAL38P4M_TO_SYS_CLK #endif -// Including 38.4MHz clock PLL ready time and application recovery time, unit: us -#define RECOVERY_TIME_FROM_LOW_POWER (1000) +/** XTAL32K clock source ppm */ +#ifndef LOW_POWER_CLOCK_PPM +#define LOW_POWER_CLOCK_PPM (100) +#endif -// Considering 32KHz clock ppm and sleep time, x = sleep time (us), the result should < PHY_SLEEP_TIME_US_MIN -#define WAKEUP_IN_ADVANCE_TIME(x) (RECOVERY_TIME_FROM_LOW_POWER + (x)*LOW_POWER_CLOCK_PPM / 1000000) +/** RCO32K clock source ppm */ +#ifndef LOW_POWER_CLOCK_PPM_RCO +#define LOW_POWER_CLOCK_PPM_RCO (1000) +#endif + +// Including 38.4MHz clock PLL ready time and application recovery time, unit: 32768Hz tick. 32tick ~= 1ms +#define RECOVERY_TIME_FROM_LOW_POWER (32) + +// Considering 32KHz clock ppm and power down time, x = low power ticks to power down ( unit: 32768 tick) +#define WAKEUP_IN_ADVANCE_TIME(x) \ + (RECOVERY_TIME_FROM_LOW_POWER + (x) * ((SYSCON->SYS_CMU & SYSCON_SYS_CMU_32K_CLK_SEL_MSK) ? LOW_POWER_CLOCK_PPM : LOW_POWER_CLOCK_PPM_RCO) / 1000000) #ifdef UWB_EN extern uint32_t slp_cnt; uint32_t slp_cnt = 0; #endif + +extern void mk_timer_start(uint32_t ticks); extern void board_prepare_for_power_down(void); extern void board_restore_from_power_down(void); @@ -130,8 +138,8 @@ } else { - // enable PMU, disable Xtal32k - SYSCON->PMU_CTRL0 |= (1U << 31) | (1 << 7); + // enable PMU + SYSCON->PMU_CTRL0 |= (1U << 31); } // DG REF from LP_BG @@ -140,18 +148,31 @@ // fix high temperature wakeup fail issue SYSCON->IVREF_ULP = 0x20000; -#if DCDC_EN - // DC-DC enable +#if POWER_SUPPLY_MODE == PSM_DCDC_MODE + // Enable DC-DC SYSCON->SYS_CTRL &= ~(3U << 18); +#elif POWER_SUPPLY_MODE == PSM_CURRENT_LIMITER_MODE + // Configure current limiter +#if CURRENT_LIMITER_LVL == 2 // peak current < 9mA + uint32_t reg = SYSCON->BUCK & ~(3U << 4); + SYSCON->BUCK = reg | (2U << 4); +#elif CURRENT_LIMITER_LVL == 1 // peak current < 18mA + SYSCON->BUCK |= (3U << 4); +#endif + // Enable current limiter + SYSCON->SYS_CTRL &= ~(1U << 30); #endif - bor_close(); +#if defined(XIP_EN) && BOR_EN + bor_open(NULL); +#endif } void power_on_radio(uint8_t tx_en, uint8_t rx_en) { // board_led_on(BOARD_LED_1); uint32_t val; + // HW gate clock #if 0 // Clock on - TX | RX @@ -161,19 +182,25 @@ SYSCON->SYS_CMU = val; #endif + if (tx_en) + { + power_fem_tx_ctrl(1); + } + + if (rx_en) + { + // promote VDD core voltage to improve ranging performance + val = REG_READ(0x40000204) & ~0x3U; + REG_WRITE(0x40000204, val | board_param.vdd_core_vol); + + power_fem_rx_ctrl(1); + } + val = REG_READ(0x40000400); // Radio on REG_WRITE(0x40000400, val | 0x30000000); power_mode_request(POWER_UNIT_RF, POWER_MODE_SLEEP); - if (tx_en) - { - power_fem_tx_ctrl(1); - } - if (rx_en) - { - power_fem_rx_ctrl(1); - } // board_led_off(BOARD_LED_1); // LOG_INFO(TRACE_MODULE_DRIVER, "power on radio %x\r\n", SYSCON->SYS_CMU); } @@ -191,6 +218,9 @@ SYSCON->SYS_CMU &= ~((1U << CLOCK_RX) | (1U << CLOCK_TX)); #endif + val = REG_READ(0x40000204) & ~0x3U; + REG_WRITE(0x40000204, val | 0x1); + power_fem_tx_ctrl(0); power_fem_rx_ctrl(0); power_mode_clear(POWER_UNIT_RF); @@ -207,8 +237,7 @@ // LOG_INFO(TRACE_MODULE_DRIVER, "WFI SLEEP\r\n"); // Ensure we SLEEP - SLEEPDEEP should be clear - // SCR[2] = 0 - SCB->SCR &= ~(1UL << 2); + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; // Wait For Interrupt __WFI(); @@ -247,11 +276,14 @@ } #endif -void RAM_FUNC enter_power_down_in_ram(void); -void enter_power_down_in_ram(void) +void RAM_FUNC enter_power_down_in_ram(uint8_t deep_en); +void enter_power_down_in_ram(uint8_t deep_en) { uint32_t wakeup_en = 0; uint32_t wakeup_lvl = 0; + uint32_t cmu_backup = 0; + uint32_t pin_mux_backup = 0; + uint32_t io_dir_backup = 0; SYSCON->PMU_CTRL1 &= ~(1U << 16); @@ -262,14 +294,24 @@ NVIC_ClearPendingIRQ(WAKEUP_IRQn); NVIC_EnableIRQ(WAKEUP_IRQn); - // flash power down - by flash_close() + uint8_t val = REG_READ_BYTE(EFUSE_SHADOW_BASE + 0x67); + + // flash power down flash_power_down(FLASH_ID0); - uint8_t val = REG_READ_BYTE(EFUSE_SHADOW_BASE + 0x67); - if ((val & 0x80) == 0) + if ((val & 0x80) == 0) // internal flash { // switch to external flash io REG_WRITE_BYTE(EFUSE_SHADOW_BASE + 0x67, val | 0x80); + } + else // external flash (CSP) + { + // configure external flash pins as GPIO + pin_mux_backup = SYSCON->PIN_MUX_1; + SYSCON->PIN_MUX_1 = pin_mux_backup & 0xF000000F; + // configure external flash pins as input + io_dir_backup = SYSCON->IO_EI; + SYSCON->IO_EI = io_dir_backup | 0x7E00; } wakeup_en = SYSCON->WAKEUP_EN & SYSCON_WAKEUP_EN_IO_MSK; @@ -287,12 +329,31 @@ SYSCON->IO_SLP_PUP[0] = SYSCON->IO_PUP[0]; SYSCON->IO_SLP_PUP[1] = SYSCON->IO_PUP[1]; SYSCON->IO_SLP_PUP[2] = SYSCON->IO_PUP[2]; + // Check J-Link debug state + if (SYSCON->DUM_AO_HI & (1U << 31)) + { + SYSCON->IO_SLP_AEN |= (1U << 31); + } // reduce DG current 60% SYSCON->CAP_DIV_CFG = 0x0; - // Clock off - CALIB (retention) - SYSCON->SYS_CMU &= ~(1U << CLOCK_CALIB); + cmu_backup = SYSCON->SYS_CMU; + + if (deep_en) + { + // power off 32K in deep power down + SYSCON->PMU_CTRL1 |= (1U << 7) | (1U << 5); + // Clock off + SYSCON->SYS_CMU = cmu_backup & (0xFU << 28); + } + else + { + // keep 32k power on in power down mode + SYSCON->PMU_CTRL1 &= ~((1U << 7) | (1U << 5)); + // Clock off, except for RTC + SYSCON->SYS_CMU = cmu_backup & ((0xFU << 28) | (1U << CLOCK_RTC)); + } SYSCON->PMU_CTRL1 &= ~(1U << 17); @@ -301,16 +362,27 @@ SYSCON->PMU_CTRL1 |= (1U << 17); - // Clock on - CALIB - SYSCON->SYS_CMU |= (1U << CLOCK_CALIB); + // Clock restore + SYSCON->SYS_CMU = cmu_backup; - if ((val & 0x80) == 0) + SYSCON->CAP_DIV_CFG = 0x7; + + // Restore IO + GPIO->DATAOUT = SYSCON->IO_SLP_OUT; + GPIO->OUTENSET = SYSCON->IO_SLP_OE; + + SYSCON->IO_SLP_AEN &= ~(1U << 31); + + if ((val & 0x80) == 0) // internal flash { // switch to internal flash io REG_WRITE_BYTE(EFUSE_SHADOW_BASE + 0x67, val & 0x7f); } - - SYSCON->CAP_DIV_CFG = 0x7; + else // (CSP) + { + SYSCON->IO_EI = io_dir_backup; + SYSCON->PIN_MUX_1 = pin_mux_backup; + } // flash power up flash_power_up(FLASH_ID0); @@ -318,12 +390,6 @@ #ifdef XIP_EN flash_open_for_xip(FLASH_ID0); #endif - NVIC_DisableIRQ(WAKEUP_IRQn); - NVIC_ClearPendingIRQ(WAKEUP_IRQn); - - // Restore IO - GPIO->DATAOUT = SYSCON->IO_SLP_OUT; - GPIO->OUTENSET = SYSCON->IO_SLP_OE; #ifdef SWD_WAKEUP_EN // power_swd_restore(); @@ -337,7 +403,11 @@ GPIO->INTENSET = wakeup_en; } -#if DCDC_EN + // can not be called before XIP ready + NVIC_DisableIRQ(WAKEUP_IRQn); + NVIC_ClearPendingIRQ(WAKEUP_IRQn); + +#if POWER_SUPPLY_MODE != PSM_BYPASS_MODE // BUCK ready <50us while ((SYSCON->CLK_STATUS & 0x20) == 0) { @@ -363,7 +433,7 @@ SYSCON->PMU_CTRL1 |= (1U << 16); } -void power_enter_power_down_mode(bool deep_en) +void power_enter_power_down_mode(uint8_t deep_en) { // // WFI SLEEPDEEP @@ -382,31 +452,14 @@ mac_ccm_key.KEY_W3 = REG_READ(0x5000A08C); phy_timer_pause(); #endif - -#if SYS_TICK_EN - sys_tick_pause(); -#endif - // Ensure we SLEEPDEEP - SLEEPDEEP should be set - // SCR[2] = 1 - SCB->SCR |= (1U << 2); + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; - if (deep_en) - { - // power off 32K in deep power down - SYSCON->PMU_CTRL1 |= (1U << 7) | (1U << 5); - } - else - { - // keep 32k power on in power down mode - SYSCON->PMU_CTRL1 &= ~((1U << 7) | (1U << 5)); - } - - // switch system clock from XTAL to RO + // switch system clock from XTAL_38M4 to RO_48M clock_attach(CLOCK_48M_RO_TO_SYS_CLK); // for XIP - enter_power_down_in_ram(); + enter_power_down_in_ram(deep_en); #ifdef UWB_EN // TODO: restore uwb configuration @@ -422,15 +475,11 @@ // REFPLL - ON SYSCON->PMU_CTRL0 &= ~(1U << 10); - // switch system clock from RO to XTAL + // switch system clock from RO_48M to XTAL_38M4 clock_attach(SYS_CLK_SOURCE); #ifdef UWB_EN slp_cnt = phy_timer_resume(); -#endif - -#if SYS_TICK_EN - sys_tick_resume(); #endif board_restore_from_power_down(); @@ -566,7 +615,7 @@ { power_mode_request(POWER_UNIT_UART, POWER_MODE_SLEEP); } - else if (uart_fifo_busy(UART_ID0) || uart_fifo_busy(UART_ID1)) + else if (uart_is_busy(UART_ID0) || uart_is_busy(UART_ID1)) { power_mode_request(POWER_UNIT_UART, POWER_MODE_ACTIVE); } @@ -593,65 +642,35 @@ #endif } -#ifdef UWB_EN static void power_check_uwb_power_mode(void) { - enum POWER_MODE_T pm; - // check os timer - uint32_t os_time_ms = PHY_SLEEP_TIME_MS_MAX; - uint32_t phy_time_us = PHY_SLEEP_TIME_MS_MAX * 1000; +#if defined(UWB_EN) + enum POWER_MODE_T pm = POWER_MODE_SLEEP; -#ifdef WSF_EN - if (wsfOsReadyToSleep()) + // if power_check_if_power_mode() requests for sleep mode, abort checking here + if ((false == mac_is_busy()) && (power_env.power_request[POWER_MODE_SLEEP] == 0)) { - pm = WsfTimerSleepCheck(&os_time_ms); + uint32_t pd_tick = phy_timer_lp_tick_left(); - if (pm) + uint32_t pd_tick_os = mk_timer_list_tick_left(); + pd_tick = MIN(pd_tick, pd_tick_os); + + // make sure wakeup in advance, need to be corrected by 32K ppm + uint32_t wakeup_in_advance = WAKEUP_IN_ADVANCE_TIME(pd_tick); + if (pd_tick > wakeup_in_advance + POWER_DOWN_TIME_TICK_MIN) { -#endif - uint8_t busy = mac_is_busy(); - if (busy) - { - pm = POWER_MODE_SLEEP; - } - else - { - if (phy_timer_is_programmed()) - { - // check phy timer - uint32_t phy_time_tick = phy_timer_count_left(); - phy_time_us = PHY_TIMER_COUNT_TO_US(phy_time_tick); - } - - // sleep time - uint32_t sleep_time_us = MIN((uint32_t)(os_time_ms * 1000), (uint32_t)phy_time_us); - - if (sleep_time_us > PHY_SLEEP_TIME_US_MIN) - { - pm = POWER_MODE_POWER_DOWN; - // make sure wakeup in advance, need to correct by 32K ppm - sleep_time_us -= WAKEUP_IN_ADVANCE_TIME(sleep_time_us); - - uint32_t sleep_time_tick = __US_TO_32K_CNT(sleep_time_us); - - sleep_timer_start(sleep_time_tick); - } - else - { - pm = POWER_MODE_SLEEP; - } - } -#ifdef WSF_EN + pm = POWER_MODE_POWER_DOWN; + mk_timer_start(pd_tick - wakeup_in_advance); + } + else if (pd_tick == UINT32_MAX) + { + pm = POWER_MODE_DEEP_POWER_DOWN; } } - else - { - pm = POWER_MODE_ACTIVE; - } -#endif + power_mode_request(POWER_UNIT_UWB, pm); -} #endif +} void power_manage(void) { @@ -660,23 +679,14 @@ // check GPIO wakeup source power_check_io_power_mode(); + // check interface wakeup source + power_check_if_power_mode(); - if (power_env.power_request[POWER_MODE_ACTIVE]) + if (!power_env.power_request[POWER_MODE_ACTIVE]) { - // stay in active mode - } - else - { -#ifdef UWB_EN power_check_uwb_power_mode(); -#endif - power_check_if_power_mode(); - if (power_env.power_request[POWER_MODE_ACTIVE]) - { - // stay in active mode - } - else if (power_env.power_request[POWER_MODE_SLEEP]) + if (power_env.power_request[POWER_MODE_SLEEP]) { // enter sleep mode power_enter_sleep_mode(); @@ -702,13 +712,13 @@ power_enter_shelf_mode(); } - power_clear_if_power_mode(); #ifdef UWB_EN power_mode_clear(POWER_UNIT_UWB); #endif } - // uint32_t int_pending = REG_READ(0xE000E200); + power_clear_if_power_mode(); + int_unlock(lock); if (wakeup_from_power_down) -- Gitblit v1.9.3