Skip to content

Commit

Permalink
SPI multiplex changes for rs911x
Browse files Browse the repository at this point in the history
  • Loading branch information
kurvaSai authored and rosahay-silabs committed Apr 25, 2023
1 parent f3f7ecd commit 39967ad
Show file tree
Hide file tree
Showing 7 changed files with 239 additions and 26 deletions.
14 changes: 7 additions & 7 deletions examples/platform/silabs/display/demo-ui.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#include "glib.h"
#include <stdio.h>
#include <string.h>
#if (defined(EFR32MG24) && defined(WF200_WIFI))
#if (defined(EFR32MG24) && defined(SL_WIFI))
#include "spi_multiplex.h"
#endif

Expand Down Expand Up @@ -108,11 +108,11 @@ void demoUIDisplayHeader(char * name)
{
GLIB_drawStringOnLine(&glibContext, name, 5, GLIB_ALIGN_CENTER, 0, 0, true);
}
#if (defined(EFR32MG24) && defined(WF200_WIFI))
#if (defined(EFR32MG24) && defined(SL_WIFI))
pre_lcd_spi_transfer();
#endif
DMD_updateDisplay();
#if (defined(EFR32MG24) && defined(WF200_WIFI))
#if (defined(EFR32MG24) && defined(SL_WIFI))
post_lcd_spi_transfer();
#endif
}
Expand All @@ -121,11 +121,11 @@ void demoUIDisplayApp(bool on)
{
GLIB_drawBitmap(&glibContext, APP_X_POSITION, APP_Y_POSITION, APP_BITMAP_WIDTH, APP_BITMAP_HEIGHT,
(on ? OnStateBitMap : OffStateBitMap));
#if (defined(EFR32MG24) && defined(WF200_WIFI))
#if (defined(EFR32MG24) && defined(SL_WIFI))
pre_lcd_spi_transfer();
#endif
DMD_updateDisplay();
#if (defined(EFR32MG24) && defined(WF200_WIFI))
#if (defined(EFR32MG24) && defined(SL_WIFI))
post_lcd_spi_transfer();
#endif
}
Expand All @@ -138,11 +138,11 @@ void demoUIDisplayProtocol(demoUIProtocol protocol, bool isConnected)
(protocol == DEMO_UI_PROTOCOL1 ? PROT1_BITMAP_HEIGHT : PROT2_BITMAP_HEIGHT),
(protocol == DEMO_UI_PROTOCOL1 ? (isConnected ? PROT1_BITMAP_CONN : PROT1_BITMAP)
: (isConnected ? PROT2_BITMAP_CONN : PROT2_BITMAP)));
#if (defined(EFR32MG24) && defined(WF200_WIFI))
#if (defined(EFR32MG24) && defined(SL_WIFI))
pre_lcd_spi_transfer();
#endif
DMD_updateDisplay();
#if (defined(EFR32MG24) && defined(WF200_WIFI))
#if (defined(EFR32MG24) && defined(SL_WIFI))
post_lcd_spi_transfer();
#endif
}
Expand Down
16 changes: 11 additions & 5 deletions examples/platform/silabs/display/lcd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@

#include "sl_board_control.h"

#if (defined(EFR32MG24) && defined(WF200_WIFI))
#if (defined(EFR32MG24) && defined(SL_WIFI))
#include "spi_multiplex.h"
#endif
#define LCD_SIZE 128
Expand Down Expand Up @@ -71,6 +71,12 @@ CHIP_ERROR SilabsLCD::Init(uint8_t * name, bool initialState)
err = CHIP_ERROR_INTERNAL;
}

#if (defined(EFR32MG24) && defined(RS911X_WIFI))
if (pr_type != LCD)
{
pr_type = LCD;
}
#endif
/* Initialize the DMD module for the DISPLAY device driver. */
status = DMD_init(0);
if (DMD_OK != status)
Expand Down Expand Up @@ -121,11 +127,11 @@ int SilabsLCD::DrawPixel(void * pContext, int32_t x, int32_t y)
int SilabsLCD::Update(void)
{
int status;
#if (defined(EFR32MG24) && defined(WF200_WIFI))
#if (defined(EFR32MG24) && defined(SL_WIFI))
pre_lcd_spi_transfer();
#endif
status = DMD_updateDisplay();
#if (defined(EFR32MG24) && defined(WF200_WIFI))
#if (defined(EFR32MG24) && defined(SL_WIFI))
post_lcd_spi_transfer();
#endif
/*
Expand Down Expand Up @@ -194,12 +200,12 @@ void SilabsLCD::WriteQRCode()
}
}
}
#if (defined(EFR32MG24) && defined(WF200_WIFI))
#if (defined(EFR32MG24) && defined(SL_WIFI))
pre_lcd_spi_transfer();
#endif

DMD_updateDisplay();
#if (defined(EFR32MG24) && defined(WF200_WIFI))
#if (defined(EFR32MG24) && defined(SL_WIFI))
post_lcd_spi_transfer();
#endif
}
Expand Down
75 changes: 74 additions & 1 deletion examples/platform/silabs/efr32/rs911x/hal/efx_spi.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,21 @@ extern SPIDRV_Handle_t sl_spidrv_exp_handle;
#define SPI_HANDLE sl_spidrv_exp_handle
#elif defined(EFR32MG24)
#include "sl_spidrv_eusart_exp_config.h"
#include "spi_multiplex.h"
StaticSemaphore_t spi_sem_peripharal;
SemaphoreHandle_t spi_sem_sync_hdl;
peripheraltype_t pr_type = EXP_HDR;
extern SPIDRV_Handle_t sl_spidrv_eusart_exp_handle;
#define SPI_HANDLE sl_spidrv_eusart_exp_handle
#else
#error "Unknown platform"
#endif

static unsigned int tx_dma_channel;
static unsigned int rx_dma_channel;

extern void rsi_gpio_irq_cb(uint8_t irqnum);
//#define RS911X_USE_LDMA
// #define RS911X_USE_LDMA

/********************************************************
* @fn sl_wfx_host_gpio_init(void)
Expand All @@ -88,6 +95,11 @@ void sl_wfx_host_gpio_init(void)
// Enable GPIO clock.
CMU_ClockEnable(cmuClock_GPIO, true);

#if defined(EFR32MG24)
// Set CS pin to high/inactive
GPIO_PinModeSet(SL_SPIDRV_EUSART_EXP_CS_PORT, SL_SPIDRV_EUSART_EXP_CS_PIN, gpioModePushPull, PINOUT_SET);
#endif

GPIO_PinModeSet(WFX_RESET_PIN.port, WFX_RESET_PIN.pin, gpioModePushPull, PINOUT_SET);
GPIO_PinModeSet(WFX_SLEEP_CONFIRM_PIN.port, WFX_SLEEP_CONFIRM_PIN.pin, gpioModePushPull, PINOUT_CLEAR);

Expand Down Expand Up @@ -139,6 +151,11 @@ void rsi_hal_board_init(void)
spiTransferLock = xSemaphoreCreateBinaryStatic(&xEfxSpiIntfSemaBuffer);
xSemaphoreGive(spiTransferLock);

#if defined(EFR32MG24)
spi_sem_sync_hdl = xSemaphoreCreateBinaryStatic(&spi_sem_peripharal);
xSemaphoreGive(spi_sem_sync_hdl);
#endif

/* GPIO INIT of MG12 & MG24 : Reset, Wakeup, Interrupt */
SILABS_LOG("RSI_HAL: init GPIO");
sl_wfx_host_gpio_init();
Expand All @@ -149,6 +166,34 @@ void rsi_hal_board_init(void)
SILABS_LOG("RSI_HAL: Init done");
}

#if defined(EFR32MG24)
/****************************************************************************
* @fn sl_status_t sl_wfx_host_spi_cs_assert()
* @brief
* Assert chip select.
* @param[in] None
* @return returns SL_STATUS_OK
*****************************************************************************/
sl_status_t sl_wfx_host_spi_cs_assert()
{
GPIO_PinOutClear(SL_SPIDRV_EUSART_EXP_CS_PORT, SL_SPIDRV_EUSART_EXP_CS_PIN);
return SL_STATUS_OK;
}

/****************************************************************************
* @fn sl_status_t sl_wfx_host_spi_cs_deassert()
* @brief
* De-Assert chip select.
* @param[in] None
* @return returns SL_STATUS_OK
*****************************************************************************/
sl_status_t sl_wfx_host_spi_cs_deassert()
{
GPIO_PinOutSet(SL_SPIDRV_EUSART_EXP_CS_PORT, SL_SPIDRV_EUSART_EXP_CS_PIN);
return SL_STATUS_OK;
}
#endif

/*****************************************************************************
*@brief
* Spi dma transfer is complete Callback
Expand All @@ -170,6 +215,16 @@ static void spi_dmaTransfertComplete(SPIDRV_HandleData_t * pxHandle, Ecode_t tra
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}

#if defined(EFR32MG24)
void rsi_update_spi(void)
{
spi_switch(EXP_HDR);
// GPIO_PinModeSet(SL_SPIDRV_EUSART_EXP_CS_PORT, SL_SPIDRV_EUSART_EXP_CS_PIN, gpioModePushPull, PINOUT_SET);
/* MG24 + rs9116 combination uses EUSART driver */
tx_dma_channel = sl_spidrv_eusart_exp_handle->txDMACh;
rx_dma_channel = sl_spidrv_eusart_exp_handle->rxDMACh;
}
#endif
/*********************************************************************
* @fn int16_t rsi_spi_transfer(uint8_t *tx_buf, uint8_t *rx_buf, uint16_t xlen, uint8_t mode)
* @brief
Expand All @@ -183,6 +238,19 @@ static void spi_dmaTransfertComplete(SPIDRV_HandleData_t * pxHandle, Ecode_t tra
**************************************************************************/
int16_t rsi_spi_transfer(uint8_t * tx_buf, uint8_t * rx_buf, uint16_t xlen, uint8_t mode)
{
#if defined(EFR32MG24)
/* In case of MG24, take multiplex synchronization semaphore to ensure SPI is
* available and then set CS of Exp Hdr SPI to low/enable */
if (xSemaphoreTake(spi_sem_sync_hdl, portMAX_DELAY) != pdTRUE)
{
return SL_STATUS_TIMEOUT;
}
if (pr_type != EXP_HDR)
{
rsi_update_spi();
}
GPIO_PinOutClear(SL_SPIDRV_EUSART_EXP_CS_PORT, SL_SPIDRV_EUSART_EXP_CS_PIN);
#endif
if (xlen <= MIN_XLEN || (tx_buf == NULL && rx_buf == NULL)) // at least one buffer needs to be provided
{
return RSI_ERROR_INVALID_PARAM;
Expand Down Expand Up @@ -238,5 +306,10 @@ int16_t rsi_spi_transfer(uint8_t * tx_buf, uint8_t * rx_buf, uint16_t xlen, uint
}

xSemaphoreGive(spiTransferLock);
#if defined(EFR32MG24)
/* In case of MG24, set CS of Exp Hdr SPI to high and release multiplex synchronization semaphore*/
GPIO_PinOutSet(SL_SPIDRV_EUSART_EXP_CS_PORT, SL_SPIDRV_EUSART_EXP_CS_PIN);
xSemaphoreGive(spi_sem_sync_hdl);
#endif
return rsiError;
}
1 change: 1 addition & 0 deletions examples/platform/silabs/efr32/rs911x/rs911x.gni
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ rs911x_src_plat = [
"${examples_plat_dir}/rs911x/hal/rsi_hal_mcu_timer.c",
"${examples_plat_dir}/rs911x/hal/efx_spi.c",
"${wifi_sdk_dir}/wfx_notify.cpp",
"${examples_plat_dir}/spi_multiplex.c",
]

#
Expand Down
111 changes: 106 additions & 5 deletions examples/platform/silabs/efr32/spi_multiplex.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,26 @@
#include "em_ldma.h"
#include "em_usart.h"
#if SL_WIFI
#include "btl_interface.h"
#include "sl_memlcd.h"
#include "spi_multiplex.h"
#endif /* SL_WIFI */

#define CONCAT(A, B) (A##B)
#define SPI_CLOCK(N) CONCAT(cmuClock_USART, N)
#ifdef WF200_WIFI
#define SL_SPIDRV_FRAME_LENGTH SL_SPIDRV_EXP_FRAME_LENGTH
#else
#define SL_SPIDRV_FRAME_LENGTH 8 // default value
#endif

const uint32_t spiBitRates[] = { [EXP_HDR] = SL_BIT_RATE_EXP_HDR, [LCD] = SL_BIT_RATE_LCD, [EXT_SPIFLASH] = SL_BIT_RATE_SPI_FLASH };

extern void efr32Log(const char *, ...);

extern SPIDRV_Handle_t sl_spidrv_eusart_exp_handle;
extern SPIDRV_Init_t sl_spidrv_eusart_init_exp;

/****************************************************************************
* @fn void spi_drv_reinit()
* @brief
Expand All @@ -47,10 +64,14 @@ void spi_drv_reinit(uint32_t baudrate)
USART_InitSync_TypeDef usartInit = USART_INITSYNC_DEFAULT;
usartInit.msbf = true;
usartInit.clockMode = usartClockMode0;
usartInit.baudrate = baudrate;
uint32_t databits = SL_SPIDRV_EXP_FRAME_LENGTH - 4U + _USART_FRAME_DATABITS_FOUR;
usartInit.databits = (USART_Databits_TypeDef) databits;
usartInit.autoCsEnable = true;
#ifdef WF200_WIFI
usartInit.baudrate = baudrate;
#elif RS911X_WIFI
usartInit.baudrate = spiBitRates[pr_type];
#endif
uint32_t databits = SL_SPIDRV_FRAME_LENGTH - 4U + _USART_FRAME_DATABITS_FOUR;
usartInit.databits = (USART_Databits_TypeDef) databits;
usartInit.autoCsEnable = true;

USART_InitSync(USART0, &usartInit);
}
Expand Down Expand Up @@ -95,7 +116,11 @@ void pre_bootloader_spi_transfer(void)
/*
* Assert CS pin for EXT SPI Flash
*/
#ifdef WF200_WIFI
spi_drv_reinit(SL_BIT_RATE_SPI_FLASH);
#else
spi_switch(EXT_SPIFLASH);
#endif
spiflash_cs_assert();
}

Expand Down Expand Up @@ -128,7 +153,11 @@ void pre_lcd_spi_transfer(void)
{
return;
}
#ifdef WF200_WIFI
spi_drv_reinit(SL_BIT_RATE_LCD);
#else
spi_switch(LCD);
#endif
/*LCD CS is handled as part of LCD gsdk*/
}

Expand All @@ -143,6 +172,78 @@ void post_lcd_spi_transfer(void)
{
xSemaphoreGive(spi_sem_sync_hdl);
}

#ifdef RS911X_WIFI
/****************************************************************************
* @fn void spi_switch(pr_type)
* @brief
* Handles switching between pheripherals spi
* @param[in] prType - enum indicating type of pheripheral to switch the SPI to
* @return returns void
*****************************************************************************/
void spi_switch(peripheraltype_t prType)
{
efr32Log("switching spi from %u to %u", pr_type, prType);
if (pr_type != EXP_HDR && prType == EXP_HDR)
{
if (pr_type == LCD)
{
/* deinit USART of LCD*/
USART_Enable(SL_MEMLCD_SPI_PERIPHERAL, usartDisable);
CMU_ClockEnable(SPI_CLOCK(SL_MEMLCD_SPI_PERIPHERAL_NO), false);
// USART_Reset(SL_MEMLCD_SPI_PERIPHERAL);
GPIO->USARTROUTE[SL_MEMLCD_SPI_PERIPHERAL_NO].ROUTEEN = 0;
}
else if (pr_type == EXT_SPIFLASH)
{
bootloader_deinit();
GPIO->USARTROUTE[0].ROUTEEN = 0;
}
pr_type = EXP_HDR;
/* init EUSART of RS911x*/
SPIDRV_Init(sl_spidrv_eusart_exp_handle, &sl_spidrv_eusart_init_exp);
}
else if (pr_type != LCD && prType == LCD)
{
if (pr_type == EXT_SPIFLASH)
{
spi_drv_reinit(SL_BIT_RATE_LCD);
pr_type = prType;
efr32Log("spi switched to %u", pr_type);
return;
}
if (pr_type == EXP_HDR)
{
efr32Log("deinited eusart of exp hdr");
SPIDRV_DeInit(sl_spidrv_eusart_exp_handle);
GPIO->EUSARTROUTE[SL_SPIDRV_EUSART_EXP_PERIPHERAL_NO].ROUTEEN = 0;
}
pr_type = LCD;
efr32Log("inited usart for lcd");
sl_memlcd_refresh(sl_memlcd_get());
}
else if (pr_type != EXT_SPIFLASH && prType == EXT_SPIFLASH)
{
if (pr_type == LCD)
{
spi_drv_reinit(SL_BIT_RATE_SPI_FLASH);
pr_type = prType;
efr32Log("spi switched to %u", pr_type);
return;
}
else if (pr_type == EXP_HDR)
{
SPIDRV_DeInit(sl_spidrv_eusart_exp_handle);
GPIO->EUSARTROUTE[SL_SPIDRV_EUSART_EXP_PERIPHERAL_NO].ROUTEEN = 0;
}
pr_type = EXT_SPIFLASH;
/* init EUSART of RS911x*/
bootloader_init();
}
efr32Log("spi switched to %u", pr_type);
}
#endif

#if (defined(EFR32MG24) && defined(WF200_WIFI))
/****************************************************************************
* @fn void pre_uart_transfer()
Expand Down Expand Up @@ -186,4 +287,4 @@ void post_uart_transfer(void)
sl_wfx_host_enable_platform_interrupt();
sl_wfx_enable_irq();
}
#endif /* EFR32MG24 && WF200_WIFI */
#endif /* EFR32MG24 && WF200_WIFI */
Loading

0 comments on commit 39967ad

Please sign in to comment.