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