[Silabs] Adds fix for BTN low power mode for SiWx917 SoC and power manager (#35808)
* Decouple UART power requirement handler
* Adds refactored BTN handler based on power manager
* Fixed incorrect API
* Adds changes for interrupt
* Replace use of RSI_xx APIs with sl_si91x_xx APIs
* Refactor button event handling and UART power requirement handler
* Adds comments based on the coding standards
Reduce into inline functions
* Renaming sl_btn0 -> btn0
* Adds changes to optimize code
* Adds CPP define in header
* Update function comments
* Replace with more readable condition
* Updates document to add BTN0 screen cycle action (#323)
* Restyled by prettier-markdown
* Adds compilation fix for EFR32 boards
* Addressing comments
---------
Co-authored-by: Restyled.io <commits@restyled.io>
diff --git a/examples/air-quality-sensor-app/silabs/README.md b/examples/air-quality-sensor-app/silabs/README.md
index 7279e23..b2687c6 100644
--- a/examples/air-quality-sensor-app/silabs/README.md
+++ b/examples/air-quality-sensor-app/silabs/README.md
@@ -257,6 +257,7 @@
- _Press and Release_ : Start, or restart, BLE advertisement in fast mode. It will advertise in this mode
for 30 seconds. The device will then switch to a slower interval advertisement.
After 15 minutes, the advertisement stops.
+ Additionally, it will cycle through the QR code, application status screen and device status screen, respectively.
- _Pressed and hold for 6 s_ : Initiates the factory reset of the device.
Releasing the button within the 6-second window cancels the factory reset
diff --git a/examples/dishwasher-app/silabs/README.md b/examples/dishwasher-app/silabs/README.md
index 9a8a102..ffc56f3 100644
--- a/examples/dishwasher-app/silabs/README.md
+++ b/examples/dishwasher-app/silabs/README.md
@@ -10,6 +10,7 @@
- [Flashing the Application](#flashing-the-application)
- [Viewing Logging Output](#viewing-logging-output)
- [Running the Complete Example](#running-the-complete-example)
+ - [Commissioning](#commissioning)
<hr>
@@ -211,6 +212,7 @@
- _Press and Release_ : Start, or restart, BLE advertisement in fast mode. It will advertise in this mode
for 30 seconds. The device will then switch to a slower interval advertisement.
After 15 minutes, the advertisement stops.
+ Additionally, it will cycle through the QR code, application status screen and device status screen, respectively.
- _Pressed and hold for 6 s_ : Initiates the factory reset of the device.
Releasing the button within the 6-second window cancels the factory reset
diff --git a/examples/energy-management-app/silabs/README.md b/examples/energy-management-app/silabs/README.md
index 5c1955a..09253af 100644
--- a/examples/energy-management-app/silabs/README.md
+++ b/examples/energy-management-app/silabs/README.md
@@ -257,6 +257,7 @@
- _Press and Release_ : Start, or restart, BLE advertisement in fast mode. It will advertise in this mode
for 30 seconds. The device will then switch to a slower interval advertisement.
After 15 minutes, the advertisement stops.
+ Additionally, it will cycle through the QR code, application status screen and device status screen, respectively.
- _Pressed and hold for 6 s_ : Initiates the factory reset of the device.
Releasing the button within the 6-second window cancels the factory reset
diff --git a/examples/light-switch-app/silabs/README.md b/examples/light-switch-app/silabs/README.md
index 898f8e8..75411dd 100644
--- a/examples/light-switch-app/silabs/README.md
+++ b/examples/light-switch-app/silabs/README.md
@@ -263,6 +263,7 @@
- _Press and Release_ : Start, or restart, BLE advertisement in fast mode. It will advertise in this mode
for 30 seconds. The device will then switch to a slower interval advertisement.
After 15 minutes, the advertisement stops.
+ Additionally, it will cycle through the QR code, application status screen and device status screen, respectively.
- _Pressed and hold for 6 s_ : Initiates the factory reset of the device.
Releasing the button within the 6-second window cancels the factory reset
diff --git a/examples/lighting-app/silabs/README.md b/examples/lighting-app/silabs/README.md
index 7052d4f..b783a6c 100644
--- a/examples/lighting-app/silabs/README.md
+++ b/examples/lighting-app/silabs/README.md
@@ -245,6 +245,7 @@
- _Press and Release_ : Start, or restart, BLE advertisement in fast mode. It will advertise in this mode
for 30 seconds. The device will then switch to a slower interval advertisement.
After 15 minutes, the advertisement stops.
+ Additionally, it will cycle through the QR code, application status screen and device status screen, respectively.
- _Pressed and hold for 6 s_ : Initiates the factory reset of the device.
Releasing the button within the 6-second window cancels the factory reset
diff --git a/examples/lit-icd-app/silabs/README.md b/examples/lit-icd-app/silabs/README.md
index 4d1dee0..1b94dc5 100644
--- a/examples/lit-icd-app/silabs/README.md
+++ b/examples/lit-icd-app/silabs/README.md
@@ -250,6 +250,7 @@
- _Press and Release_ : Start, or restart, BLE advertisement in fast mode. It will advertise in this mode
for 30 seconds. The device will then switch to a slower interval advertisement.
After 15 minutes, the advertisement stops.
+ Additionally, it will cycle through the QR code, application status screen and device status screen, respectively.
- _Pressed and hold for 6 s_ : Initiates the factory reset of the device.
Releasing the button within the 6-second window cancels the factory reset
diff --git a/examples/lock-app/silabs/README.md b/examples/lock-app/silabs/README.md
index 7b4f7fd..0688f1c 100644
--- a/examples/lock-app/silabs/README.md
+++ b/examples/lock-app/silabs/README.md
@@ -277,6 +277,7 @@
- _Press and Release_ : Start, or restart, BLE advertisement in fast mode. It will advertise in this mode
for 30 seconds. The device will then switch to a slower interval advertisement.
After 15 minutes, the advertisement stops.
+ Additionally, it will cycle through the QR code, application status screen and device status screen, respectively.
- _Pressed and hold for 6 s_ : Initiates the factory reset of the device.
Releasing the button within the 6-second window cancels the factory reset
diff --git a/examples/platform/silabs/MatterConfig.cpp b/examples/platform/silabs/MatterConfig.cpp
index 43bd2c1..c7d4487 100644
--- a/examples/platform/silabs/MatterConfig.cpp
+++ b/examples/platform/silabs/MatterConfig.cpp
@@ -41,6 +41,7 @@
#endif
#if defined(SLI_SI91X_MCU_INTERFACE) && SLI_SI91X_MCU_INTERFACE == 1
+#include "SiWxPlatformInterface.h"
#include "WifiInterfaceAbstraction.h"
#endif // SLI_SI91X_MCU_INTERFACE
@@ -328,6 +329,7 @@
extern "C" void vApplicationIdleHook(void)
{
#if (SLI_SI91X_MCU_INTERFACE && CHIP_CONFIG_ENABLE_ICD_SERVER)
- sl_si91x_invoke_btn_press_event();
+ SiWxPlatformInterface::sl_si91x_btn_event_handler();
+ SiWxPlatformInterface::sl_si91x_uart_power_requirement_handler();
#endif
}
diff --git a/examples/platform/silabs/SiWx917/SiWxPlatformInterface.h b/examples/platform/silabs/SiWx917/SiWxPlatformInterface.h
new file mode 100644
index 0000000..879ca30
--- /dev/null
+++ b/examples/platform/silabs/SiWx917/SiWxPlatformInterface.h
@@ -0,0 +1,73 @@
+/*
+ *
+ * Copyright (c) 2024 Project CHIP Authors
+ *
+ * Licensed 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.
+ */
+
+#pragma once
+
+#include <app/icd/server/ICDServerConfig.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#if CHIP_CONFIG_ENABLE_ICD_SERVER
+#if SLI_SI91X_MCU_INTERFACE
+#include "sl_si91x_button.h"
+#include "sl_si91x_button_pin_config.h"
+#include "sl_si91x_driver_gpio.h"
+/**
+ * @brief invoked when button press event is received when in sleep
+ * @param[in] pin_intr GPIO pin interrupt number.
+ * @return none.
+ * @note this is a callback from the Wiseconnect SDK
+ */
+void gpio_uulp_pin_interrupt_callback(uint32_t pin_intr);
+#endif // SLI_SI91X_MCU_INTERFACE
+#endif // CHIP_CONFIG_ENABLE_ICD_SERVER
+#ifdef __cplusplus
+}
+#endif
+
+namespace chip {
+namespace DeviceLayer {
+namespace Silabs {
+namespace SiWxPlatformInterface {
+
+#if CHIP_CONFIG_ENABLE_ICD_SERVER
+#if SLI_SI91X_MCU_INTERFACE
+/**
+ * @brief Required to invoke button press event during sleep as falling edge is not detected
+ * @param[in] none.
+ * @note flow is GPIO wakeup due to BTN0 press -> check button state in idle task required as the GPIO interrupt is not
+ * detected during sleep for BUTTON RELEASED
+ */
+inline void sl_si91x_btn_event_handler()
+{
+ sl_button_on_change(SL_BUTTON_BTN0_NUMBER,
+ (sl_si91x_gpio_get_uulp_npss_pin(SL_BUTTON_BTN0_PIN) == LOW) ? BUTTON_PRESSED : BUTTON_RELEASED);
+}
+
+/**
+ * @brief Required to enable MATTER shell UART with ICD feature flag
+ * @param[in] none.
+ * @note this requires hardware jumping of the GPIO PINs to work with the baseboard.
+ */
+void sl_si91x_uart_power_requirement_handler();
+#endif // SLI_SI91X_MCU_INTERFACE
+#endif // CHIP_CONFIG_ENABLE_ICD_SERVER
+} // namespace SiWxPlatformInterface
+} // namespace Silabs
+} // namespace DeviceLayer
+} // namespace chip
diff --git a/examples/platform/silabs/SiWx917/SiWxWifiInterface.cpp b/examples/platform/silabs/SiWx917/SiWxWifiInterface.cpp
index 26a16f9..2390365 100644
--- a/examples/platform/silabs/SiWx917/SiWxWifiInterface.cpp
+++ b/examples/platform/silabs/SiWx917/SiWxWifiInterface.cpp
@@ -74,8 +74,11 @@
#endif
#if CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI91X_MCU_INTERFACE
+#include "SiWxPlatformInterface.h"
+
#include "rsi_rom_power_save.h"
-#include "sl_si91x_button_pin_config.h"
+#include "sl_gpio_board.h"
+#include "sl_si91x_driver_gpio.h"
#include "sl_si91x_power_manager.h"
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI91X_MCU_INTERFACE
@@ -522,23 +525,27 @@
#if CHIP_CONFIG_ENABLE_ICD_SERVER
#if SLI_SI91X_MCU_INTERFACE
-// Required to invoke button press event during sleep as falling edge is not detected
-void sl_si91x_invoke_btn_press_event(void)
+void gpio_uulp_pin_interrupt_callback(uint32_t pin_intr)
{
- // TODO: should be removed once we are getting the press interrupt for button 0 with sleep
- if (!RSI_NPSSGPIO_GetPin(SL_BUTTON_BTN0_PIN) && !btn0_pressed)
+ // UULP_GPIO_2 is used to detect the button 0 press
+ VerifyOrReturn(pin_intr == RTE_UULP_GPIO_2_PIN, ChipLogError(DeviceLayer, "invalid pin interrupt: %ld", pin_intr));
+ sl_status_t status = SL_STATUS_OK;
+ uint8_t pin_intr_status = sl_si91x_gpio_get_uulp_npss_pin(pin_intr);
+ if (pin_intr_status == LOW)
{
- sl_button_on_change(SL_BUTTON_BTN0_NUMBER, 1 /* Button Pressed */);
- btn0_pressed = true;
+ // BTN_0 is pressed
+ // NOTE: the GPIO is masked since the interrupt is invoked before scheduler is started, thus this is required to hand over
+ // control to scheduler, the PIN is unmasked in the power manager flow before going to sleep
+ status = sl_si91x_gpio_driver_mask_uulp_npss_interrupt(BIT(pin_intr));
+ VerifyOrReturn(status == SL_STATUS_OK, ChipLogError(DeviceLayer, "failed to mask interrupt: %ld", status));
}
- if (RSI_NPSSGPIO_GetPin(SL_BUTTON_BTN0_PIN))
- {
- btn0_pressed = false;
- }
+}
+void chip::DeviceLayer::Silabs::SiWxPlatformInterface::sl_si91x_uart_power_requirement_handler(void)
+{
#ifdef ENABLE_CHIP_SHELL
// Checking the UULP PIN 1 status to reinit the UART and not allow the device to go to sleep
- if (RSI_NPSSGPIO_GetPin(RTE_UULP_GPIO_1_PIN))
+ if (sl_si91x_gpio_get_uulp_npss_pin(RTE_UULP_GPIO_1_PIN))
{
if (!ps_requirement_added)
{
diff --git a/examples/platform/silabs/wifi/WifiInterfaceAbstraction.h b/examples/platform/silabs/wifi/WifiInterfaceAbstraction.h
index a26ead2..f0383b2 100644
--- a/examples/platform/silabs/wifi/WifiInterfaceAbstraction.h
+++ b/examples/platform/silabs/wifi/WifiInterfaceAbstraction.h
@@ -105,9 +105,6 @@
sl_status_t sl_matter_wifi_platform_init(void);
#if CHIP_CONFIG_ENABLE_ICD_SERVER
-#if SLI_SI91X_MCU_INTERFACE
-void sl_si91x_invoke_btn_press_event();
-#endif // SLI_SI91X_MCU_INTERFACE
#if SLI_SI917
int32_t wfx_rsi_power_save(rsi_power_save_profile_mode_t sl_si91x_ble_state, sl_si91x_performance_profile_t sl_si91x_wifi_state);
#else
diff --git a/examples/pump-app/silabs/README.md b/examples/pump-app/silabs/README.md
index 70d83e4..0ca0f43 100644
--- a/examples/pump-app/silabs/README.md
+++ b/examples/pump-app/silabs/README.md
@@ -242,6 +242,7 @@
- _Press and Release_ : Start, or restart, BLE advertisement in fast mode. It will advertise in this mode
for 30 seconds. The device will then switch to a slower interval advertisement.
After 15 minutes, the advertisement stops.
+ Additionally, it will cycle through the QR code, application status screen and device status screen, respectively.
- _Pressed and hold for 6 s_ : Initiates the factory reset of the device.
Releasing the button within the 6-second window cancels the factory reset
diff --git a/examples/smoke-co-alarm-app/silabs/README.md b/examples/smoke-co-alarm-app/silabs/README.md
index 7928107..5200566 100644
--- a/examples/smoke-co-alarm-app/silabs/README.md
+++ b/examples/smoke-co-alarm-app/silabs/README.md
@@ -260,6 +260,7 @@
- _Press and Release_ : Start, or restart, BLE advertisement in fast mode. It will advertise in this mode
for 30 seconds. The device will then switch to a slower interval advertisement.
After 15 minutes, the advertisement stops.
+ Additionally, it will cycle through the QR code, application status screen and device status screen, respectively.
- _Pressed and hold for 6 s_ : Initiates the factory reset of the device.
Releasing the button within the 6-second window cancels the factory reset
diff --git a/examples/thermostat/silabs/README.md b/examples/thermostat/silabs/README.md
index 3205352..6816185 100644
--- a/examples/thermostat/silabs/README.md
+++ b/examples/thermostat/silabs/README.md
@@ -251,6 +251,7 @@
- _Press and Release_ : Start, or restart, BLE advertisement in fast mode. It will advertise in this mode
for 30 seconds. The device will then switch to a slower interval advertisement.
After 15 minutes, the advertisement stops.
+ Additionally, it will cycle through the QR code, application status screen and device status screen, respectively.
- _Pressed and hold for 6 s_ : Initiates the factory reset of the device.
Releasing the button within the 6-second window cancels the factory reset
diff --git a/src/platform/silabs/platformAbstraction/WiseMcuSpam.cpp b/src/platform/silabs/platformAbstraction/WiseMcuSpam.cpp
index cf60cf5..317d590 100644
--- a/src/platform/silabs/platformAbstraction/WiseMcuSpam.cpp
+++ b/src/platform/silabs/platformAbstraction/WiseMcuSpam.cpp
@@ -159,21 +159,21 @@
// Currently the btn0 is pull-up resistor due to which is sends a release event on every wakeup
if (btn == SL_BUTTON_BTN0_NUMBER)
{
- if (btnAction == BUTTON_PRESSED)
+ // if the btn was not pressed and only a release event came, ignore it
+ // if the btn was already pressed and another press event came, ignore it
+ // essentially, if both of them are in the same state then ignore it.
+ VerifyOrReturn(btnAction != btn0_pressed);
+
+ if ((btnAction == BUTTON_PRESSED) && (btn0_pressed == false))
{
btn0_pressed = true;
}
- else if ((btnAction == BUTTON_RELEASED) && (btn0_pressed == false))
- {
- // if the btn was not pressed and only a release event came, ignore it
- return;
- }
else if ((btnAction == BUTTON_RELEASED) && (btn0_pressed == true))
{
btn0_pressed = false;
}
}
-#endif /* SL_ICD_ENABLED */
+#endif // SL_ICD_ENABLED
if (Silabs::GetPlatform().mButtonCallback == nullptr)
{
return;
diff --git a/third_party/silabs/SiWx917_sdk.gni b/third_party/silabs/SiWx917_sdk.gni
index ab94c63..94763d8 100644
--- a/third_party/silabs/SiWx917_sdk.gni
+++ b/third_party/silabs/SiWx917_sdk.gni
@@ -321,9 +321,12 @@
"SL_ACTIVE_MODE_DURATION_MS=${sl_active_mode_duration_ms}",
"SL_IDLE_MODE_DURATION_S=${sl_idle_mode_duration_s}",
"SL_ICD_SUPPORTED_CLIENTS_PER_FABRIC=${sl_icd_supported_clients_per_fabric}",
- "SL_SI91X_NPSS_GPIO_BTN_HANDLER=1",
"SL_SI91X_POWER_MANAGER_UC_AVAILABLE=1",
"SL_SI91X_TICKLESS_MODE=1",
+
+ # Enable Wakeup source for ICD
+ "SL_ENABLE_GPIO_WAKEUP_SOURCE=1",
+ "ENABLE_NPSS_GPIO_2=1",
]
}