]>
cloudbase.mooo.com Git - z180-stamp.git/blob - avr/mmc.c
a40dc31fdb2b789b8b747f11f3a917777064c1d3
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 /*-----------------------------------------------------------------------*/
9 #include <util/atomic.h>
17 /* Port Controls (Platform dependent) */
18 /* SD card socket connections */
20 /* TODO: config.h cofig macros */
22 //#define SD_CD_0 SBIT(PORT,) /* Card detect switch */
23 //#define SD_CD_0_IN SBIT(PIN,)
24 //#define SD_CD_0_DDR SBIT(DDR,)
26 //#define SD_WP_0 SBIT(PORT,) /* Write protect switch */
27 //#define SD_WP_0_IN SBIT(PIN,)
28 //#define SD_WP_0_DDR SBIT(DDR,)
30 #define SD_CS_0 SBIT(PORTB,0) /* Chip select/Card sense pin */
31 //#define SD_CS_0_IN SBIT(PINB,0)
32 #define SD_CS_0_DDR SBIT(DDRB,0)
35 #define SD_CD_1 SBIT(PORTG,3) /* Card detect switch */
36 #define SD_CD_1_IN SBIT(PING,3)
37 #define SD_CD_1_DDR SBIT(DDRG,3)
39 //#define SD_WP_1 SBIT(PORTG,5) /* Write protect switch */
40 //#define SD_WP_1_IN SBIT(PING,5)
41 //#define SD_WP_1_DDR SBIT(DDRG,5)
43 #define SD_CS_1 SBIT(PORTG,4) /* Chip select/Card sense pin */
44 //#define SD_CS_1_IN SBIT(PING,4)
45 #define SD_CS_1_DDR SBIT(DDRG,4)
48 #define SPI_CLK_SLOW() SPISetMMCInitClock() /* Set slow clock (100k-400k) */
49 #define SPI_CLK_FAST() SPISetFastClock() /* Set fast clock (depends on the CSD) */
51 /*--------------------------------------------------------------------------
52 Definitions for MMC/SDC command
53 ---------------------------------------------------------------------------*/
55 #define CMD0 (0) /* GO_IDLE_STATE */
56 #define CMD1 (1) /* SEND_OP_COND (MMC) */
57 #define ACMD41 (0x80+41) /* SEND_OP_COND (SDC) */
58 #define CMD8 (8) /* SEND_IF_COND */
59 #define CMD9 (9) /* SEND_CSD */
60 #define CMD10 (10) /* SEND_CID */
61 #define CMD12 (12) /* STOP_TRANSMISSION */
62 #define ACMD13 (0x80+13) /* SD_STATUS (SDC) */
63 #define CMD16 (16) /* SET_BLOCKLEN */
64 #define CMD17 (17) /* READ_SINGLE_BLOCK */
65 #define CMD18 (18) /* READ_MULTIPLE_BLOCK */
66 #define CMD23 (23) /* SET_BLOCK_COUNT (MMC) */
67 #define ACMD23 (0x80+23) /* SET_WR_BLK_ERASE_COUNT (SDC) */
68 #define CMD24 (24) /* WRITE_BLOCK */
69 #define CMD25 (25) /* WRITE_MULTIPLE_BLOCK */
70 #define CMD55 (55) /* APP_CMD */
71 #define CMD58 (58) /* READ_OCR */
74 /*--------------------------------------------------------------------------
76 Module Private Functions
78 ---------------------------------------------------------------------------*/
80 struct sdsock_stat_s
{
81 volatile DSTATUS stat
; /* Disk/socket status */
82 BYTE CardType
; /* Card type flags */
92 /*-----------------------------------------------------------------------*/
93 /* Wait for card ready */
94 /*-----------------------------------------------------------------------*/
97 int wait_ready (void) /* 1:OK, 0:Timeout */
99 uint32_t to
= get_timer(0);
101 /* Wait for ready in timeout of 500ms */
103 if (spi_rcvr() == 0xFF) {
106 } while (get_timer(to
) < 500);
111 /*-----------------------------------------------------------------------*/
112 /* Deselect the card and release SPI bus */
113 /*-----------------------------------------------------------------------*/
116 void deselect(BYTE drv
)
118 //debug("*** enter deselect(%.2x)\n", drv);
125 /* Dummy clock (TODO: force DO hi-z for multiple slave SPI) */
126 if (socket
[drv
].stat
& STA_FAST
)
135 SD_CS_0_DDR
= 0; /* Input */
136 SD_CS_0
= 0; /* No Pullup */
144 //debug("*** exit deselect(%.2x)\n", drv);
147 /*-----------------------------------------------------------------------*/
148 /* Select the card and wait for ready */
149 /*-----------------------------------------------------------------------*/
152 int select(BYTE drv
) /* 1:Successful, 0:Timeout */
154 //debug("*** enter select(%.2x)\n", drv);
169 if (socket
[drv
].stat
& STA_FAST
)
174 /* Dummy clock (force DO enabled) */
178 //debug("*** exit select() == 1\n");
182 //debug("*** exit select() == 0\n");
184 return 0; /* Timeout */
187 /*-----------------------------------------------------------------------*/
188 /* Power Control (Platform dependent) */
189 /*-----------------------------------------------------------------------*/
190 /* When the target system does not support socket power control, there */
191 /* is nothing to do in these functions and chk_power always returns 1. */
194 void power_on(BYTE drv
)
196 //debug("*** enter power_on(%.2x)\n", drv);
200 SD_PWR_0
= 0; /* Drives PWR pin high */
205 SD_PWR_1
= 0; /* Drives PWR pin high */
208 #if defined SD_PWR_0 || defined SD_PWR_1
209 for (uint32_t to
= get_timer(0); get_timer(to
) < 30;)
210 ; /* Wait for 30ms */
212 //debug("*** exit power_on(%.2x)\n", drv);
216 void power_off(BYTE drv
)
218 //debug("*** enter power_off(%.2x)\n", drv);
219 select(drv
); /* Wait for card ready */
224 SD_PWR_0
= 1; /* Socket power OFF */
228 SD_PWR_1
= 1; /* Socket power OFF */
231 ATOMIC_BLOCK(ATOMIC_FORCEON
) {
232 socket
[drv
].stat
|= STA_NOINIT
;
234 //debug("*** exit power_off(%.2x)\n", drv);
239 int chk_power(BYTE drv
) /* Socket power state: 0=off, 1=on */
243 return SD_PWR_0
== 0;
246 #endif /* SD_PWR_PIN */
249 return SD_PWR_1
== 0;
252 #endif /* SD_PWR_PIN */
257 /*-----------------------------------------------------------------------*/
258 /* Receive a data packet from MMC */
259 /*-----------------------------------------------------------------------*/
263 BYTE
*buff
, /* Data buffer to store received data */
264 UINT btr
/* Byte count (must be multiple of 4) */
267 uint32_t to
= get_timer(0);
269 /* Wait for data packet in timeout of 200ms */
272 } while ((token
== 0xFF) && get_timer(to
) < 200);
273 if(token
!= 0xFE) return 0; /* If not valid data token, retutn with error */
275 tmp
= spi_rcvr(); /* shift in first byte */
276 spi_write(0xff); /* start shift in next byte */
279 asm volatile (""::"r"(buff
), "r"(btr
));
284 *buff
= tmp
; /* store last byte in buffer while SPI module shifts in crc part1 */
286 spi_rcvr(); /* second crc */
288 return 1; /* Return with success */
291 /*-----------------------------------------------------------------------*/
292 /* Send a data packet to MMC */
293 /*-----------------------------------------------------------------------*/
298 const BYTE
*buff
, /* 512 byte data block to be transmitted */
299 BYTE token
/* Data/Stop token */
305 if (!wait_ready()) return 0;
307 spi_write(token
); /* Xmit data token */
308 if (token
!= 0xFD) { /* Is data token */
316 spi_xmit(0xff); /* CRC (Dummy) */
318 resp
= spi_rcvr(); /* Reveive data response */
319 return ((resp
& 0x1F) != 0x05) ? 0 : 1; /* If not accepted, return with error */
325 #endif /* _USE_WRITE */
327 /*-----------------------------------------------------------------------*/
328 /* Send a command packet to MMC */
329 /*-----------------------------------------------------------------------*/
332 BYTE
send_cmd ( /* Returns R1 resp (bit7==1:Send failed) */
333 BYTE drv
, /* Physical drive nmuber (0) */
334 BYTE cmd
, /* Command index */
335 DWORD arg
/* Argument */
343 if (cmd
& 0x80) { /* ACMD<n> is the command sequense of CMD55-CMD<n> */
345 res
= send_cmd(drv
, CMD55
, 0);
350 //debug("*** send_cmd( %.2x )", cmd);
352 /* Select the card and wait for ready except to stop multiple block read */
356 //debug(" == %.2x\n", 0xff);
361 /* Send command packet */
362 spi_xmit(0x40 | cmd
); /* Start + Command index */
364 spi_xmit(argtmp
.as8
[3]); /* Argument[31..24] */
365 spi_xmit(argtmp
.as8
[2]); /* Argument[23..16] */
366 spi_xmit(argtmp
.as8
[1]); /* Argument[15..8] */
367 spi_xmit(argtmp
.as8
[0]); /* Argument[7..0] */
369 n
= 0x01; /* Dummy CRC + Stop */
371 n
= 0x95; /* Valid CRC for CMD0(0) */
373 n
= 0x87; /* Valid CRC for CMD8(0x1AA) */
376 /* Receive command response */
378 spi_rcvr(); /* Skip a stuff byte when stop reading */
379 n
= 10; /* Wait for a valid response in timeout of 10 attempts */
382 while ((res
& 0x80) && --n
);
384 //debug(" == %.2x\n", res);
385 return res
; /* Return with the response value */
388 /*--------------------------------------------------------------------------
392 ---------------------------------------------------------------------------*/
397 SD_PWR_1
= 1; /* Drives PWR pin low */
398 SD_PWR_0_DDR
= 1; /* Turns on PWR pin as output */
402 SD_WP_0
= 1; /* Pullup */
406 SD_PWR_1
= 1; /* Drives PWR pin low */
407 SD_PWR_1_DDR
= 1; /* Turns on PWR pin as output */
411 SD_WP_1
= 1; /* Pullup */
416 SPI_DDR
= (SPI_DDR
& ~(_BV(SPI_MISO
) | _BV(SPI_SS
)))
417 | _BV(SPI_MOSI
) | _BV(SPI_SCK
);
418 SPI_PORT
= SPI_PORT
& ~(_BV(SPI_MOSI
) | _BV(SPI_SCK
));
422 SD_CD_0
= 1; /* Pullup */
423 #elif defined SD_CS_0_IN
427 #if defined SD_CD_0 || !defined SD_CS_0_IN
434 SD_CD_1
= 1; /* Pullup */
435 #elif defined SD_CS_1_IN
437 SD_CS_1
= 0; /* No Pullup */
439 #if defined SD_CD_1 || !defined SD_CS_1_IN
440 SD_CS_1
= 1; /* Set High */
445 /*-----------------------------------------------------------------------*/
446 /* Initialize Disk Drive */
447 /*-----------------------------------------------------------------------*/
449 #define MMC_INIT_TO 1000 /* 1s */
451 DSTATUS
disk_initialize (
452 BYTE drv
/* Physical drive nmuber (0) */
455 BYTE n
, cmd
, ty
, ocr
[4];
460 res
= socket
[drv
].stat
;
461 if (res
& STA_NODISK
) {
462 return res
& STAT_MASK
; /* No card in the socket */
464 power_on(drv
); /* Force socket power on */
465 ATOMIC_BLOCK(ATOMIC_FORCEON
) {
466 socket
[drv
].stat
&= ~STA_FAST
;
470 spi_rcvr(); /* 80 dummy clocks */
473 if (send_cmd(drv
, CMD0
, 0) == 1) { /* Enter Idle state */
474 /* Init timeout timer */
475 uint32_t timer
= get_timer(0);
477 if (send_cmd(drv
, CMD8
, 0x1AA) == 1) { /* SDv2? */
478 /* Get trailing return value of R7 resp */
479 for (n
= 0; n
< 4; n
++)
481 if (ocr
[2] == 0x01 && ocr
[3] == 0xAA) {
482 /* The card can work at vdd range of 2.7-3.6V */
483 while (get_timer(timer
) < MMC_INIT_TO
484 && send_cmd(drv
, ACMD41
, 1UL << 30))
485 ; /* Wait for leaving idle state (ACMD41 with HCS bit) */
486 if (get_timer(timer
) < MMC_INIT_TO
&& send_cmd(drv
, CMD58
, 0) == 0) {
487 /* Check CCS bit in the OCR */
488 for (n
= 0; n
< 4; n
++)
490 ty
= (ocr
[0] & 0x40) ? CT_SD2
| CT_BLOCK
: CT_SD2
; /* SDv2 */
493 } else { /* SDv1 or MMCv3 */
494 if (send_cmd(drv
, ACMD41
, 0) <= 1) {
495 ty
= CT_SD1
; cmd
= ACMD41
; /* SDv1 */
497 ty
= CT_MMC
; cmd
= CMD1
; /* MMCv3 */
500 /* Wait for leaving idle state */
501 while (get_timer(timer
) < MMC_INIT_TO
&& send_cmd(drv
, cmd
, 0))
504 /* Set R/W block length to 512 */
505 if (!(get_timer(timer
) < MMC_INIT_TO
) || send_cmd(drv
, CMD16
, 512) != 0)
509 socket
[drv
].CardType
= ty
;
512 if (ty
) { /* Initialization succeded */
513 /* Clear STA_NOINIT */
514 ATOMIC_BLOCK(ATOMIC_FORCEON
) {
515 res
= (socket
[drv
].stat
& ~STA_NOINIT
) | STA_FAST
;
516 socket
[drv
].stat
= res
;
518 } else { /* Initialization failed */
522 return socket
[drv
].stat
& STAT_MASK
;
525 /*-----------------------------------------------------------------------*/
526 /* Get Disk Status */
527 /*-----------------------------------------------------------------------*/
529 DSTATUS
disk_status (
530 BYTE drv
/* Physical drive nmuber (0) */
535 //debug("***** disk_status(%.2x)", drv);
539 res
= socket
[drv
].stat
& STAT_MASK
;
541 //debug(" == %.2x\n", res);
545 /*-----------------------------------------------------------------------*/
547 /*-----------------------------------------------------------------------*/
550 BYTE drv
, /* Physical drive nmuber (0) */
551 BYTE
*buff
, /* Pointer to the data buffer to store read data */
552 DWORD sector
, /* Start sector number (LBA) */
553 UINT count
/* Sector count (1..255) */
558 if (drv
>= MAX_DRV
|| !count
)
560 if (socket
[drv
].stat
& STA_NOINIT
)
563 /* Convert to byte address if needed */
564 if (!(socket
[drv
].CardType
& CT_BLOCK
))
567 /* READ_MULTIPLE_BLOCK : READ_SINGLE_BLOCK */
568 cmd
= count
> 1 ? CMD18
: CMD17
;
569 if (send_cmd(drv
, cmd
, sector
) == 0) {
571 if (!rcvr_datablock(buff
, 512))
576 send_cmd(drv
, CMD12
, 0); /* STOP_TRANSMISSION */
580 return count
? RES_ERROR
: RES_OK
;
583 /*-----------------------------------------------------------------------*/
584 /* Write Sector(s) */
585 /*-----------------------------------------------------------------------*/
589 BYTE drv
, /* Physical drive nmuber (0) */
590 const BYTE
*buff
, /* Pointer to the data to be written */
591 DWORD sector
, /* Start sector number (LBA) */
592 UINT count
/* Sector count (1..255) */
597 if (drv
>= MAX_DRV
|| !count
)
599 res
= socket
[drv
].stat
;
600 if ( res
& STA_NOINIT
)
602 if (res
& STA_PROTECT
)
605 /* Convert to byte address if needed */
606 if (!(socket
[drv
].CardType
& CT_BLOCK
))
610 /* Single block write */
611 if ((send_cmd(drv
, CMD24
, sector
) == 0) /* WRITE_BLOCK */
612 && xmit_datablock(buff
, 0xFE))
615 /* Multiple block write */
616 if (socket
[drv
].CardType
& CT_SDC
)
617 send_cmd(drv
, ACMD23
, count
);
618 if (send_cmd(drv
, CMD25
, sector
) == 0) {
619 /* WRITE_MULTIPLE_BLOCK */
621 if (!xmit_datablock(buff
, 0xFC))
625 if (!xmit_datablock(0, 0xFD)) /* STOP_TRAN token */
631 return count
? RES_ERROR
: RES_OK
;
633 #endif /* _USE_WRITE */
635 /*-----------------------------------------------------------------------*/
636 /* Miscellaneous Functions */
637 /*-----------------------------------------------------------------------*/
641 BYTE drv
, /* Physical drive nmuber (0) */
642 BYTE cmd
, /* Control code */
643 void *buff
/* Buffer to send/receive control data */
647 BYTE n
, csd
[16], *ptr
= buff
;
655 if (socket
[drv
].stat
& STA_NOINIT
)
658 /* TODO: SPI clock? */
661 case CTRL_SYNC
: /* Make sure that no pending write process. Do not remove this or written sector might not left updated. */
666 case GET_SECTOR_COUNT
: /* Get number of sectors on the disk (DWORD) */
667 if ((send_cmd(drv
, CMD9
, 0) == 0) && rcvr_datablock(csd
, 16)) {
668 if ((csd
[0] >> 6) == 1) { /* SDC ver 2.00 */
669 csize
= csd
[9] + ((WORD
)csd
[8] << 8) + ((DWORD
)(csd
[7] & 63) << 16) + 1;
670 *(DWORD
*)buff
= csize
<< 10;
671 } else { /* SDC ver 1.XX or MMC*/
672 n
= (csd
[5] & 15) + ((csd
[10] & 128) >> 7) + ((csd
[9] & 3) << 1) + 2;
673 csize
= (csd
[8] >> 6) + ((WORD
)csd
[7] << 2) + ((WORD
)(csd
[6] & 3) << 10) + 1;
674 *(DWORD
*)buff
= csize
<< (n
- 9);
680 case GET_BLOCK_SIZE
: /* Get erase block size in unit of sector (DWORD) */
681 if (socket
[drv
].CardType
& CT_SD2
) { /* SDv2? */
682 if (send_cmd(drv
, ACMD13
, 0) == 0) { /* Read SD status */
684 if (rcvr_datablock(csd
, 16)) { /* Read partial block */
685 for (n
= 64 - 16; n
; n
--)
686 spi_rcvr(); /* Purge trailing data */
687 *(DWORD
*) buff
= 16UL << (csd
[10] >> 4);
691 } else { /* SDv1 or MMCv3 */
692 if ((send_cmd(drv
, CMD9
, 0) == 0) && rcvr_datablock(csd
, 16)) { /* Read CSD */
693 if (socket
[drv
].CardType
& CT_SD1
) { /* SDv1 */
694 *(DWORD
*)buff
= (((csd
[10] & 63) << 1) + ((WORD
)(csd
[11] & 128) >> 7) + 1) << ((csd
[13] >> 6) - 1);
696 *(DWORD
*)buff
= ((WORD
)((csd
[10] & 124) >> 2) + 1) * (((csd
[11] & 3) << 3) + ((csd
[11] & 224) >> 5) + 1);
703 /* Following commands are never used by FatFs module */
705 case MMC_GET_TYPE
: /* Get card type flags (1 byte) */
706 *ptr
= socket
[drv
].CardType
;
710 case MMC_GET_CSD
: /* Receive CSD as a data block (16 bytes) */
711 if (send_cmd(drv
, CMD9
, 0) == 0 /* READ_CSD */
712 && rcvr_datablock(ptr
, 16))
716 case MMC_GET_CID
: /* Receive CID as a data block (16 bytes) */
717 if (send_cmd(drv
, CMD10
, 0) == 0 /* READ_CID */
718 && rcvr_datablock(ptr
, 16))
722 case MMC_GET_OCR
: /* Receive OCR as an R3 resp (4 bytes) */
723 if (send_cmd(drv
, CMD58
, 0) == 0) { /* READ_OCR */
730 case MMC_GET_SDSTAT
: /* Receive SD status as a data block (64 bytes) */
731 if (send_cmd(drv
, ACMD13
, 0) == 0) { /* SD_STATUS */
733 if (rcvr_datablock(ptr
, 64))
738 case CTRL_POWER_OFF
: /* Power off */
751 #endif /* _USE_IOCTL */
753 /*-----------------------------------------------------------------------*/
754 /* Device Timer Interrupt Procedure (Platform dependent) */
755 /*-----------------------------------------------------------------------*/
756 /* This function must be called in period of 10ms */
758 void disk_timerproc (void)
764 if (SD_WP_0_IN
== 0) /* Write protected */
766 else /* Write enabled */
771 if (SD_CD_0_IN
== 0) /* Card inserted */
773 else /* Socket empty */
774 s
|= (STA_NODISK
| STA_NOINIT
);
775 #elif defined SD_CS_0_IN
776 if (SD_CS_0_DDR
== 0) {
777 if (SD_CS_0_IN
== 1) /* Card inserted */
779 else /* Socket empty */
780 s
|= (STA_NODISK
| STA_NOINIT
);
783 socket
[0].stat
= s
; /* Update MMC status */
787 if (SD_WP_1_IN
== 0) /* Write protected */
789 else /* Write enabled */
794 if (SD_CD_1_IN
== 0) /* Card inserted */
796 else /* Socket empty */
797 s
|= (STA_NODISK
| STA_NOINIT
);
798 #elif defined SD_CS_1_IN
799 if (SD_CS_1_DDR
== 0) {
800 if (SD_CS_1_IN
== 1) /* Card inserted */
802 else /* Socket empty */
803 s
|= (STA_NODISK
| STA_NOINIT
);
806 socket
[1].stat
= s
; /* Update MMC status */