Fix check when we cache the samples. Clean up.
[bertos.git] / bertos / cpu / cortex-m3 / drv / sd_sam3.c
index 8718f0757795a030db85a37938225a2d4bcb020b..75817e02b92436e8d7b31c71fa26ee87c67e167f 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>
  */
 
 
 #define SD_STATUS_READY        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_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) & 0x1E00) >> 9)
@@ -284,7 +311,6 @@ int sd_sendIfCond(Sd *sd)
                return 0;
        }
        LOG_ERR("IF_COND: %lx\n", (sd->status));
-
        return -1;
 }
 
@@ -314,6 +340,7 @@ int sd_sendAppOpCond(Sd *sd)
                        }
                }
        }
+
        return -1;
 }
 
@@ -403,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;
        }
 
@@ -425,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;
        }
 
@@ -550,7 +579,7 @@ int sd_getStatus(Sd *sd, SdSSR *ssr, uint32_t *buf, size_t words)
        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))
        {
@@ -558,8 +587,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))
@@ -595,20 +624,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)
+       {
+               sd->status |= SD_STATUS_ERROR;
                return -1;
+       }
 
-       hsmci_prgRxDMA(buf, size / 4, sd->b.blk_size);
+       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))
@@ -637,14 +671,19 @@ static size_t sd_SdReadDirect(struct KBlock *b, block_idx_t idx, void *buf, size
 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);
 
        if (sd_selectCard(sd) < 0)
-               return 0;
+       {
+               sd->status |= SD_STATUS_ERROR;
+               return -1;
+       }
 
-       hsmci_prgTxDMA(_buf, size / 4, sd->b.blk_size);
+       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))