The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.

Dependents:   hello SerialTestv11 SerialTestv12 Sierpinski ... more

mbed 2

This is the mbed 2 library. If you'd like to learn about Mbed OS please see the mbed-os docs.

Revision:
171:3a7713b1edbc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TARGET_FF_LPC546XX/TOOLCHAIN_ARM_STD/fsl_sdif.h	Thu Nov 08 11:45:42 2018 +0000
@@ -0,0 +1,831 @@
+/*
+ * The Clear BSD License
+ * Copyright (c) 2016, Freescale Semiconductor, Inc.
+ * Copyright 2016-2017 NXP
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted (subject to the limitations in the disclaimer below) provided
+ * that the following conditions are met:
+ *
+ * o Redistributions of source code must retain the above copyright notice, this list
+ *   of conditions and the following disclaimer.
+ *
+ * o Redistributions in binary form must reproduce the above copyright notice, this
+ *   list of conditions and the following disclaimer in the documentation and/or
+ *   other materials provided with the distribution.
+ *
+ * o Neither the name of the copyright holder nor the names of its
+ *   contributors may be used to endorse or promote products derived from this
+ *   software without specific prior written permission.
+ *
+ * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _FSL_SDIF_H_
+#define _FSL_SDIF_H_
+
+#include "fsl_common.h"
+
+/*!
+ * @addtogroup sdif
+ * @{
+ */
+
+/**********************************
+ * Definitions.
+ *****************************************************************************/
+
+/*! @name Driver version */
+/*@{*/
+/*! @brief Driver version 2.0.4. */
+#define FSL_SDIF_DRIVER_VERSION (MAKE_VERSION(2U, 0U, 4U))
+/*@}*/
+
+/*! @brief  SDIOCLKCTRL setting
+* Below clock delay setting should depend on specific platform, so
+* it can be redefined when timing mismatch issue occur.
+* Such as: response error/CRC error and so on
+*/
+/*! @brief clock range value which need to add delay to avoid timing issue */
+#ifndef SDIF_CLOCK_RANGE_NEED_DELAY
+#define SDIF_CLOCK_RANGE_NEED_DELAY (50000000U)
+#endif
+
+/*
+* Fixed delay configuration
+* min hold time:2ns
+* min setup time: 6ns
+* delay = (x+1)*250ps
+*/
+/*! @brief High speed mode clk_sample fixed delay*/
+#ifndef SDIF_HIGHSPEED_SAMPLE_DELAY
+#define SDIF_HIGHSPEED_SAMPLE_DELAY (0U)
+#endif
+/*! @brief High speed mode clk_drv fixed delay */
+#ifndef SDIF_HIGHSPEED_DRV_DELAY
+#define SDIF_HIGHSPEED_DRV_DELAY (0x1FU)
+#endif
+
+/*
+* Pharse shift delay configuration
+* 0 degree: no delay
+* 90 degree: 0.25/source clk value
+* 180 degree: 0.50/source clk value
+* 270 degree: 0.75/source clk value
+*/
+/*! @brief High speed mode clk_sample pharse shift */
+#ifndef SDIF_HIGHSPEED_SAMPLE_PHASE_SHIFT
+#define SDIF_HIGHSPEED_SAMPLE_PHASE_SHIFT (0U)
+#endif
+/*! @brief High speed mode clk_drv pharse shift */
+#ifndef SDIF_HIGHSPEED_DRV_PHASE_SHIFT
+#define SDIF_HIGHSPEED_DRV_PHASE_SHIFT (1U) /* 90 degrees clk_drv pharse delay */
+#endif
+
+/*! @brief SDIF status */
+enum _sdif_status
+{
+    kStatus_SDIF_DescriptorBufferLenError = MAKE_STATUS(kStatusGroup_SDIF, 0U), /*!< Set DMA descriptor failed */
+    kStatue_SDIF_InvalidArgument = MAKE_STATUS(kStatusGroup_SDIF, 1U),          /*!< invalid argument status */
+    kStatus_SDIF_SyncCmdTimeout = MAKE_STATUS(kStatusGroup_SDIF, 2U), /*!< sync command to CIU timeout status */
+    kStatus_SDIF_SendCmdFail = MAKE_STATUS(kStatusGroup_SDIF, 3U),    /* send command to card fail */
+    kStatus_SDIF_SendCmdErrorBufferFull =
+        MAKE_STATUS(kStatusGroup_SDIF, 4U), /* send command to card fail, due to command buffer full
+                                     user need to resend this command */
+    kStatus_SDIF_DMATransferFailWithFBE =
+        MAKE_STATUS(kStatusGroup_SDIF, 5U), /* DMA transfer data fail with fatal bus error ,
+                                     to do with this error :issue a hard reset/controller reset*/
+    kStatus_SDIF_DMATransferDescriptorUnavaliable = MAKE_STATUS(kStatusGroup_SDIF, 6U), /* DMA descriptor unavalible */
+    kStatus_SDIF_DataTransferFail = MAKE_STATUS(kStatusGroup_SDIF, 6U),                 /* transfer data fail */
+    kStatus_SDIF_ResponseError = MAKE_STATUS(kStatusGroup_SDIF, 7U),
+};
+
+/*! @brief Host controller capabilities flag mask */
+enum _sdif_capability_flag
+{
+    kSDIF_SupportHighSpeedFlag = 0x1U,     /*!< Support high-speed */
+    kSDIF_SupportDmaFlag = 0x2U,           /*!< Support DMA */
+    kSDIF_SupportSuspendResumeFlag = 0x4U, /*!< Support suspend/resume */
+    kSDIF_SupportV330Flag = 0x8U,          /*!< Support voltage 3.3V */
+    kSDIF_Support4BitFlag = 0x10U,         /*!< Support 4 bit mode */
+    kSDIF_Support8BitFlag = 0x20U,         /*!< Support 8 bit mode */
+};
+
+/*! @brief define the reset type */
+enum _sdif_reset_type
+{
+    kSDIF_ResetController =
+        SDIF_CTRL_CONTROLLER_RESET_MASK,                /*!< reset controller,will reset: BIU/CIU interface
+                                                          CIU and state machine,ABORT_READ_DATA,SEND_IRQ_RESPONSE
+                                                          and READ_WAIT bits of control register,START_CMD bit of the
+                                                          command register*/
+    kSDIF_ResetFIFO = SDIF_CTRL_FIFO_RESET_MASK,        /*!< reset data FIFO*/
+    kSDIF_ResetDMAInterface = SDIF_CTRL_DMA_RESET_MASK, /*!< reset DMA interface */
+
+    kSDIF_ResetAll = kSDIF_ResetController | kSDIF_ResetFIFO | /*!< reset all*/
+                     kSDIF_ResetDMAInterface,
+};
+
+/*! @brief define the card bus width type */
+typedef enum _sdif_bus_width
+{
+    kSDIF_Bus1BitWidth = 0U,                          /*!< 1bit bus width, 1bit mode and 4bit mode
+                                                      share one register bit */
+    kSDIF_Bus4BitWidth = SDIF_CTYPE_CARD_WIDTH0_MASK, /*!< 4bit mode mask */
+    kSDIF_Bus8BitWidth = SDIF_CTYPE_CARD_WIDTH1_MASK, /*!< support 8 bit mode */
+} sdif_bus_width_t;
+
+/*! @brief define the command flags */
+enum _sdif_command_flags
+{
+    kSDIF_CmdResponseExpect = SDIF_CMD_RESPONSE_EXPECT_MASK,      /*!< command request response*/
+    kSDIF_CmdResponseLengthLong = SDIF_CMD_RESPONSE_LENGTH_MASK,  /*!< command response length long */
+    kSDIF_CmdCheckResponseCRC = SDIF_CMD_CHECK_RESPONSE_CRC_MASK, /*!< request check command response CRC*/
+    kSDIF_DataExpect = SDIF_CMD_DATA_EXPECTED_MASK,               /*!< request data transfer,ethier read/write*/
+    kSDIF_DataWriteToCard = SDIF_CMD_READ_WRITE_MASK,             /*!< data transfer direction */
+    kSDIF_DataStreamTransfer = SDIF_CMD_TRANSFER_MODE_MASK,    /*!< data transfer mode :stream/block transfer command */
+    kSDIF_DataTransferAutoStop = SDIF_CMD_SEND_AUTO_STOP_MASK, /*!< data transfer with auto stop at the end of */
+    kSDIF_WaitPreTransferComplete =
+        SDIF_CMD_WAIT_PRVDATA_COMPLETE_MASK, /*!< wait pre transfer complete before sending this cmd  */
+    kSDIF_TransferStopAbort =
+        SDIF_CMD_STOP_ABORT_CMD_MASK, /*!< when host issue stop or abort cmd to stop data transfer
+                                       ,this bit should set so that cmd/data state-machines of CIU can return
+                                       to idle correctly*/
+    kSDIF_SendInitialization =
+        SDIF_CMD_SEND_INITIALIZATION_MASK, /*!< send initaliztion  80 clocks for SD card after power on  */
+    kSDIF_CmdUpdateClockRegisterOnly =
+        SDIF_CMD_UPDATE_CLOCK_REGISTERS_ONLY_MASK,                /*!< send cmd update the CIU clock register only */
+    kSDIF_CmdtoReadCEATADevice = SDIF_CMD_READ_CEATA_DEVICE_MASK, /*!< host is perform read access to CE-ATA device */
+    kSDIF_CmdExpectCCS = SDIF_CMD_CCS_EXPECTED_MASK,         /*!< command expect command completion signal signal */
+    kSDIF_BootModeEnable = SDIF_CMD_ENABLE_BOOT_MASK,        /*!< this bit should only be set for mandatory boot mode */
+    kSDIF_BootModeExpectAck = SDIF_CMD_EXPECT_BOOT_ACK_MASK, /*!< boot mode expect ack */
+    kSDIF_BootModeDisable = SDIF_CMD_DISABLE_BOOT_MASK,      /*!< when software set this bit along with START_CMD, CIU
+                                                                terminates the boot operation*/
+    kSDIF_BootModeAlternate = SDIF_CMD_BOOT_MODE_MASK,       /*!< select boot mode ,alternate or mandatory*/
+    kSDIF_CmdVoltageSwitch = SDIF_CMD_VOLT_SWITCH_MASK,      /*!< this bit set for CMD11 only */
+    kSDIF_CmdDataUseHoldReg = SDIF_CMD_USE_HOLD_REG_MASK,    /*!< cmd and data send to card through the HOLD register*/
+};
+
+/*! @brief The command type */
+enum _sdif_command_type
+{
+    kCARD_CommandTypeNormal = 0U,  /*!< Normal command */
+    kCARD_CommandTypeSuspend = 1U, /*!< Suspend command */
+    kCARD_CommandTypeResume = 2U,  /*!< Resume command */
+    kCARD_CommandTypeAbort = 3U,   /*!< Abort command */
+};
+
+/*!
+ * @brief The command response type.
+ *
+ * Define the command response type from card to host controller.
+ */
+enum _sdif_response_type
+{
+    kCARD_ResponseTypeNone = 0U, /*!< Response type: none */
+    kCARD_ResponseTypeR1 = 1U,   /*!< Response type: R1 */
+    kCARD_ResponseTypeR1b = 2U,  /*!< Response type: R1b */
+    kCARD_ResponseTypeR2 = 3U,   /*!< Response type: R2 */
+    kCARD_ResponseTypeR3 = 4U,   /*!< Response type: R3 */
+    kCARD_ResponseTypeR4 = 5U,   /*!< Response type: R4 */
+    kCARD_ResponseTypeR5 = 6U,   /*!< Response type: R5 */
+    kCARD_ResponseTypeR5b = 7U,  /*!< Response type: R5b */
+    kCARD_ResponseTypeR6 = 8U,   /*!< Response type: R6 */
+    kCARD_ResponseTypeR7 = 9U,   /*!< Response type: R7 */
+};
+
+/*! @brief define the interrupt mask flags */
+enum _sdif_interrupt_mask
+{
+    kSDIF_CardDetect = SDIF_INTMASK_CDET_MASK,                 /*!< mask for card detect */
+    kSDIF_ResponseError = SDIF_INTMASK_RE_MASK,                /*!< command response error */
+    kSDIF_CommandDone = SDIF_INTMASK_CDONE_MASK,               /*!< command transfer over*/
+    kSDIF_DataTransferOver = SDIF_INTMASK_DTO_MASK,            /*!< data transfer over flag*/
+    kSDIF_WriteFIFORequest = SDIF_INTMASK_TXDR_MASK,           /*!< write FIFO request */
+    kSDIF_ReadFIFORequest = SDIF_INTMASK_RXDR_MASK,            /*!< read FIFO request */
+    kSDIF_ResponseCRCError = SDIF_INTMASK_RCRC_MASK,           /*!< reponse CRC error */
+    kSDIF_DataCRCError = SDIF_INTMASK_DCRC_MASK,               /*!< data CRC error */
+    kSDIF_ResponseTimeout = SDIF_INTMASK_RTO_MASK,             /*!< response timeout */
+    kSDIF_DataReadTimeout = SDIF_INTMASK_DRTO_MASK,            /*!< read data timeout */
+    kSDIF_DataStarvationByHostTimeout = SDIF_INTMASK_HTO_MASK, /*!< data starvation by host time out */
+    kSDIF_FIFOError = SDIF_INTMASK_FRUN_MASK,                  /*!< indicate the FIFO underrun or overrun error */
+    kSDIF_HardwareLockError = SDIF_INTMASK_HLE_MASK,           /*!< hardware lock write error */
+    kSDIF_DataStartBitError = SDIF_INTMASK_SBE_MASK,           /*!< start bit error */
+    kSDIF_AutoCmdDone = SDIF_INTMASK_ACD_MASK,                 /*!< indicate the auto command done */
+    kSDIF_DataEndBitError = SDIF_INTMASK_EBE_MASK,             /*!< end bit error */
+    kSDIF_SDIOInterrupt = SDIF_INTMASK_SDIO_INT_MASK_MASK,     /*!< interrupt from the SDIO card */
+
+    kSDIF_CommandTransferStatus = kSDIF_ResponseError | kSDIF_CommandDone | kSDIF_ResponseCRCError |
+                                  kSDIF_ResponseTimeout |
+                                  kSDIF_HardwareLockError, /*!< command transfer status collection*/
+    kSDIF_DataTransferStatus = kSDIF_DataTransferOver | kSDIF_WriteFIFORequest | kSDIF_ReadFIFORequest |
+                               kSDIF_DataCRCError | kSDIF_DataReadTimeout | kSDIF_DataStarvationByHostTimeout |
+                               kSDIF_FIFOError | kSDIF_DataStartBitError | kSDIF_DataEndBitError |
+                               kSDIF_AutoCmdDone, /*!< data transfer status collection */
+    kSDIF_DataTransferError =
+        kSDIF_DataCRCError | kSDIF_FIFOError | kSDIF_DataStartBitError | kSDIF_DataEndBitError | kSDIF_DataReadTimeout,
+    kSDIF_AllInterruptStatus = 0x1FFFFU, /*!< all interrupt mask */
+
+};
+
+/*! @brief define the internal DMA status flags */
+enum _sdif_dma_status
+{
+    kSDIF_DMATransFinishOneDescriptor = SDIF_IDSTS_TI_MASK, /*!< DMA transfer finished for one DMA descriptor */
+    kSDIF_DMARecvFinishOneDescriptor = SDIF_IDSTS_RI_MASK,  /*!< DMA revieve finished for one DMA descriptor */
+    kSDIF_DMAFatalBusError = SDIF_IDSTS_FBE_MASK,           /*!< DMA fatal bus error */
+    kSDIF_DMADescriptorUnavailable = SDIF_IDSTS_DU_MASK,    /*!< DMA descriptor unavailable */
+    kSDIF_DMACardErrorSummary = SDIF_IDSTS_CES_MASK,        /*!< card error summary */
+    kSDIF_NormalInterruptSummary = SDIF_IDSTS_NIS_MASK,     /*!< normal interrupt summary */
+    kSDIF_AbnormalInterruptSummary = SDIF_IDSTS_AIS_MASK,   /*!< abnormal interrupt summary*/
+
+    kSDIF_DMAAllStatus = kSDIF_DMATransFinishOneDescriptor | kSDIF_DMARecvFinishOneDescriptor | kSDIF_DMAFatalBusError |
+                         kSDIF_DMADescriptorUnavailable | kSDIF_DMACardErrorSummary | kSDIF_NormalInterruptSummary |
+                         kSDIF_AbnormalInterruptSummary,
+
+};
+
+/*! @brief define the internal DMA descriptor flag */
+enum _sdif_dma_descriptor_flag
+{
+    kSDIF_DisableCompleteInterrupt = 0x2U,     /*!< disable the complete interrupt flag for the ends
+                                                in the buffer pointed to by this descriptor*/
+    kSDIF_DMADescriptorDataBufferEnd = 0x4U,   /*!< indicate this descriptor contain the last data buffer of data */
+    kSDIF_DMADescriptorDataBufferStart = 0x8U, /*!< indicate this descriptor contain the first data buffer
+                                                 of data,if first buffer size is 0,next descriptor contain
+                                                 the begaining of the data*/
+    kSDIF_DMASecondAddrChained = 0x10U,        /*!< indicate that the second addr in the descriptor is the
+                                               next descriptor addr not the data buffer */
+    kSDIF_DMADescriptorEnd = 0x20U,            /*!< indicate that the descriptor list reached its final descriptor*/
+    kSDIF_DMADescriptorOwnByDMA = 0x80000000U, /*!< indicate the descriptor is own by SD/MMC DMA */
+};
+
+/*! @brief define the internal DMA mode */
+typedef enum _sdif_dma_mode
+{
+    kSDIF_ChainDMAMode = 0x01U, /* one descriptor with one buffer,but one descriptor point to another */
+    kSDIF_DualDMAMode = 0x02U,  /* dual mode is one descriptor with two buffer */
+} sdif_dma_mode_t;
+
+/*! @brief define the internal DMA descriptor */
+typedef struct _sdif_dma_descriptor
+{
+    uint32_t dmaDesAttribute;           /*!< internal DMA attribute control and status */
+    uint32_t dmaDataBufferSize;         /*!< internal DMA transfer buffer size control */
+    const uint32_t *dmaDataBufferAddr0; /*!< internal DMA buffer 0 addr ,the buffer size must be 32bit aligned */
+    const uint32_t *dmaDataBufferAddr1; /*!< internal DMA buffer 1 addr ,the buffer size must be 32bit aligned */
+
+} sdif_dma_descriptor_t;
+
+/*! @brief Defines the internal DMA config structure. */
+typedef struct _sdif_dma_config
+{
+    bool enableFixBurstLen; /*!< fix burst len enable/disable flag,When set, the AHB will
+                             use only SINGLE, INCR4, INCR8 or INCR16 during start of
+                             normal burst transfers. When reset, the AHB will use SINGLE
+                             and INCR burst transfer operations */
+
+    sdif_dma_mode_t mode; /*!< define the DMA mode */
+
+    uint8_t dmaDesSkipLen; /*!< define the descriptor skip length ,the length between two descriptor
+                               this field is special for dual DMA mode */
+
+    uint32_t *dmaDesBufferStartAddr; /*!< internal DMA descriptor start address*/
+    uint32_t dmaDesBufferLen;        /*!< internal DMA buffer descriptor buffer len ,user need to pay attention to the
+                                        dma descriptor buffer length if it is bigger enough for your transfer */
+
+} sdif_dma_config_t;
+
+/*!
+ * @brief Card data descriptor
+ */
+typedef struct _sdif_data
+{
+    bool streamTransfer;      /*!< indicate this is a stream data transfer command */
+    bool enableAutoCommand12; /*!< indicate if auto stop will send when data transfer over */
+    bool enableIgnoreError;   /*!< indicate if enable ignore error when transfer data */
+
+    size_t blockSize;       /*!< Block size, take care when config this parameter */
+    uint32_t blockCount;    /*!< Block count */
+    uint32_t *rxData;       /*!< data buffer to recieve */
+    const uint32_t *txData; /*!< data buffer to transfer */
+} sdif_data_t;
+
+/*!
+ * @brief Card command descriptor
+ *
+ * Define card command-related attribute.
+ */
+typedef struct _sdif_command
+{
+    uint32_t index;              /*!< Command index */
+    uint32_t argument;           /*!< Command argument */
+    uint32_t response[4U];       /*!< Response for this command */
+    uint32_t type;               /*!< define the command type */
+    uint32_t responseType;       /*!< Command response type */
+    uint32_t flags;              /*!< Cmd flags */
+    uint32_t responseErrorFlags; /*!< response error flags, need to check the flags when
+                                    recieve the cmd response */
+} sdif_command_t;
+
+/*! @brief Transfer state */
+typedef struct _sdif_transfer
+{
+    sdif_data_t *data;       /*!< Data to transfer */
+    sdif_command_t *command; /*!< Command to send */
+} sdif_transfer_t;
+
+/*! @brief Data structure to initialize the sdif */
+typedef struct _sdif_config
+{
+    uint8_t responseTimeout;        /*!< command reponse timeout value */
+    uint32_t cardDetDebounce_Clock; /*!< define the debounce clock count which will used in
+                                        card detect logic,typical value is 5-25ms */
+    uint32_t endianMode;            /*!< define endian mode ,this field is not used in this
+                                    module actually, keep for compatible with middleware*/
+    uint32_t dataTimeout;           /*!< data timeout value  */
+} sdif_config_t;
+
+/*!
+ * @brief SDIF capability information.
+ * Defines a structure to get the capability information of SDIF.
+ */
+typedef struct _sdif_capability
+{
+    uint32_t sdVersion;      /*!< support SD card/sdio version */
+    uint32_t mmcVersion;     /*!< support emmc card version */
+    uint32_t maxBlockLength; /*!< Maximum block length united as byte */
+    uint32_t maxBlockCount;  /*!< Maximum byte count can be transfered */
+    uint32_t flags;          /*!< Capability flags to indicate the support information */
+} sdif_capability_t;
+
+/*! @brief sdif callback functions. */
+typedef struct _sdif_transfer_callback
+{
+    void (*cardInserted)(SDIF_Type *base, void *userData);      /*!< card insert call back */
+    void (*cardRemoved)(SDIF_Type *base, void *userData);       /*!< card remove call back */
+    void (*SDIOInterrupt)(SDIF_Type *base, void *userData);     /*!< SDIO card interrupt occurs */
+    void (*DMADesUnavailable)(SDIF_Type *base, void *userData); /*!< DMA descriptor unavailable */
+    void (*CommandReload)(SDIF_Type *base, void *userData);     /*!< command buffer full,need re-load */
+    void (*TransferComplete)(SDIF_Type *base,
+                             void *handle,
+                             status_t status,
+                             void *userData); /*!< Transfer complete callback */
+} sdif_transfer_callback_t;
+
+/*!
+ * @brief sdif handle
+ *
+ * Defines the structure to save the sdif 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
+ * sdif_interrupt_flag_t;
+ * @note All the fields except interruptFlags and transferredWords must be allocated by the user.
+ */
+typedef struct _sdif_handle
+{
+    /* Transfer parameter */
+    sdif_data_t *volatile data;       /*!< Data to transfer */
+    sdif_command_t *volatile command; /*!< Command to send */
+
+    /* Transfer status */
+    volatile uint32_t interruptFlags;    /*!< Interrupt flags of last transaction */
+    volatile uint32_t dmaInterruptFlags; /*!< DMA interrupt flags of last transaction*/
+    volatile uint32_t transferredWords;  /*!< Words transferred by polling way */
+
+    /* Callback functions */
+    sdif_transfer_callback_t callback; /*!< Callback function */
+    void *userData;                    /*!< Parameter for transfer complete callback */
+} sdif_handle_t;
+
+/*! @brief sdif transfer function. */
+typedef status_t (*sdif_transfer_function_t)(SDIF_Type *base, sdif_transfer_t *content);
+
+/*! @brief sdif host descriptor */
+typedef struct _sdif_host
+{
+    SDIF_Type *base;                   /*!< sdif peripheral base address */
+    uint32_t sourceClock_Hz;           /*!< sdif source clock frequency united in Hz */
+    sdif_config_t config;              /*!< sdif configuration */
+    sdif_transfer_function_t transfer; /*!< sdif transfer function */
+    sdif_capability_t capability;      /*!< sdif capability information */
+} sdif_host_t;
+
+/*************************************************************************************************
+ * API
+ ************************************************************************************************/
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*!
+ * @brief SDIF module initialization function.
+ *
+ * Configures the SDIF according to the user configuration.
+ * @param base SDIF peripheral base address.
+ * @param config SDIF configuration information.
+ */
+void SDIF_Init(SDIF_Type *base, sdif_config_t *config);
+
+/*!
+ * @brief SDIF module deinit function.
+ * user should call this function follow with IP reset
+ * @param base SDIF peripheral base address.
+ */
+void SDIF_Deinit(SDIF_Type *base);
+
+/*!
+ * @brief SDIF send initialize 80 clocks for SD card after initilize
+ * @param base SDIF peripheral base address.
+ * @param timeout value
+ */
+bool SDIF_SendCardActive(SDIF_Type *base, uint32_t timeout);
+
+/*!
+ * @brief SDIF module detect card insert status function.
+ * @param base SDIF peripheral base address.
+ * @param data3 indicate use data3 as card insert detect pin
+ * @retval 1 card is inserted
+ *         0 card is removed
+ */
+static inline uint32_t SDIF_DetectCardInsert(SDIF_Type *base, bool data3)
+{
+    if (data3)
+    {
+        return (base->STATUS & SDIF_STATUS_DATA_3_STATUS_MASK) == SDIF_STATUS_DATA_3_STATUS_MASK ? 1U : 0U;
+    }
+    else
+    {
+        return (base->CDETECT & SDIF_CDETECT_CARD_DETECT_MASK) == 0U ? 1U : 0U;
+    }
+}
+
+/*!
+ * @brief SDIF module enable/disable card clock.
+ * @param base SDIF peripheral base address.
+ * @param enable/disable flag
+ */
+static inline void SDIF_EnableCardClock(SDIF_Type *base, bool enable)
+{
+    if (enable)
+    {
+        base->CLKENA |= SDIF_CLKENA_CCLK_ENABLE_MASK;
+    }
+    else
+    {
+        base->CLKENA &= ~SDIF_CLKENA_CCLK_ENABLE_MASK;
+    }
+}
+
+/*!
+ * @brief SDIF module enable/disable module disable the card clock
+ * to enter low power mode when card is idle,for SDIF cards, if
+ * interrupts must be detected, clock should not be stopped
+ * @param base SDIF peripheral base address.
+ * @param enable/disable flag
+ */
+static inline void SDIF_EnableLowPowerMode(SDIF_Type *base, bool enable)
+{
+    if (enable)
+    {
+        base->CLKENA |= SDIF_CLKENA_CCLK_LOW_POWER_MASK;
+    }
+    else
+    {
+        base->CLKENA &= ~SDIF_CLKENA_CCLK_LOW_POWER_MASK;
+    }
+}
+
+/*!
+ * @brief Sets the card bus clock frequency.
+ *
+ * @param base SDIF peripheral base address.
+ * @param srcClock_Hz SDIF source clock frequency united in Hz.
+ * @param target_HZ card bus clock frequency united in Hz.
+ * @return The nearest frequency of busClock_Hz configured to SD bus.
+ */
+uint32_t SDIF_SetCardClock(SDIF_Type *base, uint32_t srcClock_Hz, uint32_t target_HZ);
+
+/*!
+ * @brief reset the different block of the interface.
+ * @param base SDIF peripheral base address.
+ * @param mask indicate which block to reset.
+ * @param timeout value,set to wait the bit self clear
+ * @return reset result.
+ */
+bool SDIF_Reset(SDIF_Type *base, uint32_t mask, uint32_t timeout);
+
+/*!
+ * @brief enable/disable the card power.
+ * once turn power on, software should wait for regulator/switch
+ * ramp-up time before trying to initialize card.
+ * @param base SDIF peripheral base address.
+ * @param enable/disable flag.
+ */
+static inline void SDIF_EnableCardPower(SDIF_Type *base, bool enable)
+{
+    if (enable)
+    {
+        base->PWREN |= SDIF_PWREN_POWER_ENABLE_MASK;
+    }
+    else
+    {
+        base->PWREN &= ~SDIF_PWREN_POWER_ENABLE_MASK;
+    }
+}
+
+/*!
+ * @brief get the card write protect status
+ * @param base SDIF peripheral base address.
+ */
+static inline uint32_t SDIF_GetCardWriteProtect(SDIF_Type *base)
+{
+    return base->WRTPRT & SDIF_WRTPRT_WRITE_PROTECT_MASK;
+}
+
+/*!
+ * @brief set card data bus width
+ * @param base SDIF peripheral base address.
+ * @param data bus width type
+ */
+static inline void SDIF_SetCardBusWidth(SDIF_Type *base, sdif_bus_width_t type)
+{
+    base->CTYPE = type;
+}
+
+/*!
+ * @brief toggle state on hardware reset PIN
+ * This is used which card has a reset PIN typically.
+ * @param base SDIF peripheral base address.
+ */
+static inline void SDIF_AssertHardwareReset(SDIF_Type *base)
+{
+    base->RST_N &= ~SDIF_RST_N_CARD_RESET_MASK;
+}
+
+/*!
+ * @brief send command to the card
+ * @param base SDIF peripheral base address.
+ * @param command configuration collection
+ * @param timeout value
+ * @return command excute status
+ */
+status_t SDIF_SendCommand(SDIF_Type *base, sdif_command_t *cmd, uint32_t timeout);
+
+/*!
+ * @brief SDIF enable/disable global interrupt
+ * @param base SDIF peripheral base address.
+ * @param enable/disable flag
+ */
+static inline void SDIF_EnableGlobalInterrupt(SDIF_Type *base, bool enable)
+{
+    if (enable)
+    {
+        base->CTRL |= SDIF_CTRL_INT_ENABLE_MASK;
+    }
+    else
+    {
+        base->CTRL &= ~SDIF_CTRL_INT_ENABLE_MASK;
+    }
+}
+
+/*!
+ * @brief SDIF enable interrupt
+ * @param base SDIF peripheral base address.
+ * @param interrupt mask
+ */
+static inline void SDIF_EnableInterrupt(SDIF_Type *base, uint32_t mask)
+{
+    base->INTMASK |= mask;
+}
+
+/*!
+ * @brief SDIF disable interrupt
+ * @param base SDIF peripheral base address.
+ * @param interrupt mask
+ */
+static inline void SDIF_DisableInterrupt(SDIF_Type *base, uint32_t mask)
+{
+    base->INTMASK &= ~mask;
+}
+
+/*!
+ * @brief SDIF get interrupt status
+ * @param base SDIF peripheral base address.
+ */
+static inline uint32_t SDIF_GetInterruptStatus(SDIF_Type *base)
+{
+    return base->MINTSTS;
+}
+
+/*!
+ * @brief SDIF clear interrupt status
+ * @param base SDIF peripheral base address.
+ * @param status mask to clear
+ */
+static inline void SDIF_ClearInterruptStatus(SDIF_Type *base, uint32_t mask)
+{
+    base->RINTSTS &= mask;
+}
+
+/*!
+ * @brief Creates the SDIF handle.
+ * register call back function for interrupt and enable the interrupt
+ * @param base SDIF peripheral base address.
+ * @param handle SDIF handle pointer.
+ * @param callback Structure pointer to contain all callback functions.
+ * @param userData Callback function parameter.
+ */
+void SDIF_TransferCreateHandle(SDIF_Type *base,
+                               sdif_handle_t *handle,
+                               sdif_transfer_callback_t *callback,
+                               void *userData);
+
+/*!
+ * @brief SDIF enable DMA interrupt
+ * @param base SDIF peripheral base address.
+ * @param interrupt mask to set
+ */
+static inline void SDIF_EnableDmaInterrupt(SDIF_Type *base, uint32_t mask)
+{
+    base->IDINTEN |= mask;
+}
+
+/*!
+ * @brief SDIF disable DMA interrupt
+ * @param base SDIF peripheral base address.
+ * @param interrupt mask to clear
+ */
+static inline void SDIF_DisableDmaInterrupt(SDIF_Type *base, uint32_t mask)
+{
+    base->IDINTEN &= ~mask;
+}
+
+/*!
+ * @brief SDIF get internal DMA status
+ * @param base SDIF peripheral base address.
+ * @return the internal DMA status register
+ */
+static inline uint32_t SDIF_GetInternalDMAStatus(SDIF_Type *base)
+{
+    return base->IDSTS;
+}
+
+/*!
+ * @brief SDIF clear internal DMA status
+ * @param base SDIF peripheral base address.
+ * @param status mask to clear
+ */
+static inline void SDIF_ClearInternalDMAStatus(SDIF_Type *base, uint32_t mask)
+{
+    base->IDSTS &= mask;
+}
+
+/*!
+ * @brief SDIF internal DMA config function
+ * @param base SDIF peripheral base address.
+ * @param internal DMA configuration collection
+ * @param data buffer pointer
+ * @param data buffer size
+ */
+status_t SDIF_InternalDMAConfig(SDIF_Type *base, sdif_dma_config_t *config, const uint32_t *data, uint32_t dataSize);
+
+/*!
+ * @brief SDIF send read wait to SDIF card function
+ * @param base SDIF peripheral base address.
+ */
+static inline void SDIF_SendReadWait(SDIF_Type *base)
+{
+    base->CTRL |= SDIF_CTRL_READ_WAIT_MASK;
+}
+
+/*!
+ * @brief SDIF abort the read data when SDIF card is in suspend state
+ * Once assert this bit,data state machine will be reset which is waiting for the
+ * next blocking data,used in SDIO card suspend sequence,should call after suspend
+ * cmd send
+ * @param base SDIF peripheral base address.
+ * @param timeout value to wait this bit self clear which indicate the data machine
+ * reset to idle
+ */
+bool SDIF_AbortReadData(SDIF_Type *base, uint32_t timeout);
+
+/*!
+ * @brief SDIF enable/disable CE-ATA card interrupt
+ * this bit should set together with the card register
+ * @param base SDIF peripheral base address.
+ * @param enable/disable flag
+ */
+static inline void SDIF_EnableCEATAInterrupt(SDIF_Type *base, bool enable)
+{
+    if (enable)
+    {
+        base->CTRL |= SDIF_CTRL_CEATA_DEVICE_INTERRUPT_STATUS_MASK;
+    }
+    else
+    {
+        base->CTRL &= ~SDIF_CTRL_CEATA_DEVICE_INTERRUPT_STATUS_MASK;
+    }
+}
+
+/*!
+ * @brief SDIF transfer function data/cmd in a non-blocking way
+ * this API should be use in interrupt mode, when use this API user
+ * must call SDIF_TransferCreateHandle first, all status check through
+ * interrupt
+ * @param base SDIF peripheral base address.
+ * @param sdif handle
+ * @param DMA config structure
+ *  This parameter can be config as:
+ *      1. NULL
+            In this condition, polling transfer mode is selected
+        2. avaliable DMA config
+            In this condition, DMA transfer mode is selected
+ * @param sdif transfer configuration collection
+ */
+status_t SDIF_TransferNonBlocking(SDIF_Type *base,
+                                  sdif_handle_t *handle,
+                                  sdif_dma_config_t *dmaConfig,
+                                  sdif_transfer_t *transfer);
+
+/*!
+ * @brief SDIF transfer function data/cmd in a blocking way
+ * @param base SDIF peripheral base address.
+ * @param DMA config structure
+ *       1. NULL
+ *           In this condition, polling transfer mode is selected
+ *       2. avaliable DMA config
+ *           In this condition, DMA transfer mode is selected
+ * @param sdif transfer configuration collection
+ */
+status_t SDIF_TransferBlocking(SDIF_Type *base, sdif_dma_config_t *dmaConfig, sdif_transfer_t *transfer);
+
+/*!
+ * @brief SDIF release the DMA descriptor to DMA engine
+ * this function should be called when DMA descriptor unavailable status occurs
+ * @param base SDIF peripheral base address.
+ * @param sdif DMA config pointer
+ */
+status_t SDIF_ReleaseDMADescriptor(SDIF_Type *base, sdif_dma_config_t *dmaConfig);
+
+/*!
+ * @brief SDIF return the controller capability
+ * @param base SDIF peripheral base address.
+ * @param sdif capability pointer
+ */
+void SDIF_GetCapability(SDIF_Type *base, sdif_capability_t *capability);
+
+/*!
+ * @brief SDIF return the controller status
+ * @param base SDIF peripheral base address.
+ */
+static inline uint32_t SDIF_GetControllerStatus(SDIF_Type *base)
+{
+    return base->STATUS;
+}
+
+/*!
+ * @brief SDIF send command  complete signal disable to CE-ATA card
+ * @param base SDIF peripheral base address.
+ * @param send auto stop flag
+ */
+static inline void SDIF_SendCCSD(SDIF_Type *base, bool withAutoStop)
+{
+    if (withAutoStop)
+    {
+        base->CTRL |= SDIF_CTRL_SEND_CCSD_MASK | SDIF_CTRL_SEND_AUTO_STOP_CCSD_MASK;
+    }
+    else
+    {
+        base->CTRL |= SDIF_CTRL_SEND_CCSD_MASK;
+    }
+}
+
+/*!
+ * @brief SDIF config the clock delay
+ * This function is used to config the cclk_in delay to
+ * sample and drvive the data ,should meet the min setup
+ * time and hold time, and user need to config this paramter
+ * according to your board setting
+ * @param target freq work mode
+ * @param clock divider which is used to decide if use pharse shift for delay
+ */
+void SDIF_ConfigClockDelay(uint32_t target_HZ, uint32_t divider);
+
+/* @} */
+
+#if defined(__cplusplus)
+}
+#endif
+/*! @} */
+
+#endif /* _FSL_sdif_H_*/