2018-12-08 10:44:56 +08:00
|
|
|
/*
|
|
|
|
* 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;
|
|
|
|
|
2023-04-14 08:03:54 +08:00
|
|
|
if (content != NULL && content->data != NULL)
|
2018-12-08 10:44:56 +08:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|