From 01223bbf96a35dc6f4d1f52923e39c4460dcd93a Mon Sep 17 00:00:00 2001 From: Jean-Francois Penven Date: Tue, 9 Apr 2024 08:59:05 -0400 Subject: [PATCH] Revert "Refactors needed for M4 power save on SiWx917 (#177)" This reverts commit 0a40429a653e1fa70c69945d461944b32e5f92ec. --- .../BRD4338A/autogen/sl_event_handler.c | 4 +- .../BRD4338A/support/inc/sl_si91x_m4_ps.h | 68 ++++ .../BRD4338A/support/src/sl_si91x_m4_ps.c | 330 ++++++++++++++++++ 3 files changed, 400 insertions(+), 2 deletions(-) create mode 100644 matter/si91x/siwx917/BRD4338A/support/inc/sl_si91x_m4_ps.h create mode 100644 matter/si91x/siwx917/BRD4338A/support/src/sl_si91x_m4_ps.c diff --git a/matter/si91x/siwx917/BRD4338A/autogen/sl_event_handler.c b/matter/si91x/siwx917/BRD4338A/autogen/sl_event_handler.c index 40959485d2..21bf83014c 100644 --- a/matter/si91x/siwx917/BRD4338A/autogen/sl_event_handler.c +++ b/matter/si91x/siwx917/BRD4338A/autogen/sl_event_handler.c @@ -19,9 +19,9 @@ void sl_platform_init(void) { sli_si91x_platform_init(); RSI_Board_Init(); DEBUGINIT(); -#if SL_ICD_ENABLED +#if SL_ICD_ENABLED && !(defined(DISPLAY_ENABLED)) sl_si91x_hardware_setup(); -#endif // SL_ICD_ENABLED +#endif // SL_ICD_ENABLED && !(defined(DISPLAY_ENABLED) osKernelInitialize(); } diff --git a/matter/si91x/siwx917/BRD4338A/support/inc/sl_si91x_m4_ps.h b/matter/si91x/siwx917/BRD4338A/support/inc/sl_si91x_m4_ps.h new file mode 100644 index 0000000000..88f9846bd8 --- /dev/null +++ b/matter/si91x/siwx917/BRD4338A/support/inc/sl_si91x_m4_ps.h @@ -0,0 +1,68 @@ +/***************************************************************************** + * @file sl_si91x_m4_ps.h + * @brief M4 power save + ******************************************************************************* + * # License + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * The licenser of this software is Silicon Laboratories Inc. Your use of this + * software is governed by the terms of Silicon Labs Master Software License + * Agreement (MSLA) available at + * www.silabs.com/about-us/legal/master-software-license-agreement. This + * software is distributed to you in Source Code format and is governed by the + * sections of the MSLA applicable to Source Code. + * + ******************************************************************************/ + +#ifndef SL_SI91X_M4_POWERSAVE_H_ +#define SL_SI91X_M4_POWERSAVE_H_ + +#ifdef DEBUG_UART +#include "rsi_debug.h" +#endif +#ifdef SLI_SI91X_MCU_INTERFACE +#include "rsi_ds_timer.h" +#include "rsi_m4.h" +#include "rsi_rom_power_save.h" +#include "rsi_rom_timer.h" +#include "rsi_rom_ulpss_clk.h" +#include "rsi_rtc.h" +#include "rsi_wisemcu_hardware_setup.h" +#include "sl_event_handler.h" + +/*=======================================================================*/ +//! Power save command parameters +/*=======================================================================*/ +//! set handshake type of power mode +#define RSI_HAND_SHAKE_TYPE M4_BASED +#define WIRELESS_WAKEUP_IRQ_PRI 8 +#define portNVIC_SHPR3_REG (*((volatile uint32_t *)0xe000ed20)) +#define portNVIC_PENDSV_PRI (((uint32_t)(0x3f << 4)) << 16UL) +#define portNVIC_SYSTICK_PRI (((uint32_t)(0x3f << 4)) << 24UL) + +// ----------------------------------------------------------------------------- +// Prototypes +/** + * @fn sl_si91x_m4_sleep_wakeup + * @brief Keeps the M4 In the Sleep + * @param[in] none + * @return none. + * @section description + * This function is used to trigger sleep in the M4 and in the case of the + * retention submitting the buffer valid to the TA for the rx packets. + */ +void sl_si91x_m4_sleep_wakeup(void); + +/** + * @fn initialize_m4_alarm. + * @brief This function is to initialize Alarm block . + * @param[in] none + * @return none. + */ +void initialize_m4_alarm(void); +void IRQ026_Handler(); +void set_alarm_interrupt_timer(uint16_t interval); +void wakeup_source_config(void); +#endif /* SLI_SI91X_MCU_INTERFACE */ +#endif /* SL_SI91X_M4_POWERSAVE_H_ */ diff --git a/matter/si91x/siwx917/BRD4338A/support/src/sl_si91x_m4_ps.c b/matter/si91x/siwx917/BRD4338A/support/src/sl_si91x_m4_ps.c new file mode 100644 index 0000000000..a8b673b7f6 --- /dev/null +++ b/matter/si91x/siwx917/BRD4338A/support/src/sl_si91x_m4_ps.c @@ -0,0 +1,330 @@ +/***************************************************************************** + * @file sl_si91x_m4_ps.h + * @brief M4 power save + ******************************************************************************* + * # License + * Copyright 2023 Silicon Laboratories Inc. www.silabs.com + ******************************************************************************* + * + * The licenser of this software is Silicon Laboratories Inc. Your use of this + * software is governed by the terms of Silicon Labs Master Software License + * Agreement (MSLA) available at + * www.silabs.com/about-us/legal/master-software-license-agreement. This + * software is distributed to you in Source Code format and is governed by the + * sections of the MSLA applicable to Source Code. + * + ******************************************************************************/ +#include "sl_si91x_m4_ps.h" +#include "cmsis_os2.h" +#ifdef SL_WIFI_COMPONENT_INCLUDED +#include "sl_si91x_host_interface.h" +#endif +#ifdef SLI_SI91X_MCU_INTERFACE + +#define WIRELESS_WAKEUP_IRQHandler NPSS_TO_MCU_WIRELESS_INTR_IRQn + +#ifndef ALARM_PERIODIC_TIME +#define ALARM_PERIODIC_TIME 30 /* */ +#else +#define IVT_OFFSET_ADDR \ + 0x8212000 /* */ +#endif +#else +#define IVT_OFFSET_ADDR \ + 0x8012000 /* \ + */ +#endif +#ifdef SLI_SI917B0 +#define WKP_RAM_USAGE_LOCATION \ + 0x24061EFC /*= (NO_OF_SECONDS_IN_A_MINUTE)) { + alarm_configuration.Second -= NO_OF_SECONDS_IN_A_MINUTE; + alarm_configuration.Minute += 1; + } + + /*Update minutes for next boundary alarm */ + alarm_configuration.Minute = + alarm_configuration.Minute + ((interval / 60) % 60); + if (alarm_configuration.Minute >= (NO_OF_MINUTES_IN_AN_HOUR)) { + alarm_configuration.Minute -= NO_OF_MINUTES_IN_AN_HOUR; + alarm_configuration.Hour += 1; + } + + /*Update hour for next boundary alarm */ + alarm_configuration.Hour = alarm_configuration.Hour + (interval / 3600) % 24; + if (alarm_configuration.Hour >= (NO_OF_HOURS_IN_A_DAY)) { + alarm_configuration.Hour -= NO_OF_HOURS_IN_A_DAY; + alarm_configuration.Day += 1; + } + + /*Update month for next boundary alarm */ + if (alarm_configuration.Day > NO_OF_DAYS_IN_A_MONTH_1) { + if (alarm_configuration.Month == February) { + if (alarm_configuration.Year % 4) { + alarm_configuration.Day = 1; + alarm_configuration.Month += 1; + } else if (alarm_configuration.Day > NO_OF_DAYS_IN_A_MONTH_2) { + alarm_configuration.Day = 1; + alarm_configuration.Month += 1; + } + } + if (alarm_configuration.Month <= July) { + if (alarm_configuration.Month % 2 == 0) { + if (alarm_configuration.Day > NO_OF_DAYS_IN_A_MONTH_3) { + alarm_configuration.Day = 1; + alarm_configuration.Month += 1; + } + } else if (alarm_configuration.Day > NO_OF_DAYS_IN_A_MONTH_4) { + alarm_configuration.Day = 1; + alarm_configuration.Month += 1; + } + + } else if (alarm_configuration.Month % 2 == 0) { + if (alarm_configuration.Day > NO_OF_DAYS_IN_A_MONTH_4) { + alarm_configuration.Day = 1; + alarm_configuration.Month += 1; + } + } else if (alarm_configuration.Day > NO_OF_DAYS_IN_A_MONTH_3) { + alarm_configuration.Day = 1; + alarm_configuration.Month += 1; + } + } + + /*Update year for next boundary alarm */ + if (alarm_configuration.Month > (NO_OF_MONTHS_IN_A_YEAR)) { + alarm_configuration.Month = 1; + alarm_configuration.Year += 1; + } + + /*Set Alarm configuration */ + RSI_RTC_SetAlarmDateTime(RTC, &alarm_configuration); +} + +void initialize_m4_alarm(void) { + /*Init RTC*/ + RSI_RTC_Init(RTC); + + /*RTC configuration with some default time */ + rtc_configuration.DayOfWeek = Saturday; + rtc_configuration.Month = March; + rtc_configuration.Day = 19; + rtc_configuration.Century = 0; + rtc_configuration.Year = 19; + rtc_configuration.Hour = 23; + rtc_configuration.Minute = 59; + rtc_configuration.Second = 50; + rtc_configuration.MilliSeconds = 0; + + /*Set the RTC configuration*/ + RSI_RTC_SetDateTime(RTC, &rtc_configuration); + /*Enable Alarm feature*/ + RSI_RTC_AlamEnable(RTC, ENABLE); + /*Enable RTC ALARM interrupts*/ + RSI_RTC_IntrUnMask(RTC_ALARM_INTR); + /*Initialization of RTC CALIBRATION*/ + RSI_RTC_CalibInitilization(); + /*To calibrate rc and ro */ + RSI_RTC_ROCLK_Calib(TIME_PERIOD, ENABLE, ENABLE, RC_TRIGGER_TIME, ENABLE, + ENABLE, RO_TRIGGER_TIME); + /*Set Alarm as a wake up source to wake up from deep sleep */ + RSI_PS_SetWkpSources(ALARM_BASED_WAKEUP); + /*Enable the RTC alarm interrupts */ + RSI_RTC_IntrUnMask(RTC_ALARM_INTR); + /*Enable NVIC for RTC */ + NVIC_EnableIRQ(NVIC_RTC_ALARM); + m4_alarm_initialization_done = 1; +} +/*RTC Alarm interrupt*/ +void RTC_ALARM_IRQHandler(void) { + volatile uint32_t statusRead = 0; + /*Get the interrupt status */ + statusRead = RSI_RTC_GetIntrStatus(); + + if (statusRead & NPSS_TO_MCU_ALARM_INTR) { + + /* TRIGGER SLEEP STATE */ + /*Clear wake up interrupt */ + RSI_RTC_IntrClear(RTC_ALARM_INTR); + } + return; +} + +/** + * @fn sl_si91x_m4_sleep_wakeup + * @brief Keeps the M4 In the Sleep + * @param[in] none + * @return none. + * @section description + * This function is used to trigger sleep in the M4 and in the case of the + * retention submitting the buffer valid to the TA for the rx packets. + */ +void sl_si91x_m4_sleep_wakeup(void) { + +#if SL_SI91X_MCU_ALARM_BASED_WAKEUP + /* Initialize the M4 alarm for the first time*/ + if (m4_alarm_initialization_done == false) { + initialize_m4_alarm(); + } + /* Update the alarm time interval, when to get next interrupt */ + set_alarm_interrupt_timer(ALARM_PERIODIC_TIME); + +#endif +#ifdef SL_SI91X_MCU_WIRELESS_BASED_WAKEUP + /* Configure Wakeup-Source */ + RSI_PS_SetWkpSources(WIRELESS_BASED_WAKEUP); + + /* sets the priority of an Wireless wakeup interrupt. */ + NVIC_SetPriority(WIRELESS_WAKEUP_IRQHandler, WIRELESS_WAKEUP_IRQ_PRI); + + NVIC_EnableIRQ(WIRELESS_WAKEUP_IRQHandler); +#endif +#if SL_SI91X_MCU_BUTTON_BASED_WAKEUP + /*Configure the UULP GPIO 2 as wakeup source */ + wakeup_source_config(); +#endif + +#ifndef SLI_SI91X_MCU_ENABLE_FLASH_BASED_EXECUTION + /* LDOSOC Default Mode needs to be disabled */ + sl_si91x_disable_default_ldo_mode(); + + /* bypass_ldorf_ctrl needs to be enabled */ + sl_si91x_enable_bypass_ldo_rf(); + + sl_si91x_disable_flash_ldo(); + + /* Configure RAM Usage and Retention Size */ + sl_si91x_configure_ram_retention(WISEMCU_48KB_RAM_IN_USE, + WISEMCU_RETAIN_DEFAULT_RAM_DURING_SLEEP); + + /* Trigger M4 Sleep */ + sl_si91x_trigger_sleep(SLEEP_WITH_RETENTION, DISABLE_LF_MODE, 0, + (uint32_t)RSI_PS_RestoreCpuContext, 0, + RSI_WAKEUP_WITH_RETENTION_WO_ULPSS_RAM); +#else + + /* Configure RAM Usage and Retention Size */ + sl_si91x_configure_ram_retention(WISEMCU_320KB_RAM_IN_USE, + WISEMCU_RETAIN_DEFAULT_RAM_DURING_SLEEP); + /* Trigger M4 Sleep*/ + MCU_RET->NPSS_GPIO_CNTRL[0].NPSS_GPIO_CTRLS_b.NPSS_GPIO_OUT = 0; + sl_si91x_trigger_sleep(SLEEP_WITH_RETENTION, DISABLE_LF_MODE, + WKP_RAM_USAGE_LOCATION, + (uint32_t)RSI_PS_RestoreCpuContext, IVT_OFFSET_ADDR, + RSI_WAKEUP_FROM_FLASH_MODE); +#endif + + /* Enable M4_TA interrupt */ + sli_m4_ta_interrupt_init(); + + /* Clear M4_wakeup_TA bit so that TA will go to sleep after M4 wakeup*/ + sl_si91x_host_clear_sleep_indicator(); + + /* Setup the systick timer */ + vPortSetupTimerInterrupt(); +} + +#endif