X-Git-Url: http://cloudbase.mooo.com/gitweb/z180-stamp.git/blobdiff_plain/8b6edd92abe1f85ba5b59934d59cbac09af0f2e2..465090d410f8fd09085a54b0fbee5bf33ae99cc1:/avr/mmc.c?ds=inline diff --git a/avr/mmc.c b/avr/mmc.c index afb1473..e1a51fe 100644 --- a/avr/mmc.c +++ b/avr/mmc.c @@ -6,7 +6,7 @@ /*-----------------------------------------------------------------------*/ #include "common.h" -#include +#include #include "timer.h" #include "spi.h" #include "diskio.h" @@ -17,33 +17,36 @@ /* 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_IN SBIT(PINB,0) +#define SD_CS_0 SBIT(PORTB,0) /* Chip select/Card sense 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 SBIT(PORTG,4) /* Chip select/Card sense pin */ +//#define SD_CS_1_IN SBIT(PING,4) #define SD_CS_1_DDR SBIT(DDRG,4) #define SPI_CLK_SLOW() SPISetMMCInitClock() /* Set slow clock (100k-400k) */ -#define SPI_CLK_FAST() SPISetFastClock() /* Set fast clock (depends on the CSD) */ +#define SPI_CLK_FAST() SPISetFastClock() /* Set fast clock (depends on the CSD) */ /*-------------------------------------------------------------------------- Definitions for MMC/SDC command @@ -112,7 +115,7 @@ int wait_ready (void) /* 1:OK, 0:Timeout */ static void deselect(BYTE drv) { - //debug("*** enter deselect()\n"); + //debug("*** enter deselect(%.2x)\n", drv); if (drv == 0) SD_CS_0 = 1; else { @@ -128,16 +131,17 @@ void deselect(BYTE drv) SPI_OFF(); if (drv == 0) { -#ifndef SD_CD_0 - // SD_CS_0 = 1; +#ifdef SD_CS_0_IN + SD_CS_0_DDR = 0; /* Input */ + SD_CS_0 = 0; /* No Pullup */ #endif } else { -#ifndef SD_CD_1 +#ifdef SD_CS_1_IN SD_CS_1_DDR = 0; SD_CS_1 = 0; #endif } - //debug("*** exit deselect()\n"); + //debug("*** exit deselect(%.2x)\n", drv); } /*-----------------------------------------------------------------------*/ @@ -147,11 +151,15 @@ void deselect(BYTE drv) static int select(BYTE drv) /* 1:Successful, 0:Timeout */ { - //debug("*** enter select()\n"); - if (drv == 0) + //debug("*** enter select(%.2x)\n", drv); + if (drv == 0) { +#ifdef SD_CS_0_IN + SD_CS_0 = 1; + SD_CS_0_DDR = 1; +#endif SD_CS_0 = 0; - else { -#ifndef SD_CD_1 + } else { +#ifdef SD_CS_1_IN SD_CS_1 = 1; SD_CS_1_DDR = 1; #endif @@ -185,61 +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(%.2x)\n", drv); 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_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 - 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_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(%.2x)\n", drv); } static void power_off(BYTE drv) { - //debug("*** enter power_off()\n"); + //debug("*** enter power_off(%.2x)\n", drv); select(drv); /* Wait for card ready */ deselect(drv); @@ -252,8 +228,10 @@ void power_off(BYTE drv) SD_PWR_1 = 1; /* Socket power OFF */ #endif } - socket[drv].stat |= STA_NOINIT; - //debug("*** exit power_off()\n"); + ATOMIC_BLOCK(ATOMIC_FORCEON) { + socket[drv].stat |= STA_NOINIT; + } + //debug("*** exit power_off(%.2x)\n", drv); } #if 0 @@ -314,7 +292,6 @@ UINT btr /* Byte count (must be multiple of 4) */ /* Send a data packet to MMC */ /*-----------------------------------------------------------------------*/ -#if _USE_WRITE static int xmit_datablock ( const BYTE *buff, /* 512 byte data block to be transmitted */ @@ -344,7 +321,6 @@ int xmit_datablock ( spi_wait(); return 1; } -#endif /* _USE_WRITE */ /*-----------------------------------------------------------------------*/ /* Send a command packet to MMC */ @@ -362,8 +338,6 @@ BYTE send_cmd ( /* Returns R1 resp (bit7==1:Send failed) */ } argtmp; BYTE n, res; - //debug("*** send_cmd( %.2x )\n", cmd); - if (cmd & 0x80) { /* ACMD is the command sequense of CMD55-CMD */ cmd &= 0x7F; res = send_cmd(drv, CMD55, 0); @@ -371,11 +345,15 @@ BYTE send_cmd ( /* Returns R1 resp (bit7==1:Send failed) */ return res; } + //debug("*** send_cmd( %.2x )", cmd); + /* Select the card and wait for ready except to stop multiple block read */ if (cmd != CMD12) { deselect(drv); - if (!select(drv)) + if (!select(drv)) { + //debug(" == %.2x\n", 0xff); return 0xFF; + } } /* Send command packet */ @@ -401,6 +379,7 @@ BYTE send_cmd ( /* Returns R1 resp (bit7==1:Send failed) */ res = spi_rcvr(); while ((res & 0x80) && --n); + //debug(" == %.2x\n", res); return res; /* Return with the response value */ } @@ -410,6 +389,57 @@ 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; /* Pullup */ +#elif defined SD_CS_0_IN + SD_CS_0_DDR = 0; + SD_CS_0 = 0; +#endif +#if defined SD_CD_0 || !defined SD_CS_0_IN + SD_CS_0 = 1; + SD_CS_0_DDR = 1; +#endif + +#if defined SD_CD_1 + SD_CD_1_DDR = 0; + SD_CD_1 = 1; /* Pullup */ +#elif defined SD_CS_1_IN + SD_CS_1_DDR = 0; + SD_CS_1 = 0; /* No Pullup */ +#endif +#if defined SD_CD_1 || !defined SD_CS_1_IN + SD_CS_1 = 1; /* Set High */ + SD_CS_1_DDR = 1; +#endif +} + /*-----------------------------------------------------------------------*/ /* Initialize Disk Drive */ /*-----------------------------------------------------------------------*/ @@ -421,14 +451,18 @@ DSTATUS disk_initialize ( ) { BYTE n, cmd, ty, ocr[4]; + DSTATUS res; 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 STA_NOINIT; + res = socket[drv].stat; + if (res & STA_NODISK) { + return res & STAT_MASK; /* No card in the socket */ + } power_on(drv); /* Force socket power on */ - socket[drv].stat &= ~STA_FAST; + ATOMIC_BLOCK(ATOMIC_FORCEON) { + socket[drv].stat &= ~STA_FAST; + } SPI_CLK_SLOW(); for (n = 10; n; n--) spi_rcvr(); /* 80 dummy clocks */ @@ -475,12 +509,15 @@ DSTATUS disk_initialize ( if (ty) { /* Initialization succeded */ /* Clear STA_NOINIT */ - socket[drv].stat = (socket[drv].stat & ~STA_NOINIT) | STA_FAST; + ATOMIC_BLOCK(ATOMIC_FORCEON) { + res = (socket[drv].stat & ~STA_NOINIT) | STA_FAST; + socket[drv].stat = res; + } } else { /* Initialization failed */ power_off(drv); } - return socket[drv].stat; + return socket[drv].stat & STAT_MASK; } /*-----------------------------------------------------------------------*/ @@ -491,9 +528,16 @@ DSTATUS disk_status ( BYTE drv /* Physical drive nmuber (0) */ ) { + DSTATUS res; + + //debug("***** disk_status(%.2x)", drv); if (drv >= MAX_DRV) - return STA_NOINIT; - return socket[drv].stat; + res = STA_NOINIT; + else + res = socket[drv].stat & STAT_MASK; + + //debug(" == %.2x\n", res); + return res; } /*-----------------------------------------------------------------------*/ @@ -538,7 +582,6 @@ DRESULT disk_read ( /* Write Sector(s) */ /*-----------------------------------------------------------------------*/ -#if _USE_WRITE DRESULT disk_write ( BYTE drv, /* Physical drive nmuber (0) */ const BYTE *buff, /* Pointer to the data to be written */ @@ -546,11 +589,14 @@ DRESULT disk_write ( UINT count /* Sector count (1..255) */ ) { + DSTATUS res; + if (drv >= MAX_DRV || !count) return RES_PARERR; - if (socket[drv].stat & STA_NOINIT) + res = socket[drv].stat; + if ( res & STA_NOINIT) return RES_NOTRDY; - if (socket[drv].stat & STA_PROTECT) + if (res & STA_PROTECT) return RES_WRPRT; /* Convert to byte address if needed */ @@ -581,13 +627,11 @@ DRESULT disk_write ( return count ? RES_ERROR : RES_OK; } -#endif /* _USE_WRITE */ /*-----------------------------------------------------------------------*/ /* Miscellaneous Functions */ /*-----------------------------------------------------------------------*/ -#if _USE_IOCTL DRESULT disk_ioctl ( BYTE drv, /* Physical drive nmuber (0) */ BYTE cmd, /* Control code */ @@ -688,7 +732,6 @@ DRESULT disk_ioctl ( case CTRL_POWER_OFF : /* Power off */ power_off(drv); - socket[drv].stat |= STA_NOINIT; res = RES_OK; break; @@ -700,7 +743,6 @@ DRESULT disk_ioctl ( return res; } -#endif /* _USE_IOCTL */ /*-----------------------------------------------------------------------*/ /* Device Timer Interrupt Procedure (Platform dependent) */ @@ -715,34 +757,43 @@ 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); -#else +#elif defined SD_CS_1_IN if (SD_CS_1_DDR == 0) { - if (SD_CS_1_IN == 1) /* Card inserted */ + if (SD_CS_1_IN == 1) /* Card inserted */ s &= ~STA_NODISK; - else /* Socket empty */ + else /* Socket empty */ s |= (STA_NODISK | STA_NOINIT); } #endif