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] Fixed the 917 NCP init #37147

Merged
merged 16 commits into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from 8 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
2 changes: 1 addition & 1 deletion examples/platform/silabs/BaseApplication.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ void BaseApplicationDelegate::OnCommissioningSessionStopped()

void BaseApplicationDelegate::OnCommissioningWindowClosed()
{
#if CHIP_CONFIG_ENABLE_ICD_SERVER && SLI_SI917
#if CHIP_CONFIG_ENABLE_ICD_SERVER && (defined(SLI_SI91X_MCU_INTERFACE) && SLI_SI91X_MCU_INTERFACE == 1)
if (!BaseApplication::GetProvisionStatus() && !isComissioningStarted)
{
int32_t status = wfx_power_save(RSI_SLEEP_MODE_8, DEEP_SLEEP_WITH_RAM_RETENTION);
Expand Down
11 changes: 7 additions & 4 deletions examples/platform/silabs/MatterConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,13 @@
#endif

// TODO: We shouldn't need any platform specific includes in this file
#if defined(SLI_SI91X_MCU_INTERFACE) && SLI_SI91X_MCU_INTERFACE == 1
#if (defined(SLI_SI91X_MCU_INTERFACE) && SLI_SI91X_MCU_INTERFACE == 1)
#include <platform/silabs/SiWx917/SiWxPlatformInterface.h>
#endif // (defined(SLI_SI91X_MCU_INTERFACE) && SLI_SI91X_MCU_INTERFACE == 1 )

#if ((defined(SLI_SI91X_MCU_INTERFACE) && SLI_SI91X_MCU_INTERFACE == 1) || defined(EXP_BOARD))
#include <platform/silabs/wifi/wiseconnect-interface/WiseconnectWifiInterface.h>
#endif // SLI_SI91X_MCU_INTERFACE
#endif // ((defined(SLI_SI91X_MCU_INTERFACE) && SLI_SI91X_MCU_INTERFACE == 1) || defined(EXP_BOARD))

#include <crypto/CHIPCryptoPAL.h>
// If building with the EFR32-provided crypto backend, we can use the
Expand Down Expand Up @@ -321,9 +324,9 @@ CHIP_ERROR SilabsMatterConfig::InitWiFi(void)
#endif // WF200_WIFI

// TODO: Platform specific init should not be required here
#if defined(SLI_SI91X_MCU_INTERFACE) && SLI_SI91X_MCU_INTERFACE == 1
#if ((defined(SLI_SI91X_MCU_INTERFACE) && SLI_SI91X_MCU_INTERFACE == 1) || defined(EXP_BOARD))
VerifyOrReturnError(InitSiWxWifi() == SL_STATUS_OK, CHIP_ERROR_INTERNAL);
#endif // SLI_SI91X_MCU_INTERFACE
#endif //((defined(SLI_SI91X_MCU_INTERFACE) && SLI_SI91X_MCU_INTERFACE == 1 ) || defined(EXP_BOARD))

return CHIP_NO_ERROR;
}
Expand Down
2 changes: 1 addition & 1 deletion scripts/examples/gn_silabs_example.sh
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ else
if [ "$2" = "rs9116" ]; then
optArgs+="use_rs9116=true "
elif [ "$2" = "SiWx917" ]; then
optArgs+="use_SiWx917=true "
optArgs+="use_SiWx917=true disable_lcd=true use_external_flash=false "
elif [ "$2" = "wf200" ]; then
optArgs+="use_wf200=true "
else
Expand Down
4 changes: 2 additions & 2 deletions src/platform/silabs/PlatformManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,10 @@ CHIP_ERROR PlatformManagerImpl::_InitChipStack(void)
err = chip::DeviceLayer::PersistedStorage::KeyValueStoreMgrImpl().Init();
SuccessOrExit(err);

#if CHIP_SYSTEM_CONFIG_USE_LWIP && !defined(SLI_SI91X_MCU_INTERFACE)
#if CHIP_SYSTEM_CONFIG_USE_LWIP && !defined(SLI_SI91X_MCU_INTERFACE) && !defined(EXP_BOARD)
// Initialize LwIP.
tcpip_init(NULL, NULL);
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP && !defined(SLI_SI91X_MCU_INTERFACE)
#endif // CHIP_SYSTEM_CONFIG_USE_LWIP && !defined(SLI_SI91X_MCU_INTERFACE) && !defined(EXP_BOARD)

ReturnErrorOnFailure(System::Clock::InitClock_RealTime());

Expand Down
13 changes: 0 additions & 13 deletions src/platform/silabs/wifi/SiWx/WifiInterfaceImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,12 +281,6 @@ sl_status_t sl_wifi_siwx917_init(void)
RSI_NPSSGPIO_InputBufferEn(RTE_UULP_GPIO_1_PIN, 1);
#endif // ENABLE_CHIP_SHELL
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER

#else
// NCP Configurations
status = InitSiWxWifi();
VerifyOrReturnError(status == SL_STATUS_OK, status,
ChipLogError(DeviceLayer, "InitSiWxWifi failed: 0x%lx", static_cast<uint32_t>(status)));
#endif // SLI_SI91X_MCU_INTERFACE

sl_wifi_firmware_version_t version = { 0 };
Expand Down Expand Up @@ -320,8 +314,6 @@ sl_status_t sl_wifi_siwx917_init(void)
return status;
}

// TODO: this changes will be reverted back after the Silabs WiFi SDK team fix the scan API
#ifndef EXP_BOARD
sl_status_t ScanCallback(sl_wifi_event_t event, sl_wifi_scan_result_t * scan_result, uint32_t result_length, void * arg)
{
sl_status_t status = SL_STATUS_OK;
Expand All @@ -346,17 +338,13 @@ sl_status_t ScanCallback(sl_wifi_event_t event, sl_wifi_scan_result_t * scan_res
osSemaphoreRelease(sScanCompleteSemaphore);
return status;
}
#endif

sl_status_t InitiateScan()
{
sl_status_t status = SL_STATUS_OK;

// TODO: this changes will be reverted back after the Silabs WiFi SDK team fix the scan API
#ifndef EXP_BOARD
sl_wifi_ssid_t ssid = { 0 };

// TODO: this changes will be reverted back after the Silabs WiFi SDK team fix the scan API
sl_wifi_scan_configuration_t wifi_scan_configuration = default_wifi_scan_configuration;

ssid.length = wfx_rsi.sec.ssid_length;
Expand All @@ -376,7 +364,6 @@ sl_status_t InitiateScan()
}

osSemaphoreRelease(sScanInProgressSemaphore);
#endif

return status;
}
Expand Down
200 changes: 69 additions & 131 deletions src/platform/silabs/wifi/SiWx/ncp/efx32_ncp_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,11 @@
#include "sl_si91x_host_interface.h"
#include "sl_si91x_ncp_utility.h"
#include "sl_si91x_status.h"
#include "sl_spidrv_exp_config.h"
#include "sl_spidrv_instances.h"
#include "sl_status.h"
#include "sl_wifi_constants.h"
#include "spidrv.h"
#include <platform/silabs/wifi/SiWx/ncp/sl_board_configuration.h>
#include <platform/silabs/wifi/ncp/spi_multiplex.h>
#include <stdbool.h>
Expand All @@ -42,35 +45,22 @@
#include "sl_board_control.h"
#endif // SL_BOARD_NAME

static bool dma_callback(unsigned int channel, unsigned int sequenceNo, void * userParam);
#define LDMA_MAX_TRANSFER_LENGTH 4096
#define LDMA_DESCRIPTOR_ARRAY_LENGTH (LDMA_MAX_TRANSFER_LENGTH / 2048)
#define SPI_HANDLE sl_spidrv_exp_handle
#define MAX_DATA_PACKET_SIZE 1800

// use SPI handle for EXP header (configured in project settings)
extern SPIDRV_Handle_t sl_spidrv_exp_handle;
static uint8_t dummy_buffer[MAX_DATA_PACKET_SIZE] = { 0 };
static sl_si91x_host_init_configuration init_config = { 0 };

uint32_t rx_ldma_channel;
uint32_t tx_ldma_channel;
osMutexId_t ncp_transfer_mutex = 0;

static uint32_t dummy_buffer;
static sl_si91x_host_init_configuration init_config = { 0 };

// LDMA descriptor and transfer configuration structures for USART TX channel
LDMA_Descriptor_t ldmaTXDescriptor;
LDMA_TransferCfg_t ldmaTXConfig;

// LDMA descriptor and transfer configuration structures for USART RX channel
LDMA_Descriptor_t ldmaRXDescriptor;
LDMA_TransferCfg_t ldmaRXConfig;

static osSemaphoreId_t transfer_done_semaphore = NULL;

static bool dma_callback([[maybe_unused]] unsigned int channel, [[maybe_unused]] unsigned int sequenceNo,
[[maybe_unused]] void * userParam)
{
#if defined(SL_CATLOG_POWER_MANAGER_PRESENT)
sl_power_manager_remove_em_requirement(SL_POWER_MANAGER_EM1);
#endif
osSemaphoreRelease(transfer_done_semaphore);
return false;
}

static void gpio_interrupt([[maybe_unused]] uint8_t interrupt_number)
{
if (NULL != init_config.rx_irq)
Expand All @@ -79,54 +69,27 @@ static void gpio_interrupt([[maybe_unused]] uint8_t interrupt_number)
}
}

static void efx32_spi_init(void)
static void spi_dma_callback(struct SPIDRV_HandleData * handle, Ecode_t transferStatus, int itemsTransferred)
{
// Default asynchronous initializer (master mode, 1 Mbps, 8-bit data)
USART_InitSync_TypeDef init = USART_INITSYNC_DEFAULT;
UNUSED_PARAMETER(handle);
UNUSED_PARAMETER(transferStatus);
UNUSED_PARAMETER(itemsTransferred);
#if defined(SL_CATLOG_POWER_MANAGER_PRESENT)
sl_power_manager_remove_em_requirement(SL_POWER_MANAGER_EM1);
#endif
osSemaphoreRelease(transfer_done_semaphore);
return;
}

init.msbf = true; // MSB first transmission for SPI compatibility
init.autoCsEnable = false;
init.baudrate = USART_INITSYNC_BAUDRATE;
static void efx32_spi_init(void)
{
SPIDRV_SetBitrate(SPI_HANDLE, USART_INITSYNC_BAUDRATE);

// Configure SPI bus pins
GPIO_PinModeSet(SPI_MISO_PIN.port, SPI_MISO_PIN.pin, gpioModeInput, 0);
GPIO_PinModeSet(SPI_MOSI_PIN.port, SPI_MOSI_PIN.pin, gpioModePushPull, 0);
GPIO_PinModeSet(SPI_CLOCK_PIN.port, SPI_CLOCK_PIN.pin, gpioModePushPullAlternate, 0);
GPIO_PinModeSet(SPI_CS_PIN.port, SPI_CS_PIN.pin, gpioModePushPull, 1);
// Enable clock (not needed on xG21)
CMU_ClockEnable(SPI_USART_CMU_CLOCK, true);

/*
* Route USART RX, TX, and CLK to the specified pins. Note that CS is
* not controlled by USART so there is no write to the corresponding
* USARTROUTE register to do this.
*/
GPIO->USARTROUTE[SPI_USART_ROUTE_INDEX].RXROUTE =
(SPI_MISO_PIN.port << _GPIO_USART_RXROUTE_PORT_SHIFT) | (SPI_MISO_PIN.pin << _GPIO_USART_RXROUTE_PIN_SHIFT);
GPIO->USARTROUTE[SPI_USART_ROUTE_INDEX].TXROUTE =
(SPI_MOSI_PIN.port << _GPIO_USART_TXROUTE_PORT_SHIFT) | (SPI_MOSI_PIN.pin << _GPIO_USART_TXROUTE_PIN_SHIFT);
GPIO->USARTROUTE[SPI_USART_ROUTE_INDEX].CLKROUTE =
(SPI_CLOCK_PIN.port << _GPIO_USART_CLKROUTE_PORT_SHIFT) | (SPI_CLOCK_PIN.pin << _GPIO_USART_CLKROUTE_PIN_SHIFT);
GPIO->USARTROUTE[SPI_USART_ROUTE_INDEX].CSROUTE =
(SPI_CS_PIN.port << _GPIO_USART_CSROUTE_PORT_SHIFT) | (SPI_CS_PIN.pin << _GPIO_USART_CSROUTE_PIN_SHIFT);

// Enable USART interface pins
GPIO->USARTROUTE[SPI_USART_ROUTE_INDEX].ROUTEEN = GPIO_USART_ROUTEEN_RXPEN | // MISO
GPIO_USART_ROUTEEN_TXPEN | // MOSI
#if !SL_SPICTRL_MUX
GPIO_USART_ROUTEEN_CSPEN |
#endif
GPIO_USART_ROUTEEN_CLKPEN;

// Set slew rate for alternate usage pins
GPIO_SlewrateSet(SPI_CLOCK_PIN.port, 7, 7);

// Configure and enable USART
USART_InitSync(SPI_USART, &init);

SPI_USART->TIMING |= USART_TIMING_TXDELAY_ONE | USART_TIMING_CSSETUP_ONE | USART_TIMING_CSHOLD_ONE;

// SPI_USART->CTRL_SET |= USART_CTRL_SMSDELAY;

// configure packet pending interrupt priority
NVIC_SetPriority(GPIO_ODD_IRQn, PACKET_PENDING_INT_PRI);
Expand All @@ -135,6 +98,45 @@ static void efx32_spi_init(void)
GPIO_ExtIntConfig(INTERRUPT_PIN.port, INTERRUPT_PIN.pin, INTERRUPT_PIN.pin, true, false, true);
}

Ecode_t si91x_SPIDRV_MTransfer(SPIDRV_Handle_t handle, const void * txBuffer, void * rxBuffer, int count,
SPIDRV_Callback_t callback)
{
USART_TypeDef * usart = handle->initData.port;
uint8_t * tx = (txBuffer != NULL) ? (uint8_t *) txBuffer : dummy_buffer;
uint8_t * rx = (rxBuffer != NULL) ? (uint8_t *) rxBuffer : dummy_buffer;

if (count < 16)
{
while (count > 0)
{
while (!(usart->STATUS & USART_STATUS_TXBL))
{
}
usart->TXDATA = (uint32_t) *tx;
while (!(usart->STATUS & USART_STATUS_TXC))
{
}
*rx = (uint8_t) usart->RXDATA;
if (txBuffer != NULL)
{
tx++;
}
if (rxBuffer != NULL)
{
rx++;
}
count--;
}
// callback(handle, ECODE_EMDRV_SPIDRV_OK, 0);
return ECODE_EMDRV_SPIDRV_OK;
}
else
{
SPIDRV_MTransfer(handle, tx, rx, count, callback);
}
return ECODE_EMDRV_SPIDRV_BUSY;
}

void sl_si91x_host_set_sleep_indicator(void)
{
GPIO_PinOutSet(SLEEP_CONFIRM_PIN.port, SLEEP_CONFIRM_PIN.pin);
Expand All @@ -160,15 +162,16 @@ sl_status_t sl_si91x_host_init(const sl_si91x_host_init_configuration * config)
return status;
}
#endif // SL_SPICTRL_MUX
init_config.rx_irq = config->rx_irq;
init_config.rx_done = config->rx_done;
init_config.rx_irq = config->rx_irq;
init_config.rx_done = config->rx_done;
init_config.boot_option = config->boot_option;

// Enable clock (not needed on xG21)
CMU_ClockEnable(cmuClock_GPIO, true);

#if SL_SPICTRL_MUX
spi_board_init();
#endif
#endif // SL_SPICTRL_MUX

if (transfer_done_semaphore == NULL)
{
Expand All @@ -189,10 +192,6 @@ sl_status_t sl_si91x_host_init(const sl_si91x_host_init_configuration * config)
GPIO_PinModeSet(SLEEP_CONFIRM_PIN.port, SLEEP_CONFIRM_PIN.pin, gpioModeWiredOrPullDown, 1);
GPIO_PinModeSet(WAKE_INDICATOR_PIN.port, WAKE_INDICATOR_PIN.pin, gpioModeWiredOrPullDown, 0);

DMADRV_Init();
DMADRV_AllocateChannel((unsigned int *) &rx_ldma_channel, NULL);
DMADRV_AllocateChannel((unsigned int *) &tx_ldma_channel, NULL);

return SL_STATUS_OK;
}

Expand Down Expand Up @@ -223,68 +222,8 @@ sl_status_t sl_si91x_host_spi_transfer(const void * tx_buffer, void * rx_buffer,
sl_wfx_host_spi_cs_assert();
#endif // SL_SPICTRL_MUX

if (buffer_length < 16)
if (ECODE_EMDRV_SPIDRV_BUSY == si91x_SPIDRV_MTransfer(SPI_HANDLE, tx_buffer, rx_buffer, buffer_length, spi_dma_callback))
{
uint8_t * tx = (tx_buffer != NULL) ? (uint8_t *) tx_buffer : (uint8_t *) &dummy_buffer;
uint8_t * rx = (rx_buffer != NULL) ? (uint8_t *) rx_buffer : (uint8_t *) &dummy_buffer;
while (buffer_length > 0)
{
while (!(SPI_USART->STATUS & USART_STATUS_TXBL))
{
}
SPI_USART->TXDATA = (uint32_t) *tx;
while (!(SPI_USART->STATUS & USART_STATUS_TXC))
{
}
*rx = (uint8_t) SPI_USART->RXDATA;
if (tx_buffer != NULL)
{
tx++;
}
if (rx_buffer != NULL)
{
rx++;
}
buffer_length--;
}
}
else
{
if (tx_buffer == NULL)
{
dummy_buffer = 0;
ldmaTXDescriptor =
(LDMA_Descriptor_t) LDMA_DESCRIPTOR_SINGLE_P2P_BYTE(&dummy_buffer, &(SPI_USART->TXDATA), buffer_length);
}
else
{
ldmaTXDescriptor = (LDMA_Descriptor_t) LDMA_DESCRIPTOR_SINGLE_M2P_BYTE(tx_buffer, &(SPI_USART->TXDATA), buffer_length);
}

if (rx_buffer == NULL)
{
ldmaRXDescriptor =
(LDMA_Descriptor_t) LDMA_DESCRIPTOR_SINGLE_P2P_BYTE(&(SPI_USART->RXDATA), &dummy_buffer, buffer_length);
}
else
{
ldmaRXDescriptor = (LDMA_Descriptor_t) LDMA_DESCRIPTOR_SINGLE_P2M_BYTE(&(SPI_USART->RXDATA), rx_buffer, buffer_length);
}

// Transfer a byte on free space in the USART buffer
ldmaTXConfig = (LDMA_TransferCfg_t) LDMA_TRANSFER_CFG_PERIPHERAL(SPI_USART_LDMA_TX);

// Transfer a byte on receive data valid
ldmaRXConfig = (LDMA_TransferCfg_t) LDMA_TRANSFER_CFG_PERIPHERAL(SPI_USART_LDMA_RX);

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

// Start both channels
DMADRV_LdmaStartTransfer(rx_ldma_channel, &ldmaRXConfig, &ldmaRXDescriptor, dma_callback, NULL);
DMADRV_LdmaStartTransfer(tx_ldma_channel, &ldmaTXConfig, &ldmaTXDescriptor, NULL, NULL);

if (osSemaphoreAcquire(transfer_done_semaphore, 1000) != osOK)
{
BREAKPOINT();
Expand All @@ -300,7 +239,6 @@ sl_status_t sl_si91x_host_spi_transfer(const void * tx_buffer, void * rx_buffer,

void sl_si91x_host_hold_in_reset(void)
{
GPIO_PinModeSet(RESET_PIN.port, RESET_PIN.pin, gpioModePushPull, 1);
GPIO_PinOutClear(RESET_PIN.port, RESET_PIN.pin);
}

Expand Down
Loading