blob: 4b876883c12b0fec71739f4eb3bca690d7ccf0f3 [file] [log] [blame]
/*
*
* Copyright (c) 2023 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.
*/
/**
* Includes
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "FreeRTOS.h"
#include "dmadrv.h"
#include "em_chip.h"
#include "em_cmu.h"
#include "em_core.h"
#include "em_device.h"
#include "em_gpio.h"
#include "em_ldma.h"
#include "event_groups.h"
#include "gpiointerrupt.h"
#include "semphr.h"
#include "spidrv.h"
#include "task.h"
#include "sl_board_control.h"
#include "sl_device_init_clocks.h"
#include "sl_device_init_hfxo.h"
#include "sl_status.h"
#include "silabs_utils.h"
#include "sl_si91x_ncp_utility.h"
#include "wfx_host_events.h"
#include "wfx_rsi.h"
#if SL_MX25CTRL_MUX
sl_status_t sl_wfx_host_spiflash_cs_assert(void);
sl_status_t sl_wfx_host_spiflash_cs_deassert(void);
#endif
#if SL_BTLCTRL_MUX
#include "btl_interface.h"
#endif // SL_BTLCTRL_MUX
#if SL_LCDCTRL_MUX
#include "sl_memlcd.h"
#include "sl_memlcd_display.h"
#define SL_SPIDRV_LCD_BITRATE SL_MEMLCD_SCLK_FREQ
#endif // SL_LCDCTRL_MUX
#if SL_MX25CTRL_MUX
#include "sl_mx25_flash_shutdown_usart_config.h"
#endif // SL_MX25CTRL_MUX
#if SL_SPICTRL_MUX
StaticSemaphore_t spi_sem_peripheral;
SemaphoreHandle_t spi_sem_sync_hdl;
#endif // SL_SPICTRL_MUX
#if SL_LCDCTRL_MUX
/********************************************************
* @fn sl_wfx_host_pre_lcd_spi_transfer(void)
* @brief
* Deal with the SPI PINS MUX that are associated with LCD. for setup before data transfer PINS.
* @return
* None
**********************************************************/
sl_status_t sl_wfx_host_pre_lcd_spi_transfer(void)
{
#if SL_SPICTRL_MUX
xSemaphoreTake(spi_sem_sync_hdl, portMAX_DELAY);
#endif // SL_SPICTRL_MUX
sl_status_t status = sl_board_enable_display();
if (SL_STATUS_OK == status)
{
SPIDRV_SetBaudrate(SL_SPIDRV_LCD_BITRATE);
}
return status;
}
/********************************************************
* @fn sl_wfx_host_post_lcd_spi_transfer(void)
* @brief
* Deal with the SPI PINS MUX that are associated with LCD. for setup after data transfer PINS.
* @return
* None
**********************************************************/
sl_status_t sl_wfx_host_post_lcd_spi_transfer(void)
{
sl_status_t status = sl_board_disable_display();
#if SL_SPICTRL_MUX
xSemaphoreGive(spi_sem_sync_hdl);
#endif // SL_SPICTRL_MUX
return status;
}
#endif // SL_LCDCTRL_MUX
#if SL_SPICTRL_MUX
void SPIDRV_SetBaudrate(uint32_t baudrate)
{
if (USART_BaudrateGet(SPI_USART) != baudrate)
{
USART_InitSync_TypeDef usartInit = USART_INITSYNC_DEFAULT;
usartInit.msbf = true;
usartInit.baudrate = baudrate;
USART_InitSync(SPI_USART, &usartInit);
}
}
/********************************************************
* @fn spi_board_init(void)
* @brief
* Deal with the SPI PINS multiplexing related changes for the initialization.
* @return
* None
**********************************************************/
sl_status_t spi_board_init()
{
#if SL_SPICTRL_MUX
if (spi_sem_sync_hdl == NULL)
{
spi_sem_sync_hdl = xSemaphoreCreateBinaryStatic(&spi_sem_peripheral);
}
configASSERT(spi_sem_sync_hdl);
xSemaphoreGive(spi_sem_sync_hdl);
#endif /* SL_SPICTRL_MUX */
return SL_STATUS_OK;
}
/********************************************************
* @fn sl_wfx_host_spi_cs_assert(void)
* @brief
* Deal with the SPI PINS multiplexing related changes for the initialization.
* @return
* None
**********************************************************/
sl_status_t sl_wfx_host_spi_cs_assert(void)
{
#if SL_SPICTRL_MUX
xSemaphoreTake(spi_sem_sync_hdl, portMAX_DELAY);
#endif /* SL_SPICTRL_MUX */
SPIDRV_SetBaudrate(USART_INITSYNC_BAUDRATE);
SPI_USART->TIMING |= USART_TIMING_TXDELAY_ONE | USART_TIMING_CSSETUP_ONE | USART_TIMING_CSHOLD_ONE;
DMADRV_Init();
DMADRV_AllocateChannel((unsigned int *) &rx_ldma_channel, NULL);
DMADRV_AllocateChannel((unsigned int *) &tx_ldma_channel, NULL);
GPIO_PinOutClear(SL_SPIDRV_EXP_CS_PORT, SL_SPIDRV_EXP_CS_PIN);
return SL_STATUS_OK;
}
sl_status_t sl_wfx_host_spi_cs_deassert(void)
{
DMADRV_DeInit();
DMADRV_StopTransfer(rx_ldma_channel);
DMADRV_StopTransfer(tx_ldma_channel);
DMADRV_FreeChannel(rx_ldma_channel);
DMADRV_FreeChannel(tx_ldma_channel);
GPIO_PinOutSet(SL_SPIDRV_EXP_CS_PORT, SL_SPIDRV_EXP_CS_PIN);
#if SL_SPICTRL_MUX
xSemaphoreGive(spi_sem_sync_hdl);
#endif
return SL_STATUS_OK;
}
#endif // SL_SPICTRL_MUX
#if SL_BTLCTRL_MUX
sl_status_t sl_wfx_host_pre_bootloader_spi_transfer(void)
{
#if SL_SPICTRL_MUX
if (sl_wfx_host_spi_cs_deassert() != SL_STATUS_OK)
{
return SL_STATUS_FAIL;
}
xSemaphoreTake(spi_sem_sync_hdl, portMAX_DELAY);
#endif // SL_SPICTRL_MUX
int32_t status = BOOTLOADER_OK;
#if defined(CHIP_9117)
LDMA_Init_t ldma_init = LDMA_INIT_DEFAULT;
LDMA_Init(&ldma_init);
#else
// bootloader_init takes care of SPIDRV_Init()
status = bootloader_init();
#endif
if (status != BOOTLOADER_OK)
{
SILABS_LOG("bootloader_init error: %x", status);
#if SL_SPICTRL_MUX
xSemaphoreGive(spi_sem_sync_hdl);
#endif // SL_SPICTRL_MUX
return SL_STATUS_FAIL;
}
#if SL_MX25CTRL_MUX
sl_wfx_host_spiflash_cs_assert();
#endif // SL_MX25CTRL_MUX
return SL_STATUS_OK;
}
sl_status_t sl_wfx_host_post_bootloader_spi_transfer(void)
{
// bootloader_deinit will do USART disable
int32_t status = bootloader_deinit();
if (status != BOOTLOADER_OK)
{
SILABS_LOG("bootloader_deinit error: %x", status);
#if SL_SPICTRL_MUX
xSemaphoreGive(spi_sem_sync_hdl);
#endif // SL_SPICTRL_MUX
return SL_STATUS_FAIL;
}
GPIO->USARTROUTE[SL_MX25_FLASH_SHUTDOWN_PERIPHERAL_NO].ROUTEEN = PINOUT_CLEAR;
#if SL_MX25CTRL_MUX
sl_wfx_host_spiflash_cs_deassert();
#endif // SL_MX25CTRL_MUX
#if SL_SPICTRL_MUX
xSemaphoreGive(spi_sem_sync_hdl);
#endif // SL_SPICTRL_MUX
return SL_STATUS_OK;
}
#endif // SL_BTLCTRL_MUX
#if SL_MX25CTRL_MUX
sl_status_t sl_wfx_host_spiflash_cs_assert(void)
{
GPIO_PinOutClear(SL_MX25_FLASH_SHUTDOWN_CS_PORT, SL_MX25_FLASH_SHUTDOWN_CS_PIN);
return SL_STATUS_OK;
}
sl_status_t sl_wfx_host_spiflash_cs_deassert(void)
{
GPIO_PinOutSet(SL_MX25_FLASH_SHUTDOWN_CS_PORT, SL_MX25_FLASH_SHUTDOWN_CS_PIN);
return SL_STATUS_OK;
}
#endif // SL_MX25CTRL_MUX