Fix set bus width function and factorize it. Add status check errors. Other minor...
authorasterix <asterix@38d2e660-2303-0410-9eaa-f027e97ec537>
Tue, 30 Aug 2011 17:02:23 +0000 (17:02 +0000)
committerasterix <asterix@38d2e660-2303-0410-9eaa-f027e97ec537>
Tue, 30 Aug 2011 17:02:23 +0000 (17:02 +0000)
git-svn-id: https://src.develer.com/svnoss/bertos/trunk@5004 38d2e660-2303-0410-9eaa-f027e97ec537

bertos/drv/sd.c
bertos/drv/sd.h

index 449971d8245baf64d9610bfc0468502dca6741b7..c2e412e5bbc5b270314c6f774e69bd98e0ce6cda 100644 (file)
@@ -589,10 +589,20 @@ LOG_INFOB(
 static void dump(const char *label, uint32_t *r, size_t len)
 {
        ASSERT(r);
-       kprintf("%s [ ", label);
-       for (size_t i = 0; i < len; i++)
-               kprintf("%lx ", r[i]);
-       kputs("]\n");
+       size_t i;
+       int j = 0;
+       kprintf("\n%s [\n", label);
+       for (i = 0; i < len; i++)
+       {
+               if (j == 5)
+               {
+                       kputs("\n");
+                       j = 0;
+               }
+               kprintf("%08lx ", r[i]);
+               j++;
+       }
+       kprintf("\n] len=%d\n\n", i);
 }
 )
 
@@ -830,92 +840,124 @@ int sd_getCsd(Sd *sd)
        return 0;
 }
 
-int sd_appStatus(Sd *sd)
+int sd_getRelativeAddr(Sd *sd)
 {
        ASSERT(sd);
-       LOG_INFO("Send to RCA: %lx\n", SD_ADDR_TO_RCA(sd->addr));
-       if (hsmci_sendCmd(13, SD_ADDR_TO_RCA(sd->addr), HSMCI_CMDR_RSPTYP_48_BIT))
+       if (hsmci_sendCmd(3, 0, HSMCI_CMDR_RSPTYP_48_BIT))
        {
-               LOG_ERR("STATUS: %lx\n", HSMCI_SR);
+               LOG_ERR("RCA: %lx\n", HSMCI_SR);
                return -1;
        }
        else
        {
-               hsmci_readResp(&(sd->status), 1);
-               LOG_INFOB(dump("STATUS", &(sd->status), 1););
+               hsmci_readResp(&sd->addr, 1);
+               LOG_INFOB(dump("RCA", &sd->addr, 1););
+
+               sd->addr = sd->addr >> 16;
        }
 
        return 0;
 }
 
-int sd_getRelativeAddr(Sd *sd)
+#define SD_STATUS_APP_CMD      BV(5)
+#define SD_STATUS_READY        BV(8)
+#define SD_STATUS_CURR_MASK    0x1E00
+#define SD_STATUS_CURR_SHIFT   9
+
+#define SD_GET_STATE(status)    (uint8_t)(((status) & SD_STATUS_CURR_MASK) >> SD_STATUS_CURR_SHIFT)
+
+int sd_appStatus(Sd *sd)
 {
        ASSERT(sd);
-       if (hsmci_sendCmd(3, 0, HSMCI_CMDR_RSPTYP_48_BIT))
+       LOG_INFO("Send to RCA: %lx\n", SD_ADDR_TO_RCA(sd->addr));
+       if (hsmci_sendCmd(13, SD_ADDR_TO_RCA(sd->addr), HSMCI_CMDR_RSPTYP_48_BIT))
        {
-               LOG_ERR("RCA: %lx\n", HSMCI_SR);
+               LOG_ERR("STATUS: %lx\n", HSMCI_SR);
                return -1;
        }
-       else
-       {
-               hsmci_readResp(&sd->addr, 1);
-               LOG_INFOB(dump("RCA", &sd->addr, 1););
 
-               sd->addr = sd->addr >> 16;
-       }
+       hsmci_readResp(&(sd->status), 1);
+       LOG_INFOB(dump("STATUS", &(sd->status), 1););
 
-       return 0;
+       LOG_INFO("State[%d]\n", SD_GET_STATE(sd->status));
+
+       if (sd->status & SD_STATUS_READY)
+               return 0;
+
+       return -1;
 }
 
-int sd_selectCard(Sd *sd)
+
+INLINE int sd_cardSelection(Sd *sd, size_t rca)
 {
        ASSERT(sd);
        LOG_INFO("Select RCA: %lx\n", SD_ADDR_TO_RCA(sd->addr));
-       if (hsmci_sendCmd(7, SD_ADDR_TO_RCA(sd->addr), HSMCI_CMDR_RSPTYP_R1B))
+       if (hsmci_sendCmd(7, rca, HSMCI_CMDR_RSPTYP_R1B))
        {
                LOG_ERR("SELECT_SD: %lx\n", HSMCI_SR);
                return -1;
        }
-       else
-       {
-               HSMCI_CHECK_BUSY();
 
-               hsmci_readResp(&(sd->status), 1);
-               LOG_INFOB(dump("SELECT_SD", &(sd->status), 1););
-       }
+       HSMCI_CHECK_BUSY();
+       hsmci_readResp(&(sd->status), 1);
+       LOG_INFOB(dump("SELECT_SD", &(sd->status), 1););
 
-       return 0;
+       LOG_INFO("State[%d]\n", SD_GET_STATE(sd->status));
+
+       if (sd->status & SD_STATUS_READY)
+               return 0;
+
+       return -1;
 }
 
+int sd_selectCard(Sd *sd)
+{
+       return sd_cardSelection(sd, SD_ADDR_TO_RCA(sd->addr));
+}
+
+int sd_deSelectCard(Sd *sd)
+{
+       uint32_t rca = 0;
+       if (!sd->addr)
+               rca = SD_ADDR_TO_RCA(sd->addr + 1);
+
+       return sd_cardSelection(sd, rca);
+}
+
+
 int sd_setBusWidth(Sd *sd, size_t len)
 {
        ASSERT(sd);
 
-       if (hsmci_sendCmd(55, 0, HSMCI_CMDR_RSPTYP_48_BIT))
+       if (hsmci_sendCmd(55, SD_ADDR_TO_RCA(sd->addr), HSMCI_CMDR_RSPTYP_48_BIT))
        {
                LOG_ERR("APP_CMD %lx\n", HSMCI_SR);
                return -1;
        }
-       else
+
+       uint32_t status = HSMCI_RSPR;
+       if (status & (SD_STATUS_APP_CMD | SD_STATUS_READY))
        {
-               LOG_INFO("APP_CMD %lx\n", HSMCI_RSPR);
-       }
+               hsmci_setBusWidth(len);
 
+               if (hsmci_sendCmd(6, len, HSMCI_CMDR_RSPTYP_48_BIT))
+               {
+                       LOG_ERR("SET_BUS_WIDTH CMD: %lx\n", HSMCI_SR);
+                       return -1;
+               }
 
-       if (hsmci_sendCmd(6, len, HSMCI_CMDR_RSPTYP_48_BIT))
-       {
-               LOG_ERR("SET_BUS_WIDTH: %lx\n", HSMCI_SR);
-               return -1;
-       }
-       else
-       {
                hsmci_readResp(&(sd->status), 1);
+               HSMCI_CHECK_BUSY();
+
                LOG_INFOB(dump("SET_BUS_WIDTH", &(sd->status), 1););
+               LOG_INFO("State[%d]\n", SD_GET_STATE(sd->status));
 
-               HSMCI_CHECK_BUSY();
+               if (sd->status & SD_STATUS_READY)
+                       return 0;
        }
 
-       return 0;
+       LOG_ERR("SET_BUS_WIDTH REP %lx\n", status);
+       return -1;
 }
 
 
@@ -925,18 +967,53 @@ int sd_set_BlockLen(Sd *sd, size_t len)
 
        if (hsmci_sendCmd(16, len, HSMCI_CMDR_RSPTYP_48_BIT))
        {
-               LOG_ERR("SET_BUS_WIDTH: %lx\n", HSMCI_SR);
+               LOG_ERR("SET_BLK_LEN: %lx\n", HSMCI_SR);
                return -1;
        }
-       else
+
+       hsmci_readResp(&(sd->status), 1);
+       HSMCI_CHECK_BUSY();
+
+       LOG_INFOB(dump("SET_BLK_LEN", &(sd->status), 1););
+       LOG_INFO("State[%d]\n", SD_GET_STATE(sd->status));
+
+       sd->csd.blk_len = len;
+
+       if (sd->status & SD_STATUS_READY)
+               return 0;
+
+       return -1;
+}
+
+int sd_readSingleBlock(Sd *sd, size_t index, void *_buf, size_t len)
+{
+       ASSERT(sd);
+       ASSERT(_buf);
+       ASSERT(!(len % sd->csd.blk_len));
+
+       uint32_t *buf = (uint32_t *)_buf;
+
+       hsmci_setBlkSize(sd->csd.blk_len);
+
+       if (hsmci_sendCmd(17, index * sd->csd.blk_len, HSMCI_CMDR_RSPTYP_48_BIT))
        {
-               hsmci_readResp(&(sd->status), 1);
-               LOG_INFOB(dump("SET_BUS_WIDTH", &(sd->status), 1););
+               LOG_ERR("SIGLE_BLK_READ: %lx\n", HSMCI_SR);
+               return -1;
+       }
+       hsmci_readResp(&(sd->status), 1);
+       HSMCI_CHECK_BUSY();
 
-               HSMCI_CHECK_BUSY();
+       LOG_INFOB(dump("SIGLE_BLK_READ", &(sd->status), 1););
+       LOG_INFO("State[%d]\n", SD_GET_STATE(sd->status));
+
+       if (sd->status & SD_STATUS_READY)
+       {
+               hsmci_read(buf, len / sizeof(uint32_t));
+               LOG_INFOB(dump("BLK", buf, 8););
+               return len;
        }
 
-       return 0;
+       return -1;
 }
 
 
index 32f411c8b1ecad72e1082a6b643981bb3f1fb1a2..d706038beed1ac31830f3c3128608917ec1bd0ab 100644 (file)
@@ -134,9 +134,13 @@ int sd_appStatus(Sd *sd);
 int sd_getRelativeAddr(Sd *sd);
 
 int sd_selectCard(Sd *sd);
+int sd_deSelectCard(Sd *sd);
 int sd_setBusWidth(Sd *sd, size_t len);
 int sd_set_BlockLen(Sd *sd, size_t len);
 
+int sd_readSingleBlock(Sd *sd, size_t index, void *_buf, size_t len);
+
+
 INLINE int sd_setBus4bit(Sd *sd)
 {
        return sd_setBusWidth(sd, 1);