rt-thread-official/bsp/rv32m1_vega/ri5cy/board/fsl_host.c

137 lines
4.0 KiB
C

/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2017 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_host.h"
#include "board.h"
#include "fsl_gpio.h"
#ifdef BOARD_USDHC_CD_PORT_BASE
#include "fsl_port.h"
#endif
/*******************************************************************************
* Definitions
******************************************************************************/
/*******************************************************************************
* Prototypes
******************************************************************************/
/*!
* @brief host controller error recovery.
* @param host base address.
*/
static void Host_ErrorRecovery(HOST_TYPE *hostBase);
/*******************************************************************************
* Variables
******************************************************************************/
/* DMA descriptor should allocate at non-cached memory */
AT_NONCACHEABLE_SECTION_ALIGN(uint32_t g_usdhcAdma2Table[USDHC_ADMA_TABLE_WORDS], USDHC_ADMA2_ADDR_ALIGN);
extern volatile uint32_t g_timeMilliseconds;
static volatile bool g_sdInsertedFlag;
/*******************************************************************************
* Code
******************************************************************************/
/* Card detect. */
status_t CardInsertDetect(HOST_TYPE *hostBase)
{
return kStatus_Success;
}
/* User defined transfer function. */
static status_t USDHC_TransferFunction(USDHC_Type *base, usdhc_transfer_t *content)
{
status_t error = kStatus_Success;
usdhc_adma_config_t dmaConfig;
if (content != NULL && content->data != NULL)
{
memset(&dmaConfig, 0, sizeof(usdhc_adma_config_t));
/* config adma */
dmaConfig.dmaMode = USDHC_DMA_MODE;
dmaConfig.burstLen = kUSDHC_EnBurstLenForINCR;
dmaConfig.admaTable = g_usdhcAdma2Table;
dmaConfig.admaTableWords = USDHC_ADMA_TABLE_WORDS;
}
error = USDHC_TransferBlocking(base, &dmaConfig, content);
if (error == kStatus_Fail)
{
/* host error recovery */
Host_ErrorRecovery(base);
}
return error;
}
static void Host_ErrorRecovery(HOST_TYPE *hostBase)
{
uint32_t status = 0U;
/* get host present status */
status = USDHC_GetPresentStatusFlags(hostBase);
/* check command inhibit status flag */
if ((status & kUSDHC_CommandInhibitFlag) != 0U)
{
/* reset command line */
USDHC_Reset(hostBase, kUSDHC_ResetCommand, 100U);
}
/* check data inhibit status flag */
if ((status & kUSDHC_DataInhibitFlag) != 0U)
{
/* reset data line */
USDHC_Reset(hostBase, kUSDHC_ResetData, 100U);
}
}
status_t HOST_Init(void *host)
{
usdhc_host_t *usdhcHost = (usdhc_host_t *)host;
/* init card power control */
HOST_INIT_SD_POWER();
HOST_INIT_MMC_POWER();
/* Initializes USDHC. */
usdhcHost->config.dataTimeout = USDHC_DATA_TIMEOUT;
usdhcHost->config.endianMode = USDHC_ENDIAN_MODE;
usdhcHost->config.readWatermarkLevel = USDHC_READ_WATERMARK_LEVEL;
usdhcHost->config.writeWatermarkLevel = USDHC_WRITE_WATERMARK_LEVEL;
usdhcHost->config.readBurstLen = USDHC_READ_BURST_LEN;
usdhcHost->config.writeBurstLen = USDHC_WRITE_BURST_LEN;
USDHC_Init(usdhcHost->base, &(usdhcHost->config));
/* Define transfer function. */
usdhcHost->transfer = USDHC_TransferFunction;
return kStatus_Success;
}
void HOST_Reset(HOST_TYPE *hostBase)
{
/* voltage switch to normal but not 1.8V */
HOST_SWITCH_VOLTAGE180V(hostBase, false);
/* Disable DDR mode */
HOST_ENABLE_DDR_MODE(hostBase, false);
/* disable tuning */
HOST_EXECUTE_STANDARD_TUNING_ENABLE(hostBase, false);
/* Disable HS400 mode */
HOST_ENABLE_HS400_MODE(hostBase, false);
/* Disable DLL */
HOST_ENABLE_STROBE_DLL(hostBase, false);
}
void HOST_Deinit(void *host)
{
usdhc_host_t *usdhcHost = (usdhc_host_t *)host;
USDHC_Deinit(usdhcHost->base);
}