sdcard.c 23 KB

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