* 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 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)
return 0;
}
LOG_ERR("IF_COND: %lx\n", (sd->status));
-
return -1;
}
}
}
}
+
return -1;
}
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;
}
if (hsmci_sendCmd(7, rca, HSMCI_CMDR_RSPTYP_R1B))
{
LOG_ERR("SELECT_SD: %lx\n", HSMCI_SR);
+ sd->status |= SD_STATUS_ERROR;
return -1;
}
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)
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));
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))
{
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))
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;
}
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;
}
if (sd->status & SD_STATUS_READY)
{
- hsmci_waitTransfer();
- sd_deSelectCard(sd);
return size;
}
- sd_deSelectCard(sd);
return -1;
}
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);