drv_sdio_sd.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. #include "drv_sdio_sd.h"
  2. #include "string.h"
  3. #include <rtthread.h>
  4. #include <dfs_fs.h>
  5. SD_HandleTypeDef SDCARD_Handler;
  6. HAL_SD_CardInfoTypedef SDCardInfo; //SD卡信息结构体
  7. DMA_HandleTypeDef SDTxDMAHandler,SDRxDMAHandler; //SD卡DMA发送和接收句柄
  8. //SD卡初始化
  9. //返回值:0 初始化正确;其他值,初始化错误
  10. rt_uint8_t SD_Init(void)
  11. {
  12. rt_uint8_t SD_Error;
  13. //初始化时的时钟不能大于400KHZ
  14. SDCARD_Handler.Instance=SDIO;
  15. SDCARD_Handler.Init.ClockEdge=SDIO_CLOCK_EDGE_RISING; //上升沿
  16. SDCARD_Handler.Init.ClockBypass=SDIO_CLOCK_BYPASS_DISABLE; //不使用bypass模式,直接用HCLK进行分频得到SDIO_CK
  17. SDCARD_Handler.Init.ClockPowerSave=SDIO_CLOCK_POWER_SAVE_DISABLE; //空闲时不关闭时钟电源
  18. SDCARD_Handler.Init.BusWide=SDIO_BUS_WIDE_1B; //1位数据线
  19. SDCARD_Handler.Init.HardwareFlowControl=SDIO_HARDWARE_FLOW_CONTROL_DISABLE;//关闭硬件流控
  20. SDCARD_Handler.Init.ClockDiv=SDIO_INIT_CLK_DIV; //初始化时钟为400KHZ
  21. SD_Error=HAL_SD_Init(&SDCARD_Handler,&SDCardInfo);
  22. if(SD_Error!=SD_OK) return 1;
  23. SD_Error=HAL_SD_WideBusOperation_Config(&SDCARD_Handler,SDIO_BUS_WIDE_4B);//使能宽总线模式
  24. if(SD_Error!=SD_OK) return 2;
  25. return 0;
  26. }
  27. //SDMMC底层驱动,时钟使能,引脚配置,DMA配置
  28. //此函数会被HAL_SD_Init()调用
  29. //hsd:SD卡句柄
  30. void HAL_SD_MspInit(SD_HandleTypeDef *hsd)
  31. {
  32. DMA_HandleTypeDef TxDMAHandler,RxDMAHandler;
  33. GPIO_InitTypeDef GPIO_Initure;
  34. __HAL_RCC_SDIO_CLK_ENABLE(); //使能SDIO时钟
  35. __HAL_RCC_DMA2_CLK_ENABLE(); //使能DMA2时钟
  36. __HAL_RCC_GPIOC_CLK_ENABLE(); //使能GPIOC时钟
  37. __HAL_RCC_GPIOD_CLK_ENABLE(); //使能GPIOD时钟
  38. //PC8,9,10,11,12
  39. GPIO_Initure.Pin=GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12;
  40. GPIO_Initure.Mode=GPIO_MODE_AF_PP; //推挽复用
  41. GPIO_Initure.Pull=GPIO_PULLUP; //上拉
  42. GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速
  43. GPIO_Initure.Alternate=GPIO_AF12_SDIO; //复用为SDIO
  44. HAL_GPIO_Init(GPIOC,&GPIO_Initure); //初始化
  45. //PD2
  46. GPIO_Initure.Pin=GPIO_PIN_2;
  47. HAL_GPIO_Init(GPIOD,&GPIO_Initure); //初始化
  48. #if (SD_DMA_MODE==1) //使用DMA模式
  49. HAL_NVIC_SetPriority(SDMMC1_IRQn,2,0); //配置SDMMC1中断,抢占优先级2,子优先级0
  50. HAL_NVIC_EnableIRQ(SDMMC1_IRQn); //使能SDMMC1中断
  51. //配置发送DMA
  52. SDRxDMAHandler.Instance=DMA2_Stream3;
  53. SDRxDMAHandler.Init.Channel=DMA_CHANNEL_4;
  54. SDRxDMAHandler.Init.Direction=DMA_PERIPH_TO_MEMORY;
  55. SDRxDMAHandler.Init.PeriphInc=DMA_PINC_DISABLE;
  56. SDRxDMAHandler.Init.MemInc=DMA_MINC_ENABLE;
  57. SDRxDMAHandler.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD;
  58. SDRxDMAHandler.Init.MemDataAlignment=DMA_MDATAALIGN_WORD;
  59. SDRxDMAHandler.Init.Mode=DMA_PFCTRL;
  60. SDRxDMAHandler.Init.Priority=DMA_PRIORITY_VERY_HIGH;
  61. SDRxDMAHandler.Init.FIFOMode=DMA_FIFOMODE_ENABLE;
  62. SDRxDMAHandler.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL;
  63. SDRxDMAHandler.Init.MemBurst=DMA_MBURST_INC4;
  64. SDRxDMAHandler.Init.PeriphBurst=DMA_PBURST_INC4;
  65. __HAL_LINKDMA(hsd, hdmarx, SDRxDMAHandler); //将接收DMA和SD卡的发送DMA连接起来
  66. HAL_DMA_DeInit(&SDRxDMAHandler);
  67. HAL_DMA_Init(&SDRxDMAHandler); //初始化接收DMA
  68. //配置接收DMA
  69. SDTxDMAHandler.Instance=DMA2_Stream6;
  70. SDTxDMAHandler.Init.Channel=DMA_CHANNEL_4;
  71. SDTxDMAHandler.Init.Direction=DMA_MEMORY_TO_PERIPH;
  72. SDTxDMAHandler.Init.PeriphInc=DMA_PINC_DISABLE;
  73. SDTxDMAHandler.Init.MemInc=DMA_MINC_ENABLE;
  74. SDTxDMAHandler.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD;
  75. SDTxDMAHandler.Init.MemDataAlignment=DMA_MDATAALIGN_WORD;
  76. SDTxDMAHandler.Init.Mode=DMA_PFCTRL;
  77. SDTxDMAHandler.Init.Priority=DMA_PRIORITY_VERY_HIGH;
  78. SDTxDMAHandler.Init.FIFOMode=DMA_FIFOMODE_ENABLE;
  79. SDTxDMAHandler.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL;
  80. SDTxDMAHandler.Init.MemBurst=DMA_MBURST_INC4;
  81. SDTxDMAHandler.Init.PeriphBurst=DMA_PBURST_INC4;
  82. __HAL_LINKDMA(hsd, hdmatx, SDTxDMAHandler);//将发送DMA和SD卡的发送DMA连接起来
  83. HAL_DMA_DeInit(&SDTxDMAHandler);
  84. HAL_DMA_Init(&SDTxDMAHandler); //初始化发送DMA
  85. HAL_NVIC_SetPriority(DMA2_Stream3_IRQn, 3, 0); //接收DMA中断优先级
  86. HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
  87. HAL_NVIC_SetPriority(DMA2_Stream6_IRQn, 3, 0); //发送DMA中断优先级
  88. HAL_NVIC_EnableIRQ(DMA2_Stream6_IRQn);
  89. #endif
  90. }
  91. //得到卡信息
  92. //cardinfo:卡信息存储区
  93. //返回值:错误状态
  94. rt_uint8_t SD_GetCardInfo(HAL_SD_CardInfoTypedef *cardinfo)
  95. {
  96. rt_uint8_t sta;
  97. sta=HAL_SD_Get_CardInfo(&SDCARD_Handler,cardinfo);
  98. return sta;
  99. }
  100. #if (SD_DMA_MODE==1) //DMA模式
  101. //通过DMA读取SD卡一个扇区
  102. //buf:读数据缓存区
  103. //sector:扇区地址
  104. //blocksize:扇区大小(一般都是512字节)
  105. //cnt:扇区个数
  106. //返回值:错误状态;0,正常;其他,错误代码;
  107. rt_uint8_t SD_ReadBlocks_DMA(uint32_t *buf,uint64_t sector ,uint32_t cnt)
  108. {
  109. rt_uint8_t err=SD_OK;
  110. err=HAL_SD_ReadBlocks_DMA(&SDCARD_Handler,buf,sector,SECTOR_SIZE,cnt);//通过DMA读取SD卡一个扇区
  111. if(err==SD_OK)//读取成功
  112. {
  113. //等待读取完成
  114. err=HAL_SD_CheckReadOperation(&SDCARD_Handler,(uint32_t)SD_TIMEOUT);
  115. }
  116. return err;
  117. }
  118. //写SD卡
  119. //buf:写数据缓存区
  120. //sector:扇区地址
  121. //blocksize:扇区大小(一般都是512字节)
  122. //cnt:扇区个数
  123. //返回值:错误状态;0,正常;其他,错误代码;
  124. rt_uint8_t SD_WriteBlocks_DMA(uint32_t *buf,uint64_t sector,uint32_t cnt)
  125. {
  126. rt_uint8_t err=SD_OK;
  127. err=HAL_SD_WriteBlocks_DMA(&SDCARD_Handler,buf,sector,SECTOR_SIZE,cnt);//通过DMA写SD卡一个扇区
  128. if(err==SD_OK)//写成功
  129. {
  130. err=HAL_SD_CheckWriteOperation(&SDCARD_Handler,(uint32_t)SD_TIMEOUT);//等待读取完成/
  131. }
  132. return err;
  133. }
  134. //SDMMC1中断服务函数
  135. void SDMMC1_IRQHandler(void)
  136. {
  137. HAL_SD_IRQHandler(&SDCARD_Handler);
  138. }
  139. //DMA2数据流6中断服务函数
  140. void DMA2_Stream6_IRQHandler(void)
  141. {
  142. HAL_DMA_IRQHandler(SDCARD_Handler.hdmatx);
  143. }
  144. //DMA2数据流3中断服务函数
  145. void DMA2_Stream3_IRQHandler(void)
  146. {
  147. HAL_DMA_IRQHandler(SDCARD_Handler.hdmarx);
  148. }
  149. #else //轮训模式
  150. //读取SD卡扇区
  151. //buf:读数据缓存区
  152. //sector:扇区地址
  153. //cnt:扇区个数
  154. //返回值:错误状态;0,正常;其他,错误代码;
  155. rt_uint8_t SD_ReadBlocks(uint32_t *buf,uint64_t sector ,uint32_t cnt)
  156. {
  157. rt_uint8_t err=SD_OK;
  158. err=HAL_SD_ReadBlocks(&SDCARD_Handler,buf,sector,SECTOR_SIZE,cnt);//通过DMA读取SD卡一个扇区
  159. return err;
  160. }
  161. //写SD扇区
  162. //buf:写数据缓存区
  163. //sector:扇区地址
  164. //cnt:扇区个数
  165. //返回值:错误状态;0,正常;其他,错误代码;
  166. rt_uint8_t SD_WriteBlocks(uint32_t *buf,uint64_t sector,uint32_t cnt)
  167. {
  168. return HAL_SD_WriteBlocks(&SDCARD_Handler,buf,sector,SECTOR_SIZE,cnt);
  169. }
  170. #endif
  171. /*
  172. * RT-Thread SD Card Driver
  173. * 20100715 Bernard support SDHC card great than 4G.
  174. * 20110905 JoyChen support to STM32F2xx
  175. */
  176. static struct rt_device sdcard_device;
  177. static struct rt_semaphore sd_lock;
  178. /* RT-Thread Device Driver Interface */
  179. static rt_err_t rt_sdcard_init(rt_device_t dev)
  180. {
  181. if (rt_sem_init(&sd_lock, "sdlock", 1, RT_IPC_FLAG_FIFO) != RT_EOK)
  182. {
  183. rt_kprintf("init sd lock semaphore failed\n");
  184. }
  185. else
  186. rt_kprintf("SD Card init OK\n");
  187. return RT_EOK;
  188. }
  189. static rt_err_t rt_sdcard_open(rt_device_t dev, rt_uint16_t oflag)
  190. {
  191. return RT_EOK;
  192. }
  193. static rt_err_t rt_sdcard_close(rt_device_t dev)
  194. {
  195. return RT_EOK;
  196. }
  197. static uint32_t sdio_buffer[512/sizeof(uint32_t)];
  198. static rt_size_t rt_sdcard_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
  199. {
  200. rt_uint8_t status = SD_OK;
  201. rt_sem_take(&sd_lock, RT_WAITING_FOREVER);
  202. if(((uint32_t)buffer & 0x03) != 0)
  203. {
  204. /* non-aligned. */
  205. uint32_t i;
  206. uint64_t sector_adr;
  207. uint8_t* copy_buffer;
  208. sector_adr = (uint64_t)pos*SECTOR_SIZE;
  209. copy_buffer = (uint8_t*)buffer;
  210. for(i=0; i<size; i++)
  211. {
  212. #if (SD_DMA_MODE==1)
  213. status=SD_ReadBlocks_DMA(sdio_buffer,sector_adr,1);//通过DMA写SD卡一个扇区
  214. #else
  215. status=SD_ReadBlocks(sdio_buffer,sector_adr,1);
  216. #endif
  217. memcpy(copy_buffer, sdio_buffer, SECTOR_SIZE);
  218. sector_adr += SECTOR_SIZE;
  219. copy_buffer += SECTOR_SIZE;
  220. }
  221. }
  222. else
  223. {
  224. #if (SD_DMA_MODE==1)
  225. status=SD_ReadBlocks_DMA(buffer,(uint64_t)pos*SECTOR_SIZE,size);//通过DMA写SD卡一个扇区
  226. #else
  227. SD_ReadBlocks(buffer,(uint64_t)pos*SECTOR_SIZE,size);
  228. #endif
  229. }
  230. rt_sem_release(&sd_lock);
  231. if (status == SD_OK) return size;
  232. rt_kprintf("read failed: %d, buffer 0x%08x\n", status, buffer);
  233. return 0;
  234. }
  235. static rt_size_t rt_sdcard_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
  236. {
  237. rt_uint8_t status = SD_OK;
  238. rt_sem_take(&sd_lock, RT_WAITING_FOREVER);
  239. if(((uint32_t)buffer & 0x03) != 0)
  240. {
  241. /* non-aligned. */
  242. uint32_t i;
  243. uint64_t sector_adr;
  244. uint8_t* copy_buffer;
  245. sector_adr = (uint64_t)pos*SECTOR_SIZE;
  246. copy_buffer = (uint8_t*)buffer;
  247. for(i=0; i<size; i++)
  248. {
  249. memcpy(sdio_buffer, copy_buffer, SECTOR_SIZE);
  250. #if (SD_DMA_MODE==1)
  251. status=SD_WriteBlocks_DMA((uint32_t*)sdio_buffer,sector_adr,1);
  252. #else
  253. status=SD_WriteBlocks((uint32_t*)sdio_buffer,sector_adr,1);
  254. #endif
  255. sector_adr += SECTOR_SIZE;
  256. copy_buffer += SECTOR_SIZE;
  257. }
  258. }
  259. else
  260. {
  261. #if (SD_DMA_MODE==1)
  262. status=SD_WriteBlocks_DMA((uint32_t*)buffer,(uint64_t)pos*SECTOR_SIZE,size);
  263. #else
  264. status=SD_WriteBlocks((uint32_t*)buffer,(uint64_t)pos*SECTOR_SIZE,size);
  265. #endif
  266. }
  267. // }
  268. rt_sem_release(&sd_lock);
  269. if (status == SD_OK) return size;
  270. rt_kprintf("write failed: %d, buffer 0x%08x\n", status, buffer);
  271. return 0;
  272. }
  273. static rt_err_t rt_sdcard_control(rt_device_t dev, int cmd, void *args)
  274. {
  275. RT_ASSERT(dev != RT_NULL);
  276. if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
  277. {
  278. struct rt_device_blk_geometry *geometry;
  279. geometry = (struct rt_device_blk_geometry *)args;
  280. if (geometry == RT_NULL) return -RT_ERROR;
  281. geometry->bytes_per_sector = 512;
  282. geometry->block_size = SDCardInfo.CardBlockSize;
  283. geometry->sector_count = SDCardInfo.CardCapacity/SDCardInfo.CardBlockSize;
  284. }
  285. return RT_EOK;
  286. }
  287. static int rt_hw_sdcard_init(void)
  288. {
  289. if (SD_Init() == SD_OK)
  290. {
  291. /* register sdcard device */
  292. sdcard_device.type = RT_Device_Class_Block;
  293. sdcard_device.init = rt_sdcard_init;
  294. sdcard_device.open = rt_sdcard_open;
  295. sdcard_device.close = rt_sdcard_close;
  296. sdcard_device.read = rt_sdcard_read;
  297. sdcard_device.write = rt_sdcard_write;
  298. sdcard_device.control = rt_sdcard_control;
  299. /* no private */
  300. sdcard_device.user_data = &SDCardInfo;
  301. rt_device_register(&sdcard_device, "sd0",
  302. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
  303. return RT_EOK;
  304. }
  305. rt_kprintf("sdcard init failed\n");
  306. return RT_ERROR;
  307. }
  308. INIT_BOARD_EXPORT(rt_hw_sdcard_init);