X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Fcpu%2Fcortex-m3%2Fdrv%2Fsd_sam3.c;h=0c1c0a0628f51acd7980c6237e59df6bfd344e33;hb=2f2be617c1e2ccc0aaefbb2e56fb34046c645126;hp=8718f0757795a030db85a37938225a2d4bcb020b;hpb=b8654961cd6761207f6fc880229b39314f6749e2;p=bertos.git diff --git a/bertos/cpu/cortex-m3/drv/sd_sam3.c b/bertos/cpu/cortex-m3/drv/sd_sam3.c index 8718f075..0c1c0a06 100644 --- a/bertos/cpu/cortex-m3/drv/sd_sam3.c +++ b/bertos/cpu/cortex-m3/drv/sd_sam3.c @@ -26,12 +26,12 @@ * 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 + * \author Daniele Basile */ @@ -60,6 +60,33 @@ #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; } @@ -495,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) @@ -513,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)); @@ -550,7 +581,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 +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)) @@ -595,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; } @@ -626,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; } @@ -661,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; } @@ -757,7 +780,6 @@ static bool sd_blockInit(Sd *sd, KFile *ch) 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);