sdcard.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799
  1. /*-----------------------------------------------------------------------*/
  2. /* MMC/SDC (in SPI mode) control module (C)ChaN, 2007 */
  3. /*-----------------------------------------------------------------------*/
  4. /* Only rcvr_spi(), xmit_spi(), disk_timerproc() and some macros */
  5. /* are platform dependent. */
  6. /*-----------------------------------------------------------------------*/
  7. /*
  8. * This file was modified from a sample available from the FatFs
  9. * web site. It was modified to work with a Luminary Micro
  10. * EK-LM3S6965 evaluation board.
  11. *
  12. * Note that the SSI port is shared with the osram display. The code
  13. * in this file does not attempt to share the SSI port with the osram,
  14. * it assumes the osram is not being used.
  15. */
  16. #include "sdcard.h"
  17. #include <inc/hw_types.h>
  18. #include <inc/hw_memmap.h>
  19. #include <driverlib/ssi.h>
  20. #include <driverlib/gpio.h>
  21. #include <driverlib/sysctl.h>
  22. /* Definitions for MMC/SDC command */
  23. #define CMD0 (0x40+0) /* GO_IDLE_STATE */
  24. #define CMD1 (0x40+1) /* SEND_OP_COND */
  25. #define CMD8 (0x40+8) /* SEND_IF_COND */
  26. #define CMD9 (0x40+9) /* SEND_CSD */
  27. #define CMD10 (0x40+10) /* SEND_CID */
  28. #define CMD12 (0x40+12) /* STOP_TRANSMISSION */
  29. #define CMD16 (0x40+16) /* SET_BLOCKLEN */
  30. #define CMD17 (0x40+17) /* READ_SINGLE_BLOCK */
  31. #define CMD18 (0x40+18) /* READ_MULTIPLE_BLOCK */
  32. #define CMD23 (0x40+23) /* SET_BLOCK_COUNT */
  33. #define CMD24 (0x40+24) /* WRITE_BLOCK */
  34. #define CMD25 (0x40+25) /* WRITE_MULTIPLE_BLOCK */
  35. #define CMD41 (0x40+41) /* SEND_OP_COND (ACMD) */
  36. #define CMD55 (0x40+55) /* APP_CMD */
  37. #define CMD58 (0x40+58) /* READ_OCR */
  38. /* Peripheral definitions for EK-LM3S6965 board */
  39. // SSI port
  40. #define SDC_SSI_BASE SSI0_BASE
  41. #define SDC_SSI_SYSCTL_PERIPH SYSCTL_PERIPH_SSI0
  42. // GPIO for SSI pins
  43. #define SDC_GPIO_PORT_BASE GPIO_PORTA_BASE
  44. #define SDC_GPIO_SYSCTL_PERIPH SYSCTL_PERIPH_GPIOA
  45. #define SDC_SSI_CLK GPIO_PIN_2
  46. #define SDC_SSI_TX GPIO_PIN_5
  47. #define SDC_SSI_RX GPIO_PIN_4
  48. #define SDC_SSI_FSS GPIO_PIN_3
  49. #define SDC_SSI_PINS (SDC_SSI_TX | SDC_SSI_RX | SDC_SSI_CLK)
  50. // GPIO for card chip select
  51. #define SDC_CS_GPIO_PORT_BASE GPIO_PORTD_BASE
  52. #define SDC_CS_GPIO_SYSCTL_PERIPH SYSCTL_PERIPH_GPIOD
  53. #define SDC_CS GPIO_PIN_0
  54. // asserts the CS pin to the card
  55. static
  56. void SELECT (void)
  57. {
  58. GPIOPinWrite(SDC_CS_GPIO_PORT_BASE, SDC_CS, 0);
  59. }
  60. // de-asserts the CS pin to the card
  61. static
  62. void DESELECT (void)
  63. {
  64. GPIOPinWrite(SDC_CS_GPIO_PORT_BASE, SDC_CS, SDC_CS);
  65. }
  66. /*--------------------------------------------------------------------------
  67. Module Private Functions
  68. ---------------------------------------------------------------------------*/
  69. static volatile
  70. DSTATUS Stat = STA_NOINIT; /* Disk status */
  71. static volatile
  72. rt_uint8_t Timer1, Timer2; /* 100Hz decrement timer */
  73. static
  74. rt_uint8_t CardType; /* b0:MMC, b1:SDC, b2:Block addressing */
  75. static
  76. rt_uint8_t PowerFlag = 0; /* indicates if "power" is on */
  77. /*-----------------------------------------------------------------------*/
  78. /* Transmit a byte to MMC via SPI (Platform dependent) */
  79. /*-----------------------------------------------------------------------*/
  80. static
  81. void xmit_spi (rt_uint8_t dat)
  82. {
  83. rt_uint32_t rcvdat;
  84. SSIDataPut(SDC_SSI_BASE, dat); /* Write the data to the tx fifo */
  85. SSIDataGet(SDC_SSI_BASE, &rcvdat); /* flush data read during the write */
  86. }
  87. /*-----------------------------------------------------------------------*/
  88. /* Receive a byte from MMC via SPI (Platform dependent) */
  89. /*-----------------------------------------------------------------------*/
  90. static
  91. rt_uint8_t rcvr_spi (void)
  92. {
  93. rt_uint32_t rcvdat;
  94. SSIDataPut(SDC_SSI_BASE, 0xFF); /* write dummy data */
  95. SSIDataGet(SDC_SSI_BASE, &rcvdat); /* read data frm rx fifo */
  96. return (rt_uint8_t)rcvdat;
  97. }
  98. static
  99. void rcvr_spi_m (rt_uint8_t *dst)
  100. {
  101. *dst = rcvr_spi();
  102. }
  103. /*-----------------------------------------------------------------------*/
  104. /* Wait for card ready */
  105. /*-----------------------------------------------------------------------*/
  106. static
  107. rt_uint8_t wait_ready (void)
  108. {
  109. rt_uint8_t res;
  110. Timer2 = 50; /* Wait for ready in timeout of 500ms */
  111. rcvr_spi();
  112. do
  113. res = rcvr_spi();
  114. while ((res != 0xFF) && Timer2);
  115. return res;
  116. }
  117. /*-----------------------------------------------------------------------*/
  118. /* Send 80 or so clock transitions with CS and DI held high. This is */
  119. /* required after card power up to get it into SPI mode */
  120. /*-----------------------------------------------------------------------*/
  121. static
  122. void send_initial_clock_train(void)
  123. {
  124. unsigned int i;
  125. rt_uint32_t dat;
  126. /* Ensure CS is held high. */
  127. DESELECT();
  128. /* Switch the SSI TX line to a GPIO and drive it high too. */
  129. GPIOPinTypeGPIOOutput(SDC_GPIO_PORT_BASE, SDC_SSI_TX);
  130. GPIOPinWrite(SDC_GPIO_PORT_BASE, SDC_SSI_TX, SDC_SSI_TX);
  131. /* Send 10 bytes over the SSI. This causes the clock to wiggle the */
  132. /* required number of times. */
  133. for(i = 0 ; i < 10 ; i++)
  134. {
  135. /* Write DUMMY data. SSIDataPut() waits until there is room in the */
  136. /* FIFO. */
  137. SSIDataPut(SDC_SSI_BASE, 0xFF);
  138. /* Flush data read during data write. */
  139. SSIDataGet(SDC_SSI_BASE, &dat);
  140. }
  141. /* Revert to hardware control of the SSI TX line. */
  142. GPIOPinTypeSSI(SDC_GPIO_PORT_BASE, SDC_SSI_TX);
  143. }
  144. /*-----------------------------------------------------------------------*/
  145. /* Power Control (Platform dependent) */
  146. /*-----------------------------------------------------------------------*/
  147. /* When the target system does not support socket power control, there */
  148. /* is nothing to do in these functions and chk_power always returns 1. */
  149. static
  150. void power_on (void)
  151. {
  152. /*
  153. * This doesn't really turn the power on, but initializes the
  154. * SSI port and pins needed to talk to the card.
  155. */
  156. /* Enable the peripherals used to drive the SDC on SSI, and the CS */
  157. SysCtlPeripheralEnable(SDC_SSI_SYSCTL_PERIPH);
  158. SysCtlPeripheralEnable(SDC_GPIO_SYSCTL_PERIPH);
  159. SysCtlPeripheralEnable(SDC_CS_GPIO_SYSCTL_PERIPH);
  160. /* Configure the appropriate pins to be SSI instead of GPIO */
  161. GPIOPinTypeSSI(SDC_GPIO_PORT_BASE, SDC_SSI_PINS);
  162. GPIOPinTypeGPIOOutput(SDC_CS_GPIO_PORT_BASE, SDC_CS);
  163. GPIOPadConfigSet(SDC_GPIO_PORT_BASE, SDC_SSI_PINS, GPIO_STRENGTH_4MA,
  164. GPIO_PIN_TYPE_STD_WPU);
  165. GPIOPadConfigSet(SDC_CS_GPIO_PORT_BASE, SDC_CS, GPIO_STRENGTH_4MA,
  166. GPIO_PIN_TYPE_STD_WPU);
  167. /* Deassert the SSI0 chip select */
  168. GPIOPinWrite(SDC_CS_GPIO_PORT_BASE, SDC_CS, SDC_CS);
  169. /* Configure the SSI0 port */
  170. SSIConfigSetExpClk(SDC_SSI_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0,
  171. SSI_MODE_MASTER, 400000, 8);
  172. SSIEnable(SDC_SSI_BASE);
  173. /* Set DI and CS high and apply more than 74 pulses to SCLK for the card */
  174. /* to be able to accept a native command. */
  175. send_initial_clock_train();
  176. PowerFlag = 1;
  177. }
  178. // set the SSI speed to the max setting
  179. static
  180. void set_max_speed(void)
  181. {
  182. unsigned long i;
  183. /* Disable the SSI */
  184. SSIDisable(SDC_SSI_BASE);
  185. /* Set the maximum speed as half the system clock, with a max of 12.5 MHz. */
  186. i = SysCtlClockGet() / 2;
  187. if(i > 12500000)
  188. {
  189. i = 12500000;
  190. }
  191. /* Configure the SSI0 port */
  192. SSIConfigSetExpClk(SDC_SSI_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0,
  193. SSI_MODE_MASTER, i, 8);
  194. /* Enable the SSI */
  195. SSIEnable(SDC_SSI_BASE);
  196. }
  197. static
  198. void power_off (void)
  199. {
  200. PowerFlag = 0;
  201. }
  202. static
  203. int chk_power(void) /* Socket power state: 0=off, 1=on */
  204. {
  205. return PowerFlag;
  206. }
  207. /*-----------------------------------------------------------------------*/
  208. /* Receive a data packet from MMC */
  209. /*-----------------------------------------------------------------------*/
  210. static
  211. rt_bool_t rcvr_datablock (
  212. rt_uint8_t *buff, /* Data buffer to store received data */
  213. unsigned int btr /* Byte count (must be even number) */
  214. )
  215. {
  216. rt_uint8_t token;
  217. Timer1 = 10;
  218. do { /* Wait for data packet in timeout of 100ms */
  219. token = rcvr_spi();
  220. } while ((token == 0xFF) && Timer1);
  221. if(token != 0xFE) return RT_FALSE; /* If not valid data token, retutn with error */
  222. do { /* Receive the data block into buffer */
  223. rcvr_spi_m(buff++);
  224. rcvr_spi_m(buff++);
  225. } while (btr -= 2);
  226. rcvr_spi(); /* Discard CRC */
  227. rcvr_spi();
  228. return RT_TRUE; /* Return with success */
  229. }
  230. /*-----------------------------------------------------------------------*/
  231. /* Send a data packet to MMC */
  232. /*-----------------------------------------------------------------------*/
  233. #if _READONLY == 0
  234. static
  235. rt_bool_t xmit_datablock (
  236. const rt_uint8_t *buff, /* 512 byte data block to be transmitted */
  237. rt_uint8_t token /* Data/Stop token */
  238. )
  239. {
  240. rt_uint8_t resp, wc;
  241. if (wait_ready() != 0xFF) return RT_FALSE;
  242. xmit_spi(token); /* Xmit data token */
  243. if (token != 0xFD) { /* Is data token */
  244. wc = 0;
  245. do { /* Xmit the 512 byte data block to MMC */
  246. xmit_spi(*buff++);
  247. xmit_spi(*buff++);
  248. } while (--wc);
  249. xmit_spi(0xFF); /* CRC (Dummy) */
  250. xmit_spi(0xFF);
  251. resp = rcvr_spi(); /* Reveive data response */
  252. if ((resp & 0x1F) != 0x05) /* If not accepted, return with error */
  253. return RT_FALSE;
  254. }
  255. return RT_TRUE;
  256. }
  257. #endif /* _READONLY */
  258. /*-----------------------------------------------------------------------*/
  259. /* Send a command packet to MMC */
  260. /*-----------------------------------------------------------------------*/
  261. static
  262. rt_uint8_t send_cmd (
  263. rt_uint8_t cmd, /* Command byte */
  264. rt_uint32_t arg /* Argument */
  265. )
  266. {
  267. rt_uint8_t n, res;
  268. if (wait_ready() != 0xFF) return 0xFF;
  269. /* Send command packet */
  270. xmit_spi(cmd); /* Command */
  271. xmit_spi((rt_uint8_t)(arg >> 24)); /* Argument[31..24] */
  272. xmit_spi((rt_uint8_t)(arg >> 16)); /* Argument[23..16] */
  273. xmit_spi((rt_uint8_t)(arg >> 8)); /* Argument[15..8] */
  274. xmit_spi((rt_uint8_t)arg); /* Argument[7..0] */
  275. n = 0;
  276. if (cmd == CMD0) n = 0x95; /* CRC for CMD0(0) */
  277. if (cmd == CMD8) n = 0x87; /* CRC for CMD8(0x1AA) */
  278. xmit_spi(n);
  279. /* Receive command response */
  280. if (cmd == CMD12) rcvr_spi(); /* Skip a stuff byte when stop reading */
  281. n = 10; /* Wait for a valid response in timeout of 10 attempts */
  282. do
  283. res = rcvr_spi();
  284. while ((res & 0x80) && --n);
  285. return res; /* Return with the response value */
  286. }
  287. /*--------------------------------------------------------------------------
  288. Public Functions
  289. ---------------------------------------------------------------------------*/
  290. /*-----------------------------------------------------------------------*/
  291. /* Initialize Disk Drive */
  292. /*-----------------------------------------------------------------------*/
  293. DSTATUS disk_initialize (
  294. rt_uint8_t drv /* Physical drive nmuber (0) */
  295. )
  296. {
  297. rt_uint8_t n, ty, ocr[4];
  298. if (drv) return STA_NOINIT; /* Supports only single drive */
  299. if (Stat & STA_NODISK) return Stat; /* No card in the socket */
  300. power_on(); /* Force socket power on */
  301. send_initial_clock_train();
  302. SELECT(); /* CS = L */
  303. ty = 0;
  304. if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */
  305. Timer1 = 100; /* Initialization timeout of 1000 msec */
  306. if (send_cmd(CMD8, 0x1AA) == 1) { /* SDC Ver2+ */
  307. for (n = 0; n < 4; n++) ocr[n] = rcvr_spi();
  308. if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */
  309. do {
  310. if (send_cmd(CMD55, 0) <= 1 && send_cmd(CMD41, 1UL << 30) == 0) break; /* ACMD41 with HCS bit */
  311. } while (Timer1);
  312. if (Timer1 && send_cmd(CMD58, 0) == 0) { /* Check CCS bit */
  313. for (n = 0; n < 4; n++) ocr[n] = rcvr_spi();
  314. ty = (ocr[0] & 0x40) ? 6 : 2;
  315. }
  316. }
  317. } else { /* SDC Ver1 or MMC */
  318. ty = (send_cmd(CMD55, 0) <= 1 && send_cmd(CMD41, 0) <= 1) ? 2 : 1; /* SDC : MMC */
  319. do {
  320. if (ty == 2) {
  321. if (send_cmd(CMD55, 0) <= 1 && send_cmd(CMD41, 0) == 0) break; /* ACMD41 */
  322. } else {
  323. if (send_cmd(CMD1, 0) == 0) break; /* CMD1 */
  324. }
  325. } while (Timer1);
  326. if (!Timer1 || send_cmd(CMD16, 512) != 0) /* Select R/W block length */
  327. ty = 0;
  328. }
  329. }
  330. CardType = ty;
  331. DESELECT(); /* CS = H */
  332. rcvr_spi(); /* Idle (Release DO) */
  333. if (ty) { /* Initialization succeded */
  334. Stat &= ~STA_NOINIT; /* Clear STA_NOINIT */
  335. set_max_speed();
  336. } else { /* Initialization failed */
  337. power_off();
  338. }
  339. return Stat;
  340. }
  341. /*-----------------------------------------------------------------------*/
  342. /* Get Disk Status */
  343. /*-----------------------------------------------------------------------*/
  344. DSTATUS disk_status (
  345. rt_uint8_t drv /* Physical drive nmuber (0) */
  346. )
  347. {
  348. if (drv) return STA_NOINIT; /* Supports only single drive */
  349. return Stat;
  350. }
  351. /*-----------------------------------------------------------------------*/
  352. /* Read Sector(s) */
  353. /*-----------------------------------------------------------------------*/
  354. DRESULT disk_read (
  355. rt_uint8_t drv, /* Physical drive nmuber (0) */
  356. rt_uint8_t *buff, /* Pointer to the data buffer to store read data */
  357. rt_uint32_t sector, /* Start sector number (LBA) */
  358. rt_uint8_t count /* Sector count (1..255) */
  359. )
  360. {
  361. if (drv || !count) return RES_PARERR;
  362. if (Stat & STA_NOINIT) return RES_NOTRDY;
  363. if (!(CardType & 4)) sector *= 512; /* Convert to byte address if needed */
  364. SELECT(); /* CS = L */
  365. if (count == 1) { /* Single block read */
  366. if ((send_cmd(CMD17, sector) == 0) /* READ_SINGLE_BLOCK */
  367. && rcvr_datablock(buff, 512))
  368. count = 0;
  369. }
  370. else { /* Multiple block read */
  371. if (send_cmd(CMD18, sector) == 0) { /* READ_MULTIPLE_BLOCK */
  372. do {
  373. if (!rcvr_datablock(buff, 512)) break;
  374. buff += 512;
  375. } while (--count);
  376. send_cmd(CMD12, 0); /* STOP_TRANSMISSION */
  377. }
  378. }
  379. DESELECT(); /* CS = H */
  380. rcvr_spi(); /* Idle (Release DO) */
  381. return count ? RES_ERROR : RES_OK;
  382. }
  383. /*-----------------------------------------------------------------------*/
  384. /* Write Sector(s) */
  385. /*-----------------------------------------------------------------------*/
  386. #if _READONLY == 0
  387. DRESULT disk_write (
  388. rt_uint8_t drv, /* Physical drive nmuber (0) */
  389. const rt_uint8_t *buff, /* Pointer to the data to be written */
  390. rt_uint32_t sector, /* Start sector number (LBA) */
  391. rt_uint8_t count /* Sector count (1..255) */
  392. )
  393. {
  394. if (drv || !count) return RES_PARERR;
  395. if (Stat & STA_NOINIT) return RES_NOTRDY;
  396. if (Stat & STA_PROTECT) return RES_WRPRT;
  397. if (!(CardType & 4)) sector *= 512; /* Convert to byte address if needed */
  398. SELECT(); /* CS = L */
  399. if (count == 1) { /* Single block write */
  400. if ((send_cmd(CMD24, sector) == 0) /* WRITE_BLOCK */
  401. && xmit_datablock(buff, 0xFE))
  402. count = 0;
  403. }
  404. else { /* Multiple block write */
  405. if (CardType & 2) {
  406. send_cmd(CMD55, 0); send_cmd(CMD23, count); /* ACMD23 */
  407. }
  408. if (send_cmd(CMD25, sector) == 0) { /* WRITE_MULTIPLE_BLOCK */
  409. do {
  410. if (!xmit_datablock(buff, 0xFC)) break;
  411. buff += 512;
  412. } while (--count);
  413. if (!xmit_datablock(0, 0xFD)) /* STOP_TRAN token */
  414. count = 1;
  415. }
  416. }
  417. DESELECT(); /* CS = H */
  418. rcvr_spi(); /* Idle (Release DO) */
  419. return count ? RES_ERROR : RES_OK;
  420. }
  421. #endif /* _READONLY */
  422. /*-----------------------------------------------------------------------*/
  423. /* Miscellaneous Functions */
  424. /*-----------------------------------------------------------------------*/
  425. DRESULT disk_ioctl (
  426. rt_uint8_t drv, /* Physical drive nmuber (0) */
  427. rt_uint8_t ctrl, /* Control code */
  428. void *buff /* Buffer to send/receive control data */
  429. )
  430. {
  431. DRESULT res;
  432. rt_uint8_t n, csd[16], *ptr = buff;
  433. rt_uint16_t csize;
  434. if (drv) return RES_PARERR;
  435. res = RES_ERROR;
  436. if (ctrl == CTRL_POWER) {
  437. switch (*ptr) {
  438. case 0: /* Sub control code == 0 (POWER_OFF) */
  439. if (chk_power())
  440. power_off(); /* Power off */
  441. res = RES_OK;
  442. break;
  443. case 1: /* Sub control code == 1 (POWER_ON) */
  444. power_on(); /* Power on */
  445. res = RES_OK;
  446. break;
  447. case 2: /* Sub control code == 2 (POWER_GET) */
  448. *(ptr+1) = (rt_uint8_t)chk_power();
  449. res = RES_OK;
  450. break;
  451. default :
  452. res = RES_PARERR;
  453. }
  454. }
  455. else {
  456. if (Stat & STA_NOINIT) return RES_NOTRDY;
  457. SELECT(); /* CS = L */
  458. switch (ctrl) {
  459. case GET_SECTOR_COUNT : /* Get number of sectors on the disk (rt_uint32_t) */
  460. if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) {
  461. if ((csd[0] >> 6) == 1) { /* SDC ver 2.00 */
  462. csize = csd[9] + ((rt_uint16_t)csd[8] << 8) + 1;
  463. *(rt_uint32_t*)buff = (rt_uint32_t)csize << 10;
  464. } else { /* MMC or SDC ver 1.XX */
  465. n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
  466. csize = (csd[8] >> 6) + ((rt_uint16_t)csd[7] << 2) + ((rt_uint16_t)(csd[6] & 3) << 10) + 1;
  467. *(rt_uint32_t*)buff = (rt_uint32_t)csize << (n - 9);
  468. }
  469. res = RES_OK;
  470. }
  471. break;
  472. case GET_SECTOR_SIZE : /* Get sectors on the disk (rt_uint16_t) */
  473. *(rt_uint16_t*)buff = 512;
  474. res = RES_OK;
  475. break;
  476. case CTRL_SYNC : /* Make sure that data has been written */
  477. if (wait_ready() == 0xFF)
  478. res = RES_OK;
  479. break;
  480. case MMC_GET_CSD : /* Receive CSD as a data block (16 bytes) */
  481. if (send_cmd(CMD9, 0) == 0 /* READ_CSD */
  482. && rcvr_datablock(ptr, 16))
  483. res = RES_OK;
  484. break;
  485. case MMC_GET_CID : /* Receive CID as a data block (16 bytes) */
  486. if (send_cmd(CMD10, 0) == 0 /* READ_CID */
  487. && rcvr_datablock(ptr, 16))
  488. res = RES_OK;
  489. break;
  490. case MMC_GET_OCR : /* Receive OCR as an R3 resp (4 bytes) */
  491. if (send_cmd(CMD58, 0) == 0) { /* READ_OCR */
  492. for (n = 0; n < 4; n++)
  493. *ptr++ = rcvr_spi();
  494. res = RES_OK;
  495. }
  496. // case MMC_GET_TYPE : /* Get card type flags (1 byte) */
  497. // *ptr = CardType;
  498. // res = RES_OK;
  499. // break;
  500. default:
  501. res = RES_PARERR;
  502. }
  503. DESELECT(); /* CS = H */
  504. rcvr_spi(); /* Idle (Release DO) */
  505. }
  506. return res;
  507. }
  508. /*-----------------------------------------------------------------------*/
  509. /* Device Timer Interrupt Procedure (Platform dependent) */
  510. /*-----------------------------------------------------------------------*/
  511. /* This function must be called in period of 10ms */
  512. void disk_timerproc (void)
  513. {
  514. // rt_uint8_t n, s;
  515. rt_uint8_t n;
  516. n = Timer1; /* 100Hz decrement timer */
  517. if (n) Timer1 = --n;
  518. n = Timer2;
  519. if (n) Timer2 = --n;
  520. }
  521. /*---------------------------------------------------------*/
  522. /* User Provided Timer Function for FatFs module */
  523. /*---------------------------------------------------------*/
  524. /* This is a real time clock service to be called from */
  525. /* FatFs module. Any valid time must be returned even if */
  526. /* the system does not support a real time clock. */
  527. rt_uint32_t get_fattime (void)
  528. {
  529. return ((2007UL-1980) << 25) // Year = 2007
  530. | (6UL << 21) // Month = June
  531. | (5UL << 16) // Day = 5
  532. | (11U << 11) // Hour = 11
  533. | (38U << 5) // Min = 38
  534. | (0U >> 1) // Sec = 0
  535. ;
  536. }
  537. /*
  538. * RT-Thread SD Card Driver
  539. * 20090705 Yi.Qiu
  540. */
  541. #include <rtthread.h>
  542. #include <dfs_fs.h>
  543. struct rt_device sdcard_device;
  544. struct dfs_partition part;
  545. /* RT-Thread Device Driver Interface */
  546. static rt_err_t rt_sdcard_init(rt_device_t dev)
  547. {
  548. return RT_EOK;
  549. }
  550. static rt_err_t rt_sdcard_open(rt_device_t dev, rt_uint16_t oflag)
  551. {
  552. return RT_EOK;
  553. }
  554. static rt_err_t rt_sdcard_close(rt_device_t dev)
  555. {
  556. return RT_EOK;
  557. }
  558. /* set sector size to 512 */
  559. #define SECTOR_SIZE 512
  560. static rt_size_t rt_sdcard_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
  561. {
  562. DRESULT status;
  563. status = disk_read(0, buffer, part.offset + pos / SECTOR_SIZE, size / SECTOR_SIZE);
  564. if (status != RES_OK)
  565. {
  566. rt_kprintf("sd card read failed\n");
  567. return 0;
  568. }
  569. return size;
  570. }
  571. static rt_size_t rt_sdcard_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
  572. {
  573. DRESULT status;
  574. status = disk_write(0, buffer, part.offset + pos / SECTOR_SIZE, size / SECTOR_SIZE);
  575. if (status != RES_OK)
  576. {
  577. rt_kprintf("sd card write failed\n");
  578. return 0;
  579. }
  580. return size;
  581. }
  582. static rt_err_t rt_sdcard_control(rt_device_t dev, rt_uint8_t cmd, void *args)
  583. {
  584. return RT_EOK;
  585. }
  586. void rt_hw_sdcard_init()
  587. {
  588. if (disk_initialize(0) == RES_OK)
  589. {
  590. DRESULT status;
  591. rt_uint8_t *sector;
  592. /* get the first sector to read partition table */
  593. sector = (rt_uint8_t*) rt_malloc (512);
  594. if (sector == RT_NULL)
  595. {
  596. rt_kprintf("allocate partition sector buffer failed\n");
  597. return;
  598. }
  599. status = disk_read(0, sector, 0, 1);
  600. if (status == RES_OK)
  601. {
  602. /* get the first partition */
  603. if (dfs_filesystem_get_partition(&part, sector, 0) != 0)
  604. {
  605. /* there is no partition */
  606. part.offset = 0;
  607. part.size = 0;
  608. }
  609. }
  610. else
  611. {
  612. /* there is no partition table */
  613. part.offset = 0;
  614. part.size = 0;
  615. }
  616. /* release sector buffer */
  617. rt_free(sector);
  618. /* register sdcard device */
  619. sdcard_device.init = rt_sdcard_init;
  620. sdcard_device.open = rt_sdcard_open;
  621. sdcard_device.close = rt_sdcard_close;
  622. sdcard_device.read = rt_sdcard_read;
  623. sdcard_device.write = rt_sdcard_write;
  624. sdcard_device.control = rt_sdcard_control;
  625. /* no private */
  626. sdcard_device.private = RT_NULL;
  627. rt_device_register(&sdcard_device, "sd0",
  628. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
  629. return;
  630. }
  631. rt_kprintf("sdcard init failed\n");
  632. }