sdcard.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503
  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. static 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. static 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. static rt_uint8_t sd_readblock(rt_uint32_t address, rt_uint8_t* buf)
  202. {
  203. rt_uint32_t status, tmp;
  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. tmp = SDIDAT;
  227. rt_memcpy(buf, &tmp, sizeof(rt_uint32_t));
  228. rd_cnt++;
  229. buf += 4;
  230. }
  231. }
  232. if(sd_data_end() == RT_ERROR)
  233. {
  234. rt_kprintf("Dat error\n");
  235. return RT_ERROR;
  236. }
  237. SDIDCON = SDIDCON &~ (7<<12);
  238. SDIFSTA = SDIFSTA & 0x200;
  239. SDIDSTA = 0x10;
  240. return RT_EOK;
  241. }
  242. static rt_uint8_t sd_writeblock(rt_uint32_t address, rt_uint8_t* buf)
  243. {
  244. rt_uint32_t status, tmp;
  245. wt_cnt=0;
  246. SDIFSTA = SDIFSTA | (1 << 16);
  247. SDIDCON = (2 << 22) | (1 << 20) | (1 << 17) | (1 << 16) | (1 << 14) | (3 << 12) | (1 << 0);
  248. SDICARG = address;
  249. REWTCMD:
  250. SDICCON = (0x1 << 9) | (0x1 << 8) |0x58;
  251. if(sd_cmd_end(24, 1) == RT_ERROR)
  252. goto REWTCMD;
  253. SDICSTA=0xa00;
  254. while(wt_cnt < 128*1)
  255. {
  256. status = SDIFSTA;
  257. if((status & 0x2000) == 0x2000)
  258. {
  259. rt_memcpy(&tmp, buf, sizeof(rt_uint32_t));
  260. SDIDAT = tmp;
  261. wt_cnt++;
  262. buf += 4;
  263. }
  264. }
  265. if(sd_data_end() == RT_ERROR)
  266. {
  267. rt_kprintf("Data Error\n");
  268. return RT_ERROR;
  269. }
  270. SDIDCON = SDIDCON &~ (7<<12);
  271. SDIDSTA = 0x10;
  272. return RT_EOK;
  273. }
  274. #ifdef RT_USING_DFS
  275. /* RT-Thread Device Driver Interface */
  276. #include <rtthread.h>
  277. #include <dfs_fs.h>
  278. struct rt_device sdcard_device[4];
  279. struct dfs_partition part[4];
  280. static rt_err_t rt_sdcard_init(rt_device_t dev)
  281. {
  282. return RT_EOK;
  283. }
  284. static rt_err_t rt_sdcard_open(rt_device_t dev, rt_uint16_t oflag)
  285. {
  286. return RT_EOK;
  287. }
  288. static rt_err_t rt_sdcard_close(rt_device_t dev)
  289. {
  290. return RT_EOK;
  291. }
  292. static rt_err_t rt_sdcard_control(rt_device_t dev, rt_uint8_t cmd, void *args)
  293. {
  294. return RT_EOK;
  295. }
  296. static rt_size_t rt_sdcard_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
  297. {
  298. int i;
  299. struct dfs_partition *part = (struct dfs_partition *)dev->user_data;
  300. if ( dev == RT_NULL )
  301. {
  302. rt_set_errno(-DFS_STATUS_EINVAL);
  303. return 0;
  304. }
  305. /* read all sectors */
  306. for (i = 0; i < size; i ++)
  307. {
  308. rt_sem_take(part->lock, RT_WAITING_FOREVER);
  309. sd_readblock((part->offset + i + pos)*SECTOR_SIZE,
  310. (rt_uint8_t*)((rt_uint8_t*)buffer + i * SECTOR_SIZE));
  311. rt_sem_release(part->lock);
  312. }
  313. /* the length of reading must align to SECTOR SIZE */
  314. return size;
  315. }
  316. static rt_size_t rt_sdcard_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
  317. {
  318. int i;
  319. struct dfs_partition *part = (struct dfs_partition *)dev->user_data;
  320. if ( dev == RT_NULL )
  321. {
  322. rt_set_errno(-DFS_STATUS_EINVAL);
  323. return 0;
  324. }
  325. /* read all sectors */
  326. for (i = 0; i < size; i++)
  327. {
  328. rt_sem_take(part->lock, RT_WAITING_FOREVER);
  329. sd_writeblock((part->offset + i + pos)*SECTOR_SIZE,
  330. (rt_uint8_t*)((rt_uint8_t*)buffer + i * SECTOR_SIZE));
  331. rt_sem_release(part->lock);
  332. }
  333. /* the length of reading must align to SECTOR SIZE */
  334. return size;
  335. }
  336. void rt_hw_sdcard_init(void)
  337. {
  338. rt_uint8_t i, status;
  339. rt_uint8_t *sector;
  340. char dname[4];
  341. char sname[8];
  342. /* Enable PCLK into SDI Block */
  343. CLKCON |= 1 << 9;
  344. /* Setup GPIO as SD and SDCMD, SDDAT[3:0] Pull up En */
  345. GPEUP = GPEUP & (~(0x3f << 5)) | (0x01 << 5);
  346. GPECON = GPECON & (~(0xfff << 10)) | (0xaaa << 10);
  347. RCA = 0;
  348. if (sd_init() == RT_EOK)
  349. {
  350. /* get the first sector to read partition table */
  351. sector = (rt_uint8_t*) rt_malloc (512);
  352. if (sector == RT_NULL)
  353. {
  354. rt_kprintf("allocate partition sector buffer failed\n");
  355. return;
  356. }
  357. status = sd_readblock(0, sector);
  358. if (status == RT_EOK)
  359. {
  360. for(i=0; i<4; i++)
  361. {
  362. /* get the first partition */
  363. status = dfs_filesystem_get_partition(&part[i], sector, i);
  364. if (status == RT_EOK)
  365. {
  366. rt_snprintf(dname, 4, "sd%d", i);
  367. rt_snprintf(sname, 8, "sem_sd%d", i);
  368. part[i].lock = rt_sem_create(sname, 1, RT_IPC_FLAG_FIFO);
  369. /* register sdcard device */
  370. sdcard_device[i].type = RT_Device_Class_Block;
  371. sdcard_device[i].init = rt_sdcard_init;
  372. sdcard_device[i].open = rt_sdcard_open;
  373. sdcard_device[i].close = rt_sdcard_close;
  374. sdcard_device[i].read = rt_sdcard_read;
  375. sdcard_device[i].write = rt_sdcard_write;
  376. sdcard_device[i].control = rt_sdcard_control;
  377. sdcard_device[i].user_data = &part[i];
  378. rt_device_register(&sdcard_device[i], dname,
  379. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
  380. }
  381. else
  382. {
  383. if(i == 0)
  384. {
  385. /* there is no partition table */
  386. part[0].offset = 0;
  387. part[0].size = 0;
  388. part[0].lock = rt_sem_create("sem_sd0", 1, RT_IPC_FLAG_FIFO);
  389. /* register sdcard device */
  390. sdcard_device[0].type = RT_Device_Class_Block;
  391. sdcard_device[0].init = rt_sdcard_init;
  392. sdcard_device[0].open = rt_sdcard_open;
  393. sdcard_device[0].close = rt_sdcard_close;
  394. sdcard_device[0].read = rt_sdcard_read;
  395. sdcard_device[0].write = rt_sdcard_write;
  396. sdcard_device[0].control = rt_sdcard_control;
  397. sdcard_device[0].user_data = &part[0];
  398. rt_device_register(&sdcard_device[0], "sd0",
  399. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
  400. break;
  401. }
  402. }
  403. }
  404. }
  405. else
  406. {
  407. rt_kprintf("read sdcard first sector failed\n");
  408. }
  409. /* release sector buffer */
  410. rt_free(sector);
  411. return;
  412. }
  413. else
  414. {
  415. rt_kprintf("sdcard init failed\n");
  416. }
  417. }
  418. #endif