drv_sd.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2017-08-08 Yang the first version
  9. * 2019-07-19 Magicoe The first version for LPC55S6x
  10. */
  11. #include <string.h>
  12. #include <board.h>
  13. #include "fsl_common.h"
  14. #include "fsl_iocon.h"
  15. #include "fsl_sdif.h"
  16. #include "fsl_sd.h"
  17. #include "drv_sd.h"
  18. #include <finsh.h>
  19. #include <dfs.h>
  20. #include <dfs_fs.h>
  21. #include "board.h"
  22. static struct mci_device *_mci_device;
  23. static uint8_t sdio_buffer[1024];
  24. #ifdef RT_USING_SDIO
  25. static rt_err_t rt_mci_init(rt_device_t dev)
  26. {
  27. rt_err_t result = RT_EOK;
  28. return result;
  29. }
  30. static rt_err_t rt_mci_open(rt_device_t dev, rt_uint16_t oflag)
  31. {
  32. return RT_EOK;
  33. }
  34. static rt_err_t rt_mci_close(rt_device_t dev)
  35. {
  36. return RT_EOK;
  37. }
  38. static rt_size_t rt_mci_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
  39. {
  40. rt_uint8_t status = kStatus_Success;
  41. struct mci_device *mci = (struct mci_device *)dev;
  42. int ret;
  43. ret = rt_mutex_take(&mci->lock, RT_WAITING_FOREVER);
  44. if (ret == -RT_ETIMEOUT)
  45. {
  46. rt_kprintf("Take mutex time out.\n");
  47. return ret;
  48. }
  49. else if (ret == -RT_ERROR)
  50. {
  51. rt_kprintf("Take mutex error.\n");
  52. return ret;
  53. }
  54. {
  55. /* non-aligned. */
  56. uint32_t i;
  57. rt_size_t sector_adr;
  58. uint8_t* copy_buffer;
  59. sector_adr = pos;
  60. copy_buffer = (uint8_t*)buffer;
  61. for(i=0; i<size; i++)
  62. {
  63. status = SD_ReadBlocks(&mci->card, sdio_buffer, sector_adr, 1);
  64. memcpy(copy_buffer, sdio_buffer, mci->card.blockSize);
  65. sector_adr ++;
  66. copy_buffer += mci->card.blockSize;
  67. }
  68. }
  69. rt_mutex_release(&_mci_device->lock);
  70. if (status == kStatus_Success) return size;
  71. return 0;
  72. }
  73. static rt_size_t rt_mci_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
  74. {
  75. rt_uint8_t status = kStatus_Success;
  76. struct mci_device *mci = (struct mci_device *)dev;
  77. int ret;
  78. ret = rt_mutex_take(&mci->lock, RT_WAITING_FOREVER);
  79. if (ret == -RT_ETIMEOUT)
  80. {
  81. rt_kprintf("Take mutex time out.\n");
  82. return ret;
  83. }
  84. else if (ret == -RT_ERROR)
  85. {
  86. rt_kprintf("Take mutex error.\n");
  87. return ret;
  88. }
  89. {
  90. /* non-aligned. */
  91. uint32_t i;
  92. rt_size_t sector_adr;
  93. uint8_t* copy_buffer;
  94. sector_adr = pos;
  95. copy_buffer = (uint8_t*)buffer;
  96. for(i = 0; i < size; i++)
  97. {
  98. memcpy(sdio_buffer, copy_buffer, mci->card.blockSize);
  99. status = SD_WriteBlocks(&mci->card, sdio_buffer, sector_adr, 1);
  100. sector_adr ++;
  101. copy_buffer += mci->card.blockSize;
  102. }
  103. }
  104. /* release and exit */
  105. rt_mutex_release(&_mci_device->lock);
  106. if (status == kStatus_Success) return size;
  107. return 0;
  108. }
  109. static rt_err_t rt_mci_control(rt_device_t dev, int cmd, void *args)
  110. {
  111. struct mci_device *mci = (struct mci_device *)dev;
  112. RT_ASSERT(dev != RT_NULL);
  113. if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
  114. {
  115. struct rt_device_blk_geometry *geometry;
  116. geometry = (struct rt_device_blk_geometry *)args;
  117. if (geometry == RT_NULL) return -RT_ERROR;
  118. geometry->bytes_per_sector = mci->card.blockSize;
  119. geometry->block_size = mci->card.csd.eraseSectorSize;
  120. geometry->sector_count = mci->card.blockCount;
  121. }
  122. return RT_EOK;
  123. }
  124. /*! @brief SDMMC host detect card configuration */
  125. static const sdmmchost_detect_card_t s_sdCardDetect = {
  126. .cdType = BOARD_SD_DETECT_TYPE,
  127. .cdTimeOut_ms = (~0U),
  128. };
  129. /*! @brief Card descriptor. */
  130. sd_card_t g_sd;
  131. int rt_hw_mci_init(void)
  132. {
  133. _mci_device = (struct mci_device *)rt_malloc(sizeof(struct mci_device));
  134. if (_mci_device == RT_NULL)
  135. {
  136. rt_kprintf("mci_hw_init _mci_device rt_malloc failed!\n");
  137. return -RT_ERROR;
  138. }
  139. rt_memset(_mci_device, 0, sizeof(struct mci_device));
  140. /* attach main clock to SDIF */
  141. CLOCK_AttachClk(kMAIN_CLK_to_SDIO_CLK);
  142. /* need call this function to clear the halt bit in clock divider register */
  143. CLOCK_SetClkDiv(kCLOCK_DivSdioClk, (uint32_t)(SystemCoreClock / FSL_FEATURE_SDIF_MAX_SOURCE_CLOCK + 1U), true);
  144. _mci_device->card = g_sd;
  145. /* Save host information. */
  146. _mci_device->card.host.base = SDIF;
  147. _mci_device->card.host.sourceClock_Hz = CLOCK_GetFreq(kCLOCK_SDio);
  148. _mci_device->card.usrParam.cd = &s_sdCardDetect;
  149. #if 1
  150. rt_kprintf("\r\nNeed wait a few seconds to SD init, Better Set SystemTick as 1000\r\n");
  151. rt_kprintf("SDCard Freq %d\r\n", _mci_device->card.host.sourceClock_Hz);
  152. #endif
  153. if (kStatus_Success != SD_HostInit(&_mci_device->card))
  154. {
  155. memset(&_mci_device->card, 0U, sizeof(_mci_device->card));
  156. rt_kprintf("SD_Init failed!\n");
  157. return -RT_ERROR;
  158. }
  159. /* power off card */
  160. SD_PowerOffCard(_mci_device->card.host.base, _mci_device->card.usrParam.pwr);
  161. /* check SD card insert */
  162. if(BOARD_SDIF_CD_STATUS() == true)
  163. {
  164. rt_kprintf("\r\nCard detect fail.\r\n");
  165. return kStatus_Fail;
  166. }
  167. /* wait card insert */
  168. if (SD_WaitCardDetectStatus(_mci_device->card.host.base, &s_sdCardDetect, true) == kStatus_Success)
  169. {
  170. /* reset host once card re-plug in */
  171. SD_HostReset(&(_mci_device->card.host));
  172. /* power on the card */
  173. SD_PowerOnCard(_mci_device->card.host.base, _mci_device->card.usrParam.pwr);
  174. }
  175. else
  176. {
  177. rt_kprintf("\r\nCard detect fail.\r\n");
  178. return kStatus_Fail;
  179. }
  180. /* Init card. */
  181. if (SD_CardInit(&_mci_device->card))
  182. {
  183. rt_kprintf("\r\nSD card init failed.\r\n");
  184. return kStatus_Fail;
  185. }
  186. /* initialize mutex lock */
  187. rt_mutex_init(&_mci_device->lock, "sdcard0", RT_IPC_FLAG_PRIO);
  188. /* create finish event */
  189. _mci_device->finish_event = rt_event_create("sdcard0", RT_IPC_FLAG_FIFO);
  190. /* register sdcard device */
  191. _mci_device->parent.type = RT_Device_Class_Block;
  192. _mci_device->geometry.bytes_per_sector = 0;
  193. _mci_device->geometry.sector_count = 0;
  194. _mci_device->geometry.block_size = 0;
  195. _mci_device->parent.init = rt_mci_init;
  196. _mci_device->parent.open = rt_mci_open;
  197. _mci_device->parent.close = rt_mci_close;
  198. _mci_device->parent.read = rt_mci_read;
  199. _mci_device->parent.write = rt_mci_write;
  200. _mci_device->parent.control = rt_mci_control;
  201. /* no private, no callback */
  202. _mci_device->parent.user_data = RT_NULL;
  203. _mci_device->parent.rx_indicate = RT_NULL;
  204. _mci_device->parent.tx_complete = RT_NULL;
  205. rt_device_register(&_mci_device->parent, "sdcard0",
  206. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE );
  207. return 0;
  208. }
  209. INIT_DEVICE_EXPORT(rt_hw_mci_init);
  210. #endif /* endif RT_USING_SDIO */