drv_sdcard.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  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-11-24 WangHuachen the first version
  9. */
  10. #include <rthw.h>
  11. #include <rtthread.h>
  12. #include <rtdevice.h>
  13. #include <dfs_fs.h>
  14. #include <drivers/mmcsd_core.h>
  15. #include <stdint.h>
  16. #include <stdio.h>
  17. #include "drv_sdcard.h"
  18. #include "xsdps_core.h"
  19. #define DBG_TAG "drv.sdcard"
  20. #define DBG_LVL DBG_INFO
  21. #include "rtdbg.h"
  22. #define FILE_SYSTEM_INTERFACE_SD
  23. #define SD_CD_DELAY 10000U
  24. typedef rt_uint8_t BYTE;
  25. typedef rt_uint32_t DWORD;
  26. typedef unsigned int UINT;
  27. /* Status of Disk Functions */
  28. typedef rt_uint8_t DSTATUS;
  29. /* Results of Disk Functions */
  30. typedef enum
  31. {
  32. RES_OK = 0, /* 0: Successful */
  33. RES_ERROR, /* 1: R/W Error */
  34. RES_WRPRT, /* 2: Write Protected */
  35. RES_NOTRDY, /* 3: Not Ready */
  36. RES_PARERR /* 4: Invalid Parameter */
  37. } DRESULT;
  38. /* Disk Status Bits (DSTATUS) */
  39. #define STA_NOINIT 0x01 /* Drive not initialized */
  40. #define STA_NODISK 0x02 /* No medium in the drive */
  41. #define STA_PROTECT 0x04 /* Write protected */
  42. static DSTATUS Stat[2] = {STA_NOINIT, STA_NOINIT}; /* Disk status */
  43. #ifdef FILE_SYSTEM_INTERFACE_SD
  44. static XSdPs SdInstance[2];
  45. static u32 BaseAddress;
  46. static u32 CardDetect;
  47. static u32 WriteProtect;
  48. static u32 SlotType[2];
  49. static u8 HostCntrlrVer[2];
  50. #endif
  51. static BYTE sdcard_drvnum = 0;
  52. static struct rt_device sdcard_device;
  53. static struct dfs_partition part;
  54. static struct rt_mutex sd_lock[2];
  55. static DSTATUS disk_status(
  56. BYTE pdrv /* Drive number (0) */
  57. )
  58. {
  59. DSTATUS s = Stat[pdrv];
  60. #ifdef FILE_SYSTEM_INTERFACE_SD
  61. u32 StatusReg;
  62. u32 DelayCount = 0;
  63. if (SdInstance[pdrv].Config.BaseAddress == (u32)0)
  64. {
  65. #ifdef XPAR_XSDPS_1_DEVICE_ID
  66. if (pdrv == 1)
  67. {
  68. BaseAddress = XPAR_XSDPS_1_BASEADDR;
  69. CardDetect = XPAR_XSDPS_1_HAS_CD;
  70. WriteProtect = XPAR_XSDPS_1_HAS_WP;
  71. }
  72. else
  73. {
  74. #endif
  75. BaseAddress = XPAR_XSDPS_0_BASEADDR;
  76. CardDetect = XPAR_XSDPS_0_HAS_CD;
  77. WriteProtect = XPAR_XSDPS_0_HAS_WP;
  78. #ifdef XPAR_XSDPS_1_DEVICE_ID
  79. }
  80. #endif
  81. HostCntrlrVer[pdrv] = (u8)(XSdPs_ReadReg16(BaseAddress,
  82. XSDPS_HOST_CTRL_VER_OFFSET) &
  83. XSDPS_HC_SPEC_VER_MASK);
  84. if (HostCntrlrVer[pdrv] == XSDPS_HC_SPEC_V3)
  85. {
  86. SlotType[pdrv] = XSdPs_ReadReg(BaseAddress,
  87. XSDPS_CAPS_OFFSET) &
  88. XSDPS_CAPS_SLOT_TYPE_MASK;
  89. }
  90. else
  91. {
  92. SlotType[pdrv] = 0;
  93. }
  94. }
  95. /* If SD is not powered up then mark it as not initialized */
  96. if ((XSdPs_ReadReg8((u32)BaseAddress, XSDPS_POWER_CTRL_OFFSET) &
  97. XSDPS_PC_BUS_PWR_MASK) == 0U)
  98. {
  99. s |= STA_NOINIT;
  100. }
  101. StatusReg = XSdPs_GetPresentStatusReg((u32)BaseAddress);
  102. if (SlotType[pdrv] != XSDPS_CAPS_EMB_SLOT)
  103. {
  104. if (CardDetect)
  105. {
  106. while ((StatusReg & XSDPS_PSR_CARD_INSRT_MASK) == 0U)
  107. {
  108. if (DelayCount == 500U)
  109. {
  110. s = STA_NODISK | STA_NOINIT;
  111. goto Label;
  112. }
  113. else
  114. {
  115. /* Wait for 10 msec */
  116. usleep(SD_CD_DELAY);
  117. DelayCount++;
  118. StatusReg = XSdPs_GetPresentStatusReg((u32)BaseAddress);
  119. }
  120. }
  121. }
  122. s &= ~STA_NODISK;
  123. if (WriteProtect)
  124. {
  125. if ((StatusReg & XSDPS_PSR_WPS_PL_MASK) == 0U)
  126. {
  127. s |= STA_PROTECT;
  128. goto Label;
  129. }
  130. }
  131. s &= ~STA_PROTECT;
  132. }
  133. else
  134. {
  135. s &= ~STA_NODISK & ~STA_PROTECT;
  136. }
  137. Label:
  138. Stat[pdrv] = s;
  139. #endif
  140. return s;
  141. }
  142. static DSTATUS disk_initialize(
  143. BYTE pdrv /* Physical drive number (0) */
  144. )
  145. {
  146. DSTATUS s;
  147. #ifdef FILE_SYSTEM_INTERFACE_SD
  148. s32 Status = XST_FAILURE;
  149. XSdPs_Config *SdConfig;
  150. #endif
  151. s = disk_status(pdrv);
  152. if ((s & STA_NODISK) != 0U)
  153. {
  154. return s;
  155. }
  156. /* If disk is already initialized */
  157. if ((s & STA_NOINIT) == 0U)
  158. {
  159. return s;
  160. }
  161. #ifdef FILE_SYSTEM_INTERFACE_SD
  162. if (CardDetect)
  163. {
  164. /*
  165. * Card detection check
  166. * If the HC detects the No Card State, power will be cleared
  167. */
  168. while (!((XSDPS_PSR_CARD_DPL_MASK |
  169. XSDPS_PSR_CARD_STABLE_MASK |
  170. XSDPS_PSR_CARD_INSRT_MASK) ==
  171. (XSdPs_GetPresentStatusReg((u32)BaseAddress) &
  172. (XSDPS_PSR_CARD_DPL_MASK |
  173. XSDPS_PSR_CARD_STABLE_MASK |
  174. XSDPS_PSR_CARD_INSRT_MASK))))
  175. ;
  176. }
  177. /*
  178. * Initialize the host controller
  179. */
  180. SdConfig = XSdPs_LookupConfig((u16)pdrv);
  181. if (NULL == SdConfig)
  182. {
  183. s |= STA_NOINIT;
  184. return s;
  185. }
  186. Status = XSdPs_CfgInitialize(&SdInstance[pdrv], SdConfig,
  187. SdConfig->BaseAddress);
  188. if (Status != XST_SUCCESS)
  189. {
  190. s |= STA_NOINIT;
  191. return s;
  192. }
  193. Status = XSdPs_CardInitialize(&SdInstance[pdrv]);
  194. if (Status != XST_SUCCESS)
  195. {
  196. s |= STA_NOINIT;
  197. return s;
  198. }
  199. /*
  200. * Disk is initialized.
  201. * Store the same in Stat.
  202. */
  203. s &= (~STA_NOINIT);
  204. Stat[pdrv] = s;
  205. #endif
  206. #ifdef FILE_SYSTEM_INTERFACE_RAM
  207. /* Assign RAMFS address value from xparameters.h */
  208. dataramfs = (char *)RAMFS_START_ADDR;
  209. /* Clearing No init Status for RAM */
  210. s &= (~STA_NOINIT);
  211. Stat[pdrv] = s;
  212. #endif
  213. return s;
  214. }
  215. static DRESULT disk_read(
  216. BYTE pdrv, /* Physical drive number (0) */
  217. BYTE *buff, /* Pointer to the data buffer to store read data */
  218. DWORD sector, /* Start sector number (LBA) */
  219. UINT count /* Sector count (1..128) */
  220. )
  221. {
  222. DSTATUS s;
  223. #ifdef FILE_SYSTEM_INTERFACE_SD
  224. s32 Status = XST_FAILURE;
  225. DWORD LocSector = sector;
  226. #endif
  227. s = disk_status(pdrv);
  228. if ((s & STA_NOINIT) != 0U)
  229. {
  230. return RES_NOTRDY;
  231. }
  232. if (count == 0U)
  233. {
  234. return RES_PARERR;
  235. }
  236. #ifdef FILE_SYSTEM_INTERFACE_SD
  237. /* Convert LBA to byte address if needed */
  238. if ((SdInstance[pdrv].HCS) == 0U)
  239. {
  240. LocSector *= (DWORD)XSDPS_BLK_SIZE_512_MASK;
  241. }
  242. Status = XSdPs_ReadPolled(&SdInstance[pdrv], (u32)LocSector, count, buff);
  243. if (Status != XST_SUCCESS)
  244. {
  245. return RES_ERROR;
  246. }
  247. #endif
  248. #ifdef FILE_SYSTEM_INTERFACE_RAM
  249. memcpy(buff, dataramfs + (sector * SECTORSIZE), count * SECTORSIZE);
  250. #endif
  251. return RES_OK;
  252. }
  253. static DRESULT disk_write(
  254. BYTE pdrv, /* Physical drive nmuber (0..) */
  255. const BYTE *buff, /* Data to be written */
  256. DWORD sector, /* Sector address (LBA) */
  257. UINT count /* Number of sectors to write (1..128) */
  258. )
  259. {
  260. DSTATUS s;
  261. #ifdef FILE_SYSTEM_INTERFACE_SD
  262. s32 Status = XST_FAILURE;
  263. DWORD LocSector = sector;
  264. #endif
  265. s = disk_status(pdrv);
  266. if ((s & STA_NOINIT) != 0U)
  267. {
  268. return RES_NOTRDY;
  269. }
  270. if (count == 0U)
  271. {
  272. return RES_PARERR;
  273. }
  274. #ifdef FILE_SYSTEM_INTERFACE_SD
  275. /* Convert LBA to byte address if needed */
  276. if ((SdInstance[pdrv].HCS) == 0U)
  277. {
  278. LocSector *= (DWORD)XSDPS_BLK_SIZE_512_MASK;
  279. }
  280. Status = XSdPs_WritePolled(&SdInstance[pdrv], (u32)LocSector, count, buff);
  281. if (Status != XST_SUCCESS)
  282. {
  283. return RES_ERROR;
  284. }
  285. #endif
  286. #ifdef FILE_SYSTEM_INTERFACE_RAM
  287. memcpy(dataramfs + (sector * SECTORSIZE), buff, count * SECTORSIZE);
  288. #endif
  289. return RES_OK;
  290. }
  291. static rt_err_t rt_sdcard_init(rt_device_t dev)
  292. {
  293. char sdlock_name[20];
  294. BYTE drvnum = *((BYTE *)dev->user_data);
  295. rt_snprintf(sdlock_name, sizeof(sdlock_name), "sdlock%d", drvnum);
  296. if (rt_mutex_init(&sd_lock[drvnum], sdlock_name, RT_IPC_FLAG_PRIO) != RT_EOK)
  297. {
  298. LOG_E("init sdlock semaphore failed\n");
  299. }
  300. else
  301. LOG_D("sdcard init OK\n");
  302. return RT_EOK;
  303. }
  304. static rt_err_t rt_sdcard_open(rt_device_t dev, rt_uint16_t oflag)
  305. {
  306. return RT_EOK;
  307. }
  308. static rt_err_t rt_sdcard_close(rt_device_t dev)
  309. {
  310. return RT_EOK;
  311. }
  312. static rt_size_t rt_sdcard_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
  313. {
  314. RT_ASSERT(((rt_uint32_t)buffer % 4) == 0);
  315. DRESULT status;
  316. BYTE drvnum = *((BYTE *)dev->user_data);
  317. rt_mutex_take(&sd_lock[drvnum], RT_WAITING_FOREVER);
  318. status = disk_read(drvnum, buffer, part.offset + pos, size);
  319. rt_mutex_release(&sd_lock[drvnum]);
  320. if (status == RES_OK)
  321. return size;
  322. LOG_E("sdcard read failed\n");
  323. return 0;
  324. }
  325. static rt_size_t rt_sdcard_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
  326. {
  327. RT_ASSERT(((rt_uint32_t)buffer % 4) == 0);
  328. DRESULT status;
  329. BYTE drvnum = *((BYTE *)dev->user_data);
  330. rt_mutex_take(&sd_lock[drvnum], RT_WAITING_FOREVER);
  331. status = disk_write(drvnum, buffer, part.offset + pos, size);
  332. rt_mutex_release(&sd_lock[drvnum]);
  333. if (status == RES_OK)
  334. return size;
  335. LOG_E("sdcard write failed\n");
  336. return 0;
  337. }
  338. static rt_err_t rt_sdcard_control(rt_device_t dev, int cmd, void *args)
  339. {
  340. RT_ASSERT(dev != RT_NULL);
  341. BYTE drvnum = *((BYTE *)dev->user_data);
  342. if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
  343. {
  344. struct rt_device_blk_geometry *geometry;
  345. geometry = (struct rt_device_blk_geometry *)args;
  346. if (geometry == RT_NULL)
  347. return -RT_ERROR;
  348. geometry->bytes_per_sector = 512;
  349. geometry->block_size = 128;
  350. geometry->sector_count = SdInstance[drvnum].SectorCount;
  351. }
  352. return RT_EOK;
  353. }
  354. #ifdef BSP_USING_SD0
  355. static int rh_hw_emmc_init(void)
  356. {
  357. if (disk_initialize(sdcard_drvnum) == RES_OK)
  358. {
  359. DRESULT status;
  360. rt_uint8_t *sector;
  361. /* get the first sector to read partition table */
  362. sector = (rt_uint8_t *)rt_malloc(512);
  363. if (sector == RT_NULL)
  364. {
  365. LOG_E("allocate partition sector buffer failed\n");
  366. return -RT_ERROR;
  367. }
  368. status = disk_read(0, sector, 0, 1);
  369. if (status == RES_OK)
  370. {
  371. /* get the first partition */
  372. if (dfs_filesystem_get_partition(&part, sector, 0) != 0)
  373. {
  374. /* there is no partition */
  375. part.offset = 0;
  376. part.size = 0;
  377. }
  378. }
  379. else
  380. {
  381. /* there is no partition table */
  382. part.offset = 0;
  383. part.size = 0;
  384. }
  385. /* release sector buffer */
  386. rt_free(sector);
  387. /* register sdcard device */
  388. sdcard_device.type = RT_Device_Class_Block;
  389. sdcard_device.init = rt_sdcard_init;
  390. sdcard_device.open = rt_sdcard_open;
  391. sdcard_device.close = rt_sdcard_close;
  392. sdcard_device.read = rt_sdcard_read;
  393. sdcard_device.write = rt_sdcard_write;
  394. sdcard_device.control = rt_sdcard_control;
  395. /* no private */
  396. sdcard_device.user_data = &sdcard_drvnum;
  397. rt_device_register(&sdcard_device, "sd0", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE);
  398. return RT_EOK;
  399. }
  400. return -RT_ERROR;
  401. }
  402. INIT_DEVICE_EXPORT(rh_hw_emmc_init);
  403. #endif