sdcard.c 10 KB

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