From 661cf8e8dc3793c0f716e783018514b9bd4e5551 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 22 May 2012 19:45:00 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4230 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/src/mmc_spi.c | 44 ++++++++++++++++++++++++++++++++++++++------ os/hal/src/sdc.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 6 deletions(-) (limited to 'os/hal/src') diff --git a/os/hal/src/mmc_spi.c b/os/hal/src/mmc_spi.c index a4ce608e3..a6dda0dc1 100644 --- a/os/hal/src/mmc_spi.c +++ b/os/hal/src/mmc_spi.c @@ -330,12 +330,12 @@ static uint8_t send_command_R3(MMCDriver *mmcp, uint8_t cmd, uint32_t arg, * * @notapi */ -static bool_t read_CSD(MMCDriver *mmcp, uint32_t csd[4]) { +static bool_t read_CxD(MMCDriver *mmcp, uint8_t cmd, uint32_t cxd[4]) { unsigned i; uint8_t *bp, buf[16]; spiSelect(mmcp->config->spip); - send_hdr(mmcp, MMCSD_CMD_SEND_CSD, 0); + send_hdr(mmcp, cmd, 0); if (recvr1(mmcp) != 0x00) { spiUnselect(mmcp->config->spip); return TRUE; @@ -349,7 +349,7 @@ static bool_t read_CSD(MMCDriver *mmcp, uint32_t csd[4]) { spiReceive(mmcp->config->spip, 16, buf); bp = buf; - for (wp = &csd[3]; wp >= csd; wp--) { + for (wp = &cxd[3]; wp >= cxd; wp--) { *wp = ((uint32_t)bp[0] << 24) | ((uint32_t)bp[1] << 16) | ((uint32_t)bp[2] << 8) | (uint32_t)bp[3]; bp += 4; @@ -491,7 +491,6 @@ void mmcStop(MMCDriver *mmcp) { bool_t mmcConnect(MMCDriver *mmcp) { unsigned i; bool_t result; - uint32_t csd[4]; chDbgCheck(mmcp != NULL, "mmcConnect"); @@ -564,12 +563,15 @@ bool_t mmcConnect(MMCDriver *mmcp) { return TRUE; /* Determine capacity.*/ - if (read_CSD(mmcp, csd)) + if (read_CxD(mmcp, MMCSD_CMD_SEND_CSD, mmcp->csd)) return TRUE; - mmcp->capacity = mmcsdGetCapacity(csd); + mmcp->capacity = mmcsdGetCapacity(mmcp->csd); if (mmcp->capacity == 0) return TRUE; + if (read_CxD(mmcp, MMCSD_CMD_SEND_CID, mmcp->cid)) + return TRUE; + /* Transition to MMC_READY state (if not extracted).*/ chSysLock(); if (mmcp->state == MMC_INSERTED) { @@ -927,6 +929,36 @@ bool_t mmcGetInfo(MMCDriver *mmcp, BlockDeviceInfo *bdip) { return FALSE; } +/** + * @brief Erases blocks. + * + * @param[in] mmcp pointer to the @p MMCDriver object + * @param[in] startblk starting block number + * @param[in] endblk ending block number + * + * @return The operation status. + * @retval FALSE the operation succeeded. + * @retval TRUE the operation failed. + * + * @api + */ +bool_t mmcErase(MMCDriver *mmcp, uint32_t startblk, uint32_t endblk) { + + chDbgCheck((mmcp != NULL), "mmcErase"); + + if (send_command_R1(mmcp, MMCSD_CMD_ERASE_RW_BLK_START, startblk)) + return TRUE; + + if (send_command_R1(mmcp, MMCSD_CMD_ERASE_RW_BLK_END, endblk)) + return TRUE; + + if (send_command_R1(mmcp, MMCSD_CMD_ERASE, 0)) + return TRUE; + + return FALSE; +} + + #endif /* HAL_USE_MMC_SPI */ /** @} */ diff --git a/os/hal/src/sdc.c b/os/hal/src/sdc.c index 653819bb3..ff90fdd62 100644 --- a/os/hal/src/sdc.c +++ b/os/hal/src/sdc.c @@ -505,6 +505,52 @@ bool_t sdcGetInfo(SDCDriver *sdcp, BlockDeviceInfo *bdip) { return CH_SUCCESS; } + +/** + * @brief Erases the supplied blocks. + * + * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] startblk starting block number + * @param[in] endblk ending block number + * + * @return The operation status. + * @retval CH_SUCCESS the operation succeeded. + * @retval CH_FAILED the operation failed. + * + * @api + */ +bool_t sdcErase(SDCDriver *sdcp, uint32_t startblk, uint32_t endblk) { + uint32_t resp[1]; + + chDbgCheck((sdcp != NULL), "sdcErase"); + + /* Driver handles data in 512 bytes blocks (just like HC cards). But if we + have not HC card than we must convert address from blocks to bytes.*/ + if (!(sdcp->cardmode & SDC_MODE_HIGH_CAPACITY)) { + startblk *= MMCSD_BLOCK_SIZE; + endblk *= MMCSD_BLOCK_SIZE; + } + + _sdc_wait_for_transfer_state( sdcp ); + + if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_ERASE_RW_BLK_START, startblk, resp) != CH_SUCCESS || MMCSD_R1_ERROR(resp[0])) + return CH_FAILED; + + if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_ERASE_RW_BLK_END, endblk, resp) != CH_SUCCESS || MMCSD_R1_ERROR(resp[0])) + return CH_FAILED; + + if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_ERASE, 0, resp) != CH_SUCCESS || MMCSD_R1_ERROR(resp[0])) + return CH_FAILED; + + /* Quick sleep to allow it to transition to programming or receiving state */ + chThdSleepMilliseconds(2); + + /* Wait for it to return to transfer state to indicate it has finished erasing */ + _sdc_wait_for_transfer_state( sdcp ); + + return CH_SUCCESS; +} + #endif /* HAL_USE_SDC */ /** @} */ -- cgit v1.2.3