X-Git-Url: http://cloudbase.mooo.com/gitweb/z180-stamp.git/blobdiff_plain/1222f338a23212010c7e2d0d7c3a2861e42fa8df..e4c4b148ced1347935dff6200380e90cb3bfcde3:/avr/mmc.c diff --git a/avr/mmc.c b/avr/mmc.c index d780fef..7c4da24 100644 --- a/avr/mmc.c +++ b/avr/mmc.c @@ -10,41 +10,43 @@ #include "timer.h" #include "spi.h" #include "diskio.h" -//#include "debug.h" +#include "debug.h" #define MAX_DRV 2 /* Port Controls (Platform dependent) */ /* SD card socket connections */ -//#define SD_CD_0 SBIT(PORT,) /* Card detect switch */ +/* TODO: config.h cofig macros */ + +//#define SD_CD_0 SBIT(PORT,) /* Card detect switch */ //#define SD_CD_0_IN SBIT(PIN,) //#define SD_CD_0_DDR SBIT(DDR,) -//#define SD_WP_0 SBIT(PORT,) /* Write protect switch */ +//#define SD_WP_0 SBIT(PORT,) /* Write protect switch */ //#define SD_WP_0_IN SBIT(PIN,) //#define SD_WP_0_DDR SBIT(DDR,) -#define SD_CS_0 SBIT(PORTB,0) /* Chip select pin */ +#define SD_CS_0 SBIT(PORTB,0) /* Chip select pin */ #define SD_CS_0_IN SBIT(PINB,0) #define SD_CS_0_DDR SBIT(DDRB,0) -#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_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) */ - +#define SPI_CLK_SLOW() SPISetMMCInitClock() /* Set slow clock (100k-400k) */ +#define SPI_CLK_FAST() SPISetFastClock() /* Set fast clock (depends on the CSD) */ /*-------------------------------------------------------------------------- Definitions for MMC/SDC command @@ -113,14 +115,33 @@ int wait_ready (void) /* 1:OK, 0:Timeout */ static void deselect(BYTE drv) { -// debug("*** enter deselect()\n"); + //debug("*** enter deselect()\n"); if (drv == 0) SD_CS_0 = 1; - else + else { SD_CS_1 = 1; + } + /* Dummy clock (TODO: force DO hi-z for multiple slave SPI) */ + if (socket[drv].stat & STA_FAST) + SPI_CLK_FAST(); + else + SPI_CLK_SLOW(); spi_rcvr(); -// debug("*** exit deselect()\n"); + SPI_OFF(); + + if (drv == 0) { +#ifdef SD_CS_0_IN + SD_CS_0_DDR = 0; + SD_CS_0 = 0; +#endif + } else { +#ifdef SD_CS_1_IN + SD_CS_1_DDR = 0; + SD_CS_1 = 0; +#endif + } + //debug("*** exit deselect()\n"); } /*-----------------------------------------------------------------------*/ @@ -130,20 +151,35 @@ void deselect(BYTE drv) static int select(BYTE drv) /* 1:Successful, 0:Timeout */ { -// debug("*** enter select()\n"); - if (drv == 0) + //debug("*** enter select()\n"); + if (drv == 0) { +#ifdef SD_CS_0_IN + SD_CS_0 = 1; + SD_CS_0_DDR = 1; +#endif SD_CS_0 = 0; - else + } else { +#ifdef SD_CS_1_IN + SD_CS_1 = 1; + SD_CS_1_DDR = 1; +#endif SD_CS_1 = 0; + } + + if (socket[drv].stat & STA_FAST) + SPI_CLK_FAST(); + else + SPI_CLK_SLOW(); + /* Dummy clock (force DO enabled) */ spi_rcvr(); if (wait_ready()) { -// debug("*** exit select() == 1\n"); + //debug("*** exit select() == 1\n"); return 1; /* OK */ } deselect(drv); -// debug("*** exit select() == 0\n"); + //debug("*** exit select() == 0\n"); return 0; /* Timeout */ } @@ -157,57 +193,29 @@ int select(BYTE drv) /* 1:Successful, 0:Timeout */ static void power_on(BYTE drv) { -// debug("*** enter power_on()\n"); + //debug("*** enter power_on()\n"); if (drv == 0) { #ifdef SD_PWR_0 - SD_PWR_0_DDR = 1; /* Turns on PWR pin as output */ SD_PWR_0 = 0; /* Drives PWR pin high */ - - for (uint32_t to = get_timer(0); get_timer(to) < 30;) - ; /* Wait for 30ms */ #endif -#ifdef SD_CD_0 - /* Card detect, input with pullup */ - SD_CD_0_DDR = 0; - SD_CD_0 = 1; -#endif -#ifdef SD_WP_0 - SD_WP_0_DDR = 0; - SD_WP_0 = 1; -#endif - SD_CS_0 = 1; - SD_CS_0_DDR = 1; } else { #ifdef SD_PWR_1 - SD_PWR_1_DDR = 1; /* Turns on PWR pin as output */ SD_PWR_1 = 0; /* Drives PWR pin high */ - +#endif + } +#if defined SD_PWR_0 || defined SD_PWR_1 for (uint32_t to = get_timer(0); get_timer(to) < 30;) ; /* Wait for 30ms */ #endif - -#ifdef SD_CD_1 - /* Card detect, input with pullup */ - SD_CD_1_DDR = 0; - SD_CD_1 = 1; -#endif -#ifdef SD_WP_1 - SD_WP_1_DDR = 0; - SD_WP_1 = 1; -#endif - SD_CS_1 = 1; - SD_CS_1_DDR = 1; - } - -// debug("*** exit power_on()\n"); + //debug("*** exit power_on()\n"); } static void power_off(BYTE drv) { -// debug("*** enter power_off()\n"); + //debug("*** enter power_off()\n"); select(drv); /* Wait for card ready */ deselect(drv); @@ -221,7 +229,7 @@ void power_off(BYTE drv) #endif } socket[drv].stat |= STA_NOINIT; -// debug("*** exit power_off()\n"); + //debug("*** exit power_off()\n"); } #if 0 @@ -330,7 +338,7 @@ BYTE send_cmd ( /* Returns R1 resp (bit7==1:Send failed) */ } argtmp; BYTE n, res; -// debug("*** send_cmd( %.2x )\n", cmd); + //debug("*** send_cmd( %.2x )\n", cmd); if (cmd & 0x80) { /* ACMD is the command sequense of CMD55-CMD */ cmd &= 0x7F; @@ -378,6 +386,55 @@ BYTE send_cmd ( /* Returns R1 resp (bit7==1:Send failed) */ ---------------------------------------------------------------------------*/ +void setup_mmc(void) +{ +#ifdef SD_PWR_0 + SD_PWR_1 = 1; /* Drives PWR pin low */ + SD_PWR_0_DDR = 1; /* Turns on PWR pin as output */ +#endif +#ifdef SD_WP_0 + SD_WP_0_DDR = 0; + SD_WP_0 = 1; /* Pullup */ +#endif + +#ifdef SD_PWR_1 + SD_PWR_1 = 1; /* Drives PWR pin low */ + SD_PWR_1_DDR = 1; /* Turns on PWR pin as output */ +#endif +#ifdef SD_WP_1 + SD_WP_1_DDR = 0; + SD_WP_1 = 1; /* Pullup */ +#endif + + /* SPI as master */ + PRR0 &= ~_BV(PRSPI); + SPI_DDR = (SPI_DDR & ~(_BV(SPI_MISO) | _BV(SPI_SS))) + | _BV(SPI_MOSI) | _BV(SPI_SCK); + SPI_PORT = SPI_PORT & ~(_BV(SPI_MOSI) | _BV(SPI_SCK)); + +#if defined SD_CD_0 + SD_CD_0_DDR = 0; + SD_CD_0 = 1; +#elif defined SD_CS_0_IN + SD_CS_0_DDR = 0; + SD_CS_0 = 0; +#else + SD_CS_0_DDR = 1; + SD_CS_0 = 1; +#endif + +#if defined SD_CD_1 + SD_CD_1_DDR = 0; + SD_CD_1 = 1; +#elif defined SD_CS_1_IN + SD_CS_1_DDR = 0; + SD_CS_1 = 0; +#else + SD_CS_1_DDR = 1; + SD_CS_1 = 1; +#endif +} + /*-----------------------------------------------------------------------*/ /* Initialize Disk Drive */ /*-----------------------------------------------------------------------*/ @@ -393,10 +450,11 @@ DSTATUS disk_initialize ( if (drv >= MAX_DRV) return STA_NOINIT; /* Supports only single drive */ if (socket[drv].stat & STA_NODISK) - return socket[drv].stat; /* No card in the socket */ + return socket[drv].stat & STAT_MASK; /* No card in the socket */ power_on(drv); /* Force socket power on */ - FCLK_SLOW(); + socket[drv].stat &= ~STA_FAST; + SPI_CLK_SLOW(); for (n = 10; n; n--) spi_rcvr(); /* 80 dummy clocks */ @@ -441,12 +499,13 @@ DSTATUS disk_initialize ( deselect(drv); if (ty) { /* Initialization succeded */ - socket[drv].stat &= ~STA_NOINIT; /* Clear STA_NOINIT */ + /* Clear STA_NOINIT */ + socket[drv].stat = (socket[drv].stat & ~STA_NOINIT) | STA_FAST; } else { /* Initialization failed */ power_off(drv); } - return socket[drv].stat; + return socket[drv].stat & STAT_MASK; } /*-----------------------------------------------------------------------*/ @@ -459,7 +518,7 @@ DSTATUS disk_status ( { if (drv >= MAX_DRV) return STA_NOINIT; - return socket[drv].stat; + return socket[drv].stat & STAT_MASK; } /*-----------------------------------------------------------------------*/ @@ -483,7 +542,6 @@ DRESULT disk_read ( /* Convert to byte address if needed */ if (!(socket[drv].CardType & CT_BLOCK)) sector *= 512; - FCLK_FAST(); /* READ_MULTIPLE_BLOCK : READ_SINGLE_BLOCK */ cmd = count > 1 ? CMD18 : CMD17; @@ -523,7 +581,6 @@ DRESULT disk_write ( /* Convert to byte address if needed */ if (!(socket[drv].CardType & CT_BLOCK)) sector *= 512; - FCLK_FAST(); if (count == 1) { /* Single block write */ @@ -574,7 +631,8 @@ DRESULT disk_ioctl ( if (socket[drv].stat & STA_NOINIT) return RES_NOTRDY; - FCLK_FAST(); + /* TODO: SPI clock? */ + switch (cmd) { case CTRL_SYNC : /* Make sure that no pending write process. Do not remove this or written sector might not left updated. */ if (select(drv)) @@ -682,29 +740,45 @@ void disk_timerproc (void) #ifdef SD_WP_0 if (SD_WP_0_IN == 0) /* Write protected */ s |= STA_PROTECT; - else /* Write enabled */ + else /* Write enabled */ s &= ~STA_PROTECT; #endif -#ifdef SD_CD_0 + +#if defined SD_CD_0 if (SD_CD_0_IN == 0) /* Card inserted */ s &= ~STA_NODISK; - else /* Socket empty */ + else /* Socket empty */ s |= (STA_NODISK | STA_NOINIT); +#elif defined SD_CS_0_IN + if (SD_CS_0_DDR == 0) { + if (SD_CS_0_IN == 1) /* Card inserted */ + s &= ~STA_NODISK; + else /* Socket empty */ + s |= (STA_NODISK | STA_NOINIT); + } #endif - socket[0].stat = s; /* Update MMC status */ + socket[0].stat = s; /* Update MMC status */ s = socket[1].stat; #ifdef SD_WP_1 if (SD_WP_1_IN == 0) /* Write protected */ s |= STA_PROTECT; - else /* Write enabled */ + else /* Write enabled */ s &= ~STA_PROTECT; #endif -#ifdef SD_CD_1 + +#if defined SD_CD_1 if (SD_CD_1_IN == 0) /* Card inserted */ s &= ~STA_NODISK; - else /* Socket empty */ + else /* Socket empty */ s |= (STA_NODISK | STA_NOINIT); +#elif defined SD_CS_1_IN + if (SD_CS_1_DDR == 0) { + if (SD_CS_1_IN == 1) /* Card inserted */ + s &= ~STA_NODISK; + else /* Socket empty */ + s |= (STA_NODISK | STA_NOINIT); + } #endif socket[1].stat = s; /* Update MMC status */ }