git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4230 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
bbea726934
commit
661cf8e8dc
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -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 */
|
||||
|
||||
/** @} */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue