drv_sdcard.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  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. * 2020-07-04 thread-liu the first version
  9. */
  10. #include "board.h"
  11. #if defined(BSP_USING_SDCARD)
  12. #include <dfs_fs.h>
  13. #define DRV_DEBUG
  14. //#define SDMMC_TX_DUMP
  15. //#define SDMMC_RX_DUMP
  16. #define LOG_TAG "drv.sdmmc"
  17. #include <drv_log.h>
  18. static SD_HandleTypeDef SDCARD_Handler = {0};
  19. static HAL_SD_CardInfoTypeDef SDCardInfo = {0};
  20. struct stm32_sd
  21. {
  22. struct rt_device sdcard;
  23. struct rt_semaphore sd_lock;
  24. volatile rt_uint8_t write_flage;
  25. volatile rt_uint8_t read_flage;
  26. volatile rt_base_t level;
  27. };
  28. static struct stm32_sd sd_device;
  29. #define SD_TIMEOUT ((uint32_t)30 * 1000)
  30. #define DETECT_PIN GET_PIN(G, 1)
  31. #define LDO_PIN GET_PIN(F, 14)
  32. struct rt_completion tx_comp;
  33. struct rt_completion rx_comp;
  34. /* SYSRAM SDMMC1/2 accesses */
  35. #define SDIO_BUFF_SIZE 512
  36. #define SDCARD_ADDR 0x2FFC0000
  37. #if defined(__ARMCC_VERSION)
  38. __attribute__((at(SDCARD_ADDR))) static rt_uint32_t cache_buf[SDIO_BUFF_SIZE];
  39. #elif defined ( __GNUC__ )
  40. static rt_uint32_t cache_buf[SDIO_BUFF_SIZE] __attribute__((section(".SdCardSection")));
  41. #elif defined(__ICCARM__)
  42. #pragma location = SDCARD_ADDR
  43. __no_init static rt_uint32_t cache_buf[SDIO_BUFF_SIZE];
  44. #endif
  45. #if defined(SDMMC_RX_DUMP) || defined(SDMMC_TX_DUMP)
  46. #define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
  47. static void dump_hex(const rt_uint8_t *ptr, rt_size_t buflen)
  48. {
  49. unsigned char *buf = (unsigned char *)ptr;
  50. int i, j;
  51. for (i = 0; i < buflen; i += 16)
  52. {
  53. rt_kprintf("%08X: ", i);
  54. for (j = 0; j < 16; j++)
  55. if (i + j < buflen)
  56. rt_kprintf("%02X ", buf[i + j]);
  57. else
  58. rt_kprintf(" ");
  59. rt_kprintf(" ");
  60. for (j = 0; j < 16; j++)
  61. if (i + j < buflen)
  62. rt_kprintf("%c", __is_print(buf[i + j]) ? buf[i + j] : '.');
  63. rt_kprintf("\n");
  64. }
  65. }
  66. #endif
  67. static rt_err_t rt_hw_sd_is_detected(void)
  68. {
  69. return rt_pin_read(DETECT_PIN);
  70. }
  71. static rt_err_t rt_hw_sd_init(void)
  72. {
  73. /* sd ldo*/
  74. rt_pin_mode(LDO_PIN, PIN_MODE_OUTPUT);
  75. /* sd detect */
  76. rt_pin_mode(DETECT_PIN, PIN_MODE_INPUT_PULLUP);
  77. /* judge we have a sd card */
  78. if (rt_hw_sd_is_detected() != 0x00)
  79. {
  80. LOG_E("can't find sd card!");
  81. return RT_ERROR;
  82. }
  83. SDCARD_Handler.Instance = SDMMC1;
  84. HAL_SD_DeInit(&SDCARD_Handler);
  85. /* if CLKDIV = 0 then SDMMC Clock frequency = SDMMC Kernel Clock
  86. else SDMMC Clock frequency = SDMMC Kernel Clock / [2 * CLKDIV].
  87. SDMMC Kernel Clock = 99MHz, SDMMC Clock frequency = 50MHz */
  88. SDCARD_Handler.Init.ClockDiv = 1;
  89. SDCARD_Handler.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
  90. SDCARD_Handler.Init.ClockEdge = SDMMC_CLOCK_EDGE_FALLING;
  91. SDCARD_Handler.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
  92. SDCARD_Handler.Init.BusWide = SDMMC_BUS_WIDE_4B;
  93. if (HAL_SD_Init(&SDCARD_Handler) != RT_EOK)
  94. {
  95. LOG_E("sd device init error!");
  96. return RT_ERROR;
  97. }
  98. if (HAL_SD_ConfigWideBusOperation(&SDCARD_Handler, SDMMC_BUS_WIDE_4B) != RT_EOK)
  99. {
  100. LOG_E("sd bus config error!");
  101. return RT_ERROR;
  102. }
  103. if (HAL_SD_GetCardInfo(&SDCARD_Handler, &SDCardInfo) != RT_EOK)
  104. {
  105. LOG_E("sd get card info error!");
  106. return RT_ERROR;
  107. }
  108. rt_thread_mdelay(100);
  109. if(HAL_SD_GetCardState(&SDCARD_Handler) != HAL_SD_CARD_TRANSFER)
  110. {
  111. LOG_E("sd get card state error!");
  112. return RT_ERROR;
  113. }
  114. return RT_EOK;
  115. }
  116. static void rt_hw_sd_deinit(void)
  117. {
  118. HAL_SD_DeInit(&SDCARD_Handler);
  119. }
  120. static rt_err_t sdcard_wait_ok(void)
  121. {
  122. rt_uint32_t tick_start = 0;
  123. tick_start = rt_tick_get();
  124. while ((rt_tick_get() - tick_start) < SD_TIMEOUT)
  125. {
  126. if (HAL_SD_GetCardState(&SDCARD_Handler) == HAL_SD_CARD_TRANSFER)
  127. {
  128. return HAL_OK;
  129. }
  130. }
  131. return HAL_ERROR;
  132. }
  133. void HAL_SD_DriveTransceiver_1_8V_Callback(FlagStatus status)
  134. {
  135. if (status == SET)
  136. {
  137. rt_pin_write(LDO_PIN, PIN_HIGH);
  138. }
  139. else
  140. {
  141. rt_pin_write(LDO_PIN, PIN_LOW);
  142. }
  143. }
  144. static rt_err_t rt_sdcard_init(rt_device_t dev)
  145. {
  146. RT_ASSERT(dev != RT_NULL);
  147. struct stm32_sd *sd = (struct stm32_sd *)dev;
  148. if (rt_sem_init(&sd->sd_lock, "sdlock", 1, RT_IPC_FLAG_FIFO) != RT_EOK)
  149. {
  150. LOG_E("init sd lock semaphore failed\n");
  151. }
  152. return RT_EOK;
  153. }
  154. static rt_err_t rt_sdcard_open(rt_device_t dev, rt_uint16_t oflag)
  155. {
  156. RT_ASSERT(dev != RT_NULL);
  157. return RT_EOK;
  158. }
  159. static rt_err_t rt_sdcard_close(rt_device_t dev)
  160. {
  161. RT_ASSERT(dev != RT_NULL);
  162. return RT_EOK;
  163. }
  164. /**
  165. * @brief Reads Sector(s)
  166. * @param dev : sd dev
  167. * @param sector: Sector address (LBA) Data buffer to store read data
  168. * @param *buffer: Data buffer to store read data
  169. * @param count: Number of sectors to read (1..128)
  170. * @retval DRESULT: Operation result
  171. */
  172. static rt_size_t rt_sdcard_read(rt_device_t dev, rt_off_t sector, void *buffer, rt_size_t count)
  173. {
  174. RT_ASSERT(dev != RT_NULL);
  175. struct stm32_sd *sd = (struct stm32_sd *)dev;
  176. rt_uint8_t ret = RT_EOK;
  177. volatile uint32_t tickstart = 0;
  178. sd->read_flage = 0;
  179. rt_memset(cache_buf, 0x00, BLOCKSIZE * count);
  180. ret = sdcard_wait_ok();
  181. if (ret != RT_EOK)
  182. {
  183. LOG_D("sdmmc busy!");
  184. return 0;
  185. }
  186. rt_sem_take(&sd->sd_lock, RT_WAITING_FOREVER);
  187. ret = HAL_SD_ReadBlocks_DMA(&SDCARD_Handler, (rt_uint8_t *)cache_buf, (uint32_t)sector, count);
  188. rt_sem_release(&sd->sd_lock);
  189. /* Wait that writing process is completed or a timeout occurs */
  190. tickstart = rt_tick_get();
  191. if (ret == HAL_OK)
  192. {
  193. while ((sd->read_flage == 0) && (rt_tick_get() - tickstart) < SD_TIMEOUT)
  194. {
  195. }
  196. /* over time */
  197. if (sd->read_flage == 0)
  198. {
  199. return 0;
  200. }
  201. else
  202. {
  203. sd->read_flage = 0;
  204. tickstart = rt_tick_get();
  205. while ((rt_tick_get() - tickstart) < SD_TIMEOUT)
  206. {
  207. if (sdcard_wait_ok() == RT_EOK)
  208. {
  209. sd->level=rt_hw_interrupt_disable();
  210. rt_memcpy((rt_uint8_t *)(buffer), cache_buf, BLOCKSIZE * count);
  211. rt_hw_interrupt_enable(sd->level);
  212. #if defined(SDMMC_RX_DUMP)
  213. rt_kprintf("\nsd rx: \n");
  214. dump_hex(cache_buf, BLOCKSIZE * count);
  215. #endif
  216. return count;
  217. }
  218. }
  219. }
  220. }
  221. return 0;
  222. }
  223. /**
  224. * @brief Writes block(s) to a specified address in an SD card, in DMA mode.
  225. * @param dev SD device
  226. * @param sector Block index from where data is to be written P
  227. * @param *buffer Pointer to the buffer that will contain the data to transmit
  228. * @param count Number of SD blocks to write
  229. * @retval BSP status
  230. */
  231. static rt_size_t rt_sdcard_write(rt_device_t dev, rt_off_t sector, const void *buffer, rt_size_t count)
  232. {
  233. RT_ASSERT(dev != RT_NULL);
  234. struct stm32_sd *sd = (struct stm32_sd *)dev;
  235. rt_uint32_t i = 0;
  236. rt_uint8_t ret = RT_EOK;
  237. for (i = 0; i < count; i++)
  238. {
  239. sd->level = rt_hw_interrupt_disable();
  240. rt_memset(cache_buf, 0x00, BLOCKSIZE);
  241. rt_memcpy(cache_buf, (rt_uint32_t *)((uintptr_t)buffer + BLOCKSIZE * i), BLOCKSIZE);
  242. rt_hw_interrupt_enable(sd->level);
  243. #if defined(SDMMC_TX_DUMP)
  244. rt_kprintf("\nsd tx: \n");
  245. dump_hex(cache_buf, BLOCKSIZE);
  246. #endif
  247. ret = sdcard_wait_ok();
  248. if (ret != RT_EOK)
  249. {
  250. LOG_D("sdmmc busy!");
  251. return 0;
  252. }
  253. rt_completion_init(&tx_comp);
  254. ret = HAL_SD_WriteBlocks_DMA(&SDCARD_Handler, (rt_uint8_t *)cache_buf, (rt_uint32_t)(sector + i), 1);
  255. if (ret != HAL_OK)
  256. {
  257. rt_kprintf("sd write error!\n");
  258. return 0;
  259. }
  260. rt_completion_wait(&tx_comp,RT_WAITING_FOREVER);
  261. }
  262. return count;
  263. }
  264. static rt_err_t rt_sdcard_control(rt_device_t dev, int cmd, void *args)
  265. {
  266. RT_ASSERT(dev != RT_NULL);
  267. if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
  268. {
  269. struct rt_device_blk_geometry *geometry;
  270. geometry = (struct rt_device_blk_geometry *)args;
  271. geometry->bytes_per_sector = 512;
  272. geometry->block_size = SDCARD_Handler.SdCard.BlockSize;
  273. geometry->sector_count = SDCARD_Handler.SdCard.BlockNbr;
  274. }
  275. return RT_EOK;
  276. }
  277. void SDMMC1_IRQHandler(void)
  278. {
  279. rt_interrupt_enter();
  280. HAL_SD_IRQHandler(&SDCARD_Handler);
  281. rt_interrupt_leave();
  282. }
  283. void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd)
  284. {
  285. if (hsd->Instance == SDCARD_Handler.Instance)
  286. {
  287. sd_device.read_flage = 1;
  288. }
  289. }
  290. void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd)
  291. {
  292. if (hsd->Instance == SDCARD_Handler.Instance)
  293. {
  294. rt_completion_done(&tx_comp);
  295. }
  296. }
  297. int rt_hw_sdcard_init(void)
  298. {
  299. if (rt_hw_sd_init() != RT_EOK)
  300. {
  301. rt_hw_sd_deinit();
  302. LOG_E("sdcard init failed");
  303. return RT_ERROR;
  304. }
  305. /* register sdcard device */
  306. sd_device.sdcard.type = RT_Device_Class_Block;
  307. sd_device.sdcard.init = rt_sdcard_init;
  308. sd_device.sdcard.open = rt_sdcard_open;
  309. sd_device.sdcard.close = rt_sdcard_close;
  310. sd_device.sdcard.read = rt_sdcard_read;
  311. sd_device.sdcard.write = rt_sdcard_write;
  312. sd_device.sdcard.control = rt_sdcard_control;
  313. /* no private */
  314. sd_device.sdcard.user_data = &SDCardInfo;
  315. rt_device_register(&sd_device.sdcard, "sd_card", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
  316. LOG_I("sd card init success!");
  317. return RT_EOK;
  318. }
  319. INIT_DEVICE_EXPORT(rt_hw_sdcard_init);
  320. #if defined(BSP_USING_SDCARD_FS)
  321. int mnt_init(void)
  322. {
  323. rt_device_t sd_dev = RT_NULL;
  324. LOG_I("init sd card file system.");
  325. #if defined(SDMMC_RX_DUMP) || defined(SDMMC_TX_DUMP)
  326. rt_thread_delay(3000);
  327. #else
  328. rt_thread_delay(RT_TICK_PER_SECOND);
  329. #endif
  330. sd_dev = rt_device_find("sd_card");
  331. if (sd_dev == RT_NULL)
  332. {
  333. LOG_E("can't find sd deivce name!");
  334. return RT_ERROR;
  335. }
  336. if (dfs_mount("sd_card", "/", "elm", 0, 0) != 0)
  337. {
  338. rt_kprintf("file system mount failed!\n");
  339. }
  340. else
  341. {
  342. rt_kprintf("file system mount success!\n");
  343. }
  344. return 0;
  345. }
  346. INIT_APP_EXPORT(mnt_init);
  347. #endif
  348. #endif