fsl_sdif.c 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303
  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. #include "fsl_sdif.h"
  31. /*******************************************************************************
  32. * Definitions
  33. ******************************************************************************/
  34. /* Typedef for interrupt handler. */
  35. typedef void (*sdif_isr_t)(SDIF_Type *base, sdif_handle_t *handle);
  36. /*******************************************************************************
  37. * Prototypes
  38. ******************************************************************************/
  39. /*!
  40. * @brief Get the instance.
  41. *
  42. * @param base SDIF peripheral base address.
  43. * @return Instance number.
  44. */
  45. static uint32_t SDIF_GetInstance(SDIF_Type *base);
  46. /*
  47. * @brief config the SDIF interface before transfer between the card and host
  48. * @param SDIF base address
  49. * @param transfer config structure
  50. */
  51. static status_t SDIF_TransferConfig(SDIF_Type *base, sdif_transfer_t *transfer);
  52. /*
  53. * @brief wait the command done function and check error status
  54. * @param SDIF base address
  55. * @param command config structure
  56. */
  57. static status_t SDIF_WaitCommandDone(SDIF_Type *base, sdif_command_t *command);
  58. /*
  59. * @brief transfer data in a blocking way
  60. * @param SDIF base address
  61. * @param data config structure
  62. * @param indicate current transfer mode:DMA or polling
  63. */
  64. static status_t SDIF_TransferDataBlocking(SDIF_Type *base, sdif_data_t *data, bool isDMA);
  65. /*
  66. * @brief read the command response
  67. * @param SDIF base address
  68. * @param sdif command pointer
  69. */
  70. static status_t SDIF_ReadCommandResponse(SDIF_Type *base, sdif_command_t *command);
  71. /*
  72. * @brief handle transfer command interrupt
  73. * @param SDIF base address
  74. * @param sdif handle
  75. * @param interrupt mask flags
  76. */
  77. static void SDIF_TransferHandleCommand(SDIF_Type *base, sdif_handle_t *handle, uint32_t interruptFlags);
  78. /*
  79. * @brief handle transfer data interrupt
  80. * @param SDIF base address
  81. * @param sdif handle
  82. * @param interrupt mask flags
  83. */
  84. static void SDIF_TransferHandleData(SDIF_Type *base, sdif_handle_t *handle, uint32_t interruptFlags);
  85. /*
  86. * @brief handle DMA transfer
  87. * @param SDIF base address
  88. * @param sdif handle
  89. * @param interrupt mask flag
  90. */
  91. static void SDIF_TransferHandleDMA(SDIF_Type *base, sdif_handle_t *handle, uint32_t interruptFlags);
  92. /*
  93. * @brief driver IRQ handler
  94. * @param SDIF base address
  95. * @param sdif handle
  96. */
  97. static void SDIF_TransferHandleIRQ(SDIF_Type *base, sdif_handle_t *handle);
  98. /*
  99. * @brief read data port
  100. * @param SDIF base address
  101. * @param sdif data
  102. * @param the number of data been transferred
  103. */
  104. static uint32_t SDIF_ReadDataPort(SDIF_Type *base, sdif_data_t *data, uint32_t transferredWords);
  105. /*
  106. * @brief write data port
  107. * @param SDIF base address
  108. * @param sdif data
  109. * @param the number of data been transferred
  110. */
  111. static uint32_t SDIF_WriteDataPort(SDIF_Type *base, sdif_data_t *data, uint32_t transferredWords);
  112. /*
  113. * @brief read data by blocking way
  114. * @param SDIF base address
  115. * @param sdif data
  116. */
  117. static status_t SDIF_ReadDataPortBlocking(SDIF_Type *base, sdif_data_t *data);
  118. /*
  119. * @brief write data by blocking way
  120. * @param SDIF base address
  121. * @param sdif data
  122. */
  123. static status_t SDIF_WriteDataPortBlocking(SDIF_Type *base, sdif_data_t *data);
  124. /*
  125. * @brief handle sdio interrupt
  126. * This function will call the SDIO interrupt callback
  127. * @param SDIF handle
  128. */
  129. static void SDIF_TransferHandleSDIOInterrupt(sdif_handle_t *handle);
  130. /*******************************************************************************
  131. * Variables
  132. ******************************************************************************/
  133. /*! @brief SDIF internal handle pointer array */
  134. static sdif_handle_t *s_sdifHandle[FSL_FEATURE_SOC_SDIF_COUNT];
  135. /*! @brief SDIF base pointer array */
  136. static SDIF_Type *const s_sdifBase[] = SDIF_BASE_PTRS;
  137. /*! @brief SDIF IRQ name array */
  138. static const IRQn_Type s_sdifIRQ[] = SDIF_IRQS;
  139. /* SDIF ISR for transactional APIs. */
  140. static sdif_isr_t s_sdifIsr;
  141. /*******************************************************************************
  142. * Code
  143. ******************************************************************************/
  144. static uint32_t SDIF_GetInstance(SDIF_Type *base)
  145. {
  146. uint8_t instance = 0U;
  147. while ((instance < ARRAY_SIZE(s_sdifBase)) && (s_sdifBase[instance] != base))
  148. {
  149. instance++;
  150. }
  151. assert(instance < ARRAY_SIZE(s_sdifBase));
  152. return instance;
  153. }
  154. static status_t SDIF_TransferConfig(SDIF_Type *base, sdif_transfer_t *transfer)
  155. {
  156. sdif_command_t *command = transfer->command;
  157. sdif_data_t *data = transfer->data;
  158. if ((command == NULL) || (data && (data->blockSize > SDIF_BLKSIZ_BLOCK_SIZE_MASK)))
  159. {
  160. return kStatue_SDIF_InvalidArgument;
  161. }
  162. if (data != NULL)
  163. {
  164. /* config the block size register ,the block size maybe smaller than FIFO
  165. depth, will test on the board */
  166. base->BLKSIZ = SDIF_BLKSIZ_BLOCK_SIZE(data->blockSize);
  167. /* config the byte count register */
  168. base->BYTCNT = SDIF_BYTCNT_BYTE_COUNT(data->blockSize * data->blockCount);
  169. command->flags |= kSDIF_DataExpect; /* need transfer data flag */
  170. if (data->txData != NULL)
  171. {
  172. command->flags |= kSDIF_DataWriteToCard; /* data transfer direction */
  173. }
  174. else
  175. {
  176. /* config the card read threshold,enable the card read threshold */
  177. if (data->blockSize <= (SDIF_FIFO_COUNT * sizeof(uint32_t)))
  178. {
  179. base->CARDTHRCTL = SDIF_CARDTHRCTL_CARDRDTHREN_MASK | SDIF_CARDTHRCTL_CARDTHRESHOLD(data->blockSize);
  180. }
  181. else
  182. {
  183. base->CARDTHRCTL &= ~SDIF_CARDTHRCTL_CARDRDTHREN_MASK;
  184. }
  185. }
  186. if (data->streamTransfer)
  187. {
  188. command->flags |= kSDIF_DataStreamTransfer; /* indicate if use stream transfer or block transfer */
  189. }
  190. if ((data->enableAutoCommand12) &&
  191. (data->blockCount > 1U)) /* indicate if auto stop will send after the data transfer done */
  192. {
  193. command->flags |= kSDIF_DataTransferAutoStop;
  194. }
  195. }
  196. /* R2 response length long */
  197. if (command->responseType == kCARD_ResponseTypeR2)
  198. {
  199. command->flags |= (kSDIF_CmdCheckResponseCRC | kSDIF_CmdResponseLengthLong | kSDIF_CmdResponseExpect);
  200. }
  201. else if ((command->responseType == kCARD_ResponseTypeR3) || (command->responseType == kCARD_ResponseTypeR4))
  202. {
  203. command->flags |= kSDIF_CmdResponseExpect; /* response R3 do not check Response CRC */
  204. }
  205. else
  206. {
  207. if (command->responseType != kCARD_ResponseTypeNone)
  208. {
  209. command->flags |= (kSDIF_CmdCheckResponseCRC | kSDIF_CmdResponseExpect);
  210. }
  211. }
  212. if (command->type == kCARD_CommandTypeAbort)
  213. {
  214. command->flags |= kSDIF_TransferStopAbort;
  215. }
  216. /* wait pre-transfer complete */
  217. command->flags |= kSDIF_WaitPreTransferComplete | kSDIF_CmdDataUseHoldReg;
  218. return kStatus_Success;
  219. }
  220. static status_t SDIF_ReadCommandResponse(SDIF_Type *base, sdif_command_t *command)
  221. {
  222. /* check if command exsit,if not, do not read the response */
  223. if (NULL != command)
  224. {
  225. /* read reponse */
  226. command->response[0U] = base->RESP[0U];
  227. if (command->responseType == kCARD_ResponseTypeR2)
  228. {
  229. command->response[1U] = base->RESP[1U];
  230. command->response[2U] = base->RESP[2U];
  231. command->response[3U] = base->RESP[3U];
  232. }
  233. if ((command->responseErrorFlags != 0U) &&
  234. ((command->responseType == kCARD_ResponseTypeR1) || (command->responseType == kCARD_ResponseTypeR1b) ||
  235. (command->responseType == kCARD_ResponseTypeR6) || (command->responseType == kCARD_ResponseTypeR5)))
  236. {
  237. if (((command->responseErrorFlags) & (command->response[0U])) != 0U)
  238. {
  239. return kStatus_SDIF_ResponseError;
  240. }
  241. }
  242. }
  243. return kStatus_Success;
  244. }
  245. static status_t SDIF_WaitCommandDone(SDIF_Type *base, sdif_command_t *command)
  246. {
  247. uint32_t status = 0U;
  248. do
  249. {
  250. status = SDIF_GetInterruptStatus(base);
  251. if ((status &
  252. (kSDIF_ResponseError | kSDIF_ResponseCRCError | kSDIF_ResponseTimeout | kSDIF_HardwareLockError)) != 0u)
  253. {
  254. SDIF_ClearInterruptStatus(base, status & (kSDIF_ResponseError | kSDIF_ResponseCRCError |
  255. kSDIF_ResponseTimeout | kSDIF_HardwareLockError));
  256. return kStatus_SDIF_SendCmdFail;
  257. }
  258. } while ((status & kSDIF_CommandDone) != kSDIF_CommandDone);
  259. /* clear the command done bit */
  260. SDIF_ClearInterruptStatus(base, status & kSDIF_CommandDone);
  261. return SDIF_ReadCommandResponse(base, command);
  262. }
  263. status_t SDIF_ReleaseDMADescriptor(SDIF_Type *base, sdif_dma_config_t *dmaConfig)
  264. {
  265. assert(NULL != dmaConfig);
  266. assert(NULL != dmaConfig->dmaDesBufferStartAddr);
  267. sdif_dma_descriptor_t *dmaDesAddr;
  268. uint32_t *tempDMADesBuffer = dmaConfig->dmaDesBufferStartAddr;
  269. uint32_t dmaDesBufferSize = 0U;
  270. dmaDesAddr = (sdif_dma_descriptor_t *)tempDMADesBuffer;
  271. /* chain descriptor mode */
  272. if (dmaConfig->mode == kSDIF_ChainDMAMode)
  273. {
  274. while (((dmaDesAddr->dmaDesAttribute & kSDIF_DMADescriptorDataBufferEnd) != kSDIF_DMADescriptorDataBufferEnd) &&
  275. (dmaDesBufferSize < dmaConfig->dmaDesBufferLen * sizeof(uint32_t)))
  276. {
  277. /* set the OWN bit */
  278. dmaDesAddr->dmaDesAttribute |= kSDIF_DMADescriptorOwnByDMA;
  279. dmaDesAddr++;
  280. dmaDesBufferSize += sizeof(sdif_dma_descriptor_t);
  281. }
  282. /* if access dma des address overflow, return fail */
  283. if (dmaDesBufferSize > dmaConfig->dmaDesBufferLen * sizeof(uint32_t))
  284. {
  285. return kStatus_Fail;
  286. }
  287. dmaDesAddr->dmaDesAttribute |= kSDIF_DMADescriptorOwnByDMA;
  288. }
  289. /* dual descriptor mode */
  290. else
  291. {
  292. while (((dmaDesAddr->dmaDesAttribute & kSDIF_DMADescriptorEnd) != kSDIF_DMADescriptorEnd) &&
  293. (dmaDesBufferSize < dmaConfig->dmaDesBufferLen * sizeof(uint32_t)))
  294. {
  295. dmaDesAddr = (sdif_dma_descriptor_t *)tempDMADesBuffer;
  296. dmaDesAddr->dmaDesAttribute |= kSDIF_DMADescriptorOwnByDMA;
  297. tempDMADesBuffer += dmaConfig->dmaDesSkipLen;
  298. }
  299. /* if access dma des address overflow, return fail */
  300. if (dmaDesBufferSize > dmaConfig->dmaDesBufferLen * sizeof(uint32_t))
  301. {
  302. return kStatus_Fail;
  303. }
  304. dmaDesAddr->dmaDesAttribute |= kSDIF_DMADescriptorOwnByDMA;
  305. }
  306. /* reload DMA descriptor */
  307. base->PLDMND = SDIF_POLL_DEMAND_VALUE;
  308. return kStatus_Success;
  309. }
  310. static uint32_t SDIF_ReadDataPort(SDIF_Type *base, sdif_data_t *data, uint32_t transferredWords)
  311. {
  312. uint32_t i;
  313. uint32_t totalWords;
  314. uint32_t wordsCanBeRead; /* The words can be read at this time. */
  315. uint32_t readWatermark = ((base->FIFOTH & SDIF_FIFOTH_RX_WMARK_MASK) >> SDIF_FIFOTH_RX_WMARK_SHIFT);
  316. if (data->blockSize % sizeof(uint32_t) != 0U)
  317. {
  318. data->blockSize +=
  319. sizeof(uint32_t) - (data->blockSize % sizeof(uint32_t)); /* make the block size as word-aligned */
  320. }
  321. totalWords = ((data->blockCount * data->blockSize) / sizeof(uint32_t));
  322. /* If watermark level is equal or bigger than totalWords, transfers totalWords data. */
  323. if (readWatermark >= totalWords)
  324. {
  325. wordsCanBeRead = totalWords;
  326. }
  327. /* If watermark level is less than totalWords and left words to be sent is equal or bigger than readWatermark,
  328. transfers watermark level words. */
  329. else if ((readWatermark < totalWords) && ((totalWords - transferredWords) >= readWatermark))
  330. {
  331. wordsCanBeRead = readWatermark;
  332. }
  333. /* If watermark level is less than totalWords and left words to be sent is less than readWatermark, transfers left
  334. words. */
  335. else
  336. {
  337. wordsCanBeRead = (totalWords - transferredWords);
  338. }
  339. i = 0U;
  340. while (i < wordsCanBeRead)
  341. {
  342. data->rxData[transferredWords++] = base->FIFO[i];
  343. i++;
  344. }
  345. return transferredWords;
  346. }
  347. static uint32_t SDIF_WriteDataPort(SDIF_Type *base, sdif_data_t *data, uint32_t transferredWords)
  348. {
  349. uint32_t i;
  350. uint32_t totalWords;
  351. uint32_t wordsCanBeWrite; /* The words can be read at this time. */
  352. uint32_t writeWatermark = ((base->FIFOTH & SDIF_FIFOTH_TX_WMARK_MASK) >> SDIF_FIFOTH_TX_WMARK_SHIFT);
  353. if (data->blockSize % sizeof(uint32_t) != 0U)
  354. {
  355. data->blockSize +=
  356. sizeof(uint32_t) - (data->blockSize % sizeof(uint32_t)); /* make the block size as word-aligned */
  357. }
  358. totalWords = ((data->blockCount * data->blockSize) / sizeof(uint32_t));
  359. /* If watermark level is equal or bigger than totalWords, transfers totalWords data. */
  360. if (writeWatermark >= totalWords)
  361. {
  362. wordsCanBeWrite = totalWords;
  363. }
  364. /* If watermark level is less than totalWords and left words to be sent is equal or bigger than writeWatermark,
  365. transfers watermark level words. */
  366. else if ((writeWatermark < totalWords) && ((totalWords - transferredWords) >= writeWatermark))
  367. {
  368. wordsCanBeWrite = writeWatermark;
  369. }
  370. /* If watermark level is less than totalWords and left words to be sent is less than writeWatermark, transfers left
  371. words. */
  372. else
  373. {
  374. wordsCanBeWrite = (totalWords - transferredWords);
  375. }
  376. i = 0U;
  377. while (i < wordsCanBeWrite)
  378. {
  379. base->FIFO[i] = data->txData[transferredWords++];
  380. i++;
  381. }
  382. return transferredWords;
  383. }
  384. static status_t SDIF_ReadDataPortBlocking(SDIF_Type *base, sdif_data_t *data)
  385. {
  386. uint32_t totalWords;
  387. uint32_t transferredWords = 0U;
  388. status_t error = kStatus_Success;
  389. uint32_t status;
  390. bool transferOver = false;
  391. if (data->blockSize % sizeof(uint32_t) != 0U)
  392. {
  393. data->blockSize +=
  394. sizeof(uint32_t) - (data->blockSize % sizeof(uint32_t)); /* make the block size as word-aligned */
  395. }
  396. totalWords = ((data->blockCount * data->blockSize) / sizeof(uint32_t));
  397. while ((transferredWords < totalWords) && (error == kStatus_Success))
  398. {
  399. /* wait data transfer complete or reach RX watermark */
  400. do
  401. {
  402. status = SDIF_GetInterruptStatus(base);
  403. if (status & kSDIF_DataTransferError)
  404. {
  405. if (!(data->enableIgnoreError))
  406. {
  407. error = kStatus_Fail;
  408. }
  409. }
  410. } while (((status & (kSDIF_DataTransferOver | kSDIF_ReadFIFORequest)) == 0U) && (!transferOver));
  411. if ((status & kSDIF_DataTransferOver) == kSDIF_DataTransferOver)
  412. {
  413. transferOver = true;
  414. }
  415. if (error == kStatus_Success)
  416. {
  417. transferredWords = SDIF_ReadDataPort(base, data, transferredWords);
  418. }
  419. /* clear interrupt status */
  420. SDIF_ClearInterruptStatus(base, status);
  421. }
  422. return error;
  423. }
  424. static status_t SDIF_WriteDataPortBlocking(SDIF_Type *base, sdif_data_t *data)
  425. {
  426. uint32_t totalWords;
  427. uint32_t transferredWords = 0U;
  428. status_t error = kStatus_Success;
  429. uint32_t status;
  430. if (data->blockSize % sizeof(uint32_t) != 0U)
  431. {
  432. data->blockSize +=
  433. sizeof(uint32_t) - (data->blockSize % sizeof(uint32_t)); /* make the block size as word-aligned */
  434. }
  435. totalWords = ((data->blockCount * data->blockSize) / sizeof(uint32_t));
  436. while ((transferredWords < totalWords) && (error == kStatus_Success))
  437. {
  438. /* wait data transfer complete or reach RX watermark */
  439. do
  440. {
  441. status = SDIF_GetInterruptStatus(base);
  442. if (status & kSDIF_DataTransferError)
  443. {
  444. if (!(data->enableIgnoreError))
  445. {
  446. error = kStatus_Fail;
  447. }
  448. }
  449. } while ((status & kSDIF_WriteFIFORequest) == 0U);
  450. if (error == kStatus_Success)
  451. {
  452. transferredWords = SDIF_WriteDataPort(base, data, transferredWords);
  453. }
  454. /* clear interrupt status */
  455. SDIF_ClearInterruptStatus(base, status);
  456. }
  457. while ((SDIF_GetInterruptStatus(base) & kSDIF_DataTransferOver) != kSDIF_DataTransferOver)
  458. {
  459. }
  460. if (SDIF_GetInterruptStatus(base) & kSDIF_DataTransferError)
  461. {
  462. if (!(data->enableIgnoreError))
  463. {
  464. error = kStatus_Fail;
  465. }
  466. }
  467. SDIF_ClearInterruptStatus(base, (kSDIF_DataTransferOver | kSDIF_DataTransferError));
  468. return error;
  469. }
  470. bool SDIF_Reset(SDIF_Type *base, uint32_t mask, uint32_t timeout)
  471. {
  472. base->CTRL |= mask;
  473. /* check software DMA reset here for DMA reset also need to check this bit */
  474. while ((base->CTRL & mask) != 0U)
  475. {
  476. if (!timeout)
  477. {
  478. break;
  479. }
  480. timeout--;
  481. }
  482. return timeout ? true : false;
  483. }
  484. static status_t SDIF_TransferDataBlocking(SDIF_Type *base, sdif_data_t *data, bool isDMA)
  485. {
  486. assert(NULL != data);
  487. uint32_t dmaStatus = 0U;
  488. status_t error = kStatus_Success;
  489. /* in DMA mode, only need to wait the complete flag and check error */
  490. if (isDMA)
  491. {
  492. do
  493. {
  494. dmaStatus = SDIF_GetInternalDMAStatus(base);
  495. if ((dmaStatus & kSDIF_DMAFatalBusError) == kSDIF_DMAFatalBusError)
  496. {
  497. SDIF_ClearInternalDMAStatus(base, kSDIF_DMAFatalBusError | kSDIF_AbnormalInterruptSummary);
  498. error = kStatus_SDIF_DMATransferFailWithFBE; /* in this condition,need reset */
  499. }
  500. /* Card error summary, include EBE,SBE,Data CRC,RTO,DRTO,Response error */
  501. if ((dmaStatus & kSDIF_DMACardErrorSummary) == kSDIF_DMACardErrorSummary)
  502. {
  503. SDIF_ClearInternalDMAStatus(base, kSDIF_DMACardErrorSummary | kSDIF_AbnormalInterruptSummary);
  504. if (!(data->enableIgnoreError))
  505. {
  506. error = kStatus_SDIF_DataTransferFail;
  507. }
  508. /* if error occur, then return */
  509. break;
  510. }
  511. } while ((dmaStatus & (kSDIF_DMATransFinishOneDescriptor | kSDIF_DMARecvFinishOneDescriptor)) == 0U);
  512. /* clear the corresponding status bit */
  513. SDIF_ClearInternalDMAStatus(base, (kSDIF_DMATransFinishOneDescriptor | kSDIF_DMARecvFinishOneDescriptor |
  514. kSDIF_NormalInterruptSummary));
  515. SDIF_ClearInterruptStatus(base, SDIF_GetInterruptStatus(base));
  516. }
  517. else
  518. {
  519. if (data->rxData != NULL)
  520. {
  521. error = SDIF_ReadDataPortBlocking(base, data);
  522. }
  523. else
  524. {
  525. error = SDIF_WriteDataPortBlocking(base, data);
  526. }
  527. }
  528. return error;
  529. }
  530. status_t SDIF_SendCommand(SDIF_Type *base, sdif_command_t *cmd, uint32_t timeout)
  531. {
  532. assert(NULL != cmd);
  533. base->CMDARG = cmd->argument;
  534. base->CMD = SDIF_CMD_CMD_INDEX(cmd->index) | SDIF_CMD_START_CMD_MASK | (cmd->flags & (~SDIF_CMD_CMD_INDEX_MASK));
  535. /* wait start_cmd bit auto clear within timeout */
  536. while ((base->CMD & SDIF_CMD_START_CMD_MASK) == SDIF_CMD_START_CMD_MASK)
  537. {
  538. if (!timeout)
  539. {
  540. break;
  541. }
  542. --timeout;
  543. }
  544. return timeout ? kStatus_Success : kStatus_Fail;
  545. }
  546. bool SDIF_SendCardActive(SDIF_Type *base, uint32_t timeout)
  547. {
  548. bool enINT = false;
  549. sdif_command_t command;
  550. memset(&command, 0U, sizeof(sdif_command_t));
  551. /* add for confict with interrupt mode,close the interrupt temporary */
  552. if ((base->CTRL & SDIF_CTRL_INT_ENABLE_MASK) == SDIF_CTRL_INT_ENABLE_MASK)
  553. {
  554. enINT = true;
  555. base->CTRL &= ~SDIF_CTRL_INT_ENABLE_MASK;
  556. }
  557. command.flags = SDIF_CMD_SEND_INITIALIZATION_MASK;
  558. if (SDIF_SendCommand(base, &command, timeout) == kStatus_Fail)
  559. {
  560. return false;
  561. }
  562. /* wait command done */
  563. while ((SDIF_GetInterruptStatus(base) & kSDIF_CommandDone) != kSDIF_CommandDone)
  564. {
  565. }
  566. /* clear status */
  567. SDIF_ClearInterruptStatus(base, kSDIF_CommandDone);
  568. /* add for confict with interrupt mode */
  569. if (enINT)
  570. {
  571. base->CTRL |= SDIF_CTRL_INT_ENABLE_MASK;
  572. }
  573. return true;
  574. }
  575. void SDIF_ConfigClockDelay(uint32_t target_HZ, uint32_t divider)
  576. {
  577. /*config the clock delay and pharse shift
  578. *should config the clk_in_drv,
  579. *clk_in_sample to meet the min hold and
  580. *setup time
  581. */
  582. if (target_HZ <= kSDIF_Freq400KHZ)
  583. {
  584. /*min hold time:5ns
  585. * min setup time: 5ns
  586. * delay = (x+1)*250ps
  587. */
  588. SYSCON->SDIOCLKCTRL = SYSCON_SDIOCLKCTRL_CCLK_SAMPLE_DELAY_ACTIVE_MASK |
  589. SYSCON_SDIOCLKCTRL_CCLK_SAMPLE_DELAY(SDIF_INDENTIFICATION_MODE_SAMPLE_DELAY) |
  590. SYSCON_SDIOCLKCTRL_CCLK_DRV_DELAY_ACTIVE_MASK |
  591. SYSCON_SDIOCLKCTRL_CCLK_DRV_DELAY(SDIF_INDENTIFICATION_MODE_DRV_DELAY);
  592. }
  593. else if (target_HZ >= kSDIF_Freq50MHZ)
  594. {
  595. /*
  596. * user need to pay attention to this parameter
  597. * can be change the setting for you card and board
  598. * min hold time:2ns
  599. * min setup time: 6ns
  600. * delay = (x+1)*250ps
  601. */
  602. SYSCON->SDIOCLKCTRL = SYSCON_SDIOCLKCTRL_CCLK_SAMPLE_DELAY_ACTIVE_MASK |
  603. SYSCON_SDIOCLKCTRL_CCLK_SAMPLE_DELAY(SDIF_HIGHSPEED_50MHZ_SAMPLE_DELAY) |
  604. SYSCON_SDIOCLKCTRL_CCLK_DRV_DELAY_ACTIVE_MASK |
  605. SYSCON_SDIOCLKCTRL_CCLK_DRV_DELAY(SDIF_HIGHSPEED_50MHZ_DRV_DELAY);
  606. /* means the input clock = 2 * card clock,
  607. * can use clock pharse shift tech
  608. */
  609. if (divider == 1U)
  610. {
  611. SYSCON->SDIOCLKCTRL |= SYSCON_SDIOCLKCTRL_PHASE_ACTIVE_MASK |
  612. SYSCON_SDIOCLKCTRL_CCLK_SAMPLE_PHASE(kSDIF_ClcokPharseShift90) |
  613. SYSCON_SDIOCLKCTRL_CCLK_DRV_PHASE(kSDIF_ClcokPharseShift180);
  614. }
  615. }
  616. else
  617. {
  618. /*
  619. * user need to pay attention to this parameter
  620. * can be change the setting for you card and board
  621. * min hold time:5ns
  622. * min setup time: 5ns
  623. * delay = (x+1)*250ps
  624. */
  625. SYSCON->SDIOCLKCTRL = SYSCON_SDIOCLKCTRL_CCLK_SAMPLE_DELAY_ACTIVE_MASK |
  626. SYSCON_SDIOCLKCTRL_CCLK_SAMPLE_DELAY(SDIF_HIGHSPEED_25MHZ_SAMPLE_DELAY) |
  627. SYSCON_SDIOCLKCTRL_CCLK_DRV_DELAY_ACTIVE_MASK |
  628. SYSCON_SDIOCLKCTRL_CCLK_DRV_DELAY(SDIF_HIGHSPEED_25MHZ_DRV_DELAY);
  629. /* means the input clock = 2 * card clock,
  630. * can use clock pharse shift tech
  631. */
  632. if (divider == 1U)
  633. {
  634. SYSCON->SDIOCLKCTRL |= SYSCON_SDIOCLKCTRL_PHASE_ACTIVE_MASK |
  635. SYSCON_SDIOCLKCTRL_CCLK_SAMPLE_PHASE(kSDIF_ClcokPharseShift90) |
  636. SYSCON_SDIOCLKCTRL_CCLK_DRV_PHASE(kSDIF_ClcokPharseShift90);
  637. }
  638. }
  639. }
  640. uint32_t SDIF_SetCardClock(SDIF_Type *base, uint32_t srcClock_Hz, uint32_t target_HZ)
  641. {
  642. assert(srcClock_Hz <= FSL_FEATURE_SDIF_MAX_SOURCE_CLOCK);
  643. sdif_command_t cmd = {0U};
  644. uint32_t divider = 0U, targetFreq = target_HZ;
  645. /* if target freq bigger than the source clk, set the target_HZ to
  646. src clk, this interface can run up to 52MHZ with card */
  647. if (srcClock_Hz < targetFreq)
  648. {
  649. targetFreq = srcClock_Hz;
  650. }
  651. /* disable the clock first,need sync to CIU*/
  652. SDIF_EnableCardClock(base, false);
  653. /* update the clock register and wait the pre-transfer complete */
  654. cmd.flags = kSDIF_CmdUpdateClockRegisterOnly | kSDIF_WaitPreTransferComplete;
  655. SDIF_SendCommand(base, &cmd, SDIF_TIMEOUT_VALUE);
  656. /*calucate the divider*/
  657. if (targetFreq != srcClock_Hz)
  658. {
  659. divider = (srcClock_Hz / targetFreq + 1U) / 2U;
  660. }
  661. /* load the clock divider */
  662. base->CLKDIV = SDIF_CLKDIV_CLK_DIVIDER0(divider);
  663. /* update the divider to CIU */
  664. cmd.flags = kSDIF_CmdUpdateClockRegisterOnly | kSDIF_WaitPreTransferComplete;
  665. SDIF_SendCommand(base, &cmd, SDIF_TIMEOUT_VALUE);
  666. /* enable the card clock and sync to CIU */
  667. SDIF_EnableCardClock(base, true);
  668. SDIF_SendCommand(base, &cmd, SDIF_TIMEOUT_VALUE);
  669. /* config the clock delay to meet the hold time and setup time */
  670. SDIF_ConfigClockDelay(target_HZ, divider);
  671. /* return the actual card clock freq */
  672. return (divider != 0U) ? (srcClock_Hz / (divider * 2U)) : srcClock_Hz;
  673. }
  674. bool SDIF_AbortReadData(SDIF_Type *base, uint32_t timeout)
  675. {
  676. /* assert this bit to reset the data machine to abort the read data */
  677. base->CTRL |= SDIF_CTRL_ABORT_READ_DATA_MASK;
  678. /* polling the bit self clear */
  679. while ((base->CTRL & SDIF_CTRL_ABORT_READ_DATA_MASK) == SDIF_CTRL_ABORT_READ_DATA_MASK)
  680. {
  681. if (!timeout)
  682. {
  683. break;
  684. }
  685. timeout--;
  686. }
  687. return base->CTRL & SDIF_CTRL_ABORT_READ_DATA_MASK ? false : true;
  688. }
  689. status_t SDIF_InternalDMAConfig(SDIF_Type *base, sdif_dma_config_t *config, const uint32_t *data, uint32_t dataSize)
  690. {
  691. assert(NULL != config);
  692. assert(NULL != data);
  693. uint32_t dmaEntry = 0U, i, dmaBufferSize = 0U, dmaBuffer1Size = 0U;
  694. uint32_t *tempDMADesBuffer = config->dmaDesBufferStartAddr;
  695. const uint32_t *dataBuffer = data;
  696. sdif_dma_descriptor_t *descriptorPoniter = NULL;
  697. uint32_t maxDMABuffer = FSL_FEATURE_SDIF_INTERNAL_DMA_MAX_BUFFER_SIZE * (config->mode);
  698. /* check the dma descriptor buffer length , it is user's responsibility to make sure the DMA descriptor table
  699. size is bigger enough to hold the transfer descriptor */
  700. if (config->dmaDesBufferLen * sizeof(uint32_t) < sizeof(sdif_dma_descriptor_t))
  701. {
  702. return kStatus_SDIF_DescriptorBufferLenError;
  703. }
  704. /* check the read/write data size,must be a multiple of 4 */
  705. if (dataSize % sizeof(uint32_t) != 0U)
  706. {
  707. dataSize += sizeof(uint32_t) - (dataSize % sizeof(uint32_t));
  708. }
  709. /*config the bus mode*/
  710. if (config->enableFixBurstLen)
  711. {
  712. base->BMOD |= SDIF_BMOD_FB_MASK;
  713. }
  714. /* calucate the dma descriptor entry due to DMA buffer size limit */
  715. /* if datasize smaller than one descriptor buffer size */
  716. if (dataSize > maxDMABuffer)
  717. {
  718. dmaEntry = dataSize / maxDMABuffer + (dataSize % maxDMABuffer ? 1U : 0U);
  719. }
  720. else /* need one dma descriptor */
  721. {
  722. dmaEntry = 1U;
  723. }
  724. /* check the DMA descriptor buffer len one more time,it is user's responsibility to make sure the DMA descriptor
  725. table
  726. size is bigger enough to hold the transfer descriptor */
  727. if (config->dmaDesBufferLen * sizeof(uint32_t) < (dmaEntry * sizeof(sdif_dma_descriptor_t) + config->dmaDesSkipLen))
  728. {
  729. return kStatus_SDIF_DescriptorBufferLenError;
  730. }
  731. switch (config->mode)
  732. {
  733. case kSDIF_DualDMAMode:
  734. base->BMOD |= SDIF_BMOD_DSL(config->dmaDesSkipLen); /* config the distance between the DMA descriptor */
  735. for (i = 0U; i < dmaEntry; i++)
  736. {
  737. if (dataSize > FSL_FEATURE_SDIF_INTERNAL_DMA_MAX_BUFFER_SIZE)
  738. {
  739. dmaBufferSize = FSL_FEATURE_SDIF_INTERNAL_DMA_MAX_BUFFER_SIZE;
  740. dataSize -= dmaBufferSize;
  741. dmaBuffer1Size = dataSize > FSL_FEATURE_SDIF_INTERNAL_DMA_MAX_BUFFER_SIZE ?
  742. FSL_FEATURE_SDIF_INTERNAL_DMA_MAX_BUFFER_SIZE :
  743. dataSize;
  744. dataSize -= dmaBuffer1Size;
  745. }
  746. else
  747. {
  748. dmaBufferSize = dataSize;
  749. dmaBuffer1Size = 0U;
  750. }
  751. descriptorPoniter = (sdif_dma_descriptor_t *)tempDMADesBuffer;
  752. if (i == 0U)
  753. {
  754. descriptorPoniter->dmaDesAttribute = kSDIF_DMADescriptorDataBufferStart;
  755. }
  756. descriptorPoniter->dmaDesAttribute |= kSDIF_DMADescriptorOwnByDMA | kSDIF_DisableCompleteInterrupt;
  757. descriptorPoniter->dmaDataBufferSize =
  758. SDIF_DMA_DESCRIPTOR_BUFFER1_SIZE(dmaBufferSize) | SDIF_DMA_DESCRIPTOR_BUFFER2_SIZE(dmaBuffer1Size);
  759. descriptorPoniter->dmaDataBufferAddr0 = dataBuffer;
  760. descriptorPoniter->dmaDataBufferAddr1 = dataBuffer + dmaBufferSize / sizeof(uint32_t);
  761. dataBuffer += (dmaBufferSize + dmaBuffer1Size) / sizeof(uint32_t);
  762. /* descriptor skip length */
  763. tempDMADesBuffer += config->dmaDesSkipLen + sizeof(sdif_dma_descriptor_t) / sizeof(uint32_t);
  764. }
  765. /* enable the completion interrupt when reach the last descriptor */
  766. descriptorPoniter->dmaDesAttribute &= ~kSDIF_DisableCompleteInterrupt;
  767. descriptorPoniter->dmaDesAttribute |= kSDIF_DMADescriptorDataBufferEnd | kSDIF_DMADescriptorEnd;
  768. break;
  769. case kSDIF_ChainDMAMode:
  770. for (i = 0U; i < dmaEntry; i++)
  771. {
  772. if (dataSize > FSL_FEATURE_SDIF_INTERNAL_DMA_MAX_BUFFER_SIZE)
  773. {
  774. dmaBufferSize = FSL_FEATURE_SDIF_INTERNAL_DMA_MAX_BUFFER_SIZE;
  775. dataSize -= FSL_FEATURE_SDIF_INTERNAL_DMA_MAX_BUFFER_SIZE;
  776. }
  777. else
  778. {
  779. dmaBufferSize = dataSize;
  780. }
  781. descriptorPoniter = (sdif_dma_descriptor_t *)tempDMADesBuffer;
  782. if (i == 0U)
  783. {
  784. descriptorPoniter->dmaDesAttribute = kSDIF_DMADescriptorDataBufferStart;
  785. }
  786. descriptorPoniter->dmaDesAttribute |=
  787. kSDIF_DMADescriptorOwnByDMA | kSDIF_DMASecondAddrChained | kSDIF_DisableCompleteInterrupt;
  788. descriptorPoniter->dmaDataBufferSize =
  789. SDIF_DMA_DESCRIPTOR_BUFFER1_SIZE(dmaBufferSize); /* use only buffer 1 for data buffer*/
  790. descriptorPoniter->dmaDataBufferAddr0 = dataBuffer;
  791. dataBuffer += dmaBufferSize / sizeof(uint32_t);
  792. tempDMADesBuffer +=
  793. sizeof(sdif_dma_descriptor_t) / sizeof(uint32_t); /* calucate the next descriptor address */
  794. /* this descriptor buffer2 pointer to the next descriptor address */
  795. descriptorPoniter->dmaDataBufferAddr1 = tempDMADesBuffer;
  796. }
  797. /* enable the completion interrupt when reach the last descriptor */
  798. descriptorPoniter->dmaDesAttribute &= ~kSDIF_DisableCompleteInterrupt;
  799. descriptorPoniter->dmaDesAttribute |= kSDIF_DMADescriptorDataBufferEnd;
  800. break;
  801. default:
  802. break;
  803. }
  804. /* use internal DMA interface */
  805. base->CTRL |= SDIF_CTRL_USE_INTERNAL_DMAC_MASK;
  806. /* enable the internal SD/MMC DMA */
  807. base->BMOD |= SDIF_BMOD_DE_MASK;
  808. /* enable DMA status check */
  809. base->IDINTEN |= kSDIF_DMAAllStatus;
  810. /* clear write/read FIFO request interrupt in DMA mode, DMA will handle the data transfer*/
  811. SDIF_DisableInterrupt(base, kSDIF_WriteFIFORequest | kSDIF_ReadFIFORequest | kSDIF_DataTransferOver);
  812. /* load DMA descriptor buffer address */
  813. base->DBADDR = (uint32_t)config->dmaDesBufferStartAddr;
  814. return kStatus_Success;
  815. }
  816. void SDIF_Init(SDIF_Type *base, sdif_config_t *config)
  817. {
  818. assert(NULL != config);
  819. uint32_t timeout;
  820. /* enable SDIF clock */
  821. CLOCK_EnableClock(kCLOCK_Sdio);
  822. /* do software reset */
  823. base->BMOD |= SDIF_BMOD_SWR_MASK;
  824. /* reset all */
  825. SDIF_Reset(base, kSDIF_ResetAll, SDIF_TIMEOUT_VALUE);
  826. /*config timeout register */
  827. timeout = base->TMOUT;
  828. timeout &= ~(SDIF_TMOUT_RESPONSE_TIMEOUT_MASK | SDIF_TMOUT_DATA_TIMEOUT_MASK);
  829. timeout |= SDIF_TMOUT_RESPONSE_TIMEOUT(config->responseTimeout) | SDIF_TMOUT_DATA_TIMEOUT(config->dataTimeout);
  830. base->TMOUT = timeout;
  831. /* config the card detect debounce clock count */
  832. base->DEBNCE = SDIF_DEBNCE_DEBOUNCE_COUNT(config->cardDetDebounce_Clock);
  833. /*config the watermark/burst transfer value */
  834. base->FIFOTH =
  835. SDIF_FIFOTH_TX_WMARK(SDIF_TX_WATERMARK) | SDIF_FIFOTH_RX_WMARK(SDIF_RX_WATERMARK) | SDIF_FIFOTH_DMA_MTS(1U);
  836. /* enable the interrupt status */
  837. SDIF_EnableInterrupt(base, kSDIF_AllInterruptStatus);
  838. /* clear all interrupt/DMA status */
  839. SDIF_ClearInterruptStatus(base, kSDIF_AllInterruptStatus);
  840. SDIF_ClearInternalDMAStatus(base, kSDIF_DMAAllStatus);
  841. }
  842. status_t SDIF_TransferBlocking(SDIF_Type *base, sdif_dma_config_t *dmaConfig, sdif_transfer_t *transfer)
  843. {
  844. assert(NULL != transfer);
  845. bool isDMA = false;
  846. sdif_data_t *data = transfer->data;
  847. /* config the transfer parameter */
  848. if (SDIF_TransferConfig(base, transfer) != kStatus_Success)
  849. {
  850. return kStatue_SDIF_InvalidArgument;
  851. }
  852. /* if need transfer data in dma mode, config the DMA descriptor first */
  853. if ((data != NULL) && (dmaConfig != NULL))
  854. {
  855. /* use internal DMA mode to transfer between the card and host*/
  856. isDMA = true;
  857. if (SDIF_InternalDMAConfig(base, dmaConfig, data->rxData ? data->rxData : data->txData,
  858. data->blockSize * data->blockCount) != kStatus_Success)
  859. {
  860. return kStatus_SDIF_DescriptorBufferLenError;
  861. }
  862. }
  863. /* send command first */
  864. if (SDIF_SendCommand(base, transfer->command, SDIF_TIMEOUT_VALUE) != kStatus_Success)
  865. {
  866. return kStatus_SDIF_SyncCmdTimeout;
  867. }
  868. /* wait the command transfer done and check if error occurs */
  869. if (SDIF_WaitCommandDone(base, transfer->command) != kStatus_Success)
  870. {
  871. return kStatus_SDIF_SendCmdFail;
  872. }
  873. /* if use DMA transfer mode ,check the corresponding status bit */
  874. if (data != NULL)
  875. {
  876. /* check the if has DMA descriptor featch error */
  877. if (isDMA &&
  878. ((SDIF_GetInternalDMAStatus(base) & kSDIF_DMADescriptorUnavailable) == kSDIF_DMADescriptorUnavailable))
  879. {
  880. SDIF_ClearInternalDMAStatus(base, kSDIF_DMADescriptorUnavailable | kSDIF_AbnormalInterruptSummary);
  881. /* release the DMA descriptor to DMA */
  882. SDIF_ReleaseDMADescriptor(base, dmaConfig);
  883. }
  884. /* handle data transfer */
  885. if (SDIF_TransferDataBlocking(base, data, isDMA) != kStatus_Success)
  886. {
  887. return kStatus_SDIF_DataTransferFail;
  888. }
  889. }
  890. return kStatus_Success;
  891. }
  892. status_t SDIF_TransferNonBlocking(SDIF_Type *base,
  893. sdif_handle_t *handle,
  894. sdif_dma_config_t *dmaConfig,
  895. sdif_transfer_t *transfer)
  896. {
  897. assert(NULL != transfer);
  898. sdif_data_t *data = transfer->data;
  899. /* save the data and command before transfer */
  900. handle->data = transfer->data;
  901. handle->command = transfer->command;
  902. handle->transferredWords = 0U;
  903. handle->interruptFlags = 0U;
  904. handle->dmaInterruptFlags = 0U;
  905. /* config the transfer parameter */
  906. if (SDIF_TransferConfig(base, transfer) != kStatus_Success)
  907. {
  908. return kStatue_SDIF_InvalidArgument;
  909. }
  910. if ((data != NULL) && (dmaConfig != NULL))
  911. {
  912. /* use internal DMA mode to transfer between the card and host*/
  913. if (SDIF_InternalDMAConfig(base, dmaConfig, data->rxData ? data->rxData : data->txData,
  914. data->blockSize * data->blockCount) != kStatus_Success)
  915. {
  916. return kStatus_SDIF_DescriptorBufferLenError;
  917. }
  918. }
  919. /* send command first */
  920. if (SDIF_SendCommand(base, transfer->command, SDIF_TIMEOUT_VALUE) != kStatus_Success)
  921. {
  922. return kStatus_SDIF_SyncCmdTimeout;
  923. }
  924. return kStatus_Success;
  925. }
  926. void SDIF_TransferCreateHandle(SDIF_Type *base,
  927. sdif_handle_t *handle,
  928. sdif_transfer_callback_t *callback,
  929. void *userData)
  930. {
  931. assert(handle);
  932. assert(callback);
  933. /* reset the handle. */
  934. memset(handle, 0U, sizeof(*handle));
  935. /* Set the callback. */
  936. handle->callback.SDIOInterrupt = callback->SDIOInterrupt;
  937. handle->callback.DMADesUnavailable = callback->DMADesUnavailable;
  938. handle->callback.CommandReload = callback->CommandReload;
  939. handle->callback.TransferComplete = callback->TransferComplete;
  940. handle->userData = userData;
  941. /* Save the handle in global variables to support the double weak mechanism. */
  942. s_sdifHandle[SDIF_GetInstance(base)] = handle;
  943. /* save IRQ handler */
  944. s_sdifIsr = SDIF_TransferHandleIRQ;
  945. /* enable the global interrupt */
  946. SDIF_EnableGlobalInterrupt(base, true);
  947. EnableIRQ(s_sdifIRQ[SDIF_GetInstance(base)]);
  948. }
  949. void SDIF_GetCapability(SDIF_Type *base, sdif_capability_t *capability)
  950. {
  951. assert(NULL != capability);
  952. capability->sdVersion = SDIF_SUPPORT_SD_VERSION;
  953. capability->mmcVersion = SDIF_SUPPORT_MMC_VERSION;
  954. capability->maxBlockLength = SDIF_BLKSIZ_BLOCK_SIZE_MASK;
  955. /* set the max block count = max byte conut / max block size */
  956. capability->maxBlockCount = SDIF_BYTCNT_BYTE_COUNT_MASK / SDIF_BLKSIZ_BLOCK_SIZE_MASK;
  957. capability->flags = kSDIF_SupportHighSpeedFlag | kSDIF_SupportDmaFlag | kSDIF_SupportSuspendResumeFlag |
  958. kSDIF_SupportV330Flag | kSDIF_Support4BitFlag | kSDIF_Support8BitFlag;
  959. }
  960. static void SDIF_TransferHandleCommand(SDIF_Type *base, sdif_handle_t *handle, uint32_t interruptFlags)
  961. {
  962. assert(handle->command);
  963. /* transfer error */
  964. if (interruptFlags & (kSDIF_ResponseError | kSDIF_ResponseCRCError | kSDIF_ResponseTimeout))
  965. {
  966. handle->callback.TransferComplete(base, handle, kStatus_SDIF_SendCmdFail, handle->userData);
  967. }
  968. /* cmd buffer full, in this condition user need re-send the command */
  969. else if (interruptFlags & kSDIF_HardwareLockError)
  970. {
  971. if (handle->callback.CommandReload)
  972. {
  973. handle->callback.CommandReload();
  974. }
  975. }
  976. /* transfer command success */
  977. else
  978. {
  979. SDIF_ReadCommandResponse(base, handle->command);
  980. if (((handle->data) == NULL) && (handle->callback.TransferComplete))
  981. {
  982. handle->callback.TransferComplete(base, handle, kStatus_Success, handle->userData);
  983. }
  984. }
  985. }
  986. static void SDIF_TransferHandleData(SDIF_Type *base, sdif_handle_t *handle, uint32_t interruptFlags)
  987. {
  988. assert(handle->data);
  989. /* data starvation by host time out, software should read/write FIFO*/
  990. if (interruptFlags & kSDIF_DataStarvationByHostTimeout)
  991. {
  992. if (handle->data->rxData != NULL)
  993. {
  994. handle->transferredWords = SDIF_ReadDataPort(base, handle->data, handle->transferredWords);
  995. }
  996. else if (handle->data->txData != NULL)
  997. {
  998. handle->transferredWords = SDIF_WriteDataPort(base, handle->data, handle->transferredWords);
  999. }
  1000. else
  1001. {
  1002. handle->callback.TransferComplete(base, handle, kStatus_SDIF_DataTransferFail, handle->userData);
  1003. }
  1004. }
  1005. /* data transfer fail */
  1006. else if (interruptFlags & kSDIF_DataTransferError)
  1007. {
  1008. if (!handle->data->enableIgnoreError)
  1009. {
  1010. handle->callback.TransferComplete(base, handle, kStatus_SDIF_DataTransferFail, handle->userData);
  1011. }
  1012. }
  1013. /* need fill data to FIFO */
  1014. else if (interruptFlags & kSDIF_WriteFIFORequest)
  1015. {
  1016. handle->transferredWords = SDIF_WriteDataPort(base, handle->data, handle->transferredWords);
  1017. }
  1018. /* need read data from FIFO */
  1019. else if (interruptFlags & kSDIF_ReadFIFORequest)
  1020. {
  1021. handle->transferredWords = SDIF_ReadDataPort(base, handle->data, handle->transferredWords);
  1022. }
  1023. else
  1024. {
  1025. }
  1026. /* data transfer over */
  1027. if (interruptFlags & kSDIF_DataTransferOver)
  1028. {
  1029. while ((handle->data->rxData != NULL) && ((base->STATUS & SDIF_STATUS_FIFO_COUNT_MASK) != 0U))
  1030. {
  1031. handle->transferredWords = SDIF_ReadDataPort(base, handle->data, handle->transferredWords);
  1032. }
  1033. handle->callback.TransferComplete(base, handle, kStatus_Success, handle->userData);
  1034. }
  1035. }
  1036. static void SDIF_TransferHandleDMA(SDIF_Type *base, sdif_handle_t *handle, uint32_t interruptFlags)
  1037. {
  1038. if (interruptFlags & kSDIF_DMAFatalBusError)
  1039. {
  1040. handle->callback.TransferComplete(base, handle, kStatus_SDIF_DMATransferFailWithFBE, handle->userData);
  1041. }
  1042. else if (interruptFlags & kSDIF_DMADescriptorUnavailable)
  1043. {
  1044. if (handle->callback.DMADesUnavailable)
  1045. {
  1046. handle->callback.DMADesUnavailable();
  1047. }
  1048. }
  1049. else if ((interruptFlags & (kSDIF_AbnormalInterruptSummary | kSDIF_DMACardErrorSummary)) &&
  1050. (!handle->data->enableIgnoreError))
  1051. {
  1052. handle->callback.TransferComplete(base, handle, kStatus_SDIF_DataTransferFail, handle->userData);
  1053. }
  1054. /* card normal summary */
  1055. else
  1056. {
  1057. handle->callback.TransferComplete(base, handle, kStatus_Success, handle->userData);
  1058. }
  1059. }
  1060. static void SDIF_TransferHandleSDIOInterrupt(sdif_handle_t *handle)
  1061. {
  1062. if (handle->callback.SDIOInterrupt != NULL)
  1063. {
  1064. handle->callback.SDIOInterrupt();
  1065. }
  1066. }
  1067. static void SDIF_TransferHandleIRQ(SDIF_Type *base, sdif_handle_t *handle)
  1068. {
  1069. assert(handle);
  1070. uint32_t interruptFlags, dmaInterruptFlags;
  1071. interruptFlags = SDIF_GetInterruptStatus(base);
  1072. dmaInterruptFlags = SDIF_GetInternalDMAStatus(base);
  1073. handle->interruptFlags = interruptFlags;
  1074. handle->dmaInterruptFlags = dmaInterruptFlags;
  1075. if ((interruptFlags & kSDIF_CommandTransferStatus) != 0U)
  1076. {
  1077. SDIF_TransferHandleCommand(base, handle, (interruptFlags & kSDIF_CommandTransferStatus));
  1078. }
  1079. if ((interruptFlags & kSDIF_DataTransferStatus) != 0U)
  1080. {
  1081. SDIF_TransferHandleData(base, handle, (interruptFlags & kSDIF_DataTransferStatus));
  1082. }
  1083. if (interruptFlags & kSDIF_SDIOInterrupt)
  1084. {
  1085. SDIF_TransferHandleSDIOInterrupt(handle);
  1086. }
  1087. if (dmaInterruptFlags & kSDIF_DMAAllStatus)
  1088. {
  1089. SDIF_TransferHandleDMA(base, handle, dmaInterruptFlags);
  1090. }
  1091. SDIF_ClearInterruptStatus(base, interruptFlags);
  1092. SDIF_ClearInternalDMAStatus(base, dmaInterruptFlags);
  1093. }
  1094. void SDIF_Deinit(SDIF_Type *base)
  1095. {
  1096. /* disable clock here*/
  1097. CLOCK_DisableClock(kCLOCK_Sdio);
  1098. /* disable the SDIOCLKCTRL */
  1099. SYSCON->SDIOCLKCTRL &= ~(SYSCON_SDIOCLKCTRL_CCLK_SAMPLE_DELAY_ACTIVE_MASK |
  1100. SYSCON_SDIOCLKCTRL_CCLK_DRV_DELAY_ACTIVE_MASK | SYSCON_SDIOCLKCTRL_PHASE_ACTIVE_MASK);
  1101. RESET_PeripheralReset(kSDIO_RST_SHIFT_RSTn);
  1102. }
  1103. #if defined(SDIF)
  1104. #include <rthw.h>
  1105. #include <rtthread.h>
  1106. void SDIF_DriverIRQHandler(void)
  1107. {
  1108. /* enter interrupt */
  1109. rt_interrupt_enter();
  1110. assert(s_sdifHandle[0]);
  1111. s_sdifIsr(SDIF, s_sdifHandle[0]);
  1112. /* leave interrupt */
  1113. rt_interrupt_leave();
  1114. }
  1115. #endif