Skip to content

Commit

Permalink
[Silabs] Enabling the sleepy device for EFR32 and rs911x combo (#25519)
Browse files Browse the repository at this point in the history
* enabling the sleepy device for EFR32 and rs911x combo

* Restyled by whitespace

* Restyled by clang-format

* Restyled by gn

* addressing review comments

* 917 modifications and addressing some review comments

* Adding comments on the DMA transactions

* Restyled by clang-format

* modifying the function signature

* switch case modifications as per the suggestions

* bugfix switch case missed break

* addressing review comments

* Restyled by clang-format

* addressing review comments

* restyle changes

* Addressing review comments

* sleepy devices when rs9116 ble is in use

---------

Co-authored-by: Restyled.io <[email protected]>
  • Loading branch information
2 people authored and pull[bot] committed Aug 26, 2023
1 parent 30aac61 commit 2280408
Show file tree
Hide file tree
Showing 12 changed files with 172 additions and 27 deletions.
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
53 changes: 44 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,19 @@ 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);
#else
GPIO_PinModeSet(LOGGING_WAKE_INDICATOR_PIN.port, LOGGING_WAKE_INDICATOR_PIN.pin, gpioModeWiredOrPullDown, PINOUT_CLEAR);
#endif
break;
case RSI_HAL_RESET_PIN:
GPIO_PinModeSet(WFX_RESET_PIN.port, WFX_RESET_PIN.pin, gpioModePushPull, PINOUT_SET);
break;
Expand All @@ -83,17 +92,26 @@ 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);
#else
GPIO_PinModeSet(LOGGING_WAKE_INDICATOR_PIN.port, LOGGING_WAKE_INDICATOR_PIN.pin, gpioModeInput, PINOUT_SET);
#endif
break;
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 +123,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 +154,22 @@ 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);
#else
GPIO_PinOutClear(LOGGING_WAKE_INDICATOR_PIN.port, LOGGING_WAKE_INDICATOR_PIN.pin);
#endif
break;
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
33 changes: 33 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,13 @@ 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
#ifndef RSI_BLE_ENABLE
// enabling the power save mode for RS9116 if sleepy device is enabled
// if BLE is used on the rs9116 then powersave config is done after ble disconnect event
wfx_rsi_power_save();
#endif /* RSI_BLE_ENABLE */
#endif /* CHIP_DEVICE_CONFIG_ENABLE_SED */
if (!hasNotifiedWifiConnectivity)
{
wfx_connected_notify(CONNECTION_STATUS_SUCCESS, &wfx_rsi.ap_mac);
Expand All @@ -673,6 +699,13 @@ void wfx_rsi_task(void * arg)
{
wfx_ipv6_notify(GET_IPV6_SUCCESS);
hasNotifiedIPV6 = true;
#if CHIP_DEVICE_CONFIG_ENABLE_SED
#ifndef RSI_BLE_ENABLE
// enabling the power save mode for RS9116 if sleepy device is enabled
// if BLE is used on the rs9116 then powersave config is done after ble disconnect event
wfx_rsi_power_save();
#endif /* RSI_BLE_ENABLE */
#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
18 changes: 18 additions & 0 deletions src/platform/silabs/efr32/rs911x/BLEManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,24 @@ void BLEManagerImpl::HandleConnectionCloseEvent(uint16_t reason)

ChipLogProgress(DeviceLayer, "Disconnect Event for handle : %d", connHandle);

#if CHIP_DEVICE_CONFIG_ENABLE_SED
int32_t status;
status = rsi_bt_power_save_profile(RSI_SLEEP_MODE_2, RSI_MAX_PSP);
if (status != RSI_SUCCESS)
{
WFX_RSI_LOG("BT Powersave Config Failed, Error Code : 0x%lX", status);
return;
}

status = rsi_wlan_power_save_profile(RSI_SLEEP_MODE_2, RSI_MAX_PSP);
if (status != RSI_SUCCESS)
{
WFX_RSI_LOG("WLAN Powersave Config Failed, Error Code : 0x%lX", status);
return;
}
WFX_RSI_LOG("Powersave Config Success");
#endif

if (RemoveConnection(connHandle))
{
ChipDeviceEvent event;
Expand Down
2 changes: 1 addition & 1 deletion src/platform/silabs/efr32/rs911x/rsi_ble_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@
//! Power save command parameters
/*=======================================================================*/
//! set handshake type of power mode
//#define RSI_HAND_SHAKE_TYPE GPIO_BASED
#define RSI_HAND_SHAKE_TYPE GPIO_BASED

#define BLE_ATT_REC_SIZE 500
#define NO_OF_VAL_ATT 5 //! Attribute value count
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 @@ -221,7 +221,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
Loading

0 comments on commit 2280408

Please sign in to comment.