diff --git a/src/W800_SDK_v1.00.10/app/app_drivers/watch_power_management/watch_power_management.c b/src/W800_SDK_v1.00.10/app/app_drivers/watch_power_management/watch_power_management.c index dd961db..550c417 100644 --- a/src/W800_SDK_v1.00.10/app/app_drivers/watch_power_management/watch_power_management.c +++ b/src/W800_SDK_v1.00.10/app/app_drivers/watch_power_management/watch_power_management.c @@ -1,10 +1,106 @@ /** * @file watch_power_management.h * @author Anatole SCHRAMM-HENRY - * @brief Watch power management functions API header file + * @brief Watch power management functions API source file * @version 0.1 * @date 2023-10-12 * * @copyright MIT * - */ \ No newline at end of file + */ + +#include "watch_power_management.h" +#include "app_common.h" +#include "lv_port_tick.h" + +static struct +{ + watch_power_state_e current_power_state; + enum CPU_CLK cpu_clock_idle; + enum CPU_CLK cpu_clock_full_speed; +} _watch_power_management = { + .current_power_state = WATCH_POWER_STATE_FULL_SPEED, + .cpu_clock_idle = CPU_CLK_80M, + .cpu_clock_full_speed = CPU_CLK_160M, + }; + +/** + * @brief Helper function to change the CPU clock of the micro. + * Internally checks that the new clock is different to the current one. + * + * @param cpu_clock the new frequency to apply @ref enum CPU_CLK + */ +static void _set_cpu_clock(enum CPU_CLK cpu_clock); + +static enum CPU_CLK _cpu_frequency_to_CPU_CLK(uint32_t frequency); + +static uint32_t _CPU_CLK_to_cpu_frequency(enum CPU_CLK cpu_clock); + +void watch_power_management_change_power_state(watch_power_state_e power_state) +{ + // If we are already in this power state, then there is nothing more to do. + if(power_state == _watch_power_management.current_power_state) return; + + switch (power_state) + { + case WATCH_POWER_STATE_IDLE: + // We set the CPU clock to the value defined for the IDLE state + _set_cpu_clock(_watch_power_management.cpu_clock_idle); + break; + case WATCH_POWER_STATE_FULL_SPEED: + // We set the CPU clock to the value defined for the FULL SPEED state + _set_cpu_clock(_watch_power_management.cpu_clock_full_speed); + break; + case WATCH_POWER_STATE_SLEEP: + break; + case WATCH_POWER_STATE_BLE_SLEEP: + APP_LOG_INFO("Entering BLE sleep mode"); + // We set the CPU clock to 40MHz (can't go lower or the BLE radio will stop working) + _set_cpu_clock(CPU_CLK_40M); + // We can stop the lvgl timer + APP_LOG_INFO("Stopping LVGL tick timer"); + lv_port_tick_stop(); + break; + case WACTH_POWER_STATE_STANDBY: + default: + break; + } + + // Let's apply the new power state + _watch_power_management.current_power_state = power_state; +} + +watch_power_state_e watch_power_management_get_current_power_state(void) +{ + return _watch_power_management.current_power_state; +} + +bool watch_power_management_check_current_power_state_is(watch_power_state_e power_state) +{ + return power_state == _watch_power_management.current_power_state; +} + +static void _set_cpu_clock(enum CPU_CLK cpu_clock) +{ + // First let's get the current clock speed + tls_sys_clk clk; + tls_sys_clk_get(&clk); + + // If the current clock is different from the clock we want to apply : + if(_cpu_frequency_to_CPU_CLK(clk.cpuclk) != cpu_clock) + { + tls_sys_clk_set(cpu_clock); + APP_LOG_INFO("New CPU frequency : %u MHz", _CPU_CLK_to_cpu_frequency(cpu_clock)); + } +} + +static enum CPU_CLK _cpu_frequency_to_CPU_CLK(uint32_t frequency) +{ + return W800_PLL_CLK_MHZ / frequency; +} + +static uint32_t _CPU_CLK_to_cpu_frequency(enum CPU_CLK cpu_clock) +{ + return W800_PLL_CLK_MHZ / cpu_clock; +} + \ No newline at end of file diff --git a/src/W800_SDK_v1.00.10/app/app_drivers/watch_power_management/watch_power_management.h b/src/W800_SDK_v1.00.10/app/app_drivers/watch_power_management/watch_power_management.h index 16653e9..fb51690 100644 --- a/src/W800_SDK_v1.00.10/app/app_drivers/watch_power_management/watch_power_management.h +++ b/src/W800_SDK_v1.00.10/app/app_drivers/watch_power_management/watch_power_management.h @@ -12,6 +12,9 @@ #ifndef WATCH_POWER_MANAGEMENT_H #define WATCH_POWER_MANAGEMENT_H +#include "wm_type_def.h" +#include "wm_cpu.h" + typedef enum watch_power_state { /** @@ -47,9 +50,10 @@ typedef enum watch_power_state WACTH_POWER_STATE_STANDBY, } watch_power_state_e; -typedef struct watch_power_management -{ - watch_power_state_e current_power_state; -} watch_power_management_t; +void watch_power_management_change_power_state(watch_power_state_e power_state); + +watch_power_state_e watch_power_management_get_current_power_state(void); + +bool watch_power_management_check_current_power_state_is(watch_power_state_e power_state); #endif //WATCH_POWER_MANAGEMENT_H \ No newline at end of file