drv_sdio_sd.c 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. #include "drv_sdio_sd.h"
  2. #include "string.h"
  3. #include <rtthread.h>
  4. #define SD_TIMEOUT (1000000U)
  5. #define SECTOR_SIZE 512
  6. //#define SD_DMA_MODE 1
  7. #define DEBUG
  8. #ifdef RT_USING_DFS
  9. #include <dfs_fs.h>
  10. static SD_HandleTypeDef hsd;
  11. static HAL_SD_CardInfoTypedef sdcard_info;
  12. static rt_uint32_t _sdcard_buffer[SECTOR_SIZE / sizeof(rt_uint32_t)];
  13. static struct rt_device sdcard_device;
  14. static struct rt_semaphore sd_lock;
  15. #ifdef SD_DMA_MODE
  16. static DMA_HandleTypeDef SDTxDMAHandler,SDRxDMAHandler;
  17. #endif
  18. #ifdef DEBUG
  19. #define DEBUG_PRINTF(...) rt_kprintf(__VA_ARGS__)
  20. #else
  21. #define DEBUG_PRINTF(...)
  22. #endif
  23. rt_err_t sdio_sd_init(void)
  24. {
  25. hsd.Instance = SDIO;
  26. hsd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
  27. hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
  28. hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
  29. hsd.Init.BusWide = SDIO_BUS_WIDE_1B;
  30. hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
  31. hsd.Init.ClockDiv = SDIO_INIT_CLK_DIV;
  32. if (HAL_SD_Init(&hsd, &sdcard_info) != HAL_OK)
  33. return RT_ERROR;
  34. if(HAL_SD_WideBusOperation_Config(&hsd, SDIO_BUS_WIDE_4B) != HAL_OK)
  35. return RT_ERROR;
  36. return RT_EOK;
  37. }
  38. void HAL_SD_MspInit(SD_HandleTypeDef *hsd)
  39. {
  40. DMA_HandleTypeDef TxDMAHandler,RxDMAHandler;
  41. GPIO_InitTypeDef GPIO_Initure;
  42. __HAL_RCC_SDIO_CLK_ENABLE();
  43. #if (SD_DMA_MODE == 1)
  44. __HAL_RCC_DMA2_CLK_ENABLE();
  45. #endif
  46. __HAL_RCC_GPIOC_CLK_ENABLE();
  47. __HAL_RCC_GPIOD_CLK_ENABLE();
  48. //PC8,9,10,11,12
  49. GPIO_Initure.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12;
  50. GPIO_Initure.Mode = GPIO_MODE_AF_PP;
  51. GPIO_Initure.Pull = GPIO_PULLUP;
  52. GPIO_Initure.Speed = GPIO_SPEED_HIGH;
  53. GPIO_Initure.Alternate = GPIO_AF12_SDIO;
  54. HAL_GPIO_Init(GPIOC, &GPIO_Initure);
  55. //PD2
  56. GPIO_Initure.Pin = GPIO_PIN_2;
  57. HAL_GPIO_Init(GPIOD,&GPIO_Initure);
  58. #if (SD_DMA_MODE==1) //使用DMA模式
  59. HAL_NVIC_SetPriority(SDMMC1_IRQn,2,0); //配置SDMMC1中断,抢占优先级2,子优先级0
  60. HAL_NVIC_EnableIRQ(SDMMC1_IRQn); //使能SDMMC1中断
  61. //配置发送DMA
  62. SDRxDMAHandler.Instance = DMA2_Stream3;
  63. SDRxDMAHandler.Init.Channel = DMA_CHANNEL_4;
  64. SDRxDMAHandler.Init.Direction = DMA_PERIPH_TO_MEMORY;
  65. SDRxDMAHandler.Init.PeriphInc = DMA_PINC_DISABLE;
  66. SDRxDMAHandler.Init.MemInc = DMA_MINC_ENABLE;
  67. SDRxDMAHandler.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
  68. SDRxDMAHandler.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
  69. SDRxDMAHandler.Init.Mode = DMA_PFCTRL;
  70. SDRxDMAHandler.Init.Priority = DMA_PRIORITY_VERY_HIGH;
  71. SDRxDMAHandler.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
  72. SDRxDMAHandler.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
  73. SDRxDMAHandler.Init.MemBurst = DMA_MBURST_INC4;
  74. SDRxDMAHandler.Init.PeriphBurst = DMA_PBURST_INC4;
  75. __HAL_LINKDMA(hsd, hdmarx, SDRxDMAHandler); //将接收DMA和SD卡的发送DMA连接起来
  76. HAL_DMA_DeInit(&SDRxDMAHandler);
  77. HAL_DMA_Init(&SDRxDMAHandler); //初始化接收DMA
  78. //配置接收DMA
  79. SDTxDMAHandler.Instance = DMA2_Stream6;
  80. SDTxDMAHandler.Init.Channel = DMA_CHANNEL_4;
  81. SDTxDMAHandler.Init.Direction = DMA_MEMORY_TO_PERIPH;
  82. SDTxDMAHandler.Init.PeriphInc = DMA_PINC_DISABLE;
  83. SDTxDMAHandler.Init.MemInc = DMA_MINC_ENABLE;
  84. SDTxDMAHandler.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
  85. SDTxDMAHandler.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
  86. SDTxDMAHandler.Init.Mode = DMA_PFCTRL;
  87. SDTxDMAHandler.Init.Priority = DMA_PRIORITY_VERY_HIGH;
  88. SDTxDMAHandler.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
  89. SDTxDMAHandler.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
  90. SDTxDMAHandler.Init.MemBurst = DMA_MBURST_INC4;
  91. SDTxDMAHandler.Init.PeriphBurst = DMA_PBURST_INC4;
  92. __HAL_LINKDMA(hsd, hdmatx, SDTxDMAHandler);//将发送DMA和SD卡的发送DMA连接起来
  93. HAL_DMA_DeInit(&SDTxDMAHandler);
  94. HAL_DMA_Init(&SDTxDMAHandler); //初始化发送DMA
  95. HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 3, 0); //接收DMA中断优先级
  96. HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
  97. HAL_NVIC_SetPriority(DMA2_Stream6_IRQn, 3, 0); //发送DMA中断优先级
  98. HAL_NVIC_EnableIRQ(DMA2_Stream6_IRQn);
  99. #endif
  100. }
  101. rt_uint8_t SD_GetCardInfo(HAL_SD_CardInfoTypedef *cardinfo)
  102. {
  103. return HAL_SD_Get_CardInfo(&hsd, cardinfo);
  104. }
  105. #if (SD_DMA_MODE==1)
  106. HAL_SD_ErrorTypedef SD_ReadBlocks(void* buf,uint64_t sector ,uint32_t cnt)
  107. {
  108. HAL_SD_ErrorTypedef err;
  109. err = HAL_SD_ReadBlocks_DMA(&hsd, buf, sector, SECTOR_SIZE, cnt);
  110. if(err != SD_OK)
  111. {
  112. DEBUG_PRINTF("err: %d\n", err);
  113. return err;
  114. }
  115. return HAL_SD_CheckReadOperation(&hsd, (uint32_t)SD_TIMEOUT);
  116. }
  117. HAL_SD_ErrorTypedef SD_WriteBlocks(const void* buf,uint64_t sector,uint32_t cnt)
  118. {
  119. HAL_SD_ErrorTypedef err;
  120. err = HAL_SD_WriteBlocks_DMA(&hsd, (uint32_t *)buf, sector, SECTOR_SIZE, cnt);
  121. if(err != SD_OK)
  122. {
  123. DEBUG_PRINTF("err: %d\n", err);
  124. return err;
  125. }
  126. return HAL_SD_CheckWriteOperation(&hsd, (uint32_t)SD_TIMEOUT);
  127. }
  128. void SDMMC1_IRQHandler(void)
  129. {
  130. HAL_SD_IRQHandler(&hsd);
  131. }
  132. void DMA2_Stream6_IRQHandler(void)
  133. {
  134. HAL_DMA_IRQHandler(hsd.hdmatx);
  135. }
  136. void DMA2_Stream3_IRQHandler(void)
  137. {
  138. HAL_DMA_IRQHandler(hsd.hdmarx);
  139. }
  140. #else
  141. HAL_SD_ErrorTypedef SD_ReadBlocks(void* buf, uint64_t sector, uint32_t cnt)
  142. {
  143. return HAL_SD_ReadBlocks(&hsd, (uint32_t * )buf, sector, SECTOR_SIZE, cnt);
  144. }
  145. HAL_SD_ErrorTypedef SD_WriteBlocks(const void* buf, uint64_t sector, uint32_t cnt)
  146. {
  147. return HAL_SD_WriteBlocks(&hsd, (uint32_t * )buf, sector, SECTOR_SIZE, cnt);
  148. }
  149. #endif
  150. static rt_err_t rt_sdcard_init(rt_device_t dev)
  151. {
  152. if (rt_sem_init(&sd_lock, "sdlock", 1, RT_IPC_FLAG_FIFO) != RT_EOK)
  153. {
  154. DEBUG_PRINTF("init sd lock semaphore failed\n");
  155. return RT_ERROR;
  156. }
  157. else
  158. {
  159. DEBUG_PRINTF("SD Card init OK\n");
  160. return RT_EOK;
  161. }
  162. }
  163. static rt_err_t rt_sdcard_open(rt_device_t dev, rt_uint16_t oflag)
  164. {
  165. return RT_EOK;
  166. }
  167. static rt_err_t rt_sdcard_close(rt_device_t dev)
  168. {
  169. return RT_EOK;
  170. }
  171. static rt_size_t rt_sdcard_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
  172. {
  173. HAL_SD_ErrorTypedef status = SD_OK;
  174. rt_uint32_t retry;
  175. rt_sem_take(&sd_lock, RT_WAITING_FOREVER);
  176. retry = 3;
  177. while(retry)
  178. {
  179. /* read all sectors */
  180. if ((rt_uint32_t)buffer % 4 != 0)
  181. {
  182. rt_uint32_t index;
  183. /* which is not alignment with 4 or chip SRAM */
  184. for (index = 0; index < size; index++)
  185. {
  186. status = SD_ReadBlocks(buffer, (uint64_t)pos * SECTOR_SIZE, 1);
  187. if (status != HAL_OK)
  188. break;
  189. /* copy to the buffer */
  190. rt_memcpy(((rt_uint8_t*)buffer + index * SECTOR_SIZE), _sdcard_buffer, SECTOR_SIZE);
  191. }
  192. }
  193. else
  194. {
  195. status = SD_ReadBlocks(buffer, (uint64_t)pos*SECTOR_SIZE, size);
  196. }
  197. if (status == HAL_OK)
  198. break;
  199. retry --;
  200. }
  201. rt_sem_release(&sd_lock);
  202. if (status == HAL_OK)
  203. {
  204. return size;
  205. }
  206. else
  207. {
  208. DEBUG_PRINTF("rt_sdcard_read, ");
  209. DEBUG_PRINTF("dev: %08X, pos: %d, ", (uint32_t)dev, pos);
  210. DEBUG_PRINTF("buffer: 0x%08X, size: %d\n", buffer, size);
  211. DEBUG_PRINTF("read failed: status/%d, buffer 0x%08x\n", status, buffer);
  212. return 0;
  213. }
  214. }
  215. static rt_size_t rt_sdcard_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
  216. {
  217. HAL_SD_ErrorTypedef status = SD_OK;
  218. rt_uint32_t retry;
  219. static rt_uint32_t count = 0;
  220. RT_ASSERT(((uint32_t)buffer & 0x3) == 0x0); //align to 4 bytes;
  221. rt_sem_take(&sd_lock, RT_WAITING_FOREVER);
  222. retry = 3;
  223. while(retry)
  224. {
  225. /* read all sectors */
  226. if ((rt_uint32_t)buffer % 4 != 0)
  227. {
  228. rt_uint32_t index;
  229. /* which is not alignment with 4 or chip SRAM */
  230. for (index = 0; index < size; index++)
  231. {
  232. /* copy to the buffer */
  233. rt_memcpy(((rt_uint8_t*)buffer + index * SECTOR_SIZE), _sdcard_buffer, SECTOR_SIZE);
  234. status = SD_WriteBlocks(buffer, (uint64_t)pos * SECTOR_SIZE, 1);
  235. if (status != HAL_OK)
  236. break;
  237. }
  238. }
  239. else
  240. {
  241. status = SD_WriteBlocks(buffer, (uint64_t)pos*SECTOR_SIZE, size);
  242. }
  243. if (status == HAL_OK)
  244. break;
  245. retry --;
  246. }
  247. rt_sem_release(&sd_lock);
  248. if (status == HAL_OK)
  249. {
  250. return size;
  251. }
  252. else
  253. {
  254. DEBUG_PRINTF("rt_sdcard_write: %d, ", count);
  255. DEBUG_PRINTF("dev: %08X, pos: %d, ", (uint32_t)dev, pos);
  256. DEBUG_PRINTF("buffer: 0x%08X, size: %d\n", (uint32_t)buffer, size);
  257. DEBUG_PRINTF("write failed: status/%d, buffer 0x%08x\n", status, buffer);
  258. return 0;
  259. }
  260. }
  261. static rt_err_t rt_sdcard_control(rt_device_t dev, rt_uint8_t cmd, void *args)
  262. {
  263. RT_ASSERT(dev != RT_NULL);
  264. if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
  265. {
  266. struct rt_device_blk_geometry *geometry = (struct rt_device_blk_geometry *)args;
  267. if (geometry == RT_NULL)
  268. return -RT_ERROR;
  269. geometry->bytes_per_sector = sdcard_info.CardBlockSize;
  270. geometry->block_size = sdcard_info.CardBlockSize;
  271. geometry->sector_count = sdcard_info.CardCapacity / sdcard_info.CardBlockSize;
  272. }
  273. return RT_EOK;
  274. }
  275. static int rt_hw_sdcard_init(void)
  276. {
  277. if (sdio_sd_init() != RT_EOK)
  278. {
  279. DEBUG_PRINTF("sdcard init failed\n");
  280. return RT_ERROR;
  281. }
  282. /* register sdcard device */
  283. sdcard_device.type = RT_Device_Class_Block;
  284. sdcard_device.init = rt_sdcard_init;
  285. sdcard_device.open = rt_sdcard_open;
  286. sdcard_device.close = rt_sdcard_close;
  287. sdcard_device.read = rt_sdcard_read;
  288. sdcard_device.write = rt_sdcard_write;
  289. sdcard_device.control = rt_sdcard_control;
  290. rt_device_register(&sdcard_device, "sd0",
  291. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
  292. return RT_EOK;
  293. }
  294. INIT_BOARD_EXPORT(rt_hw_sdcard_init);
  295. #endif