Merge pull request #2775 from NXPmicro/KSDK_SDHC_Driver_Update

Update KSDK SDHC driver for K64F & K66F
pull/2808/head
Sam Grove 2016-09-24 16:47:48 -05:00 committed by GitHub
commit 24f9612da5
4 changed files with 374 additions and 262 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -50,6 +50,9 @@
#define SDHC_NEXT_CLKFS(x) ((x) <<= 1U)
#define SDHC_PREV_CLKFS(x) ((x) >>= 1U)
/* Typedef for interrupt handler. */
typedef void (*sdhc_isr_t)(SDHC_Type *base, sdhc_handle_t *handle);
/*! @brief ADMA table configuration */
typedef struct _sdhc_adma_table_config
{
@ -230,6 +233,9 @@ static const IRQn_Type s_sdhcIRQ[] = SDHC_IRQS;
/*! @brief SDHC clock array name */
static const clock_ip_name_t s_sdhcClock[] = SDHC_CLOCKS;
/* SDHC ISR for transactional APIs. */
static sdhc_isr_t s_sdhcIsr;
/*******************************************************************************
* Code
******************************************************************************/
@ -288,10 +294,8 @@ static void SDHC_SetTransferInterrupt(SDHC_Type *base, bool usingInterruptSignal
static void SDHC_StartTransfer(SDHC_Type *base, sdhc_command_t *command, sdhc_data_t *data)
{
assert(command);
uint32_t flags = 0U;
sdhc_transfer_config_t sdhcTransferConfig;
sdhc_transfer_config_t sdhcTransferConfig = {0};
sdhc_dma_mode_t dmaMode;
/* Define the flag corresponding to each response type. */
@ -315,7 +319,7 @@ static void SDHC_StartTransfer(SDHC_Type *base, sdhc_command_t *command, sdhc_da
flags |= (kSDHC_ResponseLength48Flag);
break;
case kSDHC_ResponseTypeR5: /* Response 5 */
flags |= (kSDHC_ResponseLength48Flag | kSDHC_EnableCrcCheckFlag);
flags |= (kSDHC_ResponseLength48Flag | kSDHC_EnableCrcCheckFlag | kSDHC_EnableIndexCheckFlag);
break;
case kSDHC_ResponseTypeR5b: /* Response 5 with busy */
flags |= (kSDHC_ResponseLength48BusyFlag | kSDHC_EnableCrcCheckFlag | kSDHC_EnableIndexCheckFlag);
@ -355,18 +359,9 @@ static void SDHC_StartTransfer(SDHC_Type *base, sdhc_command_t *command, sdhc_da
flags |= kSDHC_EnableAutoCommand12Flag;
}
}
if (data->blockCount > SDHC_MAX_BLOCK_COUNT)
{
sdhcTransferConfig.dataBlockSize = data->blockSize;
sdhcTransferConfig.dataBlockCount = SDHC_MAX_BLOCK_COUNT;
flags &= ~(uint32_t)kSDHC_EnableBlockCountFlag;
}
else
{
sdhcTransferConfig.dataBlockSize = data->blockSize;
sdhcTransferConfig.dataBlockCount = data->blockCount;
}
sdhcTransferConfig.dataBlockSize = data->blockSize;
sdhcTransferConfig.dataBlockCount = data->blockCount;
}
else
{
@ -382,8 +377,6 @@ static void SDHC_StartTransfer(SDHC_Type *base, sdhc_command_t *command, sdhc_da
static void SDHC_ReceiveCommandResponse(SDHC_Type *base, sdhc_command_t *command)
{
assert(command);
uint32_t i;
if (command->responseType != kSDHC_ResponseTypeNone)
@ -412,13 +405,22 @@ static void SDHC_ReceiveCommandResponse(SDHC_Type *base, sdhc_command_t *command
static uint32_t SDHC_ReadDataPort(SDHC_Type *base, sdhc_data_t *data, uint32_t transferredWords)
{
assert(data);
uint32_t i;
uint32_t totalWords;
uint32_t wordsCanBeRead; /* The words can be read at this time. */
uint32_t readWatermark = ((base->WML & SDHC_WML_RDWML_MASK) >> SDHC_WML_RDWML_SHIFT);
/*
* Add non aligned access support ,user need make sure your buffer size is big
* enough to hold the data,in other words,user need make sure the buffer size
* is 4 byte aligned
*/
if (data->blockSize % sizeof(uint32_t) != 0U)
{
data->blockSize +=
sizeof(uint32_t) - (data->blockSize % sizeof(uint32_t)); /* make the block size as word-aligned */
}
totalWords = ((data->blockCount * data->blockSize) / sizeof(uint32_t));
/* If watermark level is equal or bigger than totalWords, transfers totalWords data. */
@ -451,12 +453,21 @@ static uint32_t SDHC_ReadDataPort(SDHC_Type *base, sdhc_data_t *data, uint32_t t
static status_t SDHC_ReadByDataPortBlocking(SDHC_Type *base, sdhc_data_t *data)
{
assert(data);
uint32_t totalWords;
uint32_t transferredWords = 0U;
status_t error = kStatus_Success;
/*
* Add non aligned access support ,user need make sure your buffer size is big
* enough to hold the data,in other words,user need make sure the buffer size
* is 4 byte aligned
*/
if (data->blockSize % sizeof(uint32_t) != 0U)
{
data->blockSize +=
sizeof(uint32_t) - (data->blockSize % sizeof(uint32_t)); /* make the block size as word-aligned */
}
totalWords = ((data->blockCount * data->blockSize) / sizeof(uint32_t));
while ((error == kStatus_Success) && (transferredWords < totalWords))
@ -489,13 +500,22 @@ static status_t SDHC_ReadByDataPortBlocking(SDHC_Type *base, sdhc_data_t *data)
static uint32_t SDHC_WriteDataPort(SDHC_Type *base, sdhc_data_t *data, uint32_t transferredWords)
{
assert(data);
uint32_t i;
uint32_t totalWords;
uint32_t wordsCanBeWrote; /* Words can be wrote at this time. */
uint32_t writeWatermark = ((base->WML & SDHC_WML_WRWML_MASK) >> SDHC_WML_WRWML_SHIFT);
/*
* Add non aligned access support ,user need make sure your buffer size is big
* enough to hold the data,in other words,user need make sure the buffer size
* is 4 byte aligned
*/
if (data->blockSize % sizeof(uint32_t) != 0U)
{
data->blockSize +=
sizeof(uint32_t) - (data->blockSize % sizeof(uint32_t)); /* make the block size as word-aligned */
}
totalWords = ((data->blockCount * data->blockSize) / sizeof(uint32_t));
/* If watermark level is equal or bigger than totalWords, transfers totalWords data.*/
@ -528,12 +548,21 @@ static uint32_t SDHC_WriteDataPort(SDHC_Type *base, sdhc_data_t *data, uint32_t
static status_t SDHC_WriteByDataPortBlocking(SDHC_Type *base, sdhc_data_t *data)
{
assert(data);
uint32_t totalWords;
uint32_t transferredWords = 0U;
status_t error = kStatus_Success;
/*
* Add non aligned access support ,user need make sure your buffer size is big
* enough to hold the data,in other words,user need make sure the buffer size
* is 4 byte aligned
*/
if (data->blockSize % sizeof(uint32_t) != 0U)
{
data->blockSize +=
sizeof(uint32_t) - (data->blockSize % sizeof(uint32_t)); /* make the block size as word-aligned */
}
totalWords = (data->blockCount * data->blockSize) / sizeof(uint32_t);
while ((error == kStatus_Success) && (transferredWords < totalWords))
@ -576,8 +605,6 @@ static status_t SDHC_WriteByDataPortBlocking(SDHC_Type *base, sdhc_data_t *data)
static status_t SDHC_SendCommandBlocking(SDHC_Type *base, sdhc_command_t *command)
{
assert(command);
status_t error = kStatus_Success;
/* Wait command complete or SDHC encounters error. */
@ -602,8 +629,6 @@ static status_t SDHC_SendCommandBlocking(SDHC_Type *base, sdhc_command_t *comman
static status_t SDHC_TransferByDataPortBlocking(SDHC_Type *base, sdhc_data_t *data)
{
assert(data);
status_t error = kStatus_Success;
if (data->rxData)
@ -669,8 +694,6 @@ static status_t SDHC_TransferDataBlocking(sdhc_dma_mode_t dmaMode, SDHC_Type *ba
static void SDHC_TransferHandleCardDetect(sdhc_handle_t *handle, uint32_t interruptFlags)
{
assert(interruptFlags & kSDHC_CardDetectFlag);
if (interruptFlags & kSDHC_CardInsertionFlag)
{
if (handle->callback.CardInserted)
@ -689,7 +712,7 @@ static void SDHC_TransferHandleCardDetect(sdhc_handle_t *handle, uint32_t interr
static void SDHC_TransferHandleCommand(SDHC_Type *base, sdhc_handle_t *handle, uint32_t interruptFlags)
{
assert(interruptFlags & kSDHC_CommandFlag);
assert(handle->command);
if ((interruptFlags & kSDHC_CommandErrorFlag) && (!(handle->data)) && (handle->callback.TransferComplete))
{
@ -709,7 +732,6 @@ static void SDHC_TransferHandleCommand(SDHC_Type *base, sdhc_handle_t *handle, u
static void SDHC_TransferHandleData(SDHC_Type *base, sdhc_handle_t *handle, uint32_t interruptFlags)
{
assert(handle->data);
assert(interruptFlags & kSDHC_DataFlag);
if ((!(handle->data->enableIgnoreError)) && (interruptFlags & (kSDHC_DataErrorFlag | kSDHC_DmaErrorFlag)) &&
(handle->callback.TransferComplete))
@ -759,6 +781,8 @@ void SDHC_Init(SDHC_Type *base, const sdhc_config_t *config)
#if !defined FSL_SDHC_ENABLE_ADMA1
assert(config->dmaMode != kSDHC_DmaModeAdma1);
#endif /* FSL_SDHC_ENABLE_ADMA1 */
assert((config->writeWatermarkLevel >= 1U) && (config->writeWatermarkLevel <= 128U));
assert((config->readWatermarkLevel >= 1U) && (config->readWatermarkLevel <= 128U));
uint32_t proctl;
uint32_t wml;
@ -850,7 +874,8 @@ void SDHC_GetCapability(SDHC_Type *base, sdhc_capability_t *capability)
uint32_t SDHC_SetSdClock(SDHC_Type *base, uint32_t srcClock_Hz, uint32_t busClock_Hz)
{
assert(busClock_Hz && (busClock_Hz < srcClock_Hz));
assert(srcClock_Hz != 0U);
assert((busClock_Hz != 0U) && (busClock_Hz <= srcClock_Hz));
uint32_t divisor;
uint32_t prescaler;
@ -898,7 +923,7 @@ bool SDHC_SetCardActive(SDHC_Type *base, uint32_t timeout)
{
base->SYSCTL |= SDHC_SYSCTL_INITA_MASK;
/* Delay some time to wait card become active state. */
while (!(base->SYSCTL & SDHC_SYSCTL_INITA_MASK))
while (base->SYSCTL & SDHC_SYSCTL_INITA_MASK)
{
if (!timeout)
{
@ -913,6 +938,8 @@ bool SDHC_SetCardActive(SDHC_Type *base, uint32_t timeout)
void SDHC_SetTransferConfig(SDHC_Type *base, const sdhc_transfer_config_t *config)
{
assert(config);
assert(config->dataBlockSize <= (SDHC_BLKATTR_BLKSIZE_MASK >> SDHC_BLKATTR_BLKSIZE_SHIFT));
assert(config->dataBlockCount <= (SDHC_BLKATTR_BLKCNT_MASK >> SDHC_BLKATTR_BLKCNT_SHIFT));
base->BLKATTR = ((base->BLKATTR & ~(SDHC_BLKATTR_BLKSIZE_MASK | SDHC_BLKATTR_BLKCNT_MASK)) |
(SDHC_BLKATTR_BLKSIZE(config->dataBlockSize) | SDHC_BLKATTR_BLKCNT(config->dataBlockCount)));
@ -975,12 +1002,13 @@ void SDHC_EnableSdioControl(SDHC_Type *base, uint32_t mask, bool enable)
void SDHC_SetMmcBootConfig(SDHC_Type *base, const sdhc_boot_config_t *config)
{
assert(config);
assert(config->ackTimeoutCount <= (SDHC_MMCBOOT_DTOCVACK_MASK >> SDHC_MMCBOOT_DTOCVACK_SHIFT));
assert(config->blockCount <= (SDHC_MMCBOOT_BOOTBLKCNT_MASK >> SDHC_MMCBOOT_BOOTBLKCNT_SHIFT));
uint32_t mmcboot;
uint32_t mmcboot = 0U;
mmcboot = base->MMCBOOT;
mmcboot |= (SDHC_MMCBOOT_DTOCVACK(config->ackTimeoutCount) | SDHC_MMCBOOT_BOOTMODE(config->bootMode) |
SDHC_MMCBOOT_BOOTBLKCNT(config->blockCount));
mmcboot = (SDHC_MMCBOOT_DTOCVACK(config->ackTimeoutCount) | SDHC_MMCBOOT_BOOTMODE(config->bootMode) |
SDHC_MMCBOOT_BOOTBLKCNT(config->blockCount));
if (config->enableBootAck)
{
mmcboot |= SDHC_MMCBOOT_BOOTACK_MASK;
@ -1016,6 +1044,9 @@ status_t SDHC_SetAdmaTableConfig(SDHC_Type *base,
(!data) || (!dataBytes)
#if !defined FSL_SDHC_ENABLE_ADMA1
|| (dmaMode == kSDHC_DmaModeAdma1)
#else
/* Buffer address configured in ADMA1 descriptor must be 4KB aligned. */
|| ((dmaMode == kSDHC_DmaModeAdma1) && (((uint32_t)data % SDHC_ADMA1_LENGTH_ALIGN) != 0U))
#endif /* FSL_SDHC_ENABLE_ADMA1 */
)
{
@ -1029,6 +1060,17 @@ status_t SDHC_SetAdmaTableConfig(SDHC_Type *base,
break;
#if defined FSL_SDHC_ENABLE_ADMA1
case kSDHC_DmaModeAdma1:
/*
* Add non aligned access support ,user need make sure your buffer size is big
* enough to hold the data,in other words,user need make sure the buffer size
* is 4 byte aligned
*/
if (dataBytes % sizeof(uint32_t) != 0U)
{
dataBytes +=
sizeof(uint32_t) - (dataBytes % sizeof(uint32_t)); /* make the data length as word-aligned */
}
startAddress = data;
/* Check if ADMA descriptor's number is enough. */
entries = ((dataBytes / SDHC_ADMA1_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) + 1U);
@ -1054,7 +1096,7 @@ status_t SDHC_SetAdmaTableConfig(SDHC_Type *base,
adma1EntryAddress[i + 1U] =
((uint32_t)(startAddress) << SDHC_ADMA1_DESCRIPTOR_ADDRESS_SHIFT);
adma1EntryAddress[i + 1U] |=
(SDHC_ADMA1_DESCRIPTOR_TYPE_TRANSFER | SDHC_ADMA1_DESCRIPTOR_END_MASK);
(kSDHC_Adma1DescriptorTypeTransfer | kSDHC_Adma1DescriptorEndFlag);
}
else
{
@ -1075,6 +1117,17 @@ status_t SDHC_SetAdmaTableConfig(SDHC_Type *base,
break;
#endif /* FSL_SDHC_ENABLE_ADMA1 */
case kSDHC_DmaModeAdma2:
/*
* Add non aligned access support ,user need make sure your buffer size is big
* enough to hold the data,in other words,user need make sure the buffer size
* is 4 byte aligned
*/
if (dataBytes % sizeof(uint32_t) != 0U)
{
dataBytes +=
sizeof(uint32_t) - (dataBytes % sizeof(uint32_t)); /* make the data length as word-aligned */
}
startAddress = data;
/* Check if ADMA descriptor's number is enough. */
entries = ((dataBytes / SDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) + 1U);
@ -1125,15 +1178,14 @@ status_t SDHC_SetAdmaTableConfig(SDHC_Type *base,
status_t SDHC_TransferBlocking(SDHC_Type *base, uint32_t *admaTable, uint32_t admaTableWords, sdhc_transfer_t *transfer)
{
assert(transfer);
assert(transfer->command); /* Command must not be NULL, data can be NULL. */
status_t error = kStatus_Success;
sdhc_dma_mode_t dmaMode = (sdhc_dma_mode_t)((base->PROCTL & SDHC_PROCTL_DMAS_MASK) >> SDHC_PROCTL_DMAS_SHIFT);
sdhc_command_t *command = transfer->command;
sdhc_data_t *data = transfer->data;
/* DATA-PORT is 32-bit align, ADMA2 4 bytes align, ADMA1 is 4096 bytes align */
if ((!command) || (data && (data->blockSize % 4U)))
/* make sure the cmd/block count is valid */
if ((!command) || (data && (data->blockCount > SDHC_MAX_BLOCK_COUNT)))
{
error = kStatus_InvalidArgument;
}
@ -1147,7 +1199,7 @@ status_t SDHC_TransferBlocking(SDHC_Type *base, uint32_t *admaTable, uint32_t ad
{
}
/* Update ADMA descriptor table if data isn't NULL. */
/* Update ADMA descriptor table according to different DMA mode(no DMA, ADMA1, ADMA2).*/
if (data && (kStatus_Success != SDHC_SetAdmaTableConfig(base, dmaMode, admaTable, admaTableWords,
(data->rxData ? data->rxData : data->txData),
(data->blockCount * data->blockSize))))
@ -1156,9 +1208,8 @@ status_t SDHC_TransferBlocking(SDHC_Type *base, uint32_t *admaTable, uint32_t ad
}
else
{
SDHC_StartTransfer(base, command, data);
/* Send command and receive data. */
SDHC_StartTransfer(base, command, data);
if (kStatus_Success != SDHC_SendCommandBlocking(base, command))
{
error = kStatus_SDHC_SendCommandFailed;
@ -1200,6 +1251,10 @@ void SDHC_TransferCreateHandle(SDHC_Type *base,
/* Enable interrupt in NVIC. */
SDHC_SetTransferInterrupt(base, true);
/* save IRQ handler */
s_sdhcIsr = SDHC_TransferHandleIRQ;
EnableIRQ(s_sdhcIRQ[SDHC_GetInstance(base)]);
}
@ -1213,8 +1268,8 @@ status_t SDHC_TransferNonBlocking(
sdhc_command_t *command = transfer->command;
sdhc_data_t *data = transfer->data;
/* DATA-PORT is 32-bit align, ADMA2 4 bytes align, ADMA1 is 4096 bytes align */
if ((!(transfer->command)) || ((transfer->data) && (transfer->data->blockSize % 4U)))
/* make sure cmd/block count is valid */
if ((!command) || (data && (data->blockCount > SDHC_MAX_BLOCK_COUNT)))
{
error = kStatus_InvalidArgument;
}
@ -1228,7 +1283,7 @@ status_t SDHC_TransferNonBlocking(
}
else
{
/* Update ADMA descriptor table and reset transferred words if data isn't NULL. */
/* Update ADMA descriptor table according to different DMA mode(no DMA, ADMA1, ADMA2).*/
if (data && (kStatus_Success != SDHC_SetAdmaTableConfig(base, dmaMode, admaTable, admaTableWords,
(data->rxData ? data->rxData : data->txData),
(data->blockCount * data->blockSize))))
@ -1243,6 +1298,7 @@ status_t SDHC_TransferNonBlocking(
handle->interruptFlags = 0U;
/* transferredWords will only be updated in ISR when transfer way is DATAPORT. */
handle->transferredWords = 0U;
SDHC_StartTransfer(base, command, data);
}
}
@ -1289,6 +1345,6 @@ void SDHC_DriverIRQHandler(void)
{
assert(s_sdhcHandle[0]);
SDHC_TransferHandleIRQ(SDHC, s_sdhcHandle[0]);
s_sdhcIsr(SDHC, s_sdhcHandle[0]);
}
#endif

View File

@ -37,16 +37,14 @@
* @{
*/
/*! @file */
/******************************************************************************
* Definitions.
*****************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief Driver version 2.0.0. */
#define FSL_SDHC_DRIVER_VERSION (MAKE_VERSION(2U, 0U, 0U))
/*! @brief Driver version 2.1.2. */
#define FSL_SDHC_DRIVER_VERSION (MAKE_VERSION(2U, 1U, 2U))
/*@}*/
/*! @brief Maximum block count can be set one time */
@ -350,7 +348,7 @@ typedef enum _sdhc_response_type
#define SDHC_ADMA1_DESCRIPTOR_LENGTH_SHIFT (12U)
/*! @brief The mask for LENGTH field in ADMA1's descriptor */
#define SDHC_ADMA1_DESCRIPTOR_LENGTH_MASK (0xFFFFU)
/*! @brief The max value of LENGTH filed in ADMA1's descriptor */
/*! @brief The maximum value of LENGTH filed in ADMA1's descriptor */
#define SDHC_ADMA1_DESCRIPTOR_MAX_LENGTH_PER_ENTRY (SDHC_ADMA1_DESCRIPTOR_LENGTH_MASK + 1U)
/*! @brief The mask for the control/status field in ADMA1 descriptor */
@ -395,7 +393,7 @@ enum _sdhc_adma1_descriptor_flag
#define SDHC_ADMA2_DESCRIPTOR_LENGTH_SHIFT (16U)
/*! @brief The bit mask for LENGTH field in ADMA2's descriptor */
#define SDHC_ADMA2_DESCRIPTOR_LENGTH_MASK (0xFFFFU)
/*! @brief The max value of LENGTH field in ADMA2's descriptor */
/*! @brief The maximum value of LENGTH field in ADMA2's descriptor */
#define SDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY (SDHC_ADMA2_DESCRIPTOR_LENGTH_MASK)
/*! @brief ADMA1 descriptor control and status mask */
@ -416,10 +414,10 @@ enum _sdhc_adma2_descriptor_flag
kSDHC_Adma2DescriptorValidFlag), /*!< Link type */
};
/*! @brief Define the adma1 descriptor structure. */
/*! @brief Defines the adma1 descriptor structure. */
typedef uint32_t sdhc_adma1_descriptor_t;
/*! @brief Define the ADMA2 descriptor structure. */
/*! @brief Defines the ADMA2 descriptor structure. */
typedef struct _sdhc_adma2_descriptor
{
uint32_t attribute; /*!< The control and status field */
@ -429,7 +427,7 @@ typedef struct _sdhc_adma2_descriptor
/*!
* @brief SDHC capability information.
*
* Define structure to save the capability information of SDHC.
* Defines a structure to save the capability information of SDHC.
*/
typedef struct _sdhc_capability
{
@ -457,9 +455,9 @@ typedef struct _sdhc_transfer_config
/*! @brief Data structure to configure the MMC boot feature */
typedef struct _sdhc_boot_config
{
uint32_t ackTimeoutCount; /*!< Timeout value for the boot ACK */
uint32_t ackTimeoutCount; /*!< Timeout value for the boot ACK. The available range is 0 ~ 15. */
sdhc_boot_mode_t bootMode; /*!< Boot mode selection. */
uint32_t blockCount; /*!< Stop at block gap value of automatic mode */
uint32_t blockCount; /*!< Stop at block gap value of automatic mode. Available range is 0 ~ 65535. */
bool enableBootAck; /*!< Enable or disable boot ACK */
bool enableBoot; /*!< Enable or disable fast boot */
bool enableAutoStopAtBlockGap; /*!< Enable or disable auto stop at block gap function in boot period */
@ -471,15 +469,15 @@ typedef struct _sdhc_config
bool cardDetectDat3; /*!< Enable DAT3 as card detection pin */
sdhc_endian_mode_t endianMode; /*!< Endian mode */
sdhc_dma_mode_t dmaMode; /*!< DMA mode */
uint32_t readWatermarkLevel; /*!< Watermark level for DMA read operation */
uint32_t writeWatermarkLevel; /*!< Watermark level for DMA write operation */
uint32_t readWatermarkLevel; /*!< Watermark level for DMA read operation. Available range is 1 ~ 128. */
uint32_t writeWatermarkLevel; /*!< Watermark level for DMA write operation. Available range is 1 ~ 128. */
} sdhc_config_t;
/*!
* @brief Card data descriptor
*
* Define structure to contain data-related attribute. 'enableIgnoreError' is used for the case that upper card driver
* want to ignore the error event to read/write all the data not to stop read/write immediately when error event
* Defines a structure to contain data-related attribute. 'enableIgnoreError' is used for the case that upper card
* driver want to ignore the error event to read/write all the data not to stop read/write immediately when error event
* happen for example bus testing procedure for MMC card.
*/
typedef struct _sdhc_data
@ -530,10 +528,11 @@ typedef struct _sdhc_transfer_callback
} sdhc_transfer_callback_t;
/*!
* @brief Host descriptor
* @brief SDHC handle
*
* Define the structure to save the SDHC state information and callback function. The detail interrupt status when
* send command or transfer data can be got from interruptFlags field by using mask defined in sdhc_interrupt_flag_t;
* Defines the structure to save the SDHC state information and callback function. The detailed interrupt status when
* sending a command or transfering data can be obtained from the interruptFlags field by using the mask defined in
* sdhc_interrupt_flag_t.
*
* @note All the fields except interruptFlags and transferredWords must be allocated by the user.
*/
@ -580,16 +579,16 @@ extern "C" {
/*!
* @brief SDHC module initialization function.
*
* Configure the SDHC according to the user configuration.
* Configures the SDHC according to the user configuration.
*
* Example:
@code
sdhc_config_t config;
config.enableDat3AsCDPin = false;
config.cardDetectDat3 = false;
config.endianMode = kSDHC_EndianModeLittle;
config.dmaMode = kSDHC_DmaModeAdma2;
config.readWatermarkLevel = 512U;
config.writeWatermarkLevel = 512U;
config.readWatermarkLevel = 128U;
config.writeWatermarkLevel = 128U;
SDHC_Init(SDHC, &config);
@endcode
*
@ -600,14 +599,14 @@ extern "C" {
void SDHC_Init(SDHC_Type *base, const sdhc_config_t *config);
/*!
* @brief Deinitialize the SDHC.
* @brief Deinitializes the SDHC.
*
* @param base SDHC peripheral base address.
*/
void SDHC_Deinit(SDHC_Type *base);
/*!
* @brief Reset the SDHC.
* @brief Resets the SDHC.
*
* @param base SDHC peripheral base address.
* @param mask The reset type mask(_sdhc_reset).
@ -625,7 +624,7 @@ bool SDHC_Reset(SDHC_Type *base, uint32_t mask, uint32_t timeout);
*/
/*!
* @brief Set ADMA descriptor table configuration.
* @brief Sets the ADMA descriptor table configuration.
*
* @param base SDHC peripheral base address.
* @param dmaMode DMA mode.
@ -651,7 +650,7 @@ status_t SDHC_SetAdmaTableConfig(SDHC_Type *base,
*/
/*!
* @brief Enable interrupt status
* @brief Enables the interrupt status.
*
* @param base SDHC peripheral base address.
* @param mask Interrupt status flags mask(_sdhc_interrupt_status_flag).
@ -662,7 +661,7 @@ static inline void SDHC_EnableInterruptStatus(SDHC_Type *base, uint32_t mask)
}
/*!
* @brief Disable interrupt status.
* @brief Disables the interrupt status.
*
* @param base SDHC peripheral base address.
* @param mask The interrupt status flags mask(_sdhc_interrupt_status_flag).
@ -673,7 +672,7 @@ static inline void SDHC_DisableInterruptStatus(SDHC_Type *base, uint32_t mask)
}
/*!
* @brief Enable interrupts signal corresponding to the interrupt status flag.
* @brief Enables the interrupt signal corresponding to the interrupt status flag.
*
* @param base SDHC peripheral base address.
* @param mask The interrupt status flags mask(_sdhc_interrupt_status_flag).
@ -684,7 +683,7 @@ static inline void SDHC_EnableInterruptSignal(SDHC_Type *base, uint32_t mask)
}
/*!
* @brief Disable interrupts signal corresponding to the interrupt status flag.
* @brief Disables the interrupt signal corresponding to the interrupt status flag.
*
* @param base SDHC peripheral base address.
* @param mask The interrupt status flags mask(_sdhc_interrupt_status_flag).
@ -702,7 +701,7 @@ static inline void SDHC_DisableInterruptSignal(SDHC_Type *base, uint32_t mask)
*/
/*!
* @brief Get current interrupt status.
* @brief Gets the current interrupt status.
*
* @param base SDHC peripheral base address.
* @return Current interrupt status flags mask(_sdhc_interrupt_status_flag).
@ -713,7 +712,7 @@ static inline uint32_t SDHC_GetInterruptStatusFlags(SDHC_Type *base)
}
/*!
* @brief Clear specified interrupt status.
* @brief Clears a specified interrupt status.
*
* @param base SDHC peripheral base address.
* @param mask The interrupt status flags mask(_sdhc_interrupt_status_flag).
@ -724,7 +723,7 @@ static inline void SDHC_ClearInterruptStatusFlags(SDHC_Type *base, uint32_t mask
}
/*!
* @brief Get the status of auto command 12 error.
* @brief Gets the status of auto command 12 error.
*
* @param base SDHC peripheral base address.
* @return Auto command 12 error status flags mask(_sdhc_auto_command12_error_status_flag).
@ -735,7 +734,7 @@ static inline uint32_t SDHC_GetAutoCommand12ErrorStatusFlags(SDHC_Type *base)
}
/*!
* @brief Get the status of ADMA error.
* @brief Gets the status of the ADMA error.
*
* @param base SDHC peripheral base address.
* @return ADMA error status flags mask(_sdhc_adma_error_status_flag).
@ -746,9 +745,9 @@ static inline uint32_t SDHC_GetAdmaErrorStatusFlags(SDHC_Type *base)
}
/*!
* @brief Get present status.
* @brief Gets a present status.
*
* This function gets the present SDHC's status except for interrupt status and error status.
* This function gets the present SDHC's status except for an interrupt status and an error status.
*
* @param base SDHC peripheral base address.
* @return Present SDHC's status flags mask(_sdhc_present_status_flag).
@ -766,7 +765,7 @@ static inline uint32_t SDHC_GetPresentStatusFlags(SDHC_Type *base)
*/
/*!
* @brief Get the capability information
* @brief Gets the capability information.
*
* @param base SDHC peripheral base address.
* @param capability Structure to save capability information.
@ -774,7 +773,7 @@ static inline uint32_t SDHC_GetPresentStatusFlags(SDHC_Type *base)
void SDHC_GetCapability(SDHC_Type *base, sdhc_capability_t *capability);
/*!
* @brief Enable or disable SD bus clock.
* @brief Enables or disables the SD bus clock.
*
* @param base SDHC peripheral base address.
* @param enable True to enable, false to disable.
@ -792,7 +791,7 @@ static inline void SDHC_EnableSdClock(SDHC_Type *base, bool enable)
}
/*!
* @brief Set SD bus clock frequency.
* @brief Sets the SD bus clock frequency.
*
* @param base SDHC peripheral base address.
* @param srcClock_Hz SDHC source clock frequency united in Hz.
@ -803,9 +802,10 @@ static inline void SDHC_EnableSdClock(SDHC_Type *base, bool enable)
uint32_t SDHC_SetSdClock(SDHC_Type *base, uint32_t srcClock_Hz, uint32_t busClock_Hz);
/*!
* @brief Send 80 clocks to the card to set it to be active state.
* @brief Sends 80 clocks to the card to set it to the active state.
*
* This function must be called after each time the card is inserted to make card can receive command correctly.
* This function must be called each time the card is inserted to ensure that the card can receive the command
* correctly.
*
* @param base SDHC peripheral base address.
* @param timeout Timeout to initialize card.
@ -815,7 +815,7 @@ uint32_t SDHC_SetSdClock(SDHC_Type *base, uint32_t srcClock_Hz, uint32_t busCloc
bool SDHC_SetCardActive(SDHC_Type *base, uint32_t timeout);
/*!
* @brief Set the data transfer width.
* @brief Sets the data transfer width.
*
* @param base SDHC peripheral base address.
* @param width Data transfer width.
@ -826,10 +826,10 @@ static inline void SDHC_SetDataBusWidth(SDHC_Type *base, sdhc_data_bus_width_t w
}
/*!
* @brief Set card transfer-related configuration.
* @brief Sets the card transfer-related configuration.
*
* This function fills card transfer-related command argument/transfer flag/data size. Command and data will be sent by
* SDHC after calling this function.
* This function fills the card transfer-related command argument/transfer flag/data size. The command and data are sent
* by SDHC after calling this function.
*
* Example:
@code
@ -848,7 +848,7 @@ static inline void SDHC_SetDataBusWidth(SDHC_Type *base, sdhc_data_bus_width_t w
void SDHC_SetTransferConfig(SDHC_Type *base, const sdhc_transfer_config_t *config);
/*!
* @brief Get the command response.
* @brief Gets the command response.
*
* @param base SDHC peripheral base address.
* @param index The index of response register, range from 0 to 3.
@ -862,9 +862,9 @@ static inline uint32_t SDHC_GetCommandResponse(SDHC_Type *base, uint32_t index)
}
/*!
* @brief Fill the the data port.
* @brief Fills the the data port.
*
* This function is mainly used to implement the data transfer by Data Port instead of DMA.
* This function is used to implement the data transfer by Data Port instead of DMA.
*
* @param base SDHC peripheral base address.
* @param data The data about to be sent.
@ -875,9 +875,9 @@ static inline void SDHC_WriteData(SDHC_Type *base, uint32_t data)
}
/*!
* @brief Retrieve the data from the data port.
* @brief Retrieves the data from the data port.
*
* This function is mainly used to implement the data transfer by Data Port instead of DMA.
* This function is used to implement the data transfer by Data Port instead of DMA.
*
* @param base SDHC peripheral base address.
* @return The data has been read.
@ -888,7 +888,7 @@ static inline uint32_t SDHC_ReadData(SDHC_Type *base)
}
/*!
* @brief Enable or disable wakeup event in low power mode
* @brief Enables or disables a wakeup event in low-power mode.
*
* @param base SDHC peripheral base address.
* @param mask Wakeup events mask(_sdhc_wakeup_event).
@ -907,7 +907,7 @@ static inline void SDHC_EnableWakeupEvent(SDHC_Type *base, uint32_t mask, bool e
}
/*!
* @brief Enable or disable card detection level for test.
* @brief Enables or disables the card detection level for testing.
*
* @param base SDHC peripheral base address.
* @param enable True to enable, false to disable.
@ -925,11 +925,11 @@ static inline void SDHC_EnableCardDetectTest(SDHC_Type *base, bool enable)
}
/*!
* @brief Set card detection test level.
* @brief Sets the card detection test level.
*
* This function set the card detection test level to indicate whether the card is inserted into SDHC when DAT[3]/
* CD pin is selected as card detection pin. This function can also assert the pin logic when DAT[3]/CD pin is select
* as the card detection pin.
* This function sets the card detection test level to indicate whether the card is inserted into the SDHC when DAT[3]/
* CD pin is selected as a card detection pin. This function can also assert the pin logic when DAT[3]/CD pin is
* selected as the card detection pin.
*
* @param base SDHC peripheral base address.
* @param high True to set the card detect level to high.
@ -947,7 +947,7 @@ static inline void SDHC_SetCardDetectTestLevel(SDHC_Type *base, bool high)
}
/*!
* @brief Enable or disable SDIO card control.
* @brief Enables or disables the SDIO card control.
*
* @param base SDHC peripheral base address.
* @param mask SDIO card control flags mask(_sdhc_sdio_control_flag).
@ -956,7 +956,7 @@ static inline void SDHC_SetCardDetectTestLevel(SDHC_Type *base, bool high)
void SDHC_EnableSdioControl(SDHC_Type *base, uint32_t mask, bool enable);
/*!
* @brief Restart a transaction which has stopped at the block gap for SDIO card.
* @brief Restarts a transaction which has stopped at the block GAP for the SDIO card.
*
* @param base SDHC peripheral base address.
*/
@ -966,18 +966,18 @@ static inline void SDHC_SetContinueRequest(SDHC_Type *base)
}
/*!
* @brief Configure the MMC boot feature.
* @brief Configures the MMC boot feature.
*
* Example:
@code
sdhc_boot_config_t bootConfig;
bootConfig.ackTimeoutCount = 4;
bootConfig.bootMode = kSDHC_BootModeNormal;
bootConfig.blockCount = 5;
bootConfig.enableBootAck = true;
bootConfig.enableBoot = true;
enableBoot.enableAutoStopAtBlockGap = true;
SDHC_SetMmcBootConfig(SDHC, &bootConfig);
sdhc_boot_config_t config;
config.ackTimeoutCount = 4;
config.bootMode = kSDHC_BootModeNormal;
config.blockCount = 5;
config.enableBootAck = true;
config.enableBoot = true;
config.enableAutoStopAtBlockGap = true;
SDHC_SetMmcBootConfig(SDHC, &config);
@endcode
*
* @param base SDHC peripheral base address.
@ -986,7 +986,7 @@ static inline void SDHC_SetContinueRequest(SDHC_Type *base)
void SDHC_SetMmcBootConfig(SDHC_Type *base, const sdhc_boot_config_t *config);
/*!
* @brief Force to generate events according to the given mask.
* @brief Forces generating events according to the given mask.
*
* @param base SDHC peripheral base address.
* @param mask The force events mask(_sdhc_force_event).
@ -1004,13 +1004,13 @@ static inline void SDHC_SetForceEvent(SDHC_Type *base, uint32_t mask)
*/
/*!
* @brief Transfer command/data using blocking way.
* @brief Transfers the command/data using a blocking method.
*
* This function waits until the command response/data is got or SDHC encounters error by polling the status flag.
* Application must not call this API in multiple threads at the same time because of that this API doesn't support
* reentry mechanism.
* This function waits until the command response/data is received or the SDHC encounters an error by polling the status
* flag. The application must not call this API in multiple threads at the same time. Because of that this API doesn't support
* the re-entry mechanism.
*
* @note Needn't to call the API 'SDHC_TransferCreateHandle' when calling this API.
* @note There is no need to call the API 'SDHC_TransferCreateHandle' when calling this API.
*
* @param base SDHC peripheral base address.
* @param admaTable ADMA table address, can't be null if transfer way is ADMA1/ADMA2.
@ -1028,7 +1028,7 @@ status_t SDHC_TransferBlocking(SDHC_Type *base,
sdhc_transfer_t *transfer);
/*!
* @brief Create the SDHC handle.
* @brief Creates the SDHC handle.
*
* @param base SDHC peripheral base address.
* @param handle SDHC handle pointer.
@ -1041,13 +1041,13 @@ void SDHC_TransferCreateHandle(SDHC_Type *base,
void *userData);
/*!
* @brief Transfer command/data using interrupt and asynchronous way.
* @brief Transfers the command/data using an interrupt and an asynchronous method.
*
* This function send command and data and return immediately. It doesn't wait the transfer complete or encounter error.
* Application must not call this API in multiple threads at the same time because of that this API doesn't support
* reentry mechanism.
* This function sends a command and data and returns immediately. It doesn't wait the transfer complete or encounter an
* error. The application must not call this API in multiple threads at the same time. Because of that this API doesn't support
* the re-entry mechanism.
*
* @note Must call the API 'SDHC_TransferCreateHandle' when calling this API.
* @note Call the API 'SDHC_TransferCreateHandle' when calling this API.
*
* @param base SDHC peripheral base address.
* @param handle SDHC handle.
@ -1063,9 +1063,9 @@ status_t SDHC_TransferNonBlocking(
SDHC_Type *base, sdhc_handle_t *handle, uint32_t *admaTable, uint32_t admaTableWords, sdhc_transfer_t *transfer);
/*!
* @brief IRQ handler for SDHC
* @brief IRQ handler for the SDHC.
*
* This function deals with IRQs on the given host controller.
* This function deals with the IRQs on the given host controller.
*
* @param base SDHC peripheral base address.
* @param handle SDHC handle.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Freescale Semiconductor, Inc.
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -50,6 +50,9 @@
#define SDHC_NEXT_CLKFS(x) ((x) <<= 1U)
#define SDHC_PREV_CLKFS(x) ((x) >>= 1U)
/* Typedef for interrupt handler. */
typedef void (*sdhc_isr_t)(SDHC_Type *base, sdhc_handle_t *handle);
/*! @brief ADMA table configuration */
typedef struct _sdhc_adma_table_config
{
@ -230,6 +233,9 @@ static const IRQn_Type s_sdhcIRQ[] = SDHC_IRQS;
/*! @brief SDHC clock array name */
static const clock_ip_name_t s_sdhcClock[] = SDHC_CLOCKS;
/* SDHC ISR for transactional APIs. */
static sdhc_isr_t s_sdhcIsr;
/*******************************************************************************
* Code
******************************************************************************/
@ -288,10 +294,8 @@ static void SDHC_SetTransferInterrupt(SDHC_Type *base, bool usingInterruptSignal
static void SDHC_StartTransfer(SDHC_Type *base, sdhc_command_t *command, sdhc_data_t *data)
{
assert(command);
uint32_t flags = 0U;
sdhc_transfer_config_t sdhcTransferConfig;
sdhc_transfer_config_t sdhcTransferConfig = {0};
sdhc_dma_mode_t dmaMode;
/* Define the flag corresponding to each response type. */
@ -315,7 +319,7 @@ static void SDHC_StartTransfer(SDHC_Type *base, sdhc_command_t *command, sdhc_da
flags |= (kSDHC_ResponseLength48Flag);
break;
case kSDHC_ResponseTypeR5: /* Response 5 */
flags |= (kSDHC_ResponseLength48Flag | kSDHC_EnableCrcCheckFlag);
flags |= (kSDHC_ResponseLength48Flag | kSDHC_EnableCrcCheckFlag | kSDHC_EnableIndexCheckFlag);
break;
case kSDHC_ResponseTypeR5b: /* Response 5 with busy */
flags |= (kSDHC_ResponseLength48BusyFlag | kSDHC_EnableCrcCheckFlag | kSDHC_EnableIndexCheckFlag);
@ -355,18 +359,9 @@ static void SDHC_StartTransfer(SDHC_Type *base, sdhc_command_t *command, sdhc_da
flags |= kSDHC_EnableAutoCommand12Flag;
}
}
if (data->blockCount > SDHC_MAX_BLOCK_COUNT)
{
sdhcTransferConfig.dataBlockSize = data->blockSize;
sdhcTransferConfig.dataBlockCount = SDHC_MAX_BLOCK_COUNT;
flags &= ~(uint32_t)kSDHC_EnableBlockCountFlag;
}
else
{
sdhcTransferConfig.dataBlockSize = data->blockSize;
sdhcTransferConfig.dataBlockCount = data->blockCount;
}
sdhcTransferConfig.dataBlockSize = data->blockSize;
sdhcTransferConfig.dataBlockCount = data->blockCount;
}
else
{
@ -382,8 +377,6 @@ static void SDHC_StartTransfer(SDHC_Type *base, sdhc_command_t *command, sdhc_da
static void SDHC_ReceiveCommandResponse(SDHC_Type *base, sdhc_command_t *command)
{
assert(command);
uint32_t i;
if (command->responseType != kSDHC_ResponseTypeNone)
@ -412,13 +405,22 @@ static void SDHC_ReceiveCommandResponse(SDHC_Type *base, sdhc_command_t *command
static uint32_t SDHC_ReadDataPort(SDHC_Type *base, sdhc_data_t *data, uint32_t transferredWords)
{
assert(data);
uint32_t i;
uint32_t totalWords;
uint32_t wordsCanBeRead; /* The words can be read at this time. */
uint32_t readWatermark = ((base->WML & SDHC_WML_RDWML_MASK) >> SDHC_WML_RDWML_SHIFT);
/*
* Add non aligned access support ,user need make sure your buffer size is big
* enough to hold the data,in other words,user need make sure the buffer size
* is 4 byte aligned
*/
if (data->blockSize % sizeof(uint32_t) != 0U)
{
data->blockSize +=
sizeof(uint32_t) - (data->blockSize % sizeof(uint32_t)); /* make the block size as word-aligned */
}
totalWords = ((data->blockCount * data->blockSize) / sizeof(uint32_t));
/* If watermark level is equal or bigger than totalWords, transfers totalWords data. */
@ -451,12 +453,21 @@ static uint32_t SDHC_ReadDataPort(SDHC_Type *base, sdhc_data_t *data, uint32_t t
static status_t SDHC_ReadByDataPortBlocking(SDHC_Type *base, sdhc_data_t *data)
{
assert(data);
uint32_t totalWords;
uint32_t transferredWords = 0U;
status_t error = kStatus_Success;
/*
* Add non aligned access support ,user need make sure your buffer size is big
* enough to hold the data,in other words,user need make sure the buffer size
* is 4 byte aligned
*/
if (data->blockSize % sizeof(uint32_t) != 0U)
{
data->blockSize +=
sizeof(uint32_t) - (data->blockSize % sizeof(uint32_t)); /* make the block size as word-aligned */
}
totalWords = ((data->blockCount * data->blockSize) / sizeof(uint32_t));
while ((error == kStatus_Success) && (transferredWords < totalWords))
@ -489,13 +500,22 @@ static status_t SDHC_ReadByDataPortBlocking(SDHC_Type *base, sdhc_data_t *data)
static uint32_t SDHC_WriteDataPort(SDHC_Type *base, sdhc_data_t *data, uint32_t transferredWords)
{
assert(data);
uint32_t i;
uint32_t totalWords;
uint32_t wordsCanBeWrote; /* Words can be wrote at this time. */
uint32_t writeWatermark = ((base->WML & SDHC_WML_WRWML_MASK) >> SDHC_WML_WRWML_SHIFT);
/*
* Add non aligned access support ,user need make sure your buffer size is big
* enough to hold the data,in other words,user need make sure the buffer size
* is 4 byte aligned
*/
if (data->blockSize % sizeof(uint32_t) != 0U)
{
data->blockSize +=
sizeof(uint32_t) - (data->blockSize % sizeof(uint32_t)); /* make the block size as word-aligned */
}
totalWords = ((data->blockCount * data->blockSize) / sizeof(uint32_t));
/* If watermark level is equal or bigger than totalWords, transfers totalWords data.*/
@ -528,12 +548,21 @@ static uint32_t SDHC_WriteDataPort(SDHC_Type *base, sdhc_data_t *data, uint32_t
static status_t SDHC_WriteByDataPortBlocking(SDHC_Type *base, sdhc_data_t *data)
{
assert(data);
uint32_t totalWords;
uint32_t transferredWords = 0U;
status_t error = kStatus_Success;
/*
* Add non aligned access support ,user need make sure your buffer size is big
* enough to hold the data,in other words,user need make sure the buffer size
* is 4 byte aligned
*/
if (data->blockSize % sizeof(uint32_t) != 0U)
{
data->blockSize +=
sizeof(uint32_t) - (data->blockSize % sizeof(uint32_t)); /* make the block size as word-aligned */
}
totalWords = (data->blockCount * data->blockSize) / sizeof(uint32_t);
while ((error == kStatus_Success) && (transferredWords < totalWords))
@ -576,8 +605,6 @@ static status_t SDHC_WriteByDataPortBlocking(SDHC_Type *base, sdhc_data_t *data)
static status_t SDHC_SendCommandBlocking(SDHC_Type *base, sdhc_command_t *command)
{
assert(command);
status_t error = kStatus_Success;
/* Wait command complete or SDHC encounters error. */
@ -602,8 +629,6 @@ static status_t SDHC_SendCommandBlocking(SDHC_Type *base, sdhc_command_t *comman
static status_t SDHC_TransferByDataPortBlocking(SDHC_Type *base, sdhc_data_t *data)
{
assert(data);
status_t error = kStatus_Success;
if (data->rxData)
@ -669,8 +694,6 @@ static status_t SDHC_TransferDataBlocking(sdhc_dma_mode_t dmaMode, SDHC_Type *ba
static void SDHC_TransferHandleCardDetect(sdhc_handle_t *handle, uint32_t interruptFlags)
{
assert(interruptFlags & kSDHC_CardDetectFlag);
if (interruptFlags & kSDHC_CardInsertionFlag)
{
if (handle->callback.CardInserted)
@ -689,7 +712,7 @@ static void SDHC_TransferHandleCardDetect(sdhc_handle_t *handle, uint32_t interr
static void SDHC_TransferHandleCommand(SDHC_Type *base, sdhc_handle_t *handle, uint32_t interruptFlags)
{
assert(interruptFlags & kSDHC_CommandFlag);
assert(handle->command);
if ((interruptFlags & kSDHC_CommandErrorFlag) && (!(handle->data)) && (handle->callback.TransferComplete))
{
@ -709,7 +732,6 @@ static void SDHC_TransferHandleCommand(SDHC_Type *base, sdhc_handle_t *handle, u
static void SDHC_TransferHandleData(SDHC_Type *base, sdhc_handle_t *handle, uint32_t interruptFlags)
{
assert(handle->data);
assert(interruptFlags & kSDHC_DataFlag);
if ((!(handle->data->enableIgnoreError)) && (interruptFlags & (kSDHC_DataErrorFlag | kSDHC_DmaErrorFlag)) &&
(handle->callback.TransferComplete))
@ -759,6 +781,8 @@ void SDHC_Init(SDHC_Type *base, const sdhc_config_t *config)
#if !defined FSL_SDHC_ENABLE_ADMA1
assert(config->dmaMode != kSDHC_DmaModeAdma1);
#endif /* FSL_SDHC_ENABLE_ADMA1 */
assert((config->writeWatermarkLevel >= 1U) && (config->writeWatermarkLevel <= 128U));
assert((config->readWatermarkLevel >= 1U) && (config->readWatermarkLevel <= 128U));
uint32_t proctl;
uint32_t wml;
@ -850,7 +874,8 @@ void SDHC_GetCapability(SDHC_Type *base, sdhc_capability_t *capability)
uint32_t SDHC_SetSdClock(SDHC_Type *base, uint32_t srcClock_Hz, uint32_t busClock_Hz)
{
assert(busClock_Hz && (busClock_Hz < srcClock_Hz));
assert(srcClock_Hz != 0U);
assert((busClock_Hz != 0U) && (busClock_Hz <= srcClock_Hz));
uint32_t divisor;
uint32_t prescaler;
@ -898,7 +923,7 @@ bool SDHC_SetCardActive(SDHC_Type *base, uint32_t timeout)
{
base->SYSCTL |= SDHC_SYSCTL_INITA_MASK;
/* Delay some time to wait card become active state. */
while (!(base->SYSCTL & SDHC_SYSCTL_INITA_MASK))
while (base->SYSCTL & SDHC_SYSCTL_INITA_MASK)
{
if (!timeout)
{
@ -913,6 +938,8 @@ bool SDHC_SetCardActive(SDHC_Type *base, uint32_t timeout)
void SDHC_SetTransferConfig(SDHC_Type *base, const sdhc_transfer_config_t *config)
{
assert(config);
assert(config->dataBlockSize <= (SDHC_BLKATTR_BLKSIZE_MASK >> SDHC_BLKATTR_BLKSIZE_SHIFT));
assert(config->dataBlockCount <= (SDHC_BLKATTR_BLKCNT_MASK >> SDHC_BLKATTR_BLKCNT_SHIFT));
base->BLKATTR = ((base->BLKATTR & ~(SDHC_BLKATTR_BLKSIZE_MASK | SDHC_BLKATTR_BLKCNT_MASK)) |
(SDHC_BLKATTR_BLKSIZE(config->dataBlockSize) | SDHC_BLKATTR_BLKCNT(config->dataBlockCount)));
@ -975,12 +1002,13 @@ void SDHC_EnableSdioControl(SDHC_Type *base, uint32_t mask, bool enable)
void SDHC_SetMmcBootConfig(SDHC_Type *base, const sdhc_boot_config_t *config)
{
assert(config);
assert(config->ackTimeoutCount <= (SDHC_MMCBOOT_DTOCVACK_MASK >> SDHC_MMCBOOT_DTOCVACK_SHIFT));
assert(config->blockCount <= (SDHC_MMCBOOT_BOOTBLKCNT_MASK >> SDHC_MMCBOOT_BOOTBLKCNT_SHIFT));
uint32_t mmcboot;
uint32_t mmcboot = 0U;
mmcboot = base->MMCBOOT;
mmcboot |= (SDHC_MMCBOOT_DTOCVACK(config->ackTimeoutCount) | SDHC_MMCBOOT_BOOTMODE(config->bootMode) |
SDHC_MMCBOOT_BOOTBLKCNT(config->blockCount));
mmcboot = (SDHC_MMCBOOT_DTOCVACK(config->ackTimeoutCount) | SDHC_MMCBOOT_BOOTMODE(config->bootMode) |
SDHC_MMCBOOT_BOOTBLKCNT(config->blockCount));
if (config->enableBootAck)
{
mmcboot |= SDHC_MMCBOOT_BOOTACK_MASK;
@ -1016,6 +1044,9 @@ status_t SDHC_SetAdmaTableConfig(SDHC_Type *base,
(!data) || (!dataBytes)
#if !defined FSL_SDHC_ENABLE_ADMA1
|| (dmaMode == kSDHC_DmaModeAdma1)
#else
/* Buffer address configured in ADMA1 descriptor must be 4KB aligned. */
|| ((dmaMode == kSDHC_DmaModeAdma1) && (((uint32_t)data % SDHC_ADMA1_LENGTH_ALIGN) != 0U))
#endif /* FSL_SDHC_ENABLE_ADMA1 */
)
{
@ -1029,6 +1060,17 @@ status_t SDHC_SetAdmaTableConfig(SDHC_Type *base,
break;
#if defined FSL_SDHC_ENABLE_ADMA1
case kSDHC_DmaModeAdma1:
/*
* Add non aligned access support ,user need make sure your buffer size is big
* enough to hold the data,in other words,user need make sure the buffer size
* is 4 byte aligned
*/
if (dataBytes % sizeof(uint32_t) != 0U)
{
dataBytes +=
sizeof(uint32_t) - (dataBytes % sizeof(uint32_t)); /* make the data length as word-aligned */
}
startAddress = data;
/* Check if ADMA descriptor's number is enough. */
entries = ((dataBytes / SDHC_ADMA1_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) + 1U);
@ -1054,7 +1096,7 @@ status_t SDHC_SetAdmaTableConfig(SDHC_Type *base,
adma1EntryAddress[i + 1U] =
((uint32_t)(startAddress) << SDHC_ADMA1_DESCRIPTOR_ADDRESS_SHIFT);
adma1EntryAddress[i + 1U] |=
(SDHC_ADMA1_DESCRIPTOR_TYPE_TRANSFER | SDHC_ADMA1_DESCRIPTOR_END_MASK);
(kSDHC_Adma1DescriptorTypeTransfer | kSDHC_Adma1DescriptorEndFlag);
}
else
{
@ -1075,6 +1117,17 @@ status_t SDHC_SetAdmaTableConfig(SDHC_Type *base,
break;
#endif /* FSL_SDHC_ENABLE_ADMA1 */
case kSDHC_DmaModeAdma2:
/*
* Add non aligned access support ,user need make sure your buffer size is big
* enough to hold the data,in other words,user need make sure the buffer size
* is 4 byte aligned
*/
if (dataBytes % sizeof(uint32_t) != 0U)
{
dataBytes +=
sizeof(uint32_t) - (dataBytes % sizeof(uint32_t)); /* make the data length as word-aligned */
}
startAddress = data;
/* Check if ADMA descriptor's number is enough. */
entries = ((dataBytes / SDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) + 1U);
@ -1125,15 +1178,14 @@ status_t SDHC_SetAdmaTableConfig(SDHC_Type *base,
status_t SDHC_TransferBlocking(SDHC_Type *base, uint32_t *admaTable, uint32_t admaTableWords, sdhc_transfer_t *transfer)
{
assert(transfer);
assert(transfer->command); /* Command must not be NULL, data can be NULL. */
status_t error = kStatus_Success;
sdhc_dma_mode_t dmaMode = (sdhc_dma_mode_t)((base->PROCTL & SDHC_PROCTL_DMAS_MASK) >> SDHC_PROCTL_DMAS_SHIFT);
sdhc_command_t *command = transfer->command;
sdhc_data_t *data = transfer->data;
/* DATA-PORT is 32-bit align, ADMA2 4 bytes align, ADMA1 is 4096 bytes align */
if ((!command) || (data && (data->blockSize % 4U)))
/* make sure the cmd/block count is valid */
if ((!command) || (data && (data->blockCount > SDHC_MAX_BLOCK_COUNT)))
{
error = kStatus_InvalidArgument;
}
@ -1147,7 +1199,7 @@ status_t SDHC_TransferBlocking(SDHC_Type *base, uint32_t *admaTable, uint32_t ad
{
}
/* Update ADMA descriptor table if data isn't NULL. */
/* Update ADMA descriptor table according to different DMA mode(no DMA, ADMA1, ADMA2).*/
if (data && (kStatus_Success != SDHC_SetAdmaTableConfig(base, dmaMode, admaTable, admaTableWords,
(data->rxData ? data->rxData : data->txData),
(data->blockCount * data->blockSize))))
@ -1156,9 +1208,8 @@ status_t SDHC_TransferBlocking(SDHC_Type *base, uint32_t *admaTable, uint32_t ad
}
else
{
SDHC_StartTransfer(base, command, data);
/* Send command and receive data. */
SDHC_StartTransfer(base, command, data);
if (kStatus_Success != SDHC_SendCommandBlocking(base, command))
{
error = kStatus_SDHC_SendCommandFailed;
@ -1200,6 +1251,10 @@ void SDHC_TransferCreateHandle(SDHC_Type *base,
/* Enable interrupt in NVIC. */
SDHC_SetTransferInterrupt(base, true);
/* save IRQ handler */
s_sdhcIsr = SDHC_TransferHandleIRQ;
EnableIRQ(s_sdhcIRQ[SDHC_GetInstance(base)]);
}
@ -1213,8 +1268,8 @@ status_t SDHC_TransferNonBlocking(
sdhc_command_t *command = transfer->command;
sdhc_data_t *data = transfer->data;
/* DATA-PORT is 32-bit align, ADMA2 4 bytes align, ADMA1 is 4096 bytes align */
if ((!(transfer->command)) || ((transfer->data) && (transfer->data->blockSize % 4U)))
/* make sure cmd/block count is valid */
if ((!command) || (data && (data->blockCount > SDHC_MAX_BLOCK_COUNT)))
{
error = kStatus_InvalidArgument;
}
@ -1228,7 +1283,7 @@ status_t SDHC_TransferNonBlocking(
}
else
{
/* Update ADMA descriptor table and reset transferred words if data isn't NULL. */
/* Update ADMA descriptor table according to different DMA mode(no DMA, ADMA1, ADMA2).*/
if (data && (kStatus_Success != SDHC_SetAdmaTableConfig(base, dmaMode, admaTable, admaTableWords,
(data->rxData ? data->rxData : data->txData),
(data->blockCount * data->blockSize))))
@ -1243,6 +1298,7 @@ status_t SDHC_TransferNonBlocking(
handle->interruptFlags = 0U;
/* transferredWords will only be updated in ISR when transfer way is DATAPORT. */
handle->transferredWords = 0U;
SDHC_StartTransfer(base, command, data);
}
}
@ -1289,6 +1345,6 @@ void SDHC_DriverIRQHandler(void)
{
assert(s_sdhcHandle[0]);
SDHC_TransferHandleIRQ(SDHC, s_sdhcHandle[0]);
s_sdhcIsr(SDHC, s_sdhcHandle[0]);
}
#endif

View File

@ -37,16 +37,14 @@
* @{
*/
/*! @file */
/******************************************************************************
* Definitions.
*****************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief Driver version 2.0.0. */
#define FSL_SDHC_DRIVER_VERSION (MAKE_VERSION(2U, 0U, 0U))
/*! @brief Driver version 2.1.2. */
#define FSL_SDHC_DRIVER_VERSION (MAKE_VERSION(2U, 1U, 2U))
/*@}*/
/*! @brief Maximum block count can be set one time */
@ -350,7 +348,7 @@ typedef enum _sdhc_response_type
#define SDHC_ADMA1_DESCRIPTOR_LENGTH_SHIFT (12U)
/*! @brief The mask for LENGTH field in ADMA1's descriptor */
#define SDHC_ADMA1_DESCRIPTOR_LENGTH_MASK (0xFFFFU)
/*! @brief The max value of LENGTH filed in ADMA1's descriptor */
/*! @brief The maximum value of LENGTH filed in ADMA1's descriptor */
#define SDHC_ADMA1_DESCRIPTOR_MAX_LENGTH_PER_ENTRY (SDHC_ADMA1_DESCRIPTOR_LENGTH_MASK + 1U)
/*! @brief The mask for the control/status field in ADMA1 descriptor */
@ -395,7 +393,7 @@ enum _sdhc_adma1_descriptor_flag
#define SDHC_ADMA2_DESCRIPTOR_LENGTH_SHIFT (16U)
/*! @brief The bit mask for LENGTH field in ADMA2's descriptor */
#define SDHC_ADMA2_DESCRIPTOR_LENGTH_MASK (0xFFFFU)
/*! @brief The max value of LENGTH field in ADMA2's descriptor */
/*! @brief The maximum value of LENGTH field in ADMA2's descriptor */
#define SDHC_ADMA2_DESCRIPTOR_MAX_LENGTH_PER_ENTRY (SDHC_ADMA2_DESCRIPTOR_LENGTH_MASK)
/*! @brief ADMA1 descriptor control and status mask */
@ -416,10 +414,10 @@ enum _sdhc_adma2_descriptor_flag
kSDHC_Adma2DescriptorValidFlag), /*!< Link type */
};
/*! @brief Define the adma1 descriptor structure. */
/*! @brief Defines the adma1 descriptor structure. */
typedef uint32_t sdhc_adma1_descriptor_t;
/*! @brief Define the ADMA2 descriptor structure. */
/*! @brief Defines the ADMA2 descriptor structure. */
typedef struct _sdhc_adma2_descriptor
{
uint32_t attribute; /*!< The control and status field */
@ -429,7 +427,7 @@ typedef struct _sdhc_adma2_descriptor
/*!
* @brief SDHC capability information.
*
* Define structure to save the capability information of SDHC.
* Defines a structure to save the capability information of SDHC.
*/
typedef struct _sdhc_capability
{
@ -457,9 +455,9 @@ typedef struct _sdhc_transfer_config
/*! @brief Data structure to configure the MMC boot feature */
typedef struct _sdhc_boot_config
{
uint32_t ackTimeoutCount; /*!< Timeout value for the boot ACK */
uint32_t ackTimeoutCount; /*!< Timeout value for the boot ACK. The available range is 0 ~ 15. */
sdhc_boot_mode_t bootMode; /*!< Boot mode selection. */
uint32_t blockCount; /*!< Stop at block gap value of automatic mode */
uint32_t blockCount; /*!< Stop at block gap value of automatic mode. Available range is 0 ~ 65535. */
bool enableBootAck; /*!< Enable or disable boot ACK */
bool enableBoot; /*!< Enable or disable fast boot */
bool enableAutoStopAtBlockGap; /*!< Enable or disable auto stop at block gap function in boot period */
@ -471,15 +469,15 @@ typedef struct _sdhc_config
bool cardDetectDat3; /*!< Enable DAT3 as card detection pin */
sdhc_endian_mode_t endianMode; /*!< Endian mode */
sdhc_dma_mode_t dmaMode; /*!< DMA mode */
uint32_t readWatermarkLevel; /*!< Watermark level for DMA read operation */
uint32_t writeWatermarkLevel; /*!< Watermark level for DMA write operation */
uint32_t readWatermarkLevel; /*!< Watermark level for DMA read operation. Available range is 1 ~ 128. */
uint32_t writeWatermarkLevel; /*!< Watermark level for DMA write operation. Available range is 1 ~ 128. */
} sdhc_config_t;
/*!
* @brief Card data descriptor
*
* Define structure to contain data-related attribute. 'enableIgnoreError' is used for the case that upper card driver
* want to ignore the error event to read/write all the data not to stop read/write immediately when error event
* Defines a structure to contain data-related attribute. 'enableIgnoreError' is used for the case that upper card
* driver want to ignore the error event to read/write all the data not to stop read/write immediately when error event
* happen for example bus testing procedure for MMC card.
*/
typedef struct _sdhc_data
@ -530,10 +528,11 @@ typedef struct _sdhc_transfer_callback
} sdhc_transfer_callback_t;
/*!
* @brief Host descriptor
* @brief SDHC handle
*
* Define the structure to save the SDHC state information and callback function. The detail interrupt status when
* send command or transfer data can be obtained from interruptFlags field by using mask defined in sdhc_interrupt_flag_t;
* Defines the structure to save the SDHC state information and callback function. The detailed interrupt status when
* sending a command or transfering data can be obtained from the interruptFlags field by using the mask defined in
* sdhc_interrupt_flag_t.
*
* @note All the fields except interruptFlags and transferredWords must be allocated by the user.
*/
@ -580,16 +579,16 @@ extern "C" {
/*!
* @brief SDHC module initialization function.
*
* Configure the SDHC according to the user configuration.
* Configures the SDHC according to the user configuration.
*
* Example:
@code
sdhc_config_t config;
config.enableDat3AsCDPin = false;
config.cardDetectDat3 = false;
config.endianMode = kSDHC_EndianModeLittle;
config.dmaMode = kSDHC_DmaModeAdma2;
config.readWatermarkLevel = 512U;
config.writeWatermarkLevel = 512U;
config.readWatermarkLevel = 128U;
config.writeWatermarkLevel = 128U;
SDHC_Init(SDHC, &config);
@endcode
*
@ -600,14 +599,14 @@ extern "C" {
void SDHC_Init(SDHC_Type *base, const sdhc_config_t *config);
/*!
* @brief Deinitialize the SDHC.
* @brief Deinitializes the SDHC.
*
* @param base SDHC peripheral base address.
*/
void SDHC_Deinit(SDHC_Type *base);
/*!
* @brief Reset the SDHC.
* @brief Resets the SDHC.
*
* @param base SDHC peripheral base address.
* @param mask The reset type mask(_sdhc_reset).
@ -625,7 +624,7 @@ bool SDHC_Reset(SDHC_Type *base, uint32_t mask, uint32_t timeout);
*/
/*!
* @brief Set ADMA descriptor table configuration.
* @brief Sets the ADMA descriptor table configuration.
*
* @param base SDHC peripheral base address.
* @param dmaMode DMA mode.
@ -651,7 +650,7 @@ status_t SDHC_SetAdmaTableConfig(SDHC_Type *base,
*/
/*!
* @brief Enable interrupt status
* @brief Enables the interrupt status.
*
* @param base SDHC peripheral base address.
* @param mask Interrupt status flags mask(_sdhc_interrupt_status_flag).
@ -662,7 +661,7 @@ static inline void SDHC_EnableInterruptStatus(SDHC_Type *base, uint32_t mask)
}
/*!
* @brief Disable interrupt status.
* @brief Disables the interrupt status.
*
* @param base SDHC peripheral base address.
* @param mask The interrupt status flags mask(_sdhc_interrupt_status_flag).
@ -673,7 +672,7 @@ static inline void SDHC_DisableInterruptStatus(SDHC_Type *base, uint32_t mask)
}
/*!
* @brief Enable interrupts signal corresponding to the interrupt status flag.
* @brief Enables the interrupt signal corresponding to the interrupt status flag.
*
* @param base SDHC peripheral base address.
* @param mask The interrupt status flags mask(_sdhc_interrupt_status_flag).
@ -684,7 +683,7 @@ static inline void SDHC_EnableInterruptSignal(SDHC_Type *base, uint32_t mask)
}
/*!
* @brief Disable interrupts signal corresponding to the interrupt status flag.
* @brief Disables the interrupt signal corresponding to the interrupt status flag.
*
* @param base SDHC peripheral base address.
* @param mask The interrupt status flags mask(_sdhc_interrupt_status_flag).
@ -702,7 +701,7 @@ static inline void SDHC_DisableInterruptSignal(SDHC_Type *base, uint32_t mask)
*/
/*!
* @brief Get current interrupt status.
* @brief Gets the current interrupt status.
*
* @param base SDHC peripheral base address.
* @return Current interrupt status flags mask(_sdhc_interrupt_status_flag).
@ -713,7 +712,7 @@ static inline uint32_t SDHC_GetInterruptStatusFlags(SDHC_Type *base)
}
/*!
* @brief Clear specified interrupt status.
* @brief Clears a specified interrupt status.
*
* @param base SDHC peripheral base address.
* @param mask The interrupt status flags mask(_sdhc_interrupt_status_flag).
@ -724,7 +723,7 @@ static inline void SDHC_ClearInterruptStatusFlags(SDHC_Type *base, uint32_t mask
}
/*!
* @brief Get the status of auto command 12 error.
* @brief Gets the status of auto command 12 error.
*
* @param base SDHC peripheral base address.
* @return Auto command 12 error status flags mask(_sdhc_auto_command12_error_status_flag).
@ -735,7 +734,7 @@ static inline uint32_t SDHC_GetAutoCommand12ErrorStatusFlags(SDHC_Type *base)
}
/*!
* @brief Get the status of ADMA error.
* @brief Gets the status of the ADMA error.
*
* @param base SDHC peripheral base address.
* @return ADMA error status flags mask(_sdhc_adma_error_status_flag).
@ -746,9 +745,9 @@ static inline uint32_t SDHC_GetAdmaErrorStatusFlags(SDHC_Type *base)
}
/*!
* @brief Get present status.
* @brief Gets a present status.
*
* This function gets the present SDHC's status except for interrupt status and error status.
* This function gets the present SDHC's status except for an interrupt status and an error status.
*
* @param base SDHC peripheral base address.
* @return Present SDHC's status flags mask(_sdhc_present_status_flag).
@ -766,7 +765,7 @@ static inline uint32_t SDHC_GetPresentStatusFlags(SDHC_Type *base)
*/
/*!
* @brief Get the capability information
* @brief Gets the capability information.
*
* @param base SDHC peripheral base address.
* @param capability Structure to save capability information.
@ -774,7 +773,7 @@ static inline uint32_t SDHC_GetPresentStatusFlags(SDHC_Type *base)
void SDHC_GetCapability(SDHC_Type *base, sdhc_capability_t *capability);
/*!
* @brief Enable or disable SD bus clock.
* @brief Enables or disables the SD bus clock.
*
* @param base SDHC peripheral base address.
* @param enable True to enable, false to disable.
@ -792,7 +791,7 @@ static inline void SDHC_EnableSdClock(SDHC_Type *base, bool enable)
}
/*!
* @brief Set SD bus clock frequency.
* @brief Sets the SD bus clock frequency.
*
* @param base SDHC peripheral base address.
* @param srcClock_Hz SDHC source clock frequency united in Hz.
@ -803,9 +802,10 @@ static inline void SDHC_EnableSdClock(SDHC_Type *base, bool enable)
uint32_t SDHC_SetSdClock(SDHC_Type *base, uint32_t srcClock_Hz, uint32_t busClock_Hz);
/*!
* @brief Send 80 clocks to the card to set it to be active state.
* @brief Sends 80 clocks to the card to set it to the active state.
*
* This function must be called after each time the card is inserted to make card can receive command correctly.
* This function must be called each time the card is inserted to ensure that the card can receive the command
* correctly.
*
* @param base SDHC peripheral base address.
* @param timeout Timeout to initialize card.
@ -815,7 +815,7 @@ uint32_t SDHC_SetSdClock(SDHC_Type *base, uint32_t srcClock_Hz, uint32_t busCloc
bool SDHC_SetCardActive(SDHC_Type *base, uint32_t timeout);
/*!
* @brief Set the data transfer width.
* @brief Sets the data transfer width.
*
* @param base SDHC peripheral base address.
* @param width Data transfer width.
@ -826,10 +826,10 @@ static inline void SDHC_SetDataBusWidth(SDHC_Type *base, sdhc_data_bus_width_t w
}
/*!
* @brief Set card transfer-related configuration.
* @brief Sets the card transfer-related configuration.
*
* This function fills card transfer-related command argument/transfer flag/data size. Command and data will be sent by
* SDHC after calling this function.
* This function fills the card transfer-related command argument/transfer flag/data size. The command and data are sent
* by SDHC after calling this function.
*
* Example:
@code
@ -848,7 +848,7 @@ static inline void SDHC_SetDataBusWidth(SDHC_Type *base, sdhc_data_bus_width_t w
void SDHC_SetTransferConfig(SDHC_Type *base, const sdhc_transfer_config_t *config);
/*!
* @brief Get the command response.
* @brief Gets the command response.
*
* @param base SDHC peripheral base address.
* @param index The index of response register, range from 0 to 3.
@ -862,9 +862,9 @@ static inline uint32_t SDHC_GetCommandResponse(SDHC_Type *base, uint32_t index)
}
/*!
* @brief Fill the the data port.
* @brief Fills the the data port.
*
* This function is mainly used to implement the data transfer by Data Port instead of DMA.
* This function is used to implement the data transfer by Data Port instead of DMA.
*
* @param base SDHC peripheral base address.
* @param data The data about to be sent.
@ -875,9 +875,9 @@ static inline void SDHC_WriteData(SDHC_Type *base, uint32_t data)
}
/*!
* @brief Retrieve the data from the data port.
* @brief Retrieves the data from the data port.
*
* This function is mainly used to implement the data transfer by Data Port instead of DMA.
* This function is used to implement the data transfer by Data Port instead of DMA.
*
* @param base SDHC peripheral base address.
* @return The data has been read.
@ -888,7 +888,7 @@ static inline uint32_t SDHC_ReadData(SDHC_Type *base)
}
/*!
* @brief Enable or disable wakeup event in low power mode
* @brief Enables or disables a wakeup event in low-power mode.
*
* @param base SDHC peripheral base address.
* @param mask Wakeup events mask(_sdhc_wakeup_event).
@ -907,7 +907,7 @@ static inline void SDHC_EnableWakeupEvent(SDHC_Type *base, uint32_t mask, bool e
}
/*!
* @brief Enable or disable card detection level for test.
* @brief Enables or disables the card detection level for testing.
*
* @param base SDHC peripheral base address.
* @param enable True to enable, false to disable.
@ -925,11 +925,11 @@ static inline void SDHC_EnableCardDetectTest(SDHC_Type *base, bool enable)
}
/*!
* @brief Set card detection test level.
* @brief Sets the card detection test level.
*
* This function set the card detection test level to indicate whether the card is inserted into SDHC when DAT[3]/
* CD pin is selected as card detection pin. This function can also assert the pin logic when DAT[3]/CD pin is select
* as the card detection pin.
* This function sets the card detection test level to indicate whether the card is inserted into the SDHC when DAT[3]/
* CD pin is selected as a card detection pin. This function can also assert the pin logic when DAT[3]/CD pin is
* selected as the card detection pin.
*
* @param base SDHC peripheral base address.
* @param high True to set the card detect level to high.
@ -947,7 +947,7 @@ static inline void SDHC_SetCardDetectTestLevel(SDHC_Type *base, bool high)
}
/*!
* @brief Enable or disable SDIO card control.
* @brief Enables or disables the SDIO card control.
*
* @param base SDHC peripheral base address.
* @param mask SDIO card control flags mask(_sdhc_sdio_control_flag).
@ -956,7 +956,7 @@ static inline void SDHC_SetCardDetectTestLevel(SDHC_Type *base, bool high)
void SDHC_EnableSdioControl(SDHC_Type *base, uint32_t mask, bool enable);
/*!
* @brief Restart a transaction which has stopped at the block gap for SDIO card.
* @brief Restarts a transaction which has stopped at the block GAP for the SDIO card.
*
* @param base SDHC peripheral base address.
*/
@ -966,18 +966,18 @@ static inline void SDHC_SetContinueRequest(SDHC_Type *base)
}
/*!
* @brief Configure the MMC boot feature.
* @brief Configures the MMC boot feature.
*
* Example:
@code
sdhc_boot_config_t bootConfig;
bootConfig.ackTimeoutCount = 4;
bootConfig.bootMode = kSDHC_BootModeNormal;
bootConfig.blockCount = 5;
bootConfig.enableBootAck = true;
bootConfig.enableBoot = true;
enableBoot.enableAutoStopAtBlockGap = true;
SDHC_SetMmcBootConfig(SDHC, &bootConfig);
sdhc_boot_config_t config;
config.ackTimeoutCount = 4;
config.bootMode = kSDHC_BootModeNormal;
config.blockCount = 5;
config.enableBootAck = true;
config.enableBoot = true;
config.enableAutoStopAtBlockGap = true;
SDHC_SetMmcBootConfig(SDHC, &config);
@endcode
*
* @param base SDHC peripheral base address.
@ -986,7 +986,7 @@ static inline void SDHC_SetContinueRequest(SDHC_Type *base)
void SDHC_SetMmcBootConfig(SDHC_Type *base, const sdhc_boot_config_t *config);
/*!
* @brief Force to generate events according to the given mask.
* @brief Forces generating events according to the given mask.
*
* @param base SDHC peripheral base address.
* @param mask The force events mask(_sdhc_force_event).
@ -1004,13 +1004,13 @@ static inline void SDHC_SetForceEvent(SDHC_Type *base, uint32_t mask)
*/
/*!
* @brief Transfer command/data using blocking way.
* @brief Transfers the command/data using a blocking method.
*
* This function waits until the command response/data is got or SDHC encounters error by polling the status flag.
* Application must not call this API in multiple threads at the same time because of that this API doesn't support
* reentry mechanism.
* This function waits until the command response/data is received or the SDHC encounters an error by polling the status
* flag. The application must not call this API in multiple threads at the same time. Because of that this API doesn't support
* the re-entry mechanism.
*
* @note Needn't to call the API 'SDHC_TransferCreateHandle' when calling this API.
* @note There is no need to call the API 'SDHC_TransferCreateHandle' when calling this API.
*
* @param base SDHC peripheral base address.
* @param admaTable ADMA table address, can't be null if transfer way is ADMA1/ADMA2.
@ -1028,7 +1028,7 @@ status_t SDHC_TransferBlocking(SDHC_Type *base,
sdhc_transfer_t *transfer);
/*!
* @brief Create the SDHC handle.
* @brief Creates the SDHC handle.
*
* @param base SDHC peripheral base address.
* @param handle SDHC handle pointer.
@ -1041,13 +1041,13 @@ void SDHC_TransferCreateHandle(SDHC_Type *base,
void *userData);
/*!
* @brief Transfer command/data using interrupt and asynchronous way.
* @brief Transfers the command/data using an interrupt and an asynchronous method.
*
* This function send command and data and return immediately. It doesn't wait the transfer complete or encounter error.
* Application must not call this API in multiple threads at the same time because of that this API doesn't support
* reentry mechanism.
* This function sends a command and data and returns immediately. It doesn't wait the transfer complete or encounter an
* error. The application must not call this API in multiple threads at the same time. Because of that this API doesn't support
* the re-entry mechanism.
*
* @note Must call the API 'SDHC_TransferCreateHandle' when calling this API.
* @note Call the API 'SDHC_TransferCreateHandle' when calling this API.
*
* @param base SDHC peripheral base address.
* @param handle SDHC handle.
@ -1063,9 +1063,9 @@ status_t SDHC_TransferNonBlocking(
SDHC_Type *base, sdhc_handle_t *handle, uint32_t *admaTable, uint32_t admaTableWords, sdhc_transfer_t *transfer);
/*!
* @brief IRQ handler for SDHC
* @brief IRQ handler for the SDHC.
*
* This function deals with IRQs on the given host controller.
* This function deals with the IRQs on the given host controller.
*
* @param base SDHC peripheral base address.
* @param handle SDHC handle.