Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions examples/platform/silabs/FreeRTOSConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ extern uint32_t SystemCoreClock;
#include "SEGGER_SYSVIEW_FreeRTOS.h"
#endif

#if defined(SL_MATTER_EM4_SLEEP) && (SL_MATTER_EM4_SLEEP == 1)
void sl_matter_em4_check(uint32_t expected_idle_time_ms);
#endif // defined(SL_MATTER_EM4_SLEEP) && (SL_MATTER_EM4_SLEEP == 1)

/*-----------------------------------------------------------
* Application specific definitions.
*
Expand All @@ -143,6 +147,9 @@ extern uint32_t SystemCoreClock;
/* Energy saving modes. */
#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
#define configUSE_TICKLESS_IDLE 1
#if defined(SL_MATTER_EM4_SLEEP) && (SL_MATTER_EM4_SLEEP == 1)
#define configPRE_SLEEP_PROCESSING(x) sl_matter_em4_check(x)
#endif // defined(SL_MATTER_EM4_SLEEP) && (SL_MATTER_EM4_SLEEP == 1)
#elif (SLI_SI91X_MCU_INTERFACE && SL_ICD_ENABLED)
#define configUSE_TICKLESS_IDLE 1
#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 70
Expand Down
64 changes: 64 additions & 0 deletions examples/platform/silabs/MatterConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@

#include <mbedtls/platform.h>

#if CHIP_CONFIG_ENABLE_ICD_SERVER
#if defined(SL_MATTER_EM4_SLEEP) && (SL_MATTER_EM4_SLEEP == 1)
#include "sl_sleeptimer.h"
#include <app/icd/server/ICDConfigurationData.h> // nogncheck

#include "em_burtc.h"
#include "em_cmu.h"
#include "em_emu.h"
#endif // defined(SL_MATTER_EM4_SLEEP) && (SL_MATTER_EM4_SLEEP == 1)
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER

#ifdef SL_WIFI
#include <platform/silabs/NetworkCommissioningWiFiDriver.h>
#include <platform/silabs/wifi/WifiInterface.h> // nogncheck
Expand Down Expand Up @@ -339,9 +350,35 @@ CHIP_ERROR SilabsMatterConfig::InitMatter(const char * appName)
return CHIP_NO_ERROR;
}

#if defined(SL_MATTER_EM4_SLEEP) && (SL_MATTER_EM4_SLEEP == 1)
void OnEM4Trigger(uint32_t duration)
{
CMU_ClockSelectSet(cmuClock_EM4GRPACLK, cmuSelect_ULFRCO);
CMU_ClockEnable(cmuClock_BURTC, true);
CMU_ClockEnable(cmuClock_BURAM, true);

BURTC_Init_TypeDef burtcInit = BURTC_INIT_DEFAULT;
burtcInit.compare0Top = true; // reset counter when counter reaches compare value
burtcInit.em4comp = true; // BURTC compare interrupt wakes from EM4 (causes reset)
BURTC_Init(&burtcInit);

BURTC_CounterReset();
BURTC_CompareSet(0, duration);

BURTC_IntEnable(BURTC_IEN_COMP); // compare match
NVIC_EnableIRQ(BURTC_IRQn);
BURTC_Enable(true);
EMU_EM4Init_TypeDef em4Init = EMU_EM4INIT_DEFAULT;
EMU_EM4Init(&em4Init);
BURTC_CounterReset();
EMU_EnterEM4();
}

#endif // defined(SL_MATTER_EM4_SLEEP) && (SL_MATTER_EM4_SLEEP == 1)
// ================================================================================
// FreeRTOS Callbacks
// ================================================================================

extern "C" void vApplicationIdleHook(void)
{
#if (SLI_SI91X_MCU_INTERFACE && CHIP_CONFIG_ENABLE_ICD_SERVER)
Expand All @@ -351,3 +388,30 @@ extern "C" void vApplicationIdleHook(void)
SiWxPlatformInterface::sl_si91x_uart_power_requirement_handler();
#endif
}

#if CHIP_CONFIG_ENABLE_ICD_SERVER
#if defined(SL_MATTER_EM4_SLEEP) && (SL_MATTER_EM4_SLEEP == 1)

#ifndef SL_MATTER_EM4_THRESHOLD_PERCENTAGE
#define SL_MATTER_EM4_THRESHOLD_PERCENTAGE 90
#endif

static_assert(SL_MATTER_EM4_THRESHOLD_PERCENTAGE > 0 && SL_MATTER_EM4_THRESHOLD_PERCENTAGE < 100,
"SL_MATTER_EM4_THRESHOLD_PERCENTAGE must be between 1 and 99");

extern "C" void sl_matter_em4_check(uint32_t expected_idle_time_ms)
{
if (chip::ICDConfigurationData::GetInstance().GetICDMode() == chip::ICDConfigurationData::ICDMode::LIT)
{
uint32_t idleDuration_seconds = chip::ICDConfigurationData::GetInstance().GetIdleModeDuration().count();
uint32_t threshold_ms = idleDuration_seconds * SL_EM4_THRESHOLD_PERCENTAGE * 10;
// Since the sleep timer will never match the actual idle time (hardware latency, etc), we set a threshold
// Multiply by 10 to converts seconds into milliseconds (e.g. 90% of 1000sec in ms is 1000*90*10 = 900000ms)
if (expected_idle_time_ms >= threshold_ms)
{
OnEM4Trigger(expected_idle_time_ms);
}
}
}
#endif // defined(SL_MATTER_EM4_SLEEP) && (SL_MATTER_EM4_SLEEP == 1)
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER
4 changes: 4 additions & 0 deletions third_party/silabs/efr32_sdk.gni
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ declare_args() {
sl_enable_test_event_trigger = false

sl_verbose_mode = false

sl_em4_sleep = false
}

examples_plat_dir = "${chip_root}/examples/platform/silabs/efr32"
Expand Down Expand Up @@ -506,6 +508,7 @@ template("efr32_sdk") {
"SL_CODE_COMPONENT_OPENTHREAD=openthread",
"SL_CODE_COMPONENT_INTERRUPT_MANAGER=interrupt_manager",
"SL_APP_PROPERTIES",
"SL_MATTER_EM4_SLEEP=${sl_em4_sleep}",
]

if (silabs_log_enabled && chip_logging) {
Expand Down Expand Up @@ -739,6 +742,7 @@ template("efr32_sdk") {
"${efr32_sdk_root}/platform/emdrv/nvm3/src/nvm3_object.c",
"${efr32_sdk_root}/platform/emdrv/nvm3/src/nvm3_page.c",
"${efr32_sdk_root}/platform/emdrv/nvm3/src/nvm3_utils.c",
"${efr32_sdk_root}/platform/emlib/src/em_burtc.c",
"${efr32_sdk_root}/platform/emlib/src/em_cmu.c",
"${efr32_sdk_root}/platform/emlib/src/em_crypto.c",
"${efr32_sdk_root}/platform/emlib/src/em_emu.c",
Expand Down
Loading