fsl_sdif.h 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824
  1. /*
  2. * Copyright (c) 2016, Freescale Semiconductor, Inc.
  3. * Copyright 2016-2017 NXP
  4. *
  5. * Redistribution and use in source and binary forms, with or without modification,
  6. * are permitted provided that the following conditions are met:
  7. *
  8. * o Redistributions of source code must retain the above copyright notice, this list
  9. * of conditions and the following disclaimer.
  10. *
  11. * o Redistributions in binary form must reproduce the above copyright notice, this
  12. * list of conditions and the following disclaimer in the documentation and/or
  13. * other materials provided with the distribution.
  14. *
  15. * o Neither the name of the copyright holder nor the names of its
  16. * contributors may be used to endorse or promote products derived from this
  17. * software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  20. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  21. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  23. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  25. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  26. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. #ifndef _FSL_SDIF_H_
  31. #define _FSL_SDIF_H_
  32. #include "fsl_common.h"
  33. /*!
  34. * @addtogroup sdif
  35. * @{
  36. */
  37. /******************************************************************************
  38. * Definitions.
  39. *****************************************************************************/
  40. /*! @name Driver version */
  41. /*@{*/
  42. /*! @brief Driver version 2.0.1. */
  43. #define FSL_SDIF_DRIVER_VERSION (MAKE_VERSION(2U, 0U, 1U))
  44. /*@}*/
  45. #define SDIF_DriverIRQHandler SDIO_DriverIRQHandler /*!< convert the name here, due to RM use SDIO */
  46. #define SDIF_SUPPORT_SD_VERSION (0x20) /*!< define the controller support sd/sdio card version 2.0 */
  47. #define SDIF_SUPPORT_MMC_VERSION (0x44) /*!< define the controller support mmc card version 4.4 */
  48. #define SDIF_TIMEOUT_VALUE (65535U) /*!< define the timeout counter */
  49. #define SDIF_POLL_DEMAND_VALUE (0xFFU) /*!< this value can be any value */
  50. #define SDIF_DMA_DESCRIPTOR_BUFFER1_SIZE(x) (x & 0x1FFFU) /*!< DMA descriptor buffer1 size */
  51. #define SDIF_DMA_DESCRIPTOR_BUFFER2_SIZE(x) ((x & 0x1FFFU) << 13U) /*!<DMA descriptor buffer2 size */
  52. #define SDIF_RX_WATERMARK (15U) /*!<RX water mark value */
  53. #define SDIF_TX_WATERMARK (16U) /*!<TX water mark value */
  54. /*! @brief SDIOCLKCTRL setting
  55. * below clock delay setting should meet you board layout
  56. * user can change it when you meet timing mismatch issue
  57. * such as: response error/CRC error and so on
  58. */
  59. #define SDIF_INDENTIFICATION_MODE_SAMPLE_DELAY (0X17U)
  60. #define SDIF_INDENTIFICATION_MODE_DRV_DELAY (0X17U)
  61. #define SDIF_HIGHSPEED_25MHZ_SAMPLE_DELAY (0x10U)
  62. #define SDIF_HIGHSPEED_25MHZ_DRV_DELAY (0x10U)
  63. #define SDIF_HIGHSPEED_50MHZ_SAMPLE_DELAY (0x1FU)
  64. #define SDIF_HIGHSPEED_50MHZ_DRV_DELAY (0x1FU)
  65. /*! @brief SDIF status */
  66. enum _sdif_status
  67. {
  68. kStatus_SDIF_DescriptorBufferLenError = MAKE_STATUS(kStatusGroup_SDIF, 0U), /*!< Set DMA descriptor failed */
  69. kStatue_SDIF_InvalidArgument = MAKE_STATUS(kStatusGroup_SDIF, 1U), /*!< invalid argument status */
  70. kStatus_SDIF_SyncCmdTimeout = MAKE_STATUS(kStatusGroup_SDIF, 2U), /*!< sync command to CIU timeout status */
  71. kStatus_SDIF_SendCmdFail = MAKE_STATUS(kStatusGroup_SDIF, 3U), /* send command to card fail */
  72. kStatus_SDIF_SendCmdErrorBufferFull =
  73. MAKE_STATUS(kStatusGroup_SDIF, 4U), /* send command to card fail, due to command buffer full
  74. user need to resend this command */
  75. kStatus_SDIF_DMATransferFailWithFBE =
  76. MAKE_STATUS(kStatusGroup_SDIF, 5U), /* DMA transfer data fail with fatal bus error ,
  77. to do with this error :issue a hard reset/controller reset*/
  78. kStatus_SDIF_DMATransferDescriptorUnavaliable = MAKE_STATUS(kStatusGroup_SDIF, 6U), /* DMA descriptor unavalible */
  79. kStatus_SDIF_DataTransferFail = MAKE_STATUS(kStatusGroup_SDIF, 6U), /* transfer data fail */
  80. kStatus_SDIF_ResponseError = MAKE_STATUS(kStatusGroup_SDIF, 7U),
  81. };
  82. /*! @brief Host controller capabilities flag mask */
  83. enum _sdif_capability_flag
  84. {
  85. kSDIF_SupportHighSpeedFlag = 0x1U, /*!< Support high-speed */
  86. kSDIF_SupportDmaFlag = 0x2U, /*!< Support DMA */
  87. kSDIF_SupportSuspendResumeFlag = 0x4U, /*!< Support suspend/resume */
  88. kSDIF_SupportV330Flag = 0x8U, /*!< Support voltage 3.3V */
  89. kSDIF_Support4BitFlag = 0x10U, /*!< Support 4 bit mode */
  90. kSDIF_Support8BitFlag = 0x20U, /*!< Support 8 bit mode */
  91. };
  92. /*! @brief define the reset type */
  93. enum _sdif_reset_type
  94. {
  95. kSDIF_ResetController =
  96. SDIF_CTRL_CONTROLLER_RESET_MASK, /*!< reset controller,will reset: BIU/CIU interface
  97. CIU and state machine,ABORT_READ_DATA,SEND_IRQ_RESPONSE
  98. and READ_WAIT bits of control register,START_CMD bit of the
  99. command register*/
  100. kSDIF_ResetFIFO = SDIF_CTRL_FIFO_RESET_MASK, /*!< reset data FIFO*/
  101. kSDIF_ResetDMAInterface = SDIF_CTRL_DMA_RESET_MASK, /*!< reset DMA interface */
  102. kSDIF_ResetAll = kSDIF_ResetController | kSDIF_ResetFIFO | /*!< reset all*/
  103. kSDIF_ResetDMAInterface,
  104. };
  105. /*! @brief define the card bus width type */
  106. typedef enum _sdif_bus_width
  107. {
  108. kSDIF_Bus1BitWidth = 0U, /*!< 1bit bus width, 1bit mode and 4bit mode
  109. share one register bit */
  110. kSDIF_Bus4BitWidth = SDIF_CTYPE_CARD_WIDTH0_MASK, /*!< 4bit mode mask */
  111. kSDIF_Bus8BitWidth = SDIF_CTYPE_CARD_WIDTH1_MASK, /*!< support 8 bit mode */
  112. } sdif_bus_width_t;
  113. /*! @brief define the command flags */
  114. enum _sdif_command_flags
  115. {
  116. kSDIF_CmdResponseExpect = SDIF_CMD_RESPONSE_EXPECT_MASK, /*!< command request response*/
  117. kSDIF_CmdResponseLengthLong = SDIF_CMD_RESPONSE_LENGTH_MASK, /*!< command response length long */
  118. kSDIF_CmdCheckResponseCRC = SDIF_CMD_CHECK_RESPONSE_CRC_MASK, /*!< request check command response CRC*/
  119. kSDIF_DataExpect = SDIF_CMD_DATA_EXPECTED_MASK, /*!< request data transfer,ethier read/write*/
  120. kSDIF_DataWriteToCard = SDIF_CMD_READ_WRITE_MASK, /*!< data transfer direction */
  121. kSDIF_DataStreamTransfer = SDIF_CMD_TRANSFER_MODE_MASK, /*!< data transfer mode :stream/block transfer command */
  122. kSDIF_DataTransferAutoStop = SDIF_CMD_SEND_AUTO_STOP_MASK, /*!< data transfer with auto stop at the end of */
  123. kSDIF_WaitPreTransferComplete =
  124. SDIF_CMD_WAIT_PRVDATA_COMPLETE_MASK, /*!< wait pre transfer complete before sending this cmd */
  125. kSDIF_TransferStopAbort =
  126. SDIF_CMD_STOP_ABORT_CMD_MASK, /*!< when host issue stop or abort cmd to stop data transfer
  127. ,this bit should set so that cmd/data state-machines of CIU can return
  128. to idle correctly*/
  129. kSDIF_SendInitialization =
  130. SDIF_CMD_SEND_INITIALIZATION_MASK, /*!< send initaliztion 80 clocks for SD card after power on */
  131. kSDIF_CmdUpdateClockRegisterOnly =
  132. SDIF_CMD_UPDATE_CLOCK_REGISTERS_ONLY_MASK, /*!< send cmd update the CIU clock register only */
  133. kSDIF_CmdtoReadCEATADevice = SDIF_CMD_READ_CEATA_DEVICE_MASK, /*!< host is perform read access to CE-ATA device */
  134. kSDIF_CmdExpectCCS = SDIF_CMD_CCS_EXPECTED_MASK, /*!< command expect command completion signal signal */
  135. kSDIF_BootModeEnable = SDIF_CMD_ENABLE_BOOT_MASK, /*!< this bit should only be set for mandatory boot mode */
  136. kSDIF_BootModeExpectAck = SDIF_CMD_EXPECT_BOOT_ACK_MASK, /*!< boot mode expect ack */
  137. kSDIF_BootModeDisable = SDIF_CMD_DISABLE_BOOT_MASK, /*!< when software set this bit along with START_CMD, CIU
  138. terminates the boot operation*/
  139. kSDIF_BootModeAlternate = SDIF_CMD_BOOT_MODE_MASK, /*!< select boot mode ,alternate or mandatory*/
  140. kSDIF_CmdVoltageSwitch = SDIF_CMD_VOLT_SWITCH_MASK, /*!< this bit set for CMD11 only */
  141. kSDIF_CmdDataUseHoldReg = SDIF_CMD_USE_HOLD_REG_MASK, /*!< cmd and data send to card through the HOLD register*/
  142. };
  143. /*! @brief The command type */
  144. enum _sdif_command_type
  145. {
  146. kCARD_CommandTypeNormal = 0U, /*!< Normal command */
  147. kCARD_CommandTypeSuspend = 1U, /*!< Suspend command */
  148. kCARD_CommandTypeResume = 2U, /*!< Resume command */
  149. kCARD_CommandTypeAbort = 3U, /*!< Abort command */
  150. };
  151. /*!
  152. * @brief The command response type.
  153. *
  154. * Define the command response type from card to host controller.
  155. */
  156. enum _sdif_response_type
  157. {
  158. kCARD_ResponseTypeNone = 0U, /*!< Response type: none */
  159. kCARD_ResponseTypeR1 = 1U, /*!< Response type: R1 */
  160. kCARD_ResponseTypeR1b = 2U, /*!< Response type: R1b */
  161. kCARD_ResponseTypeR2 = 3U, /*!< Response type: R2 */
  162. kCARD_ResponseTypeR3 = 4U, /*!< Response type: R3 */
  163. kCARD_ResponseTypeR4 = 5U, /*!< Response type: R4 */
  164. kCARD_ResponseTypeR5 = 6U, /*!< Response type: R5 */
  165. kCARD_ResponseTypeR5b = 7U, /*!< Response type: R5b */
  166. kCARD_ResponseTypeR6 = 8U, /*!< Response type: R6 */
  167. kCARD_ResponseTypeR7 = 9U, /*!< Response type: R7 */
  168. };
  169. /*! @brief define the interrupt mask flags */
  170. enum _sdif_interrupt_mask
  171. {
  172. kSDIF_CardDetect = SDIF_INTMASK_CDET_MASK, /*!< mask for card detect */
  173. kSDIF_ResponseError = SDIF_INTMASK_RE_MASK, /*!< command response error */
  174. kSDIF_CommandDone = SDIF_INTMASK_CDONE_MASK, /*!< command transfer over*/
  175. kSDIF_DataTransferOver = SDIF_INTMASK_DTO_MASK, /*!< data transfer over flag*/
  176. kSDIF_WriteFIFORequest = SDIF_INTMASK_TXDR_MASK, /*!< write FIFO request */
  177. kSDIF_ReadFIFORequest = SDIF_INTMASK_RXDR_MASK, /*!< read FIFO request */
  178. kSDIF_ResponseCRCError = SDIF_INTMASK_RCRC_MASK, /*!< reponse CRC error */
  179. kSDIF_DataCRCError = SDIF_INTMASK_DCRC_MASK, /*!< data CRC error */
  180. kSDIF_ResponseTimeout = SDIF_INTMASK_RTO_MASK, /*!< response timeout */
  181. kSDIF_DataReadTimeout = SDIF_INTMASK_DRTO_MASK, /*!< read data timeout */
  182. kSDIF_DataStarvationByHostTimeout = SDIF_INTMASK_HTO_MASK, /*!< data starvation by host time out */
  183. kSDIF_FIFOError = SDIF_INTMASK_FRUN_MASK, /*!< indicate the FIFO underrun or overrun error */
  184. kSDIF_HardwareLockError = SDIF_INTMASK_HLE_MASK, /*!< hardware lock write error */
  185. kSDIF_DataStartBitError = SDIF_INTMASK_SBE_MASK, /*!< start bit error */
  186. kSDIF_AutoCmdDone = SDIF_INTMASK_ACD_MASK, /*!< indicate the auto command done */
  187. kSDIF_DataEndBitError = SDIF_INTMASK_EBE_MASK, /*!< end bit error */
  188. kSDIF_SDIOInterrupt = SDIF_INTMASK_SDIO_INT_MASK_MASK, /*!< interrupt from the SDIO card */
  189. kSDIF_CommandTransferStatus = kSDIF_ResponseError | kSDIF_CommandDone | kSDIF_ResponseCRCError |
  190. kSDIF_ResponseTimeout |
  191. kSDIF_HardwareLockError, /*!< command transfer status collection*/
  192. kSDIF_DataTransferStatus = kSDIF_DataTransferOver | kSDIF_WriteFIFORequest | kSDIF_ReadFIFORequest |
  193. kSDIF_DataCRCError | kSDIF_DataReadTimeout | kSDIF_DataStarvationByHostTimeout |
  194. kSDIF_FIFOError | kSDIF_DataStartBitError | kSDIF_DataEndBitError |
  195. kSDIF_AutoCmdDone, /*!< data transfer status collection */
  196. kSDIF_DataTransferError =
  197. kSDIF_DataCRCError | kSDIF_FIFOError | kSDIF_DataStartBitError | kSDIF_DataEndBitError | kSDIF_DataReadTimeout,
  198. kSDIF_AllInterruptStatus = 0x1FFFFU, /*!< all interrupt mask */
  199. };
  200. /*! @brief define the internal DMA status flags */
  201. enum _sdif_dma_status
  202. {
  203. kSDIF_DMATransFinishOneDescriptor = SDIF_IDSTS_TI_MASK, /*!< DMA transfer finished for one DMA descriptor */
  204. kSDIF_DMARecvFinishOneDescriptor = SDIF_IDSTS_RI_MASK, /*!< DMA revieve finished for one DMA descriptor */
  205. kSDIF_DMAFatalBusError = SDIF_IDSTS_FBE_MASK, /*!< DMA fatal bus error */
  206. kSDIF_DMADescriptorUnavailable = SDIF_IDSTS_DU_MASK, /*!< DMA descriptor unavailable */
  207. kSDIF_DMACardErrorSummary = SDIF_IDSTS_CES_MASK, /*!< card error summary */
  208. kSDIF_NormalInterruptSummary = SDIF_IDSTS_NIS_MASK, /*!< normal interrupt summary */
  209. kSDIF_AbnormalInterruptSummary = SDIF_IDSTS_AIS_MASK, /*!< abnormal interrupt summary*/
  210. kSDIF_DMAAllStatus = kSDIF_DMATransFinishOneDescriptor | kSDIF_DMARecvFinishOneDescriptor | kSDIF_DMAFatalBusError |
  211. kSDIF_DMADescriptorUnavailable | kSDIF_DMACardErrorSummary | kSDIF_NormalInterruptSummary |
  212. kSDIF_AbnormalInterruptSummary,
  213. };
  214. /*! @brief define the internal DMA descriptor flag */
  215. enum _sdif_dma_descriptor_flag
  216. {
  217. kSDIF_DisableCompleteInterrupt = 0x2U, /*!< disable the complete interrupt flag for the ends
  218. in the buffer pointed to by this descriptor*/
  219. kSDIF_DMADescriptorDataBufferEnd = 0x4U, /*!< indicate this descriptor contain the last data buffer of data */
  220. kSDIF_DMADescriptorDataBufferStart = 0x8U, /*!< indicate this descriptor contain the first data buffer
  221. of data,if first buffer size is 0,next descriptor contain
  222. the begaining of the data*/
  223. kSDIF_DMASecondAddrChained = 0x10U, /*!< indicate that the second addr in the descriptor is the
  224. next descriptor addr not the data buffer */
  225. kSDIF_DMADescriptorEnd = 0x20U, /*!< indicate that the descriptor list reached its final descriptor*/
  226. kSDIF_DMADescriptorOwnByDMA = 0x80000000U, /*!< indicate the descriptor is own by SD/MMC DMA */
  227. };
  228. /*! @brief define the internal DMA mode */
  229. typedef enum _sdif_dma_mode
  230. {
  231. kSDIF_ChainDMAMode = 0x01U, /* one descriptor with one buffer,but one descriptor point to another */
  232. kSDIF_DualDMAMode = 0x02U, /* dual mode is one descriptor with two buffer */
  233. } sdif_dma_mode_t;
  234. /*! @brief define the card work freq mode */
  235. enum _sdif_card_freq
  236. {
  237. kSDIF_Freq50MHZ = 50000000U, /*!< 50MHZ mode*/
  238. kSDIF_Freq400KHZ = 400000U, /*!< identificatioin mode*/
  239. };
  240. /*! @brief define the clock pharse shift */
  241. enum _sdif_clock_pharse_shift
  242. {
  243. kSDIF_ClcokPharseShift0, /*!< clock pharse shift 0*/
  244. kSDIF_ClcokPharseShift90, /*!< clock pharse shift 90*/
  245. kSDIF_ClcokPharseShift180, /*!< clock pharse shift 180*/
  246. kSDIF_ClcokPharseShift270, /*!< clock pharse shift 270*/
  247. };
  248. /*! @brief define the internal DMA descriptor */
  249. typedef struct _sdif_dma_descriptor
  250. {
  251. uint32_t dmaDesAttribute; /*!< internal DMA attribute control and status */
  252. uint32_t dmaDataBufferSize; /*!< internal DMA transfer buffer size control */
  253. const uint32_t *dmaDataBufferAddr0; /*!< internal DMA buffer 0 addr ,the buffer size must be 32bit aligned */
  254. const uint32_t *dmaDataBufferAddr1; /*!< internal DMA buffer 1 addr ,the buffer size must be 32bit aligned */
  255. } sdif_dma_descriptor_t;
  256. /*! @brief Defines the internal DMA config structure. */
  257. typedef struct _sdif_dma_config
  258. {
  259. bool enableFixBurstLen; /*!< fix burst len enable/disable flag,When set, the AHB will
  260. use only SINGLE, INCR4, INCR8 or INCR16 during start of
  261. normal burst transfers. When reset, the AHB will use SINGLE
  262. and INCR burst transfer operations */
  263. sdif_dma_mode_t mode; /*!< define the DMA mode */
  264. uint8_t dmaDesSkipLen; /*!< define the descriptor skip length ,the length between two descriptor
  265. this field is special for dual DMA mode */
  266. uint32_t *dmaDesBufferStartAddr; /*!< internal DMA descriptor start address*/
  267. uint32_t dmaDesBufferLen; /*!< internal DMA buffer descriptor buffer len ,user need to pay attention to the
  268. dma descriptor buffer length if it is bigger enough for your transfer */
  269. } sdif_dma_config_t;
  270. /*!
  271. * @brief Card data descriptor
  272. */
  273. typedef struct _sdif_data
  274. {
  275. bool streamTransfer; /*!< indicate this is a stream data transfer command */
  276. bool enableAutoCommand12; /*!< indicate if auto stop will send when data transfer over */
  277. bool enableIgnoreError; /*!< indicate if enable ignore error when transfer data */
  278. size_t blockSize; /*!< Block size, take care when config this parameter */
  279. uint32_t blockCount; /*!< Block count */
  280. uint32_t *rxData; /*!< data buffer to recieve */
  281. const uint32_t *txData; /*!< data buffer to transfer */
  282. } sdif_data_t;
  283. /*!
  284. * @brief Card command descriptor
  285. *
  286. * Define card command-related attribute.
  287. */
  288. typedef struct _sdif_command
  289. {
  290. uint32_t index; /*!< Command index */
  291. uint32_t argument; /*!< Command argument */
  292. uint32_t response[4U]; /*!< Response for this command */
  293. uint32_t type; /*!< define the command type */
  294. uint32_t responseType; /*!< Command response type */
  295. uint32_t flags; /*!< Cmd flags */
  296. uint32_t responseErrorFlags; /*!< response error flags, need to check the flags when
  297. recieve the cmd response */
  298. } sdif_command_t;
  299. /*! @brief Transfer state */
  300. typedef struct _sdif_transfer
  301. {
  302. sdif_data_t *data; /*!< Data to transfer */
  303. sdif_command_t *command; /*!< Command to send */
  304. } sdif_transfer_t;
  305. /*! @brief Data structure to initialize the sdif */
  306. typedef struct _sdif_config
  307. {
  308. uint8_t responseTimeout; /*!< command reponse timeout value */
  309. uint32_t cardDetDebounce_Clock; /*!< define the debounce clock count which will used in
  310. card detect logic,typical value is 5-25ms */
  311. uint32_t endianMode; /*!< define endian mode ,this field is not used in this
  312. module actually, keep for compatible with middleware*/
  313. uint32_t dataTimeout; /*!< data timeout value */
  314. } sdif_config_t;
  315. /*!
  316. * @brief SDIF capability information.
  317. * Defines a structure to get the capability information of SDIF.
  318. */
  319. typedef struct _sdif_capability
  320. {
  321. uint32_t sdVersion; /*!< support SD card/sdio version */
  322. uint32_t mmcVersion; /*!< support emmc card version */
  323. uint32_t maxBlockLength; /*!< Maximum block length united as byte */
  324. uint32_t maxBlockCount; /*!< Maximum byte count can be transfered */
  325. uint32_t flags; /*!< Capability flags to indicate the support information */
  326. } sdif_capability_t;
  327. /*! @brief sdif callback functions. */
  328. typedef struct _sdif_transfer_callback
  329. {
  330. void (*SDIOInterrupt)(void); /*!< SDIO card interrupt occurs */
  331. void (*DMADesUnavailable)(void); /*!< DMA descriptor unavailable */
  332. void (*CommandReload)(void); /*!< command buffer full,need re-load */
  333. void (*TransferComplete)(SDIF_Type *base,
  334. void *handle,
  335. status_t status,
  336. void *userData); /*!< Transfer complete callback */
  337. } sdif_transfer_callback_t;
  338. /*!
  339. * @brief sdif handle
  340. *
  341. * Defines the structure to save the sdif state information and callback function. The detail interrupt status when
  342. * send command or transfer data can be obtained from interruptFlags field by using mask defined in
  343. * sdif_interrupt_flag_t;
  344. * @note All the fields except interruptFlags and transferredWords must be allocated by the user.
  345. */
  346. typedef struct _sdif_handle
  347. {
  348. /* Transfer parameter */
  349. sdif_data_t *volatile data; /*!< Data to transfer */
  350. sdif_command_t *volatile command; /*!< Command to send */
  351. /* Transfer status */
  352. volatile uint32_t interruptFlags; /*!< Interrupt flags of last transaction */
  353. volatile uint32_t dmaInterruptFlags; /*!< DMA interrupt flags of last transaction*/
  354. volatile uint32_t transferredWords; /*!< Words transferred by polling way */
  355. /* Callback functions */
  356. sdif_transfer_callback_t callback; /*!< Callback function */
  357. void *userData; /*!< Parameter for transfer complete callback */
  358. } sdif_handle_t;
  359. /*! @brief sdif transfer function. */
  360. typedef status_t (*sdif_transfer_function_t)(SDIF_Type *base, sdif_transfer_t *content);
  361. /*! @brief sdif host descriptor */
  362. typedef struct _sdif_host
  363. {
  364. SDIF_Type *base; /*!< sdif peripheral base address */
  365. uint32_t sourceClock_Hz; /*!< sdif source clock frequency united in Hz */
  366. sdif_config_t config; /*!< sdif configuration */
  367. sdif_transfer_function_t transfer; /*!< sdif transfer function */
  368. sdif_capability_t capability; /*!< sdif capability information */
  369. } sdif_host_t;
  370. /*************************************************************************************************
  371. * API
  372. ************************************************************************************************/
  373. #if defined(__cplusplus)
  374. extern "C" {
  375. #endif
  376. /*!
  377. * @brief SDIF module initialization function.
  378. *
  379. * Configures the SDIF according to the user configuration.
  380. * @param base SDIF peripheral base address.
  381. * @param config SDIF configuration information.
  382. */
  383. void SDIF_Init(SDIF_Type *base, sdif_config_t *config);
  384. /*!
  385. * @brief SDIF module deinit function.
  386. * user should call this function follow with IP reset
  387. * @param base SDIF peripheral base address.
  388. */
  389. void SDIF_Deinit(SDIF_Type *base);
  390. /*!
  391. * @brief SDIF send initialize 80 clocks for SD card after initilize
  392. * @param base SDIF peripheral base address.
  393. * @param timeout value
  394. */
  395. bool SDIF_SendCardActive(SDIF_Type *base, uint32_t timeout);
  396. /*!
  397. * @brief SDIF module detect card insert status function.
  398. * @param base SDIF peripheral base address.
  399. * @param data3 indicate use data3 as card insert detect pin
  400. * will return the data3 PIN status in this condition
  401. */
  402. static inline uint32_t SDIF_DetectCardInsert(SDIF_Type *base, bool data3)
  403. {
  404. if (data3)
  405. {
  406. return base->STATUS & SDIF_STATUS_DATA_3_STATUS_MASK;
  407. }
  408. else
  409. {
  410. return base->CDETECT & SDIF_CDETECT_CARD_DETECT_MASK;
  411. }
  412. }
  413. /*!
  414. * @brief SDIF module enable/disable card clock.
  415. * @param base SDIF peripheral base address.
  416. * @param enable/disable flag
  417. */
  418. static inline void SDIF_EnableCardClock(SDIF_Type *base, bool enable)
  419. {
  420. if (enable)
  421. {
  422. base->CLKENA |= SDIF_CLKENA_CCLK_ENABLE_MASK;
  423. }
  424. else
  425. {
  426. base->CLKENA &= ~SDIF_CLKENA_CCLK_ENABLE_MASK;
  427. }
  428. }
  429. /*!
  430. * @brief SDIF module enable/disable module disable the card clock
  431. * to enter low power mode when card is idle,for SDIF cards, if
  432. * interrupts must be detected, clock should not be stopped
  433. * @param base SDIF peripheral base address.
  434. * @param enable/disable flag
  435. */
  436. static inline void SDIF_EnableLowPowerMode(SDIF_Type *base, bool enable)
  437. {
  438. if (enable)
  439. {
  440. base->CLKENA |= SDIF_CLKENA_CCLK_LOW_POWER_MASK;
  441. }
  442. else
  443. {
  444. base->CLKENA &= ~SDIF_CLKENA_CCLK_LOW_POWER_MASK;
  445. }
  446. }
  447. /*!
  448. * @brief Sets the card bus clock frequency.
  449. *
  450. * @param base SDIF peripheral base address.
  451. * @param srcClock_Hz SDIF source clock frequency united in Hz.
  452. * @param target_HZ card bus clock frequency united in Hz.
  453. * @return The nearest frequency of busClock_Hz configured to SD bus.
  454. */
  455. uint32_t SDIF_SetCardClock(SDIF_Type *base, uint32_t srcClock_Hz, uint32_t target_HZ);
  456. /*!
  457. * @brief reset the different block of the interface.
  458. * @param base SDIF peripheral base address.
  459. * @param mask indicate which block to reset.
  460. * @param timeout value,set to wait the bit self clear
  461. * @return reset result.
  462. */
  463. bool SDIF_Reset(SDIF_Type *base, uint32_t mask, uint32_t timeout);
  464. /*!
  465. * @brief enable/disable the card power.
  466. * once turn power on, software should wait for regulator/switch
  467. * ramp-up time before trying to initialize card.
  468. * @param base SDIF peripheral base address.
  469. * @param enable/disable flag.
  470. */
  471. static inline void SDIF_EnableCardPower(SDIF_Type *base, bool enable)
  472. {
  473. if (enable)
  474. {
  475. base->PWREN |= SDIF_PWREN_POWER_ENABLE_MASK;
  476. }
  477. else
  478. {
  479. base->PWREN &= ~SDIF_PWREN_POWER_ENABLE_MASK;
  480. }
  481. }
  482. /*!
  483. * @brief get the card write protect status
  484. * @param base SDIF peripheral base address.
  485. */
  486. static inline uint32_t SDIF_GetCardWriteProtect(SDIF_Type *base)
  487. {
  488. return base->WRTPRT & SDIF_WRTPRT_WRITE_PROTECT_MASK;
  489. }
  490. /*!
  491. * @brief set card data bus width
  492. * @param base SDIF peripheral base address.
  493. * @param data bus width type
  494. */
  495. static inline void SDIF_SetCardBusWidth(SDIF_Type *base, sdif_bus_width_t type)
  496. {
  497. base->CTYPE = type;
  498. }
  499. /*!
  500. * @brief toggle state on hardware reset PIN
  501. * This is used which card has a reset PIN typically.
  502. * @param base SDIF peripheral base address.
  503. */
  504. static inline void SDIF_AssertHardwareReset(SDIF_Type *base)
  505. {
  506. base->RST_N &= ~SDIF_RST_N_CARD_RESET_MASK;
  507. }
  508. /*!
  509. * @brief send command to the card
  510. * @param base SDIF peripheral base address.
  511. * @param command configuration collection
  512. * @param timeout value
  513. * @return command excute status
  514. */
  515. status_t SDIF_SendCommand(SDIF_Type *base, sdif_command_t *cmd, uint32_t timeout);
  516. /*!
  517. * @brief SDIF enable/disable global interrupt
  518. * @param base SDIF peripheral base address.
  519. * @param enable/disable flag
  520. */
  521. static inline void SDIF_EnableGlobalInterrupt(SDIF_Type *base, bool enable)
  522. {
  523. if (enable)
  524. {
  525. base->CTRL |= SDIF_CTRL_INT_ENABLE_MASK;
  526. }
  527. else
  528. {
  529. base->CTRL &= ~SDIF_CTRL_INT_ENABLE_MASK;
  530. }
  531. }
  532. /*!
  533. * @brief SDIF enable interrupt
  534. * @param base SDIF peripheral base address.
  535. * @param interrupt mask
  536. */
  537. static inline void SDIF_EnableInterrupt(SDIF_Type *base, uint32_t mask)
  538. {
  539. base->INTMASK |= mask;
  540. }
  541. /*!
  542. * @brief SDIF disable interrupt
  543. * @param base SDIF peripheral base address.
  544. * @param interrupt mask
  545. */
  546. static inline void SDIF_DisableInterrupt(SDIF_Type *base, uint32_t mask)
  547. {
  548. base->INTMASK &= ~mask;
  549. }
  550. /*!
  551. * @brief SDIF get interrupt status
  552. * @param base SDIF peripheral base address.
  553. */
  554. static inline uint32_t SDIF_GetInterruptStatus(SDIF_Type *base)
  555. {
  556. return base->MINTSTS;
  557. }
  558. /*!
  559. * @brief SDIF clear interrupt status
  560. * @param base SDIF peripheral base address.
  561. * @param status mask to clear
  562. */
  563. static inline void SDIF_ClearInterruptStatus(SDIF_Type *base, uint32_t mask)
  564. {
  565. base->RINTSTS &= mask;
  566. }
  567. /*!
  568. * @brief Creates the SDIF handle.
  569. * register call back function for interrupt and enable the interrupt
  570. * @param base SDIF peripheral base address.
  571. * @param handle SDIF handle pointer.
  572. * @param callback Structure pointer to contain all callback functions.
  573. * @param userData Callback function parameter.
  574. */
  575. void SDIF_TransferCreateHandle(SDIF_Type *base,
  576. sdif_handle_t *handle,
  577. sdif_transfer_callback_t *callback,
  578. void *userData);
  579. /*!
  580. * @brief SDIF enable DMA interrupt
  581. * @param base SDIF peripheral base address.
  582. * @param interrupt mask to set
  583. */
  584. static inline void SDIF_EnableDmaInterrupt(SDIF_Type *base, uint32_t mask)
  585. {
  586. base->IDINTEN |= mask;
  587. }
  588. /*!
  589. * @brief SDIF disable DMA interrupt
  590. * @param base SDIF peripheral base address.
  591. * @param interrupt mask to clear
  592. */
  593. static inline void SDIF_DisableDmaInterrupt(SDIF_Type *base, uint32_t mask)
  594. {
  595. base->IDINTEN &= ~mask;
  596. }
  597. /*!
  598. * @brief SDIF get internal DMA status
  599. * @param base SDIF peripheral base address.
  600. * @return the internal DMA status register
  601. */
  602. static inline uint32_t SDIF_GetInternalDMAStatus(SDIF_Type *base)
  603. {
  604. return base->IDSTS;
  605. }
  606. /*!
  607. * @brief SDIF clear internal DMA status
  608. * @param base SDIF peripheral base address.
  609. * @param status mask to clear
  610. */
  611. static inline void SDIF_ClearInternalDMAStatus(SDIF_Type *base, uint32_t mask)
  612. {
  613. base->IDSTS &= mask;
  614. }
  615. /*!
  616. * @brief SDIF internal DMA config function
  617. * @param base SDIF peripheral base address.
  618. * @param internal DMA configuration collection
  619. * @param data buffer pointer
  620. * @param data buffer size
  621. */
  622. status_t SDIF_InternalDMAConfig(SDIF_Type *base, sdif_dma_config_t *config, const uint32_t *data, uint32_t dataSize);
  623. /*!
  624. * @brief SDIF send read wait to SDIF card function
  625. * @param base SDIF peripheral base address.
  626. */
  627. static inline void SDIF_SendReadWait(SDIF_Type *base)
  628. {
  629. base->CTRL |= SDIF_CTRL_READ_WAIT_MASK;
  630. }
  631. /*!
  632. * @brief SDIF abort the read data when SDIF card is in suspend state
  633. * Once assert this bit,data state machine will be reset which is waiting for the
  634. * next blocking data,used in SDIO card suspend sequence,should call after suspend
  635. * cmd send
  636. * @param base SDIF peripheral base address.
  637. * @param timeout value to wait this bit self clear which indicate the data machine
  638. * reset to idle
  639. */
  640. bool SDIF_AbortReadData(SDIF_Type *base, uint32_t timeout);
  641. /*!
  642. * @brief SDIF enable/disable CE-ATA card interrupt
  643. * this bit should set together with the card register
  644. * @param base SDIF peripheral base address.
  645. * @param enable/disable flag
  646. */
  647. static inline void SDIF_EnableCEATAInterrupt(SDIF_Type *base, bool enable)
  648. {
  649. if (enable)
  650. {
  651. base->CTRL |= SDIF_CTRL_CEATA_DEVICE_INTERRUPT_STATUS_MASK;
  652. }
  653. else
  654. {
  655. base->CTRL &= ~SDIF_CTRL_CEATA_DEVICE_INTERRUPT_STATUS_MASK;
  656. }
  657. }
  658. /*!
  659. * @brief SDIF transfer function data/cmd in a non-blocking way
  660. * this API should be use in interrupt mode, when use this API user
  661. * must call SDIF_TransferCreateHandle first, all status check through
  662. * interrupt
  663. * @param base SDIF peripheral base address.
  664. * @param sdif handle
  665. * @param DMA config structure
  666. * This parameter can be config as:
  667. * 1. NULL
  668. In this condition, polling transfer mode is selected
  669. 2. avaliable DMA config
  670. In this condition, DMA transfer mode is selected
  671. * @param sdif transfer configuration collection
  672. */
  673. status_t SDIF_TransferNonBlocking(SDIF_Type *base,
  674. sdif_handle_t *handle,
  675. sdif_dma_config_t *dmaConfig,
  676. sdif_transfer_t *transfer);
  677. /*!
  678. * @brief SDIF transfer function data/cmd in a blocking way
  679. * @param base SDIF peripheral base address.
  680. * @param DMA config structure
  681. * 1. NULL
  682. * In this condition, polling transfer mode is selected
  683. * 2. avaliable DMA config
  684. * In this condition, DMA transfer mode is selected
  685. * @param sdif transfer configuration collection
  686. */
  687. status_t SDIF_TransferBlocking(SDIF_Type *base, sdif_dma_config_t *dmaConfig, sdif_transfer_t *transfer);
  688. /*!
  689. * @brief SDIF release the DMA descriptor to DMA engine
  690. * this function should be called when DMA descriptor unavailable status occurs
  691. * @param base SDIF peripheral base address.
  692. * @param sdif DMA config pointer
  693. */
  694. status_t SDIF_ReleaseDMADescriptor(SDIF_Type *base, sdif_dma_config_t *dmaConfig);
  695. /*!
  696. * @brief SDIF return the controller capability
  697. * @param base SDIF peripheral base address.
  698. * @param sdif capability pointer
  699. */
  700. void SDIF_GetCapability(SDIF_Type *base, sdif_capability_t *capability);
  701. /*!
  702. * @brief SDIF return the controller status
  703. * @param base SDIF peripheral base address.
  704. */
  705. static inline uint32_t SDIF_GetControllerStatus(SDIF_Type *base)
  706. {
  707. return base->STATUS;
  708. }
  709. /*!
  710. * @brief SDIF send command complete signal disable to CE-ATA card
  711. * @param base SDIF peripheral base address.
  712. * @param send auto stop flag
  713. */
  714. static inline void SDIF_SendCCSD(SDIF_Type *base, bool withAutoStop)
  715. {
  716. if (withAutoStop)
  717. {
  718. base->CTRL |= SDIF_CTRL_SEND_CCSD_MASK | SDIF_CTRL_SEND_AUTO_STOP_CCSD_MASK;
  719. }
  720. else
  721. {
  722. base->CTRL |= SDIF_CTRL_SEND_CCSD_MASK;
  723. }
  724. }
  725. /*!
  726. * @brief SDIF config the clock delay
  727. * This function is used to config the cclk_in delay to
  728. * sample and drvive the data ,should meet the min setup
  729. * time and hold time, and user need to config this paramter
  730. * according to your board setting
  731. * @param target freq work mode
  732. * @param clock divider which is used to decide if use pharse shift for delay
  733. */
  734. void SDIF_ConfigClockDelay(uint32_t target_HZ, uint32_t divider);
  735. /* @} */
  736. #if defined(__cplusplus)
  737. }
  738. #endif
  739. /*! @} */
  740. #endif /* _FSL_sdif_H_*/