diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K66F/drivers/fsl_sdhc.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K66F/drivers/fsl_sdhc.c index 0c5dd2b625d..d2774eeabc9 100644 --- a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K66F/drivers/fsl_sdhc.c +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K66F/drivers/fsl_sdhc.c @@ -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 diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K66F/drivers/fsl_sdhc.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K66F/drivers/fsl_sdhc.h index ea92e6b5540..4976649d91a 100644 --- a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K66F/drivers/fsl_sdhc.h +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_K66F/drivers/fsl_sdhc.h @@ -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. diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K64F/drivers/fsl_sdhc.c b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K64F/drivers/fsl_sdhc.c index 0c5dd2b625d..d2774eeabc9 100755 --- a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K64F/drivers/fsl_sdhc.c +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K64F/drivers/fsl_sdhc.c @@ -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 diff --git a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K64F/drivers/fsl_sdhc.h b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K64F/drivers/fsl_sdhc.h index 2272402bb15..4976649d91a 100755 --- a/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K64F/drivers/fsl_sdhc.h +++ b/hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_MCU_K64F/drivers/fsl_sdhc.h @@ -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.