blob: 6b8d6539d760c5204f0e8c86b290e2d68559b141 [file] [log] [blame]
/*
*
* 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.
*/
#if (defined(EFR32MG24) && defined(WF200_WIFI))
#include "sl_wfx.h"
#endif /* EFR32MG24 && WF200_WIFI */
#include "dmadrv.h"
#include "em_bus.h"
#include "em_cmu.h"
#include "em_gpio.h"
#include "em_ldma.h"
#include "em_usart.h"
#if SL_WIFI
#include "spi_multiplex.h"
#endif /* SL_WIFI */
/****************************************************************************
* @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)
{
if (USART_BaudrateGet(USART0) == baudrate)
{
// USART synced to baudrate already
return;
}
// 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 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;
}
/*
* Assert CS pin for EXT SPI Flash
*/
spi_drv_reinit(SL_BIT_RATE_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;
}
spi_drv_reinit(SL_BIT_RATE_LCD);
/*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);
}
#if (defined(EFR32MG24) && defined(WF200_WIFI))
/****************************************************************************
* @fn void pre_uart_transfer()
* @brief
* Take a semaphore and setting GPIO, disable IRQ
* @param[in] None
* @return returns void
*****************************************************************************/
void pre_uart_transfer(void)
{
if (spi_sem_sync_hdl == NULL)
{
// UART is initialized before host SPI interface
// spi_sem_sync_hdl will not be initalized during execution
GPIO_PinModeSet(gpioPortA, 8, gpioModePushPull, 1);
return;
}
sl_wfx_disable_irq();
sl_wfx_host_disable_platform_interrupt();
if (xSemaphoreTake(spi_sem_sync_hdl, portMAX_DELAY) != pdTRUE)
{
return;
}
GPIO_PinModeSet(gpioPortA, 8, gpioModePushPull, 1);
}
/****************************************************************************
* @fn void post_uart_transfer()
* @brief
* Reset GPIO, enabled IRQ, release semaphore
* @param[in] None
* @return returns void
*****************************************************************************/
void post_uart_transfer(void)
{
if (spi_sem_sync_hdl == NULL)
{
return;
}
GPIO_PinModeSet(gpioPortA, 8, gpioModeInputPull, 1);
xSemaphoreGive(spi_sem_sync_hdl);
sl_wfx_host_enable_platform_interrupt();
sl_wfx_enable_irq();
}
#endif /* EFR32MG24 && WF200_WIFI */