diff options
-rw-r--r-- | avr/mmc.c | 99 | ||||
-rw-r--r-- | include/diskio.h | 1 | ||||
-rw-r--r-- | include/spi.h | 7 |
3 files changed, 75 insertions, 32 deletions
@@ -10,7 +10,7 @@ #include "timer.h" #include "spi.h" #include "diskio.h" -//#include "debug.h" +#include "debug.h" #define MAX_DRV 2 @@ -42,9 +42,8 @@ #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 +112,32 @@ 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) { +#ifndef SD_CD_0 + // SD_CS_0 = 1; +#endif + } else { +#ifndef SD_CD_1 + SD_CS_1_DDR = 0; + SD_CS_1 = 0; +#endif + } + debug("*** exit deselect()\n"); } /*-----------------------------------------------------------------------*/ @@ -130,20 +147,31 @@ void deselect(BYTE drv) static int select(BYTE drv) /* 1:Successful, 0:Timeout */ { -// debug("*** enter select()\n"); + debug("*** enter select()\n"); if (drv == 0) SD_CS_0 = 0; - else + else { +#ifndef SD_CD_1 + 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,7 +185,7 @@ 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 @@ -168,15 +196,15 @@ void power_on(BYTE drv) ; /* Wait for 30ms */ #endif +#ifdef SD_WP_0 + SD_WP_0_DDR = 0; + SD_WP_0 = 1; +#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 { @@ -188,26 +216,30 @@ void power_on(BYTE drv) ; /* 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 +#ifdef SD_CD_1 + /* Card detect, input with pullup */ + SD_CD_1_DDR = 0; + SD_CD_1 = 1; SD_CS_1 = 1; SD_CS_1_DDR = 1; +#else + /* Input, no pullup */ + SD_CS_1 = 0; + SD_CS_1_DDR = 0; +#endif } -// 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 +253,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 +362,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<n> is the command sequense of CMD55-CMD<n> */ cmd &= 0x7F; @@ -396,7 +428,8 @@ DSTATUS disk_initialize ( return socket[drv].stat; /* 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 */ @@ -483,7 +516,7 @@ DRESULT disk_read ( /* Convert to byte address if needed */ if (!(socket[drv].CardType & CT_BLOCK)) sector *= 512; - FCLK_FAST(); + socket[drv].stat |= STA_FAST; /* READ_MULTIPLE_BLOCK : READ_SINGLE_BLOCK */ cmd = count > 1 ? CMD18 : CMD17; @@ -523,7 +556,7 @@ DRESULT disk_write ( /* Convert to byte address if needed */ if (!(socket[drv].CardType & CT_BLOCK)) sector *= 512; - FCLK_FAST(); + socket[drv].stat |= STA_FAST; if (count == 1) { /* Single block write */ @@ -574,7 +607,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)) @@ -705,6 +739,13 @@ void disk_timerproc (void) s &= ~STA_NODISK; else /* Socket empty */ s |= (STA_NODISK | STA_NOINIT); +#else + 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 */ } diff --git a/include/diskio.h b/include/diskio.h index f5ba3e0..f7a764c 100644 --- a/include/diskio.h +++ b/include/diskio.h @@ -45,6 +45,7 @@ void disk_timerproc (void); #define STA_NOINIT 0x01 /* Drive not initialized */ #define STA_NODISK 0x02 /* No medium in the drive */ #define STA_PROTECT 0x04 /* Write protected */ +#define STA_FAST 0x08 /* Fast SPI clock */ /* Command code for disk_ioctrl() */ diff --git a/include/spi.h b/include/spi.h index 04ea726..6358f62 100644 --- a/include/spi.h +++ b/include/spi.h @@ -27,10 +27,11 @@ #define SPI_SET_SPEED_F_128 do {SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR1) | (1<<SPR0); SPSR = (0<<SPI2X); } while(0) /** switch to fast SPI Clock */ -#define SPISetFastClock() SPI_SET_SPEED_F_2 -#define SPISetSlowClock() SPI_SET_SPEED_F_8 -#define SPISetMMCInitClock() SPI_SET_SPEED_F_64 +#define SPISetFastClock() SPI_SET_SPEED_F_2 +#define SPISetSlowClock() SPI_SET_SPEED_F_8 +#define SPISetMMCInitClock() SPI_SET_SPEED_F_64 +#define SPI_OFF() do { SPCR = 0; } while(0) static inline void spi_wait() { loop_until_bit_is_set(SPSR,SPIF); |