From 44db1fb9d330755e54b72f1aa4725bfaca99abaa Mon Sep 17 00:00:00 2001 From: Rohan Sahay <103027015+rosahay-silabs@users.noreply.github.com> Date: Wed, 6 Nov 2024 18:05:57 +0530 Subject: [PATCH] [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 --- .../air-quality-sensor-app/silabs/README.md | 1 + examples/dishwasher-app/silabs/README.md | 2 + .../energy-management-app/silabs/README.md | 1 + examples/light-switch-app/silabs/README.md | 1 + examples/lighting-app/silabs/README.md | 1 + examples/lit-icd-app/silabs/README.md | 1 + examples/lock-app/silabs/README.md | 1 + examples/platform/silabs/MatterConfig.cpp | 4 +- .../silabs/SiWx917/SiWxPlatformInterface.h | 73 +++++++++++++++++++ .../silabs/SiWx917/SiWxWifiInterface.cpp | 31 +++++--- .../silabs/wifi/WifiInterfaceAbstraction.h | 3 - examples/pump-app/silabs/README.md | 1 + examples/smoke-co-alarm-app/silabs/README.md | 1 + examples/thermostat/silabs/README.md | 1 + .../platformAbstraction/WiseMcuSpam.cpp | 14 ++-- third_party/silabs/SiWx917_sdk.gni | 5 +- 16 files changed, 117 insertions(+), 24 deletions(-) create mode 100644 examples/platform/silabs/SiWx917/SiWxPlatformInterface.h diff --git a/examples/air-quality-sensor-app/silabs/README.md b/examples/air-quality-sensor-app/silabs/README.md index 7279e23457ef01..b2687c6cadb8b0 100644 --- a/examples/air-quality-sensor-app/silabs/README.md +++ b/examples/air-quality-sensor-app/silabs/README.md @@ -257,6 +257,7 @@ combination with JLinkRTTClient as follows: - _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 9a8a102cbd147d..ffc56f3580697b 100644 --- a/examples/dishwasher-app/silabs/README.md +++ b/examples/dishwasher-app/silabs/README.md @@ -10,6 +10,7 @@ An example showing the use of Matter on the Silicon Labs EFR32 MG24 boards. - [Flashing the Application](#flashing-the-application) - [Viewing Logging Output](#viewing-logging-output) - [Running the Complete Example](#running-the-complete-example) + - [Commissioning](#commissioning)
@@ -211,6 +212,7 @@ combination with JLinkRTTClient as follows: - _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 5c1955a5071f3c..09253afa55524c 100644 --- a/examples/energy-management-app/silabs/README.md +++ b/examples/energy-management-app/silabs/README.md @@ -257,6 +257,7 @@ combination with JLinkRTTClient as follows: - _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 898f8e8f299112..75411dd3055e72 100644 --- a/examples/light-switch-app/silabs/README.md +++ b/examples/light-switch-app/silabs/README.md @@ -263,6 +263,7 @@ combination with JLinkRTTClient as follows: - _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 7052d4f71221c3..b783a6c328fac1 100644 --- a/examples/lighting-app/silabs/README.md +++ b/examples/lighting-app/silabs/README.md @@ -245,6 +245,7 @@ combination with JLinkRTTClient as follows: - _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 4d1dee045c2e40..1b94dc5b902b73 100644 --- a/examples/lit-icd-app/silabs/README.md +++ b/examples/lit-icd-app/silabs/README.md @@ -250,6 +250,7 @@ combination with JLinkRTTClient as follows: - _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 7b4f7fdbdfaddf..0688f1ce70e93c 100644 --- a/examples/lock-app/silabs/README.md +++ b/examples/lock-app/silabs/README.md @@ -277,6 +277,7 @@ combination with JLinkRTTClient as follows: - _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 43bd2c181fd044..c7d4487cfc4f5d 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 @@ CHIP_ERROR SilabsMatterConfig::InitWiFi(void) 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 00000000000000..879ca3013c7b41 --- /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 + +#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 26a16f9aa87f8f..2390365384481d 100644 --- a/examples/platform/silabs/SiWx917/SiWxWifiInterface.cpp +++ b/examples/platform/silabs/SiWx917/SiWxWifiInterface.cpp @@ -74,8 +74,11 @@ extern "C" { #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 @@ int32_t sl_wifi_platform_disconnect(void) #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) - { - sl_button_on_change(SL_BUTTON_BTN0_NUMBER, 1 /* Button Pressed */); - btn0_pressed = true; - } - if (RSI_NPSSGPIO_GetPin(SL_BUTTON_BTN0_PIN)) + // 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) { - btn0_pressed = false; + // 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)); } +} +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 a26ead2579b16a..f0383b20e25f85 100644 --- a/examples/platform/silabs/wifi/WifiInterfaceAbstraction.h +++ b/examples/platform/silabs/wifi/WifiInterfaceAbstraction.h @@ -105,9 +105,6 @@ extern "C" { 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 70d83e4de5f70c..0ca0f43a7a5784 100644 --- a/examples/pump-app/silabs/README.md +++ b/examples/pump-app/silabs/README.md @@ -242,6 +242,7 @@ combination with JLinkRTTClient as follows: - _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 7928107b35de47..520056661d8b3d 100644 --- a/examples/smoke-co-alarm-app/silabs/README.md +++ b/examples/smoke-co-alarm-app/silabs/README.md @@ -260,6 +260,7 @@ combination with JLinkRTTClient as follows: - _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 3205352bf07f1c..681618545b7a1a 100644 --- a/examples/thermostat/silabs/README.md +++ b/examples/thermostat/silabs/README.md @@ -251,6 +251,7 @@ combination with JLinkRTTClient as follows: - _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 cf60cf5c5892fe..317d59074af323 100644 --- a/src/platform/silabs/platformAbstraction/WiseMcuSpam.cpp +++ b/src/platform/silabs/platformAbstraction/WiseMcuSpam.cpp @@ -159,21 +159,21 @@ void sl_button_on_change(uint8_t btn, uint8_t btnAction) // 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 ab94c6372d18e0..94763d8311dce6 100644 --- a/third_party/silabs/SiWx917_sdk.gni +++ b/third_party/silabs/SiWx917_sdk.gni @@ -321,9 +321,12 @@ template("siwx917_sdk") { "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", ] }