Disable uneeded assert.
[bertos.git] / bertos / cpu / cortex-m3 / drv / sd_sam3.c
index 3c228347d8d3e3eb776b85ac2f05bb5df4a1ce52..0c1c0a0628f51acd7980c6237e59df6bfd344e33 100644 (file)
  * invalidate any other reasons why the executable file might be covered by
  * the GNU General Public License.
  *
- * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2011 Develer S.r.l. (http://www.develer.com/)
  * -->
  *
  * \brief Function library for secure digital memory.
  *
- * \author Francesco Sacchi <batt@develer.com>
+ * \author Daniele Basile <asterix@develer.com>
  */
 
 
 #include <string.h> /* memset */
 
 
+#define SD_SEND_ALL_CID        BV(0)
 #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_CARD_IS_LOCKED      BV(25)
 
-#define SD_READY_FOR_DATA         BV(8)
-#define SD_CARD_IS_LOCKED         BV(25)
+#define SD_OCR_CCS              BV(30)     /**< SD Card Capacity Status (CCS) */
+#define SD_OCR_BUSY             BV(31)     /**< SD/MMC Card power up status bit (busy) */
 
-#define SD_SEND_CID_RCA     0
-#define SD_SEND_ALL_CID   BV(0)
+#define SD_OCR_VDD_27_28        BV(15)
+#define SD_OCR_VDD_28_29        BV(16)
+#define SD_OCR_VDD_29_30        BV(17)
+#define SD_OCR_VDD_30_31        BV(18)
+#define SD_OCR_VDD_31_32        BV(19)
+#define SD_OCR_VDD_32_33        BV(20)
 
 
+#define SD_HOST_VOLTAGE_RANGE     (SD_OCR_VDD_27_28 | \
+                                   SD_OCR_VDD_28_29 | \
+                                   SD_OCR_VDD_29_30 | \
+                                   SD_OCR_VDD_30_31 | \
+                                   SD_OCR_VDD_31_32 | \
+                                   SD_OCR_VDD_32_33)
+
+
+#define CMD8_V_RANGE_CHECK_PAT    0xAA
+#define CMD8_V_RANGE_27V_36V      (0x100 | CMD8_V_RANGE_CHECK_PAT)
+#define CMD8_V_RANGE_LOW          (0x1000 | CMD8_V_RANGE_CHECK_PAT)
+#define CMD8_V_ECHO_REPLY         0xFF
+#define CMD8_SUPP_V_RANGE_REPLY   0xFF00
+
+#define SD_STATUS_ERROR          BV(19)
+
+#define SD_GET_ERRORS(status)   ((status) & 0xFFF80000)
 #define SD_ADDR_TO_RCA(addr)    (uint32_t)(((addr) << 16) & 0xFFFF0000)
-#define SD_GET_STATE(status)    (uint8_t)(((status) & SD_STATUS_CURR_MASK) >> SD_STATUS_CURR_SHIFT)
+#define SD_GET_STATE(status)    (uint8_t)(((status) & 0x1E00) >> 9)
 
 static const uint32_t tran_exp[] =
 {
@@ -83,22 +104,22 @@ static const uint8_t tran_mant[] =
 };
 
 
-void sd_dumpCsd(SDcsd *csd);
-void sd_dumpCid(SDcid *cid);
-void sd_dumpSsr(SDssr *ssr);
+void sd_dumpCsd(SdCSD *csd);
+void sd_dumpCid(SdCID *cid);
+void sd_dumpSsr(SdSSR *ssr);
 
 void sd_sendInit(void);
 void sd_goIdle(void);
 int sd_sendIfCond(Sd *sd);
 int sd_sendAppOpCond(Sd *sd);
 
-int sd_getCid(Sd *sd, SDcid *cid, uint32_t addr, uint8_t flag);
-int sd_getCsd(Sd *sd, SDcsd *csd);
+int sd_getCid(Sd *sd, SdCID *cid, uint32_t addr, uint8_t flag);
+int sd_getCsd(Sd *sd, SdCSD *csd);
 int sd_getSrc(Sd *sd);
 
 int sd_appStatus(Sd *sd);
 int sd_getRelativeAddr(Sd *sd);
-int sd_getStatus(Sd *sd, SDssr *ssr, uint32_t *buf, size_t words);
+int sd_getStatus(Sd *sd, SdSSR *ssr, uint32_t *buf, size_t words);
 
 int sd_selectCard(Sd *sd);
 int sd_deSelectCard(Sd *sd);
@@ -139,7 +160,7 @@ static void dump(const char *label, uint32_t *r, size_t len)
 }
 )
 
-void sd_dumpCsd(SDcsd *csd)
+void sd_dumpCsd(SdCSD *csd)
 {
        ASSERT(csd);
 
@@ -157,7 +178,7 @@ void sd_dumpCsd(SDcsd *csd)
 
 }
 
-void sd_dumpCid(SDcid *cid)
+void sd_dumpCid(SdCID *cid)
 {
        ASSERT(cid);
 
@@ -170,7 +191,7 @@ void sd_dumpCid(SDcid *cid)
                                                                                                (BCD_TO_INT_32BIT(cid->year_off) % 12));
 }
 
-void sd_dumpSsr(SDssr *ssr)
+void sd_dumpSsr(SdSSR *ssr)
 {
        ASSERT(ssr);
 
@@ -182,7 +203,7 @@ void sd_dumpSsr(SDssr *ssr)
 }
 
 
-static int sd_decodeCsd(SDcsd *csd, uint32_t *resp, size_t len)
+static int sd_decodeCsd(SdCSD *csd, uint32_t *resp, size_t len)
 {
        ASSERT(csd);
        ASSERT(resp);
@@ -290,7 +311,6 @@ int sd_sendIfCond(Sd *sd)
                return 0;
        }
        LOG_ERR("IF_COND: %lx\n", (sd->status));
-
        return -1;
 }
 
@@ -318,8 +338,6 @@ int sd_sendAppOpCond(Sd *sd)
                                LOG_INFO("SD power up! Hight Capability [%d]\n", (bool)((sd->status) & SD_OCR_CCS));
                                return 0;
                        }
-
-                       LOG_ERR("sd not ready.\n");
                }
        }
 
@@ -327,11 +345,11 @@ int sd_sendAppOpCond(Sd *sd)
 }
 
 
-int sd_getCid(Sd *sd, SDcid *cid, uint32_t addr, uint8_t flag)
+int sd_getCid(Sd *sd, SdCID *cid, uint32_t addr, uint8_t flag)
 {
        ASSERT(sd);
        ASSERT(cid);
-       memset(cid, 0, sizeof(SDcid));
+       memset(cid, 0, sizeof(SdCID));
 
        uint8_t idx = 9; // CMD9 get cid from gived sd address (RCA)
        if (flag & SD_SEND_ALL_CID)
@@ -365,11 +383,11 @@ int sd_getCid(Sd *sd, SDcid *cid, uint32_t addr, uint8_t flag)
        return 0;
 }
 
-int sd_getCsd(Sd *sd, SDcsd *csd)
+int sd_getCsd(Sd *sd, SdCSD *csd)
 {
        ASSERT(sd);
        ASSERT(csd);
-       memset(csd, 0, sizeof(SDcsd));
+       memset(csd, 0, sizeof(SdCSD));
 
        LOG_INFO("Send to RCA: %lx\n", SD_ADDR_TO_RCA(sd->addr));
        if (hsmci_sendCmd(9, SD_ADDR_TO_RCA(sd->addr), HSMCI_CMDR_RSPTYP_136_BIT))
@@ -412,6 +430,7 @@ int sd_appStatus(Sd *sd)
        if (hsmci_sendCmd(13, SD_ADDR_TO_RCA(sd->addr), HSMCI_CMDR_RSPTYP_48_BIT))
        {
                LOG_ERR("STATUS: %lx\n", HSMCI_SR);
+               sd->status |= SD_STATUS_ERROR;
                return -1;
        }
 
@@ -434,6 +453,7 @@ INLINE int sd_cardSelection(Sd *sd, uint32_t rca)
        if (hsmci_sendCmd(7, rca, HSMCI_CMDR_RSPTYP_R1B))
        {
                LOG_ERR("SELECT_SD: %lx\n", HSMCI_SR);
+               sd->status |= SD_STATUS_ERROR;
                return -1;
        }
 
@@ -504,7 +524,6 @@ int sd_setBusWidth(Sd *sd, size_t len)
        hsmci_readResp(&(sd->status), 1);
        if ((sd->status) & (SD_STATUS_APP_CMD | SD_STATUS_READY))
        {
-               hsmci_setBusWidth(len);
 
                uint8_t arg = 0;
                if (len == 4)
@@ -522,7 +541,10 @@ int sd_setBusWidth(Sd *sd, size_t len)
                LOG_INFO("State[%d]\n", SD_GET_STATE(sd->status));
 
                if (sd->status & SD_STATUS_READY)
+               {
+                       hsmci_setBusWidth(len);
                        return 0;
+               }
        }
 
        LOG_ERR("SET_BUS_WIDTH REP %lx\n", (sd->status));
@@ -553,13 +575,13 @@ int sd_set_BlockLen(Sd *sd, size_t len)
        return -1;
 }
 
-int sd_getStatus(Sd *sd, SDssr *ssr, uint32_t *buf, size_t words)
+int sd_getStatus(Sd *sd, SdSSR *ssr, uint32_t *buf, size_t words)
 {
        ASSERT(sd);
        ASSERT(ssr);
 
        // Status reply with 512bit data, so the block size in byte is 64
-       hsmci_prgRxDMA(buf, words, 64);
+       hsmci_read(buf, words, 64);
 
        if (hsmci_sendCmd(55, SD_ADDR_TO_RCA(sd->addr), HSMCI_CMDR_RSPTYP_48_BIT))
        {
@@ -567,8 +589,8 @@ int sd_getStatus(Sd *sd, SDssr *ssr, uint32_t *buf, size_t words)
                return -1;
        }
 
-       uint32_t status = HSMCI_RSPR;
-       if (status & (SD_STATUS_APP_CMD | SD_STATUS_READY))
+       hsmci_readResp(&(sd->status), 1);
+       if (sd->status & (SD_STATUS_APP_CMD | SD_STATUS_READY))
        {
                if (hsmci_sendCmd(13, 0, HSMCI_CMDR_RSPTYP_48_BIT |
                                BV(HSMCI_CMDR_TRDIR) | HSMCI_CMDR_TRCMD_START_DATA | HSMCI_CMDR_TRTYP_SINGLE))
@@ -586,7 +608,7 @@ int sd_getStatus(Sd *sd, SDssr *ssr, uint32_t *buf, size_t words)
                        hsmci_waitTransfer();
 
                        LOG_INFOB(dump("STATUS", buf, words););
-                       memset(ssr, 0, sizeof(SDssr));
+                       memset(ssr, 0, sizeof(SdSSR));
                        ssr->bus_width  = UNSTUFF_BITS(buf, 510, 2);
                        ssr->card_type  = UNSTUFF_BITS(buf, 480, 16);
                        ssr->au_size  = UNSTUFF_BITS(buf, 432, 8);
@@ -604,26 +626,25 @@ int sd_getStatus(Sd *sd, SDssr *ssr, uint32_t *buf, size_t words)
 void sd_setHightSpeed(Sd *sd)
 {
        (void)sd;
-       hsmci_setSpeed(2100000, true);
+       hsmci_setSpeed(HSMCI_HIGH_SPEED, HSMCI_HS_MODE);
 }
 
 
 static size_t sd_SdReadDirect(struct KBlock *b, block_idx_t idx, void *buf, size_t offset, size_t size)
 {
        ASSERT(buf);
+       ASSERT(!((uint32_t)buf & 0x3));
+
        Sd *sd = SD_CAST(b);
        LOG_INFO("reading from block %ld, offset %d, size %d\n", idx, offset, size);
 
-       if (sd_selectCard(sd) < 0)
-               return -1;
-
-       hsmci_prgRxDMA(buf, size / 4, sd->b.blk_size);
+       hsmci_waitTransfer();
+       hsmci_read(buf, size / 4, sd->b.blk_size);
 
        if (hsmci_sendCmd(17, idx * sd->b.blk_size + offset, HSMCI_CMDR_RSPTYP_48_BIT |
                        BV(HSMCI_CMDR_TRDIR) | HSMCI_CMDR_TRCMD_START_DATA | HSMCI_CMDR_TRTYP_SINGLE))
        {
                LOG_ERR("SIGLE_BLK_READ: %lx\n", HSMCI_SR);
-               sd_deSelectCard(sd);
                return -1;
        }
 
@@ -635,31 +656,27 @@ static size_t sd_SdReadDirect(struct KBlock *b, block_idx_t idx, void *buf, size
        if (sd->status & SD_STATUS_READY)
        {
                hsmci_waitTransfer();
-               sd_deSelectCard(sd);
                return size;
        }
-
-       sd_deSelectCard(sd);
        return -1;
 }
 
 static size_t sd_SdWriteDirect(KBlock *b, block_idx_t idx, const void *buf, size_t offset, size_t size)
 {
        ASSERT(buf);
+       ASSERT(!((uint32_t)buf & 0x3));
+
        Sd *sd = SD_CAST(b);
        const uint32_t *_buf = (const uint32_t *)buf;
-       LOG_INFO("reading from block %ld, offset %d, size %d\n", idx, offset, size);
+       LOG_INFO("writing block %ld, offset %d, size %d\n", idx, offset, size);
 
-       if (sd_selectCard(sd) < 0)
-               return 0;
-
-       hsmci_prgTxDMA(_buf, size / 4, sd->b.blk_size);
+       hsmci_waitTransfer();
+       hsmci_write(_buf, size / 4, sd->b.blk_size);
 
        if (hsmci_sendCmd(24, idx * sd->b.blk_size + offset, HSMCI_CMDR_RSPTYP_48_BIT |
                                                HSMCI_CMDR_TRCMD_START_DATA | HSMCI_CMDR_TRTYP_SINGLE))
        {
                LOG_ERR("SIGLE_BLK_WRITE: %lx\n", HSMCI_SR);
-               sd_deSelectCard(sd);
                return -1;
        }
 
@@ -670,12 +687,9 @@ static size_t sd_SdWriteDirect(KBlock *b, block_idx_t idx, const void *buf, size
 
        if (sd->status & SD_STATUS_READY)
        {
-               hsmci_waitTransfer();
-               sd_deSelectCard(sd);
                return size;
        }
 
-       sd_deSelectCard(sd);
        return -1;
 }
 
@@ -683,7 +697,7 @@ static size_t sd_SdWriteDirect(KBlock *b, block_idx_t idx, const void *buf, size
 static int sd_SdError(KBlock *b)
 {
        Sd *sd = SD_CAST(b);
-       return 0;//sd->status;
+       return SD_GET_ERRORS(sd->status);
 }
 
 static void sd_SdClearerr(KBlock *b)
@@ -694,6 +708,7 @@ static void sd_SdClearerr(KBlock *b)
 
 static bool sd_blockInit(Sd *sd, KFile *ch)
 {
+       (void)ch;
        ASSERT(sd);
        memset(sd, 0, sizeof(*sd));
        DB(sd->b.priv.type = KBT_SD);
@@ -722,7 +737,7 @@ static bool sd_blockInit(Sd *sd, KFile *ch)
 
        if (sd_power_on)
        {
-               SDcid cid;
+               SdCID cid;
                if(sd_getCid(sd, &cid, 0, SD_SEND_ALL_CID) < 0)
                        return false;
                else
@@ -737,7 +752,7 @@ static bool sd_blockInit(Sd *sd, KFile *ch)
                        LOG_INFO("RCA: %0lx\n", sd->addr);
                }
 
-               SDcsd csd;
+               SdCSD csd;
                if (sd_getCsd(sd, &csd) < 0)
                        return false;
                else
@@ -759,13 +774,12 @@ static bool sd_blockInit(Sd *sd, KFile *ch)
                        return false;
                }
 
-               if (sd->status & SD_READY_FOR_DATA)
+               if (sd->status & SD_STATUS_READY)
                {
                        sd_selectCard(sd);
                        sd_set_BlockLen(sd, SD_DEFAULT_BLOCKLEN);
                        sd_setBus4bit(sd);
                        sd_setHightSpeed(sd);
-                       sd_deSelectCard(sd);
 
                        #if CONFIG_SD_AUTOASSIGN_FAT
                                disk_assignDrive(&sd->b, 0);
@@ -774,7 +788,7 @@ static bool sd_blockInit(Sd *sd, KFile *ch)
                        return true;
                }
        }
-
+       LOG_ERR("SD not ready.\n");
        return false;
 }