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

[SL-UP] Add brd4357a support #115

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
16 changes: 9 additions & 7 deletions src/platform/silabs/wifi/SiWx/WifiInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,19 @@ osMessageQueueId_t sWifiEventQueue = nullptr;
sl_net_wifi_lwip_context_t wifi_client_context;
sl_wifi_security_t security = SL_WIFI_SECURITY_UNKNOWN;

// TODO : Temporary work-around for wifi-init failure in 917NCP ACX module board(BRD4357A). Can be removed after
// Wiseconnect fixes region code for all ACX module boards.
#ifdef EXP_BOARD
#define REGION_CODE IGNORE_REGION
#else
#define REGION_CODE US
#endif // EXP_BOARD
mkardous-silabs marked this conversation as resolved.
Show resolved Hide resolved

const sl_wifi_device_configuration_t config = {
.boot_option = LOAD_NWP_FW,
.mac_address = NULL,
.band = SL_SI91X_WIFI_BAND_2_4GHZ,
.region_code = US,
.region_code = REGION_CODE,
.boot_config = { .oper_mode = SL_SI91X_CLIENT_MODE,
.coex_mode = SL_SI91X_WLAN_BLE_MODE,
.feature_bit_map =
Expand Down Expand Up @@ -281,8 +289,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 @@ -307,14 +313,11 @@ 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
Expand All @@ -337,7 +340,6 @@ sl_status_t InitiateScan()
}

osSemaphoreRelease(sScanInProgressSemaphore);
#endif

return status;
}
Expand Down
196 changes: 72 additions & 124 deletions src/platform/silabs/wifi/rs911x/platform/efx32_ncp_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
#include "sl_constants.h"
#include "sl_rsi_utility.h"
#include "sl_si91x_host_interface.h"
#include "sl_si91x_ncp_utility.h"
#include "sl_si91x_status.h"
#include "sl_si91x_ncp_utility.h"
#include "sl_status.h"
#include "sl_wifi_constants.h"
#include <platform/silabs/wifi/wf200/platform/spi_multiplex.h>
Expand All @@ -42,35 +42,35 @@
#include "sl_board_control.h"
#endif // SL_BOARD_NAME

static bool dma_callback(unsigned int channel, unsigned int sequenceNo, void * userParam);
#include "sl_spidrv_exp_config.h"
#include "sl_spidrv_instances.h"
#include "spidrv.h"

#define MAX_DATA_PACKET_SIZE 1800
#define LDMA_MAX_TRANSFER_LENGTH 4096
#define LDMA_DESCRIPTOR_ARRAY_LENGTH (LDMA_MAX_TRANSFER_LENGTH / 2048)

// use SPI handle for EXP header (configured in project settings)
extern SPIDRV_Handle_t sl_spidrv_exp_handle;
#define SPI_HANDLE sl_spidrv_exp_handle
static uint8_t dummy_buffer[MAX_DATA_PACKET_SIZE] = { 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_Descriptor_t ldmaTXDescriptor[LDMA_DESCRIPTOR_ARRAY_LENGTH];
LDMA_TransferCfg_t ldmaTXConfig;

// LDMA descriptor and transfer configuration structures for USART RX channel
LDMA_Descriptor_t ldmaRXDescriptor;
LDMA_Descriptor_t ldmaRXDescriptor[LDMA_DESCRIPTOR_ARRAY_LENGTH];
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 +79,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 +108,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))
arun-silabs marked this conversation as resolved.
Show resolved Hide resolved
{
}
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 +172,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 +202,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 +232,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)
{
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 (ECODE_EMDRV_SPIDRV_BUSY == si91x_SPIDRV_MTransfer(SPI_HANDLE, tx_buffer, rx_buffer, buffer_length, spi_dma_callback))
{
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 +249,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