Skip to content

Commit

Permalink
[EFR32]Wi-Fi MG24-WF200 Pin Multiplexing and OTA Update support (#23830)
Browse files Browse the repository at this point in the history
* WF200 SPI multiplexing for LCD,EXT flash and EXP Header changes

* Restyled by whitespace

* Restyled by clang-format

* Adding License for header file

Co-authored-by: Restyled.io <commits@restyled.io>
  • Loading branch information
2 people authored and pull[bot] committed Aug 30, 2023
1 parent dae1991 commit 1935363
Show file tree
Hide file tree
Showing 7 changed files with 324 additions and 6 deletions.
21 changes: 21 additions & 0 deletions examples/platform/silabs/efr32/display/demo-ui.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
#include "glib.h"
#include <stdio.h>
#include <string.h>
#if (defined(EFR32MG24) && defined(WF200_WIFI))
#include "spi_multiplex.h"
#endif

// Main Logo and App image
#define SILICONLABS_X_POSITION ((glibContext.pDisplayGeometry->xSize - SILICONLABS_BITMAP_WIDTH) / 2)
Expand Down Expand Up @@ -105,14 +108,26 @@ void demoUIDisplayHeader(char * name)
{
GLIB_drawStringOnLine(&glibContext, name, 5, GLIB_ALIGN_CENTER, 0, 0, true);
}
#if (defined(EFR32MG24) && defined(WF200_WIFI))
pre_lcd_spi_transfer();
#endif
DMD_updateDisplay();
#if (defined(EFR32MG24) && defined(WF200_WIFI))
post_lcd_spi_transfer();
#endif
}

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))
pre_lcd_spi_transfer();
#endif
DMD_updateDisplay();
#if (defined(EFR32MG24) && defined(WF200_WIFI))
post_lcd_spi_transfer();
#endif
}

void demoUIDisplayProtocol(demoUIProtocol protocol, bool isConnected)
Expand All @@ -123,7 +138,13 @@ 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))
pre_lcd_spi_transfer();
#endif
DMD_updateDisplay();
#if (defined(EFR32MG24) && defined(WF200_WIFI))
post_lcd_spi_transfer();
#endif
}

void demoUIClearMainScreen(uint8_t * name)
Expand Down
28 changes: 27 additions & 1 deletion examples/platform/silabs/efr32/display/lcd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@

#include "sl_board_control.h"

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

#if (defined(EFR32MG24) && defined(WF200_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 @@ -117,7 +126,18 @@ int SilabsLCD::DrawPixel(void * pContext, int32_t x, int32_t y)

int SilabsLCD::Update(void)
{
return DMD_updateDisplay();
int status;
#if (defined(EFR32MG24) && defined(WF200_WIFI))
pre_lcd_spi_transfer();
#endif
status = DMD_updateDisplay();
#if (defined(EFR32MG24) && defined(WF200_WIFI))
post_lcd_spi_transfer();
#endif
/*
* TO-DO; Above logic can be optimised by writing a common API
*/
return status;
}

void SilabsLCD::WriteDemoUI(bool state)
Expand Down Expand Up @@ -180,8 +200,14 @@ void SilabsLCD::WriteQRCode()
}
}
}
#if (defined(EFR32MG24) && defined(WF200_WIFI))
pre_lcd_spi_transfer();
#endif

DMD_updateDisplay();
#if (defined(EFR32MG24) && defined(WF200_WIFI))
post_lcd_spi_transfer();
#endif
}

void SilabsLCD::SetQRCode(uint8_t * str, uint32_t size)
Expand Down
165 changes: 165 additions & 0 deletions examples/platform/silabs/efr32/spi_multiplex.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
/*
*
* Copyright (c) 2022 Project CHIP Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "spi_multiplex.h"
#include "dmadrv.h"
#include "em_bus.h"
#include "em_cmu.h"
#include "em_gpio.h"
#include "em_ldma.h"
#include "em_usart.h"

/****************************************************************************
* @fn void spi_drv_reinit()
* @brief
* Re-Intializes SPI driver to required baudrate
* @param[in] None
* @return returns void
*****************************************************************************/
void spi_drv_reinit(uint32_t baudrate)
{
// USART is used in MG24 + WF200 combination
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;

USART_InitSync(USART0, &usartInit);
}

/****************************************************************************
* @fn void set_spi_baudrate()
* @brief
* Setting the appropriate SPI baudrate
* @param[in] None
* @return returns void
*****************************************************************************/
void set_spi_baudrate(peripheraltype_t pr_type)
{
if (pr_type == LCD)
{
spi_drv_reinit(LCD_BIT_RATE);
}
else if (pr_type == EXP_HDR)
{
spi_drv_reinit(EXP_HDR_BIT_RATE);
}
else if (pr_type == EXT_SPIFLASH)
{
spi_drv_reinit(SPI_FLASH_BIT_RATE);
}
}

/****************************************************************************
* @fn void spiflash_cs_assert()
* @brief
* Assert SPI flash chip select.
* @param[in] None
* @return returns void
*****************************************************************************/
void spiflash_cs_assert(void)
{
GPIO_PinOutClear(SL_MX25_FLASH_SHUTDOWN_CS_PORT, SL_MX25_FLASH_SHUTDOWN_CS_PIN);
}

/****************************************************************************
* @fn void spiflash_cs_deassert()
* @brief
* De-Assert SPI flash chip select.
* @param[in] None
* @return returns void
*****************************************************************************/
void spiflash_cs_deassert(void)
{
GPIO_PinOutSet(SL_MX25_FLASH_SHUTDOWN_CS_PORT, SL_MX25_FLASH_SHUTDOWN_CS_PIN);
}

/****************************************************************************
* @fn void pre_bootloader_spi_transfer()
* @brief
* Take a semaphore and controlling CS pin for EXP header and SPI flash
* @param[in] None
* @return returns void
*****************************************************************************/
void pre_bootloader_spi_transfer(void)
{
if (xSemaphoreTake(spi_sem_sync_hdl, portMAX_DELAY) != pdTRUE)
{
return;
}
/*
* CS for Expansion header controlled within GSDK,
* however we need to ensure CS for Expansion header is High/disabled before use of EXT SPI Flash
*/
sl_wfx_host_spi_cs_deassert();
/*
* Assert CS pin for EXT SPI Flash
*/
spiflash_cs_assert();
}

/****************************************************************************
* @fn void post_bootloader_spi_transfer()
* @brief
* De-Assert EXT SPI flash CS pin and release semaphore
* @param[in] None
* @return returns void
*****************************************************************************/
void post_bootloader_spi_transfer(void)
{
/*
* De-Assert CS pin for EXT SPI Flash
*/
spiflash_cs_deassert();
xSemaphoreGive(spi_sem_sync_hdl);
}

/****************************************************************************
* @fn void pre_lcd_spi_transfer()
* @brief
* Take a semaphore and setting LCD baudrate
* @param[in] None
* @return returns void
*****************************************************************************/
void pre_lcd_spi_transfer(void)
{
if (xSemaphoreTake(spi_sem_sync_hdl, portMAX_DELAY) != pdTRUE)
{
return;
}
if (pr_type != LCD)
{
pr_type = LCD;
set_spi_baudrate(pr_type);
}
/*LCD CS is handled as part of LCD gsdk*/
}

/****************************************************************************
* @fn void post_lcd_spi_transfer()
* @brief
* Release semaphore
* @param[in] None
* @return returns void
*****************************************************************************/
void post_lcd_spi_transfer(void)
{
xSemaphoreGive(spi_sem_sync_hdl);
}
57 changes: 57 additions & 0 deletions examples/platform/silabs/efr32/spi_multiplex.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
*
* Copyright (c) 2022 Project CHIP Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#ifdef __cplusplus
extern "C" {
#endif
#include "FreeRTOS.h"
#include "semphr.h"
#include "sl_mx25_flash_shutdown_usart_config.h"
#include "sl_spidrv_exp_config.h"
#include "sl_wfx_host_api.h"

#define LCD_BIT_RATE 1100000
#define EXP_HDR_BIT_RATE 16000000
#define SPI_FLASH_BIT_RATE 16000000

typedef enum PERIPHERAL_TYPE
{
EXP_HDR = 0,
LCD,
EXT_SPIFLASH,
} peripheraltype_t;

extern SemaphoreHandle_t spi_sem_sync_hdl;
extern peripheraltype_t pr_type;

void spi_drv_reinit(uint32_t);
void set_spi_baudrate(peripheraltype_t);

void spiflash_cs_assert(void);
void spiflash_cs_deassert(void);

void pre_bootloader_spi_transfer(void);
void post_bootloader_spi_transfer(void);

void pre_lcd_spi_transfer(void);
void post_lcd_spi_transfer(void);

#ifdef __cplusplus
}
#endif
Loading

0 comments on commit 1935363

Please sign in to comment.