drv_sd.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. /*
  2. * Copyright (c) 2006-2018, 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. rt_mutex_take(&mci->lock, RT_WAITING_FOREVER);
  43. {
  44. /* non-aligned. */
  45. uint32_t i;
  46. rt_size_t sector_adr;
  47. uint8_t* copy_buffer;
  48. sector_adr = pos;
  49. copy_buffer = (uint8_t*)buffer;
  50. for(i=0; i<size; i++)
  51. {
  52. status=SD_ReadBlocks(&mci->card, sdio_buffer, sector_adr, 1);
  53. memcpy(copy_buffer, sdio_buffer, mci->card.blockSize);
  54. sector_adr ++;
  55. copy_buffer += mci->card.blockSize;
  56. }
  57. }
  58. rt_mutex_release(&_mci_device->lock);
  59. if (status == kStatus_Success) return size;
  60. return 0;
  61. }
  62. static rt_size_t rt_mci_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
  63. {
  64. rt_uint8_t status = kStatus_Success;
  65. struct mci_device *mci = (struct mci_device *)dev;
  66. rt_mutex_take(&mci->lock, RT_WAITING_FOREVER);
  67. {
  68. /* non-aligned. */
  69. uint32_t i;
  70. rt_size_t sector_adr;
  71. uint8_t* copy_buffer;
  72. sector_adr = pos;
  73. copy_buffer = (uint8_t*)buffer;
  74. for(i = 0; i < size; i++)
  75. {
  76. memcpy(sdio_buffer, copy_buffer, mci->card.blockSize);
  77. status = SD_WriteBlocks(&mci->card, sdio_buffer, sector_adr, 1);
  78. sector_adr ++;
  79. copy_buffer += mci->card.blockSize;
  80. }
  81. }
  82. /* release and exit */
  83. rt_mutex_release(&_mci_device->lock);
  84. if (status == kStatus_Success) return size;
  85. return 0;
  86. }
  87. static rt_err_t rt_mci_control(rt_device_t dev, int cmd, void *args)
  88. {
  89. struct mci_device *mci = (struct mci_device *)dev;
  90. RT_ASSERT(dev != RT_NULL);
  91. if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
  92. {
  93. struct rt_device_blk_geometry *geometry;
  94. geometry = (struct rt_device_blk_geometry *)args;
  95. if (geometry == RT_NULL) return -RT_ERROR;
  96. geometry->bytes_per_sector = mci->card.blockSize;
  97. geometry->block_size = mci->card.csd.eraseSectorSize;
  98. geometry->sector_count = mci->card.blockCount;
  99. }
  100. return RT_EOK;
  101. }
  102. /*! @brief SDMMC host detect card configuration */
  103. static const sdmmchost_detect_card_t s_sdCardDetect = {
  104. .cdType = BOARD_SD_DETECT_TYPE,
  105. .cdTimeOut_ms = (~0U),
  106. };
  107. /*! @brief Card descriptor. */
  108. sd_card_t g_sd;
  109. int rt_hw_mci_init(void)
  110. {
  111. _mci_device = (struct mci_device *)rt_malloc(sizeof(struct mci_device));
  112. if (_mci_device == RT_NULL)
  113. {
  114. rt_kprintf("mci_hw_init _mci_device rt_malloc failed!\n");
  115. return -RT_ERROR;
  116. }
  117. rt_memset(_mci_device, 0, sizeof(struct mci_device));
  118. /* attach main clock to SDIF */
  119. CLOCK_AttachClk(kMAIN_CLK_to_SDIO_CLK);
  120. /* need call this function to clear the halt bit in clock divider register */
  121. CLOCK_SetClkDiv(kCLOCK_DivSdioClk, (uint32_t)(SystemCoreClock / FSL_FEATURE_SDIF_MAX_SOURCE_CLOCK + 1U), true);
  122. _mci_device->card = g_sd;
  123. /* Save host information. */
  124. _mci_device->card.host.base = SDIF;
  125. _mci_device->card.host.sourceClock_Hz = CLOCK_GetFreq(kCLOCK_SDio);
  126. _mci_device->card.usrParam.cd = &s_sdCardDetect;
  127. #if 1
  128. rt_kprintf("\r\nNeed wait a few seconds to SD init, Better Set SystemTick as 1000\r\n");
  129. rt_kprintf("SDCard Freq %d\r\n", _mci_device->card.host.sourceClock_Hz);
  130. #endif
  131. if (kStatus_Success != SD_HostInit(&_mci_device->card))
  132. {
  133. memset(&_mci_device->card, 0U, sizeof(_mci_device->card));
  134. rt_kprintf("SD_Init failed!\n");
  135. return -RT_ERROR;
  136. }
  137. /* power off card */
  138. SD_PowerOffCard(_mci_device->card.host.base, _mci_device->card.usrParam.pwr);
  139. /* check SD card insert */
  140. if(BOARD_SDIF_CD_STATUS() == true)
  141. {
  142. rt_kprintf("\r\nCard detect fail.\r\n");
  143. return kStatus_Fail;
  144. }
  145. /* wait card insert */
  146. if (SD_WaitCardDetectStatus(_mci_device->card.host.base, &s_sdCardDetect, true) == kStatus_Success)
  147. {
  148. /* reset host once card re-plug in */
  149. SD_HostReset(&(_mci_device->card.host));
  150. /* power on the card */
  151. SD_PowerOnCard(_mci_device->card.host.base, _mci_device->card.usrParam.pwr);
  152. }
  153. else
  154. {
  155. rt_kprintf("\r\nCard detect fail.\r\n");
  156. return kStatus_Fail;
  157. }
  158. /* Init card. */
  159. if (SD_CardInit(&_mci_device->card))
  160. {
  161. rt_kprintf("\r\nSD card init failed.\r\n");
  162. return kStatus_Fail;
  163. }
  164. /* initialize mutex lock */
  165. rt_mutex_init(&_mci_device->lock, "sdcard0", RT_IPC_FLAG_FIFO);
  166. /* create finish event */
  167. _mci_device->finish_event = rt_event_create("sdcard0", RT_IPC_FLAG_FIFO);
  168. /* register sdcard device */
  169. _mci_device->parent.type = RT_Device_Class_Block;
  170. _mci_device->geometry.bytes_per_sector = 0;
  171. _mci_device->geometry.sector_count = 0;
  172. _mci_device->geometry.block_size = 0;
  173. _mci_device->parent.init = rt_mci_init;
  174. _mci_device->parent.open = rt_mci_open;
  175. _mci_device->parent.close = rt_mci_close;
  176. _mci_device->parent.read = rt_mci_read;
  177. _mci_device->parent.write = rt_mci_write;
  178. _mci_device->parent.control = rt_mci_control;
  179. /* no private, no callback */
  180. _mci_device->parent.user_data = RT_NULL;
  181. _mci_device->parent.rx_indicate = RT_NULL;
  182. _mci_device->parent.tx_complete = RT_NULL;
  183. rt_device_register(&_mci_device->parent, "sdcard0",
  184. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE );
  185. return 0;
  186. }
  187. INIT_DEVICE_EXPORT(rt_hw_mci_init);
  188. #endif /* endif RT_USING_SDIO */