diff options
Diffstat (limited to 'avr/mmc.c')
-rw-r--r-- | avr/mmc.c | 173 |
1 files changed, 77 insertions, 96 deletions
@@ -5,16 +5,38 @@ /* are platform dependent. */ /*-----------------------------------------------------------------------*/ -#include <avr/io.h> +#include "common.h" #include <stdbool.h> #include "timer.h" #include "spi.h" #include "diskio.h" -#include "debug.h" -#include "print-utils.h" +//#include "debug.h" -/* Definitions for MMC/SDC command */ +/* Port Controls (Platform dependent) */ +/* SD card socket connections */ + +#define SD_CD_1 SBIT(PORTG,3) /* Card detect switch */ +#define SD_CD_1_IN SBIT(PING,3) +#define SD_CD_1_DDR SBIT(DDRG,3) + +//#define SD_WP_1 SBIT(PORTG,5) /* Write protect switch */ +#define SD_WP_1_IN SBIT(PING,5) +#define SD_WP_1_DDR SBIT(DDRG,5) + +#define SD_CS_1 SBIT(PORTG,4) /* Chip select pin */ +#define SD_CS_1_IN SBIT(PING,4) +#define SD_CS_1_DDR SBIT(DDRG,4) + + +#define FCLK_SLOW() SPISetMMCInitClock() /* Set slow clock (100k-400k) */ +#define FCLK_FAST() SPISetFastClock() /* Set fast clock (depends on the CSD) */ + + +/*-------------------------------------------------------------------------- + Definitions for MMC/SDC command + ---------------------------------------------------------------------------*/ + #define CMD0 (0) /* GO_IDLE_STATE */ #define CMD1 (1) /* SEND_OP_COND (MMC) */ #define ACMD41 (0x80+41) /* SEND_OP_COND (SDC) */ @@ -34,64 +56,23 @@ #define CMD58 (58) /* READ_OCR */ -/* SD card socket connections */ -#if 0 -//#define MMC_PORT PORTG /* Socket contact port */ -//#define MMC_INPORT PING -//#define SD_WP_PIN 5 /* Write protect switch */ -#endif - -/* SD card SPI access */ -#define SD_CD_PORT PORTG -#define SD_CD_DDR DDRG -#define SD_CD_INPORT PING -#define SD_CD_PIN 3 /* Card detect switch */ - -#define SD_WP_PORT PORTG -#define SD_WP_DDR DDRG -#define SD_WP_INPORT PING -//#define SD_WP_PIN 5 /* Write protect switch */ - -#define SD_CS_PORT PORTG -#define SD_CS_DDR DDRG -#define SD_CS_PIN 4 /* Chip select pin */ - - -/* Port Controls (Platform dependent) */ - -#ifdef SD_CD_PIN -static inline -bool sd_cd(void) -{ - return (SD_CD_INPORT & _BV(SD_CD_PIN)) == 0; -} -#endif - -#ifdef SD_WP_PIN -static inline -bool sd_wp(void) -{ - return (SD_WP_INPORT & _BV(SD_WP_PIN)) == 0; -} -#endif - -#define CS_LOW() SD_CS_PORT &= ~(1<<SD_CS_PIN) /* MMC CS = L */ -#define CS_HIGH() SD_CS_PORT |= (1<<SD_CS_PIN) /* MMC CS = H */ - -#define FCLK_SLOW() SPISetMMCInitClock() /* Set slow clock (100k-400k) */ -#define FCLK_FAST() SPISetFastClock() /* Set fast clock (depends on the CSD) */ - /*-------------------------------------------------------------------------- Module Private Functions ---------------------------------------------------------------------------*/ -static volatile -DSTATUS disk_stat = STA_NOINIT; /* Disk status */ +struct sdsock_stat_s { + volatile DSTATUS stat; /* Disk/socket status */ + BYTE CardType; /* Card type flags */ +}; static -BYTE CardType; /* Card type flags */ +struct sdsock_stat_s + socket[2] = { + {.stat=STA_NOINIT}, + {.stat=STA_NOINIT} + }; /*-----------------------------------------------------------------------*/ /* Wait for card ready */ @@ -120,7 +101,7 @@ static void deselect (void) { // debug("*** enter deselect()\n"); - CS_HIGH(); + SD_CS_1 = 1; /* Dummy clock (TODO: force DO hi-z for multiple slave SPI) */ spi_rcvr(); // debug("*** exit deselect()\n"); @@ -136,7 +117,7 @@ static int select (void) /* 1:Successful, 0:Timeout */ { // debug("*** enter select()\n"); - CS_LOW(); + SD_CS_1 = 0; /* Dummy clock (force DO enabled) */ spi_rcvr(); @@ -161,25 +142,25 @@ void power_on(void) { // debug("*** enter power_on()\n"); -#ifdef SD_PWR_PIN - SD_PWR_DDR |= _BV(SD_PWR_PIN); // Turns on PWR pin as output - SD_PWR_PORT &= ~_BV(SD_PWR_PIN); // Drives PWR pin high +#ifdef SD_PWR_1 + SD_PWR_1_DDR = 1; /* Turns on PWR pin as output */ + SD_PWR_1 = 0; /* Drives PWR pin high */ for (uint32_t to = get_timer(0); get_timer(to) < 30;) ; /* Wait for 30ms */ #endif -#ifdef SD_CD_PIN +#ifdef SD_CD_1 /* Card detect, input with pullup */ - SD_CD_DDR &= ~_BV(SD_CD_PIN); - SD_CD_PORT |= _BV(SD_CD_PIN); + SD_CD_1_DDR = 0; + SD_CD_1 = 1; #endif -#ifdef SD_WP_PIN - SD_WP_DDR &= ~_BV(SD_WP_PIN); - SD_WP_PORT |= _BV(SD_WP_PIN); +#ifdef SD_WP_1 + SD_WP_1_DDR = 0; + SD_WP_1 = 1; #endif - SD_CS_PORT |= _BV(SD_CS_PIN); - SD_CS_DDR |= _BV(SD_CS_PIN); // Turns on CS pin as output + SD_CS_1 = 1; + SD_CS_1_DDR = 1; // debug("*** exit power_on()\n"); } @@ -188,13 +169,13 @@ static void power_off (void) { // debug("*** enter power_off()\n"); - select(); /* Wait for card ready */ + select(); /* Wait for card ready */ deselect(); -#ifdef SD_PWR_PIN - SD_PWR_PORT |= (1 << SD_PWR_PIN); /* Socket power OFF */ +#ifdef SD_PWR_1 + SD_PWR_1 = 1; /* Socket power OFF */ #endif - disk_stat |= STA_NOINIT; /* Set STA_NOINIT */ + socket[0].stat |= STA_NOINIT; // debug("*** exit power_off()\n"); } @@ -202,8 +183,8 @@ void power_off (void) static int chk_power(void) /* Socket power state: 0=off, 1=on */ { -#ifdef SD_PWR_PIN - return (SD_PWR_PORT & (1 << SD_PWR_PIN)) ? 0 : 1; +#ifdef SD_PWR_1 + return SD_PWR_1 == 0; #else return 1; #endif /* SD_PWR_PIN */ @@ -357,8 +338,8 @@ DSTATUS disk_initialize ( if (drv) return STA_NOINIT; /* Supports only single drive */ - if (disk_stat & STA_NODISK) - return disk_stat; /* No card in the socket */ + if (socket[drv].stat & STA_NODISK) + return socket[drv].stat; /* No card in the socket */ power_on(); /* Force socket power on */ FCLK_SLOW(); @@ -394,17 +375,17 @@ DSTATUS disk_initialize ( ty = 0; } } - CardType = ty; + socket[drv].CardType = ty; deselect(); if (ty) { /* Initialization succeded */ - disk_stat &= ~STA_NOINIT; /* Clear STA_NOINIT */ + socket[drv].stat &= ~STA_NOINIT; /* Clear STA_NOINIT */ FCLK_FAST(); } else { /* Initialization failed */ power_off(); } - return disk_stat; + return socket[drv].stat; } /*-----------------------------------------------------------------------*/ @@ -416,7 +397,7 @@ DSTATUS disk_status ( ) { if (drv) return STA_NOINIT; /* Supports only single drive */ - return disk_stat; + return socket[drv].stat; } /*-----------------------------------------------------------------------*/ @@ -433,9 +414,9 @@ DRESULT disk_read ( BYTE cmd; if (drv || !count) return RES_PARERR; - if (disk_stat & STA_NOINIT) return RES_NOTRDY; + if (socket[drv].stat & STA_NOINIT) return RES_NOTRDY; - if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */ + if (!(socket[drv].CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */ cmd = count > 1 ? CMD18 : CMD17; /* READ_MULTIPLE_BLOCK : READ_SINGLE_BLOCK */ if (send_cmd(cmd, sector) == 0) { @@ -465,10 +446,10 @@ DRESULT disk_write ( ) { if (drv || !count) return RES_PARERR; - if (disk_stat & STA_NOINIT) return RES_NOTRDY; - if (disk_stat & STA_PROTECT) return RES_WRPRT; + if (socket[drv].stat & STA_NOINIT) return RES_NOTRDY; + if (socket[drv].stat & STA_PROTECT) return RES_WRPRT; - if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */ + if (!(socket[drv].CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */ if (count == 1) { /* Single block write */ if ((send_cmd(CMD24, sector) == 0) /* WRITE_BLOCK */ @@ -476,7 +457,7 @@ DRESULT disk_write ( count = 0; } else { /* Multiple block write */ - if (CardType & CT_SDC) send_cmd(ACMD23, count); + if (socket[drv].CardType & CT_SDC) send_cmd(ACMD23, count); if (send_cmd(CMD25, sector) == 0) { /* WRITE_MULTIPLE_BLOCK */ do { if (!xmit_datablock(buff, 0xFC)) break; @@ -512,7 +493,7 @@ DRESULT disk_ioctl ( res = RES_ERROR; - if (disk_stat & STA_NOINIT) return RES_NOTRDY; + if (socket[drv].stat & STA_NOINIT) return RES_NOTRDY; switch (cmd) { case CTRL_SYNC : /* Make sure that no pending write process. Do not remove this or written sector might not left updated. */ @@ -535,7 +516,7 @@ DRESULT disk_ioctl ( break; case GET_BLOCK_SIZE: /* Get erase block size in unit of sector (DWORD) */ - if (CardType & CT_SD2) { /* SDv2? */ + if (socket[drv].CardType & CT_SD2) { /* SDv2? */ if (send_cmd(ACMD13, 0) == 0) { /* Read SD status */ spi_rcvr(); if (rcvr_datablock(csd, 16)) { /* Read partial block */ @@ -547,7 +528,7 @@ DRESULT disk_ioctl ( } } else { /* SDv1 or MMCv3 */ if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { /* Read CSD */ - if (CardType & CT_SD1) { /* SDv1 */ + if (socket[drv].CardType & CT_SD1) { /* SDv1 */ *(DWORD*)buff = (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1); } else { /* MMCv3 */ *(DWORD*)buff = ((WORD)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1); @@ -560,7 +541,7 @@ DRESULT disk_ioctl ( /* Following commands are never used by FatFs module */ case MMC_GET_TYPE: /* Get card type flags (1 byte) */ - *ptr = CardType; + *ptr = socket[drv].CardType; res = RES_OK; break; @@ -594,7 +575,7 @@ DRESULT disk_ioctl ( case CTRL_POWER_OFF : /* Power off */ power_off(); - disk_stat |= STA_NOINIT; + socket[drv].stat |= STA_NOINIT; res = RES_OK; break; @@ -617,21 +598,21 @@ void disk_timerproc (void) { BYTE s; - s = disk_stat; + s = socket[0].stat; -#ifdef SD_WP_PIN - if (sd_wp()) /* Write protected */ +#ifdef SD_WP_1 + if (SD_WP_1_IN == 0) /* Write protected */ s |= STA_PROTECT; else /* Write enabled */ s &= ~STA_PROTECT; #endif -#ifdef SD_CD_PIN - if (sd_cd()) /* Card inserted */ +#ifdef SD_CD_1 + if (SD_CD_1_IN == 0) /* Card inserted */ s &= ~STA_NODISK; else /* Socket empty */ s |= (STA_NODISK | STA_NOINIT); #endif - disk_stat = s; /* Update MMC status */ + socket[0].stat = s; /* Update MMC status */ } |