]> cloudbase.mooo.com Git - z180-stamp.git/commitdiff
mmc card select/detect changes and bug fixes.
authorLeo C <erbl259-lmu@yahoo.de>
Thu, 3 Sep 2015 23:16:21 +0000 (01:16 +0200)
committerLeo C <erbl259-lmu@yahoo.de>
Thu, 3 Sep 2015 23:16:21 +0000 (01:16 +0200)
Make access to socket[drv].stat atomic.

avr/mmc.c

index b7cff71ff31427446cf8e0ee239349d46387667c..d45cdf540dba8c76ebe99010fdf48365476f84ff 100644 (file)
--- a/avr/mmc.c
+++ b/avr/mmc.c
@@ -7,6 +7,7 @@
 
 #include "common.h"
 #include <stdbool.h>
+#include <util/atomic.h>
 #include "timer.h"
 #include "spi.h"
 #include "diskio.h"
 
 /* TODO: config.h cofig macros */
 
-//#define SD_CD_0              SBIT(PORT,)             /* Card detect switch */
+//#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                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              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)
 
 
@@ -115,7 +116,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 {
@@ -132,8 +133,8 @@ void deselect(BYTE drv)
 
        if (drv == 0) {
 #ifdef SD_CS_0_IN
-               SD_CS_0_DDR = 0;
-               SD_CS_0 = 0;
+               SD_CS_0_DDR = 0;                /* Input */
+               SD_CS_0 = 0;                    /* No Pullup */
 #endif
        } else {
 #ifdef SD_CS_1_IN
@@ -141,7 +142,7 @@ void deselect(BYTE drv)
                SD_CS_1 = 0;
 #endif
        }
-       //debug("***  exit deselect()\n");
+       //debug("***  exit deselect(%.2x)\n", drv);
 }
 
 /*-----------------------------------------------------------------------*/
@@ -151,7 +152,7 @@ void deselect(BYTE drv)
 static
 int select(BYTE drv)   /* 1:Successful, 0:Timeout */
 {
-       //debug("*** enter select()\n");
+       //debug("*** enter select(%.2x)\n", drv);
        if (drv == 0) {
 #ifdef SD_CS_0_IN
                SD_CS_0 = 1;
@@ -193,7 +194,7 @@ 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
@@ -209,13 +210,13 @@ void power_on(BYTE drv)
                for (uint32_t to = get_timer(0); get_timer(to) < 30;)
                        ; /* Wait for 30ms */
 #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);
 
@@ -228,8 +229,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
@@ -338,8 +341,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<n> is the command sequense of CMD55-CMD<n> */
                cmd &= 0x7F;
                res = send_cmd(drv, CMD55, 0);
@@ -347,11 +348,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 */
@@ -377,6 +382,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 */
 }
 
@@ -414,24 +420,26 @@ void setup_mmc(void)
 
 #if defined SD_CD_0
        SD_CD_0_DDR = 0;
-       SD_CD_0 = 1;
+       SD_CD_0 = 1;                    /* Pullup */
 #elif defined SD_CS_0_IN
        SD_CS_0_DDR = 0;
        SD_CS_0 = 0;
-#else
-       SD_CS_0_DDR = 1;
+#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;
+       SD_CD_1 = 1;                    /* Pullup */
 #elif defined SD_CS_1_IN
        SD_CS_1_DDR = 0;
-       SD_CS_1 = 0;
-#else
+       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;
-       SD_CS_1 = 1;
 #endif
 }
 
@@ -446,14 +454,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 & STAT_MASK; /* 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 */
@@ -500,7 +512,10 @@ 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);
        }
@@ -516,9 +531,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 & STAT_MASK;
+               res = STA_NOINIT;
+       else
+               res = socket[drv].stat & STAT_MASK;
+
+       //debug(" == %.2x\n", res);
+       return res;
 }
 
 /*-----------------------------------------------------------------------*/
@@ -571,11 +593,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 */
@@ -713,7 +738,6 @@ DRESULT disk_ioctl (
 
        case CTRL_POWER_OFF :   /* Power off */
                power_off(drv);
-               socket[drv].stat |= STA_NOINIT;
                res = RES_OK;
                break;