Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Silabs] Enabling the sleepy device for EFR32 and rs911x combo #25519

Merged
Merged
Show file tree
Hide file tree
Changes from 15 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
31 changes: 25 additions & 6 deletions examples/platform/silabs/efr32/rs911x/hal/efx_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@
#include "sl_device_init_dpll.h"
#include "sl_device_init_hfxo.h"

#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
#include "sl_power_manager.h"
#endif

StaticSemaphore_t xEfxSpiIntfSemaBuffer;
static SemaphoreHandle_t spi_sem;

Expand Down Expand Up @@ -159,10 +163,11 @@ void rsi_hal_board_init(void)
}

/*****************************************************************************
*@fn static bool rx_dma_complete(unsigned int channel, unsigned int sequenceNo, void *userParam)
*@fn static bool dma_complete_cb(unsigned int channel, unsigned int sequenceNo, void *userParam)
*
*@brief
* complete dma
* DMA transfer completion callback. Called by the DMA interrupt handler.
* This is being set in the tx/rx of the DMA
*
* @param[in] channel:
* @param[in] sequenceNO: sequence number
Expand All @@ -171,7 +176,7 @@ void rsi_hal_board_init(void)
* @return
* None
******************************************************************************/
static bool rx_dma_complete(unsigned int channel, unsigned int sequenceNo, void * userParam)
static bool dma_complete_cb(unsigned int channel, unsigned int sequenceNo, void * userParam)
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
// uint8_t *buf = (void *)userParam;
Expand All @@ -184,6 +189,10 @@ static bool rx_dma_complete(unsigned int channel, unsigned int sequenceNo, void
xSemaphoreGiveFromISR(spi_sem, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);

#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
sl_power_manager_remove_em_requirement(SL_POWER_MANAGER_EM1);
#endif

return true;
}

Expand All @@ -205,8 +214,13 @@ static void receiveDMA(uint8_t * rx_buf, uint16_t xlen)
* The xmit can be dummy data (no src increment for tx)
*/
dummy_data = 0;
#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
sl_power_manager_add_em_requirement(SL_POWER_MANAGER_EM1);
#endif

// Start receive DMA
DMADRV_PeripheralMemory(rx_dma_channel, MY_USART_RX_SIGNAL, (void *) rx_buf, (void *) &(MY_USART->RXDATA), true, xlen,
dmadrvDataSize1, rx_dma_complete, NULL);
dmadrvDataSize1, dma_complete_cb, NULL);

// Start transmit DMA.
DMADRV_MemoryPeripheral(tx_dma_channel, MY_USART_TX_SIGNAL, (void *) &(MY_USART->TXDATA), (void *) &(dummy_data), false, xlen,
Expand Down Expand Up @@ -248,8 +262,13 @@ static void transmitDMA(uint8_t * rx_buf, uint8_t * tx_buf, uint16_t xlen)
/* DEBUG */ rx_buf[0] = 0xAA;
rx_buf[1] = 0x55;
}
#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
sl_power_manager_add_em_requirement(SL_POWER_MANAGER_EM1);
#endif

// Start receive DMA
DMADRV_PeripheralMemory(rx_dma_channel, MY_USART_RX_SIGNAL, buf, (void *) &(MY_USART->RXDATA), srcinc, xlen, dmadrvDataSize1,
rx_dma_complete, buf);
dma_complete_cb, buf);
// Start transmit DMA.
DMADRV_MemoryPeripheral(tx_dma_channel, MY_USART_TX_SIGNAL, (void *) &(MY_USART->TXDATA), (void *) tx_buf, true, xlen,
dmadrvDataSize1, NULL, NULL);
Expand Down Expand Up @@ -289,7 +308,7 @@ int16_t rsi_spi_transfer(uint8_t * tx_buf, uint8_t * rx_buf, uint16_t xlen, uint
* receiveDMA() and transmitDMA() are asynchronous
* Our application design assumes that this function is synchronous
* To make it synchronous, we wait to re-acquire the semaphore before exiting this function
* rx_dma_complete() gives back the semaphore when the SPI transfer is done
* dma_complete_cb() gives back the semaphore when the SPI transfer is done
*/
if (xSemaphoreTake(spi_sem, pdMS_TO_TICKS(RSI_SEM_BLOCK_MIN_TIMER_VALUE_MS)) == pdTRUE)
{
Expand Down
1 change: 1 addition & 0 deletions examples/platform/silabs/efr32/rs911x/hal/rsi_hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#define RSI_HAL_SLEEP_CONFIRM_PIN 2
#define RSI_HAL_WAKEUP_INDICATION_PIN 3
#define RSI_HAL_MODULE_INTERRUPT_PIN 4
#define RSI_HAL_LP_SLEEP_CONFIRM_PIN 6

//! Timer related macros
//! Macro to configure timer type in single shot
Expand Down
56 changes: 47 additions & 9 deletions examples/platform/silabs/efr32/rs911x/hal/rsi_hal_mcu_ioports.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@

#include "rsi_board_configuration.h"
#include "rsi_driver.h"

/*===========================================================*/
/**
* @fn void rsi_hal_config_gpio(uint8_t gpio_number,uint8_t mode,uint8_t value)
Expand All @@ -61,9 +60,20 @@ void rsi_hal_config_gpio(uint8_t gpio_number, uint8_t mode, uint8_t value)

CMU_ClockEnable(cmuClock_GPIO, true);

// WFX_RSI_LOG ("RSI: CFG GPIO: 0x%x", gpio_number);
switch (gpio_number)
{
case RSI_HAL_SLEEP_CONFIRM_PIN:
case RSI_HAL_LP_SLEEP_CONFIRM_PIN:
GPIO_PinModeSet(WFX_SLEEP_CONFIRM_PIN.port, WFX_SLEEP_CONFIRM_PIN.pin, gpioModeWiredOrPullDown, PINOUT_SET);
break;
case RSI_HAL_WAKEUP_INDICATION_PIN:
#ifndef LOGGING_STATS
GPIO_PinModeSet(WAKE_INDICATOR_PIN.port, WAKE_INDICATOR_PIN.pin, gpioModeWiredOrPullDown, PINOUT_CLEAR);
break;
#else
GPIO_PinModeSet(LOGGING_WAKE_INDICATOR_PIN.port, LOGGING_WAKE_INDICATOR_PIN.pin, gpioModeWiredOrPullDown, PINOUT_CLEAR);
break;
#endif
case RSI_HAL_RESET_PIN:
GPIO_PinModeSet(WFX_RESET_PIN.port, WFX_RESET_PIN.pin, gpioModePushPull, PINOUT_SET);
break;
Expand All @@ -83,17 +93,27 @@ void rsi_hal_config_gpio(uint8_t gpio_number, uint8_t mode, uint8_t value)
*/
void rsi_hal_set_gpio(uint8_t gpio_number)
{
// WFX_RSI_LOG ("RSI: SET GPIO: 0x%x", gpio_number);
switch (gpio_number)
{
case RSI_HAL_SLEEP_CONFIRM_PIN:
case RSI_HAL_LP_SLEEP_CONFIRM_PIN:
GPIO_PinModeSet(WFX_SLEEP_CONFIRM_PIN.port, WFX_SLEEP_CONFIRM_PIN.pin, gpioModeWiredOrPullDown, PINOUT_SET);
break;
case RSI_HAL_WAKEUP_INDICATION_PIN:
#ifndef LOGGING_STATS
GPIO_PinModeSet(WAKE_INDICATOR_PIN.port, WAKE_INDICATOR_PIN.pin, gpioModeInput, PINOUT_SET);
break;
#else
GPIO_PinModeSet(LOGGING_WAKE_INDICATOR_PIN.port, LOGGING_WAKE_INDICATOR_PIN.pin, gpioModeInput, PINOUT_SET);
break;
#endif
case RSI_HAL_RESET_PIN:
GPIO_PinModeSet(WFX_RESET_PIN.port, WFX_RESET_PIN.pin, gpioModeWiredOrPullDown, PINOUT_SET);
break;
default:
break;
}
}

/*===========================================================*/
/**
* @fn uint8_t rsi_hal_get_gpio(void)
Expand All @@ -105,20 +125,26 @@ void rsi_hal_set_gpio(uint8_t gpio_number)
*/
uint8_t rsi_hal_get_gpio(uint8_t gpio_number)
{
// WFX_RSI_LOG ("RSI: GET GPIO: 0x%x", gpio_number);
switch (gpio_number)
{
case RSI_HAL_SLEEP_CONFIRM_PIN:
case RSI_HAL_LP_SLEEP_CONFIRM_PIN:
return GPIO_PinInGet(WFX_SLEEP_CONFIRM_PIN.port, WFX_SLEEP_CONFIRM_PIN.pin);
case RSI_HAL_WAKEUP_INDICATION_PIN:
#ifndef LOGGING_STATS
return GPIO_PinInGet(WAKE_INDICATOR_PIN.port, WAKE_INDICATOR_PIN.pin);
#else
return GPIO_PinInGet(LOGGING_WAKE_INDICATOR_PIN.port, LOGGING_WAKE_INDICATOR_PIN.pin);
#endif
case RSI_HAL_RESET_PIN:
return GPIO_PinInGet(WFX_RESET_PIN.port, WFX_RESET_PIN.pin);
case RSI_HAL_MODULE_INTERRUPT_PIN:
return GPIO_PinInGet(WFX_INTERRUPT_PIN.port, WFX_INTERRUPT_PIN.pin);
default:
break;
}

return 0;
}

/*===========================================================*/
/**
* @fn void rsi_hal_set_gpio(uint8_t gpio_number)
Expand All @@ -130,11 +156,23 @@ uint8_t rsi_hal_get_gpio(uint8_t gpio_number)
*/
void rsi_hal_clear_gpio(uint8_t gpio_number)
{
// WFX_RSI_LOG ("RSI: CLR GPIO: 0x%x", gpio_number);
switch (gpio_number)
{
case RSI_HAL_SLEEP_CONFIRM_PIN:
case RSI_HAL_LP_SLEEP_CONFIRM_PIN:
GPIO_PinOutClear(WFX_SLEEP_CONFIRM_PIN.port, WFX_SLEEP_CONFIRM_PIN.pin);
break;
case RSI_HAL_WAKEUP_INDICATION_PIN:
#ifndef LOGGING_STATS
GPIO_PinOutClear(WAKE_INDICATOR_PIN.port, WAKE_INDICATOR_PIN.pin);
break;
#else
GPIO_PinOutClear(LOGGING_WAKE_INDICATOR_PIN.port, LOGGING_WAKE_INDICATOR_PIN.pin);
break;
#endif
case RSI_HAL_RESET_PIN:
return GPIO_PinOutClear(WFX_RESET_PIN.port, WFX_RESET_PIN.pin);
GPIO_PinOutClear(WFX_RESET_PIN.port, WFX_RESET_PIN.pin);
break;
default:
break;
}
Expand Down
27 changes: 27 additions & 0 deletions examples/platform/silabs/efr32/rs911x/rsi_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,25 @@ int32_t wfx_rsi_disconnect()
return status;
}

/******************************************************************
* @fn wfx_rsi_power_save()
* @brief
* Setting the RS911x in DTIM sleep based mode
*
* @param[in] None
* @return
* None
*********************************************************************/
void wfx_rsi_power_save()
{
int32_t status = rsi_wlan_power_save_profile(RSI_SLEEP_MODE_2, RSI_MAX_PSP);
if (status != RSI_SUCCESS)
{
WFX_RSI_LOG("Powersave Config Failed, Error Code : 0x%lX", status);
return;
}
WFX_RSI_LOG("Powersave Config Success");
}
/******************************************************************
* @fn wfx_rsi_join_cb(uint16_t status, const uint8_t *buf, const uint16_t len)
* @brief
Expand Down Expand Up @@ -654,6 +673,10 @@ void wfx_rsi_task(void * arg)
{
wfx_dhcp_got_ipv4((uint32_t) sta_netif->ip_addr.u_addr.ip4.addr);
hasNotifiedIPV4 = true;
#if CHIP_DEVICE_CONFIG_ENABLE_SED
// enabling the power save mode for RS9116 if sleepy device is enabled
wfx_rsi_power_save();
#endif /* CHIP_DEVICE_CONFIG_ENABLE_SED */
if (!hasNotifiedWifiConnectivity)
{
wfx_connected_notify(CONNECTION_STATUS_SUCCESS, &wfx_rsi.ap_mac);
Expand All @@ -673,6 +696,10 @@ void wfx_rsi_task(void * arg)
{
wfx_ipv6_notify(GET_IPV6_SUCCESS);
hasNotifiedIPV6 = true;
#if CHIP_DEVICE_CONFIG_ENABLE_SED
// enabling the power save mode for RS9116 if sleepy device is enabled
wfx_rsi_power_save();
#endif /* CHIP_DEVICE_CONFIG_ENABLE_SED */
if (!hasNotifiedWifiConnectivity)
{
wfx_connected_notify(CONNECTION_STATUS_SUCCESS, &wfx_rsi.ap_mac);
Expand Down
17 changes: 9 additions & 8 deletions examples/platform/silabs/efr32/rs911x/rsi_wlan_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,18 +54,19 @@

//! To set Extended custom feature select bit map
#if WIFI_ENABLE_SECURITY_WPA3
#ifdef RSI_M4_INTERFACE
#define RSI_EXT_CUSTOM_FEATURE_BIT_MAP (EXT_FEAT_256K_MODE | EXT_FEAT_IEEE_80211W)
#ifdef CHIP_9117
#define RSI_EXT_CUSTOM_FEATURE_BIT_MAP \
(EXT_FEAT_448K_M4SS_256K | EXT_FEAT_IEEE_80211W | EXT_FEAT_LOW_POWER_MODE | EXT_FEAT_XTAL_CLK_ENABLE)
#else
#define RSI_EXT_CUSTOM_FEATURE_BIT_MAP (EXT_FEAT_384K_MODE | EXT_FEAT_IEEE_80211W)
#endif
#endif /* CHIP_9117 */
#else
#ifdef RSI_M4_INTERFACE
#define RSI_EXT_CUSTOM_FEATURE_BIT_MAP EXT_FEAT_256K_MODE
#ifdef CHIP_9117
#define RSI_EXT_CUSTOM_FEATURE_BIT_MAP (EXT_FEAT_448K_M4SS_256K | EXT_FEAT_LOW_POWER_MODE | EXT_FEAT_XTAL_CLK_ENABLE)
#else
#define RSI_EXT_CUSTOM_FEATURE_BIT_MAP EXT_FEAT_384K_MODE
#endif
#endif
#endif /* CHIP_9117 */
#endif /* WIFI_ENABLE_SECURITY_WPA3 */

//! To set Extended TCPIP feature select bit map
#define RSI_EXT_TCPIP_FEATURE_BITMAP (/*EXT_FEAT_HTTP_OTAF_SUPPORT |*/ EXT_TCP_IP_SSL_16K_RECORD)
Expand Down Expand Up @@ -309,7 +310,7 @@
//! Power save command parameters
/*=======================================================================*/
//! set handshake type of power mode
#define RSI_HAND_SHAKE_TYPE MSG_BASED
#define RSI_HAND_SHAKE_TYPE GPIO_BASED

//! 0 - LP, 1- ULP mode with RAM retention and 2 - ULP with Non RAM retention
#define RSI_SELECT_LP_OR_ULP_MODE RSI_ULP_WITH_RAM_RET
Expand Down
5 changes: 5 additions & 0 deletions src/platform/silabs/CHIPDevicePlatformConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@
#define CHIP_DEVICE_CONFIG_ENABLE_IPV4 0
#endif /* CHIP_DEVICE_CONFIG_ENABLE_IPV4 */

#ifdef CHIP_DEVICE_CONFIG_ENABLE_SED
#define CHIP_DEVICE_CONFIG_SED_IDLE_INTERVAL chip::System::Clock::Milliseconds32(300)
#define CHIP_DEVICE_CONFIG_SED_ACTIVE_INTERVAL chip::System::Clock::Milliseconds32(10)
#endif /* CHIP_DEVICE_CONFIG_ENABLE_SED */

#endif /* SL_WIFI */

// ========== Platform-specific Configuration =========
Expand Down
8 changes: 7 additions & 1 deletion src/platform/silabs/ConnectivityManagerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,13 @@ class ConnectivityManagerImpl final : public ConnectivityManager,
bool _CanStartWiFiScan();
void _OnWiFiScanDone();
void _OnWiFiStationProvisionChange();
#endif
#if CHIP_DEVICE_CONFIG_ENABLE_SED
ConnectivityManager::SEDIntervalsConfig mIntervalsConfig;
CHIP_ERROR _GetSEDIntervalsConfig(ConnectivityManager::SEDIntervalsConfig & intervalsConfig);
CHIP_ERROR _SetSEDIntervalsConfig(const ConnectivityManager::SEDIntervalsConfig & intervalsConfig);
CHIP_ERROR _RequestSEDActiveMode(bool onOff, bool delayIdle = false);
#endif /* CHIP_DEVICE_CONFIG_ENABLE_SED */
#endif /* CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION */
// ===== Members for internal use by the following friends.

friend ConnectivityManager & ConnectivityMgr(void);
Expand Down
23 changes: 23 additions & 0 deletions src/platform/silabs/ConnectivityManagerImpl_WIFI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,29 @@ void ConnectivityManagerImpl::_OnWiFiStationProvisionChange()
DeviceLayer::SystemLayer().ScheduleWork(DriveStationState, NULL);
}

#if CHIP_DEVICE_CONFIG_ENABLE_SED
CHIP_ERROR ConnectivityManagerImpl::_GetSEDIntervalsConfig(ConnectivityManager::SEDIntervalsConfig & SEDIntervalsConfig)
{
// For now Wi-Fi uses DTIM power save mode so it varies from AP to AP
// TODO: Change this to DTIM read from DUT once it is done. For now hardcoding it
SEDIntervalsConfig.ActiveIntervalMS = CHIP_DEVICE_CONFIG_SED_ACTIVE_INTERVAL;
SEDIntervalsConfig.IdleIntervalMS = CHIP_DEVICE_CONFIG_SED_IDLE_INTERVAL;
return CHIP_NO_ERROR;
}

CHIP_ERROR ConnectivityManagerImpl::_SetSEDIntervalsConfig(const ConnectivityManager::SEDIntervalsConfig & intervalsConfig)
{
// not required
return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
}

CHIP_ERROR ConnectivityManagerImpl::_RequestSEDActiveMode(bool onOff, bool delayIdle)
{
// not required
return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE;
}
#endif /* CHIP_DEVICE_CONFIG_ENABLE_SED */

// == == == == == == == == == == ConnectivityManager Private Methods == == == == == == == == == ==

void ConnectivityManagerImpl::DriveStationState()
Expand Down
6 changes: 5 additions & 1 deletion third_party/silabs/efr32_sdk.gni
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,11 @@ template("efr32_sdk") {
if (use_SiWx917) {
#Added this flag only for SiwX917 NCP board
#TODO: Remove when rsi_wlan_ext_stats gets implemented using Wisemcu SDK
defines += [ "SiWx917_WIFI" ]
defines += [
"SiWx917_WIFI",
"EXP_BOARD=1",
"CHIP_9117=1",
]
} else if (use_wf200) {
defines += [
"SL_HEAP_SIZE=24576",
Expand Down