From 0dbd0dd89fa90dc6e0d1d2636563ea980c010c19 Mon Sep 17 00:00:00 2001
From: Jean-Francois Penven <67962328+jepenven-silabs@users.noreply.github.com>
Date: Tue, 9 Apr 2024 09:01:14 -0400
Subject: [PATCH] Revert "Refactors needed for M4 power save on SiWx917 (#177)"
(#181)
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