sdcard.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548
  1. /*
  2. * File : sd.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006, 2007, RT-Thread Develop Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://www.rt-thread.org/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2007-12-02 Yi.Qiu the first version
  13. * 2010-01-01 Bernard Modify for mini2440
  14. * 2012-12-15 amr168 support SDHC
  15. */
  16. #include "sdcard.h"
  17. extern rt_uint32_t PCLK;
  18. volatile rt_uint32_t rd_cnt;
  19. volatile rt_uint32_t wt_cnt;
  20. volatile rt_int32_t RCA;
  21. volatile rt_int32_t sd_type;
  22. static void sd_delay(rt_uint32_t ms)
  23. {
  24. ms *= 7326;
  25. while(--ms);
  26. }
  27. static int sd_cmd_end(int cmd, int be_resp)
  28. {
  29. int finish0;
  30. if (!be_resp)
  31. {
  32. finish0 = SDICSTA;
  33. while ((finish0&0x800) != 0x800)
  34. finish0 = SDICSTA;
  35. SDICSTA = finish0;
  36. return RT_EOK;
  37. }
  38. else
  39. {
  40. finish0 = SDICSTA;
  41. while (!(((finish0&0x200)==0x200) | ((finish0&0x400) == 0x400)))
  42. finish0=SDICSTA;
  43. if (cmd == 1 || cmd == 41)
  44. {
  45. if ((finish0 & 0xf00) != 0xa00)
  46. {
  47. SDICSTA = finish0;
  48. if ((finish0&0x400) == 0x400)
  49. return RT_ERROR;
  50. }
  51. SDICSTA = finish0;
  52. }
  53. else
  54. {
  55. if ((finish0 & 0x1f00) != 0xa00)
  56. {
  57. /* rt_kprintf("CMD%d:SDICSTA=0x%x, SDIRSP0=0x%x\n", cmd, SDICSTA, SDIRSP0); */
  58. SDICSTA = finish0;
  59. if ((finish0 & 0x400) == 0x400)
  60. return RT_ERROR;
  61. }
  62. SDICSTA = finish0;
  63. }
  64. return RT_EOK;
  65. }
  66. }
  67. static int sd_data_end(void)
  68. {
  69. int finish;
  70. finish = SDIDSTA;
  71. while (!(((finish & 0x10) == 0x10) | ((finish & 0x20) == 0x20)))
  72. {
  73. finish = SDIDSTA;
  74. }
  75. if ((finish & 0xfc) != 0x10)
  76. {
  77. SDIDSTA = 0xec;
  78. return RT_ERROR;
  79. }
  80. return RT_EOK;
  81. }
  82. static void sd_cmd0(void)
  83. {
  84. SDICARG = 0x0;
  85. SDICCON = (1<<8) | 0x40;
  86. sd_cmd_end(0, 0);
  87. SDICSTA = 0x800; /* Clear cmd_end(no rsp) */
  88. }
  89. static int sd_cmd55(void)
  90. {
  91. SDICARG = RCA << 16;
  92. SDICCON = (0x1 << 9) | (0x1 << 8) | 0x77;
  93. if (sd_cmd_end(55, 1) == RT_ERROR)
  94. {
  95. /* rt_kprintf("CMD55 error\n"); */
  96. return RT_ERROR;
  97. }
  98. SDICSTA = 0xa00;
  99. return RT_EOK;
  100. }
  101. static void sd_sel_desel(char sel_desel)
  102. {
  103. if (sel_desel)
  104. {
  105. RECMDS7:
  106. SDICARG = RCA << 16;
  107. SDICCON = (0x1 << 9) | (0x1 << 8) | 0x47;
  108. if (sd_cmd_end(7, 1) == RT_ERROR)
  109. goto RECMDS7;
  110. SDICSTA = 0xa00;
  111. if (SDIRSP0 & 0x1e00 != 0x800)
  112. goto RECMDS7;
  113. }
  114. else
  115. {
  116. RECMDD7:
  117. SDICARG = 0 << 16;
  118. SDICCON = (0x1 << 8) | 0x47;
  119. if (sd_cmd_end(7, 0) == RT_ERROR)
  120. goto RECMDD7;
  121. SDICSTA = 0x800;
  122. }
  123. }
  124. static void sd_setbus(void)
  125. {
  126. do
  127. {
  128. sd_cmd55();
  129. SDICARG = 1 << 1; /* 4bit bus */
  130. SDICCON = (0x1<<9) | (0x1<<8) | 0x46; /* sht_resp, wait_resp, start, CMD55 */
  131. }while (sd_cmd_end(6, 1) == RT_ERROR);
  132. SDICSTA=0xa00; /* Clear cmd_end(with rsp) */
  133. }
  134. static int sd_ocr(void)
  135. {
  136. int i, ver=0;
  137. /* Negotiate operating condition for SD, it makes card ready state */
  138. for (i = 0; i < 50; i ++)
  139. {
  140. sd_cmd55();
  141. SDICARG = 0x40ff8000; /* HCS=1, compatible v1.x and v2.0 */
  142. SDICCON = (0x1<<9) | (0x1<<8) | 0x69;
  143. /* if using real board, should replace code here. need to modify qemu in near future*/
  144. /* Check end of ACMD41 */
  145. if (sd_cmd_end(41, 1) == RT_EOK)
  146. {
  147. if (SDIRSP0 == 0x80ff8000)
  148. {
  149. ver = 1; /* SD V1.x, CCS=0 */
  150. break;
  151. }
  152. else if (SDIRSP0 == 0xc0ff8000)
  153. {
  154. ver = 2; /* SD V2.0, CCS=1 */
  155. break;
  156. }
  157. }
  158. sd_delay(200);
  159. }
  160. SDICSTA = 0xa00;
  161. return ver;
  162. }
  163. rt_err_t sd_cmd8(void)
  164. {
  165. SDICARG = 0x000001AA;
  166. SDICCON = (0x1<<9) | (0x1<<8) | 0x48; //sht_resp, wait_resp, start
  167. if (sd_cmd_end(8, 1) == RT_ERROR)
  168. return RT_ERROR;
  169. SDICSTA = 0xa00;
  170. if ((SDIRSP0&0x1aa) == 0x1aa)
  171. return RT_EOK;
  172. else
  173. return RT_ERROR;
  174. }
  175. static rt_uint8_t sd_init(void)
  176. {
  177. //-- SD controller & card initialize
  178. int i;
  179. /* Important notice for MMC test condition */
  180. /* Cmd & Data lines must be enabled by pull up resister */
  181. SDIPRE = PCLK / (INICLK) - 1;
  182. SDICON = (0<<4) | 1; // Type A, clk enable
  183. SDIFSTA = SDIFSTA | (1<<16);
  184. SDIBSIZE = 0x200; /* 512byte per one block */
  185. SDIDTIMER = 0x7fffff; /* timeout count */
  186. /* Wait 74SDCLK for MMC card */
  187. for (i = 0; i < 0x1000; i ++);
  188. sd_cmd0();
  189. sd_cmd8(); /* Must be use it, Host shall supports high capacity */
  190. /* Check SD card OCR */
  191. sd_type = sd_ocr();
  192. if (sd_type > 0)
  193. {
  194. rt_kprintf("In SD ready\n");
  195. }
  196. else
  197. {
  198. rt_kprintf("Initialize fail\nNo Card assertion\n");
  199. return RT_ERROR;
  200. }
  201. RECMD2:
  202. SDICARG = 0x0;
  203. SDICCON = (0x1<<10)|(0x1<<9)|(0x1<<8)|0x42; /* lng_resp, wait_resp, start, CMD2 */
  204. if (sd_cmd_end(2, 1) == RT_ERROR)
  205. goto RECMD2;
  206. SDICSTA = 0xa00; /* Clear cmd_end(with rsp) */
  207. RECMD3:
  208. SDICARG = 0<<16; /* CMD3(MMC:Set RCA, SD:Ask RCA-->SBZ) */
  209. SDICCON = (0x1<<9)|(0x1<<8)|0x43; /* sht_resp, wait_resp, start, CMD3 */
  210. if (sd_cmd_end(3, 1) == RT_ERROR)
  211. goto RECMD3;
  212. SDICSTA=0xa00; /* Clear cmd_end(with rsp) */
  213. RCA = (SDIRSP0 & 0xffff0000) >> 16;
  214. SDIPRE = PCLK / (SDCLK) - 1; /* Normal clock=25MHz */
  215. if (SDIRSP0 & 0x1e00 != 0x600)
  216. goto RECMD3;
  217. sd_sel_desel(1);
  218. sd_delay(200);
  219. sd_setbus();
  220. return RT_EOK;
  221. }
  222. static rt_uint8_t sd_readblock(rt_uint32_t address, rt_uint8_t *buf)
  223. {
  224. rt_uint32_t status, tmp;
  225. rd_cnt = 0;
  226. SDIFSTA = SDIFSTA | (1<<16);
  227. SDIDCON = (2 << 22) | (1 << 19) | (1 << 17) | (1 << 16) | (1 << 14) | (2 << 12) | (1 << 0);
  228. SDICARG = address;
  229. RERDCMD:
  230. SDICCON = (0x1 << 9 ) | (0x1 << 8) | 0x51;
  231. if (sd_cmd_end(17, 1) == RT_ERROR)
  232. {
  233. rt_kprintf("Read CMD Error\n");
  234. goto RERDCMD;
  235. }
  236. SDICSTA = 0xa00;
  237. while (rd_cnt < 128)
  238. {
  239. if ((SDIDSTA & 0x20) == 0x20)
  240. {
  241. SDIDSTA = (0x1 << 0x5);
  242. break;
  243. }
  244. status = SDIFSTA;
  245. if ((status & 0x1000) == 0x1000)
  246. {
  247. tmp = SDIDAT;
  248. rt_memcpy(buf, &tmp, sizeof(rt_uint32_t));
  249. rd_cnt ++;
  250. buf += 4;
  251. }
  252. }
  253. if (sd_data_end() == RT_ERROR)
  254. {
  255. rt_kprintf("Dat error\n");
  256. return RT_ERROR;
  257. }
  258. SDIDCON = SDIDCON &~ (7<<12);
  259. SDIFSTA = SDIFSTA & 0x200;
  260. SDIDSTA = 0x10;
  261. return RT_EOK;
  262. }
  263. static rt_uint8_t sd_writeblock(rt_uint32_t address, rt_uint8_t *buf)
  264. {
  265. rt_uint32_t status, tmp;
  266. wt_cnt = 0;
  267. SDIFSTA = SDIFSTA | (1 << 16);
  268. SDIDCON = (2 << 22) | (1 << 20) | (1 << 17) | (1 << 16) | (1 << 14) | (3 << 12) | (1 << 0);
  269. SDICARG = address;
  270. REWTCMD:
  271. SDICCON = (0x1 << 9) | (0x1 << 8) |0x58;
  272. if (sd_cmd_end(24, 1) == RT_ERROR)
  273. goto REWTCMD;
  274. SDICSTA = 0xa00;
  275. while (wt_cnt < 128)
  276. {
  277. status = SDIFSTA;
  278. if ((status & 0x2000) == 0x2000)
  279. {
  280. rt_memcpy(&tmp, buf, sizeof(rt_uint32_t));
  281. SDIDAT = tmp;
  282. wt_cnt ++;
  283. buf += 4;
  284. }
  285. }
  286. if (sd_data_end() == RT_ERROR)
  287. {
  288. rt_kprintf("Data Error\n");
  289. return RT_ERROR;
  290. }
  291. SDIDCON = SDIDCON &~ (7<<12);
  292. SDIDSTA = 0x10;
  293. return RT_EOK;
  294. }
  295. #ifdef RT_USING_DFS
  296. /* RT-Thread Device Driver Interface */
  297. #include <rtthread.h>
  298. #include <dfs_fs.h>
  299. struct rt_device sdcard_device[4];
  300. struct dfs_partition part[4];
  301. static rt_err_t rt_sdcard_init(rt_device_t dev)
  302. {
  303. return RT_EOK;
  304. }
  305. static rt_err_t rt_sdcard_open(rt_device_t dev, rt_uint16_t oflag)
  306. {
  307. return RT_EOK;
  308. }
  309. static rt_err_t rt_sdcard_close(rt_device_t dev)
  310. {
  311. return RT_EOK;
  312. }
  313. static rt_err_t rt_sdcard_control(rt_device_t dev, rt_uint8_t cmd, void *args)
  314. {
  315. return RT_EOK;
  316. }
  317. static rt_size_t rt_sdcard_read(rt_device_t dev,
  318. rt_off_t pos,
  319. void *buffer,
  320. rt_size_t size)
  321. {
  322. int i, addr;
  323. struct dfs_partition *part = (struct dfs_partition *)dev->user_data;
  324. if (dev == RT_NULL)
  325. {
  326. rt_set_errno(-DFS_STATUS_EINVAL);
  327. return 0;
  328. }
  329. /* read all sectors */
  330. for (i = 0; i < size; i ++)
  331. {
  332. rt_sem_take(part->lock, RT_WAITING_FOREVER);
  333. if (sd_type == 1)
  334. addr = (part->offset + i + pos)*SECTOR_SIZE;
  335. else
  336. addr = (part->offset + i + pos);
  337. sd_readblock(addr, (rt_uint8_t *)((rt_uint8_t *)buffer + i * SECTOR_SIZE));
  338. rt_sem_release(part->lock);
  339. }
  340. /* the length of reading must align to SECTOR SIZE */
  341. return size;
  342. }
  343. static rt_size_t rt_sdcard_write(rt_device_t dev,
  344. rt_off_t pos,
  345. const void *buffer,
  346. rt_size_t size)
  347. {
  348. int i, addr;
  349. struct dfs_partition *part = (struct dfs_partition *)dev->user_data;
  350. if (dev == RT_NULL)
  351. {
  352. rt_set_errno(-DFS_STATUS_EINVAL);
  353. return 0;
  354. }
  355. /* read all sectors */
  356. for (i = 0; i < size; i++)
  357. {
  358. rt_sem_take(part->lock, RT_WAITING_FOREVER);
  359. if (sd_type == 1)
  360. addr = (part->offset + i + pos)*SECTOR_SIZE;
  361. else
  362. addr = (part->offset + i + pos);
  363. sd_writeblock(addr, (rt_uint8_t*)((rt_uint8_t*)buffer + i * SECTOR_SIZE));
  364. rt_sem_release(part->lock);
  365. }
  366. /* the length of reading must align to SECTOR SIZE */
  367. return size;
  368. }
  369. void rt_hw_sdcard_init(void)
  370. {
  371. rt_uint8_t i, status;
  372. rt_uint8_t *sector;
  373. char dname[4];
  374. char sname[8];
  375. /* Enable PCLK into SDI Block */
  376. CLKCON |= 1 << 9;
  377. /* Setup GPIO as SD and SDCMD, SDDAT[3:0] Pull up En */
  378. GPEUP = GPEUP & (~(0x3f << 5)) | (0x01 << 5);
  379. GPECON = GPECON & (~(0xfff << 10)) | (0xaaa << 10);
  380. RCA = 0;
  381. if (sd_init() == RT_EOK)
  382. {
  383. /* get the first sector to read partition table */
  384. sector = (rt_uint8_t*) rt_malloc (512);
  385. if (sector == RT_NULL)
  386. {
  387. rt_kprintf("allocate partition sector buffer failed\n");
  388. return;
  389. }
  390. status = sd_readblock(0, sector);
  391. if (status == RT_EOK)
  392. {
  393. for (i = 0; i < 4; i ++)
  394. {
  395. /* get the first partition */
  396. status = dfs_filesystem_get_partition(&part[i], sector, i);
  397. if (status == RT_EOK)
  398. {
  399. rt_snprintf(dname, 4, "sd%d", i);
  400. rt_snprintf(sname, 8, "sem_sd%d", i);
  401. part[i].lock = rt_sem_create(sname, 1, RT_IPC_FLAG_FIFO);
  402. /* register sdcard device */
  403. sdcard_device[i].type = RT_Device_Class_Block;
  404. sdcard_device[i].init = rt_sdcard_init;
  405. sdcard_device[i].open = rt_sdcard_open;
  406. sdcard_device[i].close = rt_sdcard_close;
  407. sdcard_device[i].read = rt_sdcard_read;
  408. sdcard_device[i].write = rt_sdcard_write;
  409. sdcard_device[i].control = rt_sdcard_control;
  410. sdcard_device[i].user_data = &part[i];
  411. rt_device_register(&sdcard_device[i], dname,
  412. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
  413. }
  414. else
  415. {
  416. if (i == 0)
  417. {
  418. /* there is no partition table */
  419. part[0].offset = 0;
  420. part[0].size = 0;
  421. part[0].lock = rt_sem_create("sem_sd0", 1, RT_IPC_FLAG_FIFO);
  422. /* register sdcard device */
  423. sdcard_device[0].type = RT_Device_Class_Block;
  424. sdcard_device[0].init = rt_sdcard_init;
  425. sdcard_device[0].open = rt_sdcard_open;
  426. sdcard_device[0].close = rt_sdcard_close;
  427. sdcard_device[0].read = rt_sdcard_read;
  428. sdcard_device[0].write = rt_sdcard_write;
  429. sdcard_device[0].control = rt_sdcard_control;
  430. sdcard_device[0].user_data = &part[0];
  431. rt_device_register(&sdcard_device[0], "sd0",
  432. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
  433. break;
  434. }
  435. }
  436. }
  437. }
  438. else
  439. {
  440. rt_kprintf("read sdcard first sector failed\n");
  441. }
  442. /* release sector buffer */
  443. rt_free(sector);
  444. return;
  445. }
  446. else
  447. {
  448. rt_kprintf("sdcard init failed\n");
  449. }
  450. }
  451. #endif