]>
cloudbase.mooo.com Git - z180-stamp.git/blob - avr/mmc.c
1 /*-----------------------------------------------------------------------*/
2 /* MMCv3/SDv1/SDv2 (in SPI mode) control module (C)ChaN, 2007 */
3 /*-----------------------------------------------------------------------*/
4 /* Only spi_rcvr(), spi_xmit(), disk_timerproc() and some macros */
5 /* are platform dependent. */
6 /*-----------------------------------------------------------------------*/
16 /* Port Controls (Platform dependent) */
17 /* SD card socket connections */
19 #define SD_CD_1 SBIT(PORTG,3) /* Card detect switch */
20 #define SD_CD_1_IN SBIT(PING,3)
21 #define SD_CD_1_DDR SBIT(DDRG,3)
23 //#define SD_WP_1 SBIT(PORTG,5) /* Write protect switch */
24 #define SD_WP_1_IN SBIT(PING,5)
25 #define SD_WP_1_DDR SBIT(DDRG,5)
27 #define SD_CS_1 SBIT(PORTG,4) /* Chip select pin */
28 #define SD_CS_1_IN SBIT(PING,4)
29 #define SD_CS_1_DDR SBIT(DDRG,4)
32 #define FCLK_SLOW() SPISetMMCInitClock() /* Set slow clock (100k-400k) */
33 #define FCLK_FAST() SPISetFastClock() /* Set fast clock (depends on the CSD) */
36 /*--------------------------------------------------------------------------
37 Definitions for MMC/SDC command
38 ---------------------------------------------------------------------------*/
40 #define CMD0 (0) /* GO_IDLE_STATE */
41 #define CMD1 (1) /* SEND_OP_COND (MMC) */
42 #define ACMD41 (0x80+41) /* SEND_OP_COND (SDC) */
43 #define CMD8 (8) /* SEND_IF_COND */
44 #define CMD9 (9) /* SEND_CSD */
45 #define CMD10 (10) /* SEND_CID */
46 #define CMD12 (12) /* STOP_TRANSMISSION */
47 #define ACMD13 (0x80+13) /* SD_STATUS (SDC) */
48 #define CMD16 (16) /* SET_BLOCKLEN */
49 #define CMD17 (17) /* READ_SINGLE_BLOCK */
50 #define CMD18 (18) /* READ_MULTIPLE_BLOCK */
51 #define CMD23 (23) /* SET_BLOCK_COUNT (MMC) */
52 #define ACMD23 (0x80+23) /* SET_WR_BLK_ERASE_COUNT (SDC) */
53 #define CMD24 (24) /* WRITE_BLOCK */
54 #define CMD25 (25) /* WRITE_MULTIPLE_BLOCK */
55 #define CMD55 (55) /* APP_CMD */
56 #define CMD58 (58) /* READ_OCR */
59 /*--------------------------------------------------------------------------
61 Module Private Functions
63 ---------------------------------------------------------------------------*/
65 struct sdsock_stat_s
{
66 volatile DSTATUS stat
; /* Disk/socket status */
67 BYTE CardType
; /* Card type flags */
77 /*-----------------------------------------------------------------------*/
78 /* Wait for card ready */
79 /*-----------------------------------------------------------------------*/
82 int wait_ready (void) /* 1:OK, 0:Timeout */
84 uint32_t to
= get_timer(0);
86 /* Wait for ready in timeout of 500ms */
88 if (spi_rcvr() == 0xFF) {
91 } while (get_timer(to
) < 500);
96 /*-----------------------------------------------------------------------*/
97 /* Deselect the card and release SPI bus */
98 /*-----------------------------------------------------------------------*/
103 // debug("*** enter deselect()\n");
105 /* Dummy clock (TODO: force DO hi-z for multiple slave SPI) */
107 // debug("*** exit deselect()\n");
112 /*-----------------------------------------------------------------------*/
113 /* Select the card and wait for ready */
114 /*-----------------------------------------------------------------------*/
117 int select (void) /* 1:Successful, 0:Timeout */
119 // debug("*** enter select()\n");
121 /* Dummy clock (force DO enabled) */
125 // debug("*** exit select() == 1\n");
129 // debug("*** exit select() == 0\n");
131 return 0; /* Timeout */
134 /*-----------------------------------------------------------------------*/
135 /* Power Control (Platform dependent) */
136 /*-----------------------------------------------------------------------*/
137 /* When the target system does not support socket power control, there */
138 /* is nothing to do in these functions and chk_power always returns 1. */
143 // debug("*** enter power_on()\n");
146 SD_PWR_1_DDR
= 1; /* Turns on PWR pin as output */
147 SD_PWR_1
= 0; /* Drives PWR pin high */
149 for (uint32_t to
= get_timer(0); get_timer(to
) < 30;)
150 ; /* Wait for 30ms */
154 /* Card detect, input with pullup */
165 // debug("*** exit power_on()\n");
169 void power_off (void)
171 // debug("*** enter power_off()\n");
172 select(); /* Wait for card ready */
176 SD_PWR_1
= 1; /* Socket power OFF */
178 socket
[0].stat
|= STA_NOINIT
;
179 // debug("*** exit power_off()\n");
184 int chk_power(void) /* Socket power state: 0=off, 1=on */
187 return SD_PWR_1
== 0;
190 #endif /* SD_PWR_PIN */
194 /*-----------------------------------------------------------------------*/
195 /* Receive a data packet from MMC */
196 /*-----------------------------------------------------------------------*/
200 BYTE
*buff
, /* Data buffer to store received data */
201 UINT btr
/* Byte count (must be multiple of 4) */
204 uint32_t to
= get_timer(0);
206 /* Wait for data packet in timeout of 200ms */
209 } while ((token
== 0xFF) && get_timer(to
) < 200);
210 if(token
!= 0xFE) return 0; /* If not valid data token, retutn with error */
212 tmp
= spi_rcvr(); /* shift in first byte */
213 spi_write(0xff); /* start shift in next byte */
216 asm volatile (""::"r"(buff
), "r"(btr
));
221 *buff
= tmp
; /* store last byte in buffer while SPI module shifts in crc part1 */
223 spi_rcvr(); /* second crc */
225 return 1; /* Return with success */
228 /*-----------------------------------------------------------------------*/
229 /* Send a data packet to MMC */
230 /*-----------------------------------------------------------------------*/
235 const BYTE
*buff
, /* 512 byte data block to be transmitted */
236 BYTE token
/* Data/Stop token */
242 if (!wait_ready()) return 0;
244 spi_write(token
); /* Xmit data token */
245 if (token
!= 0xFD) { /* Is data token */
253 spi_xmit(0xff); /* CRC (Dummy) */
255 resp
= spi_rcvr(); /* Reveive data response */
256 return ((resp
& 0x1F) != 0x05) ? 0 : 1; /* If not accepted, return with error */
262 #endif /* _USE_WRITE */
264 /*-----------------------------------------------------------------------*/
265 /* Send a command packet to MMC */
266 /*-----------------------------------------------------------------------*/
269 BYTE
send_cmd ( /* Returns R1 resp (bit7==1:Send failed) */
270 BYTE cmd
, /* Command index */
271 DWORD arg
/* Argument */
279 // debug("*** send_cmd( %.2x )\n", cmd);
281 if (cmd
& 0x80) { /* ACMD<n> is the command sequense of CMD55-CMD<n> */
283 res
= send_cmd(CMD55
, 0);
288 /* Select the card and wait for ready except to stop multiple block read */
295 /* Send command packet */
296 spi_xmit(0x40 | cmd
); /* Start + Command index */
298 spi_xmit(argtmp
.as8
[3]); /* Argument[31..24] */
299 spi_xmit(argtmp
.as8
[2]); /* Argument[23..16] */
300 spi_xmit(argtmp
.as8
[1]); /* Argument[15..8] */
301 spi_xmit(argtmp
.as8
[0]); /* Argument[7..0] */
303 n
= 0x01; /* Dummy CRC + Stop */
305 n
= 0x95; /* Valid CRC for CMD0(0) */
307 n
= 0x87; /* Valid CRC for CMD8(0x1AA) */
310 /* Receive command response */
312 spi_rcvr(); /* Skip a stuff byte when stop reading */
313 n
= 10; /* Wait for a valid response in timeout of 10 attempts */
316 while ((res
& 0x80) && --n
);
318 return res
; /* Return with the response value */
321 /*--------------------------------------------------------------------------
325 ---------------------------------------------------------------------------*/
327 /*-----------------------------------------------------------------------*/
328 /* Initialize Disk Drive */
329 /*-----------------------------------------------------------------------*/
331 #define MMC_INIT_TO 1000 /* 1s */
333 DSTATUS
disk_initialize (
334 BYTE drv
/* Physical drive nmuber (0) */
337 BYTE n
, cmd
, ty
, ocr
[4];
340 return STA_NOINIT
; /* Supports only single drive */
341 if (socket
[drv
].stat
& STA_NODISK
)
342 return socket
[drv
].stat
; /* No card in the socket */
344 power_on(); /* Force socket power on */
347 spi_rcvr(); /* 80 dummy clocks */
350 if (send_cmd(CMD0
, 0) == 1) { /* Enter Idle state */
351 /* Init timeout timer */
352 uint32_t timer
= get_timer(0);
354 if (send_cmd(CMD8
, 0x1AA) == 1) { /* SDv2? */
355 for (n
= 0; n
< 4; n
++) ocr
[n
] = spi_rcvr(); /* Get trailing return value of R7 resp */
356 if (ocr
[2] == 0x01 && ocr
[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */
357 while (get_timer(timer
) < MMC_INIT_TO
&& send_cmd(ACMD41
, 1UL << 30)); /* Wait for leaving idle state (ACMD41 with HCS bit) */
358 if (get_timer(timer
) < MMC_INIT_TO
&& send_cmd(CMD58
, 0) == 0) { /* Check CCS bit in the OCR */
359 for (n
= 0; n
< 4; n
++) ocr
[n
] = spi_rcvr();
360 ty
= (ocr
[0] & 0x40) ? CT_SD2
| CT_BLOCK
: CT_SD2
; /* SDv2 */
363 } else { /* SDv1 or MMCv3 */
364 if (send_cmd(ACMD41
, 0) <= 1) {
365 ty
= CT_SD1
; cmd
= ACMD41
; /* SDv1 */
367 ty
= CT_MMC
; cmd
= CMD1
; /* MMCv3 */
370 /* Wait for leaving idle state */
371 while (get_timer(timer
) < MMC_INIT_TO
&& send_cmd(cmd
, 0));
373 /* Set R/W block length to 512 */
374 if (!(get_timer(timer
) < MMC_INIT_TO
) || send_cmd(CMD16
, 512) != 0)
378 socket
[drv
].CardType
= ty
;
381 if (ty
) { /* Initialization succeded */
382 socket
[drv
].stat
&= ~STA_NOINIT
; /* Clear STA_NOINIT */
384 } else { /* Initialization failed */
388 return socket
[drv
].stat
;
391 /*-----------------------------------------------------------------------*/
392 /* Get Disk Status */
393 /*-----------------------------------------------------------------------*/
395 DSTATUS
disk_status (
396 BYTE drv
/* Physical drive nmuber (0) */
399 if (drv
) return STA_NOINIT
; /* Supports only single drive */
400 return socket
[drv
].stat
;
403 /*-----------------------------------------------------------------------*/
405 /*-----------------------------------------------------------------------*/
408 BYTE drv
, /* Physical drive nmuber (0) */
409 BYTE
*buff
, /* Pointer to the data buffer to store read data */
410 DWORD sector
, /* Start sector number (LBA) */
411 UINT count
/* Sector count (1..255) */
416 if (drv
|| !count
) return RES_PARERR
;
417 if (socket
[drv
].stat
& STA_NOINIT
) return RES_NOTRDY
;
419 if (!(socket
[drv
].CardType
& CT_BLOCK
)) sector
*= 512; /* Convert to byte address if needed */
421 cmd
= count
> 1 ? CMD18
: CMD17
; /* READ_MULTIPLE_BLOCK : READ_SINGLE_BLOCK */
422 if (send_cmd(cmd
, sector
) == 0) {
424 if (!rcvr_datablock(buff
, 512))
429 send_cmd(CMD12
, 0); /* STOP_TRANSMISSION */
433 return count
? RES_ERROR
: RES_OK
;
436 /*-----------------------------------------------------------------------*/
437 /* Write Sector(s) */
438 /*-----------------------------------------------------------------------*/
442 BYTE drv
, /* Physical drive nmuber (0) */
443 const BYTE
*buff
, /* Pointer to the data to be written */
444 DWORD sector
, /* Start sector number (LBA) */
445 UINT count
/* Sector count (1..255) */
448 if (drv
|| !count
) return RES_PARERR
;
449 if (socket
[drv
].stat
& STA_NOINIT
) return RES_NOTRDY
;
450 if (socket
[drv
].stat
& STA_PROTECT
) return RES_WRPRT
;
452 if (!(socket
[drv
].CardType
& CT_BLOCK
)) sector
*= 512; /* Convert to byte address if needed */
454 if (count
== 1) { /* Single block write */
455 if ((send_cmd(CMD24
, sector
) == 0) /* WRITE_BLOCK */
456 && xmit_datablock(buff
, 0xFE))
459 else { /* Multiple block write */
460 if (socket
[drv
].CardType
& CT_SDC
) send_cmd(ACMD23
, count
);
461 if (send_cmd(CMD25
, sector
) == 0) { /* WRITE_MULTIPLE_BLOCK */
463 if (!xmit_datablock(buff
, 0xFC)) break;
466 if (!xmit_datablock(0, 0xFD)) /* STOP_TRAN token */
472 return count
? RES_ERROR
: RES_OK
;
474 #endif /* _USE_WRITE */
476 /*-----------------------------------------------------------------------*/
477 /* Miscellaneous Functions */
478 /*-----------------------------------------------------------------------*/
482 BYTE drv
, /* Physical drive nmuber (0) */
483 BYTE cmd
, /* Control code */
484 void *buff
/* Buffer to send/receive control data */
488 BYTE n
, csd
[16], *ptr
= buff
;
496 if (socket
[drv
].stat
& STA_NOINIT
) return RES_NOTRDY
;
499 case CTRL_SYNC
: /* Make sure that no pending write process. Do not remove this or written sector might not left updated. */
504 case GET_SECTOR_COUNT
: /* Get number of sectors on the disk (DWORD) */
505 if ((send_cmd(CMD9
, 0) == 0) && rcvr_datablock(csd
, 16)) {
506 if ((csd
[0] >> 6) == 1) { /* SDC ver 2.00 */
507 csize
= csd
[9] + ((WORD
)csd
[8] << 8) + ((DWORD
)(csd
[7] & 63) << 16) + 1;
508 *(DWORD
*)buff
= csize
<< 10;
509 } else { /* SDC ver 1.XX or MMC*/
510 n
= (csd
[5] & 15) + ((csd
[10] & 128) >> 7) + ((csd
[9] & 3) << 1) + 2;
511 csize
= (csd
[8] >> 6) + ((WORD
)csd
[7] << 2) + ((WORD
)(csd
[6] & 3) << 10) + 1;
512 *(DWORD
*)buff
= csize
<< (n
- 9);
518 case GET_BLOCK_SIZE
: /* Get erase block size in unit of sector (DWORD) */
519 if (socket
[drv
].CardType
& CT_SD2
) { /* SDv2? */
520 if (send_cmd(ACMD13
, 0) == 0) { /* Read SD status */
522 if (rcvr_datablock(csd
, 16)) { /* Read partial block */
523 for (n
= 64 - 16; n
; n
--)
524 spi_rcvr(); /* Purge trailing data */
525 *(DWORD
*) buff
= 16UL << (csd
[10] >> 4);
529 } else { /* SDv1 or MMCv3 */
530 if ((send_cmd(CMD9
, 0) == 0) && rcvr_datablock(csd
, 16)) { /* Read CSD */
531 if (socket
[drv
].CardType
& CT_SD1
) { /* SDv1 */
532 *(DWORD
*)buff
= (((csd
[10] & 63) << 1) + ((WORD
)(csd
[11] & 128) >> 7) + 1) << ((csd
[13] >> 6) - 1);
534 *(DWORD
*)buff
= ((WORD
)((csd
[10] & 124) >> 2) + 1) * (((csd
[11] & 3) << 3) + ((csd
[11] & 224) >> 5) + 1);
541 /* Following commands are never used by FatFs module */
543 case MMC_GET_TYPE
: /* Get card type flags (1 byte) */
544 *ptr
= socket
[drv
].CardType
;
548 case MMC_GET_CSD
: /* Receive CSD as a data block (16 bytes) */
549 if (send_cmd(CMD9
, 0) == 0 /* READ_CSD */
550 && rcvr_datablock(ptr
, 16))
554 case MMC_GET_CID
: /* Receive CID as a data block (16 bytes) */
555 if (send_cmd(CMD10
, 0) == 0 /* READ_CID */
556 && rcvr_datablock(ptr
, 16))
560 case MMC_GET_OCR
: /* Receive OCR as an R3 resp (4 bytes) */
561 if (send_cmd(CMD58
, 0) == 0) { /* READ_OCR */
568 case MMC_GET_SDSTAT
: /* Receive SD status as a data block (64 bytes) */
569 if (send_cmd(ACMD13
, 0) == 0) { /* SD_STATUS */
571 if (rcvr_datablock(ptr
, 64))
576 case CTRL_POWER_OFF
: /* Power off */
578 socket
[drv
].stat
|= STA_NOINIT
;
590 #endif /* _USE_IOCTL */
592 /*-----------------------------------------------------------------------*/
593 /* Device Timer Interrupt Procedure (Platform dependent) */
594 /*-----------------------------------------------------------------------*/
595 /* This function must be called in period of 10ms */
597 void disk_timerproc (void)
604 if (SD_WP_1_IN
== 0) /* Write protected */
606 else /* Write enabled */
611 if (SD_CD_1_IN
== 0) /* Card inserted */
613 else /* Socket empty */
614 s
|= (STA_NODISK
| STA_NOINIT
);
617 socket
[0].stat
= s
; /* Update MMC status */