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/include/mmc_spi.h | 9 +++++++ os/hal/include/mmcsd.h | 4 +++ os/hal/include/sdc.h | 1 + os/hal/src/mmc_spi.c | 44 +++++++++++++++++++++++++----- os/hal/src/sdc.c | 46 ++++++++++++++++++++++++++++++++ os/various/fatfs_bindings/fatfs_diskio.c | 12 ++++++++- 6 files changed, 109 insertions(+), 7 deletions(-) diff --git a/os/hal/include/mmc_spi.h b/os/hal/include/mmc_spi.h index a1a33c72d..307ffd3ca 100644 --- a/os/hal/include/mmc_spi.h +++ b/os/hal/include/mmc_spi.h @@ -157,6 +157,14 @@ typedef struct { * @brief Addresses use blocks instead of bytes. */ bool_t block_addresses; + /** + * @brief Card CID. + */ + uint32_t cid[4]; + /** + * @brief Card CSD. + */ + uint32_t csd[4]; /** * @brief Total number of blocks in card. */ @@ -215,6 +223,7 @@ extern "C" { bool_t mmcStopSequentialWrite(MMCDriver *mmcp); bool_t mmcSync(MMCDriver *mmcp); bool_t mmcGetInfo(MMCDriver *mmcp, BlockDeviceInfo *bdip); + bool_t mmcErase(MMCDriver *mmcp, uint32_t startblk, uint32_t endblk); bool_t mmc_lld_is_card_inserted(MMCDriver *mmcp); bool_t mmc_lld_is_write_protected(MMCDriver *mmcp); #ifdef __cplusplus diff --git a/os/hal/include/mmcsd.h b/os/hal/include/mmcsd.h index b21c29442..7595e1202 100644 --- a/os/hal/include/mmcsd.h +++ b/os/hal/include/mmcsd.h @@ -77,6 +77,7 @@ #define MMCSD_CMD_SEL_DESEL_CARD 7 #define MMCSD_CMD_SEND_IF_COND 8 #define MMCSD_CMD_SEND_CSD 9 +#define MMCSD_CMD_SEND_CID 10 #define MMCSD_CMD_STOP_TRANSMISSION 12 #define MMCSD_CMD_SEND_STATUS 13 #define MMCSD_CMD_SET_BLOCKLEN 16 @@ -85,6 +86,9 @@ #define MMCSD_CMD_SET_BLOCK_COUNT 23 #define MMCSD_CMD_WRITE_BLOCK 24 #define MMCSD_CMD_WRITE_MULTIPLE_BLOCK 25 +#define MMCSD_CMD_ERASE_RW_BLK_START 32 +#define MMCSD_CMD_ERASE_RW_BLK_END 33 +#define MMCSD_CMD_ERASE 38 #define MMCSD_CMD_APP_OP_COND 41 #define MMCSD_CMD_LOCK_UNLOCK 42 #define MMCSD_CMD_APP_CMD 55 diff --git a/os/hal/include/sdc.h b/os/hal/include/sdc.h index f54007f44..d2624d306 100644 --- a/os/hal/include/sdc.h +++ b/os/hal/include/sdc.h @@ -203,6 +203,7 @@ extern "C" { sdcflags_t sdcGetAndClearErrors(SDCDriver *sdcp); bool_t sdcSync(SDCDriver *sdcp); bool_t sdcGetInfo(SDCDriver *sdcp, BlockDeviceInfo *bdip); + bool_t sdcErase(SDCDriver *mmcp, uint32_t startblk, uint32_t endblk); bool_t _sdc_wait_for_transfer_state(SDCDriver *sdcp); #ifdef __cplusplus } 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 */ /** @} */ diff --git a/os/various/fatfs_bindings/fatfs_diskio.c b/os/various/fatfs_bindings/fatfs_diskio.c index 06ee81acc..3a8b6866e 100644 --- a/os/various/fatfs_bindings/fatfs_diskio.c +++ b/os/various/fatfs_bindings/fatfs_diskio.c @@ -7,7 +7,7 @@ #include "ch.h" #include "hal.h" - +#include "ffconf.h" #include "diskio.h" #if HAL_USE_MMC_SPI && HAL_USE_SDC @@ -207,6 +207,11 @@ DRESULT disk_ioctl ( case GET_SECTOR_SIZE: *((WORD *)buff) = MMC_SECTOR_SIZE; return RES_OK; +#if _USE_ERASE + case CTRL_ERASE_SECTOR: + mmcErase(&MMCD1, *((DWORD *)buff), *((DWORD *)buff + 1)); + return RES_OK; +#endif default: return RES_PARERR; } @@ -224,6 +229,11 @@ DRESULT disk_ioctl ( case GET_BLOCK_SIZE: *((DWORD *)buff) = 256; /* 512b blocks in one erase block */ return RES_OK; +#if _USE_ERASE + case CTRL_ERASE_SECTOR: + sdcErase(&SDCD1, *((DWORD *)buff), *((DWORD *)buff + 1)); + return RES_OK; +#endif default: return RES_PARERR; } -- cgit v1.2.3