git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4347 35acf78f-673a-0410-8e92-d51de3d6d3f4
parent
1d674cc603
commit
80443125b2
|
@ -59,21 +59,6 @@
|
||||||
#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__)
|
#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__)
|
||||||
#define MMC_NICE_WAITING TRUE
|
#define MMC_NICE_WAITING TRUE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Number of positive insertion queries before generating the
|
|
||||||
* insertion event.
|
|
||||||
*/
|
|
||||||
#if !defined(MMC_POLLING_INTERVAL) || defined(__DOXYGEN__)
|
|
||||||
#define MMC_POLLING_INTERVAL 10
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Interval, in milliseconds, between insertion queries.
|
|
||||||
*/
|
|
||||||
#if !defined(MMC_POLLING_DELAY) || defined(__DOXYGEN__)
|
|
||||||
#define MMC_POLLING_DELAY 10
|
|
||||||
#endif
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -92,13 +77,14 @@
|
||||||
* @brief Driver state machine possible states.
|
* @brief Driver state machine possible states.
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
MMC_UNINIT = 0, /**< Not initialized. */
|
MMC_UNINIT = 0, /**< Not initialized. */
|
||||||
MMC_STOP = 1, /**< Stopped. */
|
MMC_STOP = 1, /**< Stopped. */
|
||||||
MMC_WAIT = 2, /**< Waiting card. */
|
MMC_READY = 2, /**< Ready. */
|
||||||
MMC_INSERTED = 3, /**< Card inserted. */
|
MMC_CONNECTING = 3, /**< Card connection in progress. */
|
||||||
MMC_READY = 4, /**< Card ready. */
|
MMC_DISCONNECTING = 4, /**< Card disconnection in progress. */
|
||||||
MMC_READING = 5, /**< Reading. */
|
MMC_ACTIVE = 5, /**< Cart initialized. */
|
||||||
MMC_WRITING = 6 /**< Writing. */
|
MMC_READING = 6, /**< Read operation in progress. */
|
||||||
|
MMC_WRITING = 7, /**< Write operation in progress. */
|
||||||
} mmcstate_t;
|
} mmcstate_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -153,22 +139,6 @@ typedef struct {
|
||||||
* @brief Current configuration data.
|
* @brief Current configuration data.
|
||||||
*/
|
*/
|
||||||
const MMCConfig *config;
|
const MMCConfig *config;
|
||||||
/**
|
|
||||||
* @brief Card insertion event source.
|
|
||||||
*/
|
|
||||||
EventSource inserted_event;
|
|
||||||
/**
|
|
||||||
* @brief Card removal event source.
|
|
||||||
*/
|
|
||||||
EventSource removed_event;
|
|
||||||
/**
|
|
||||||
* @brief MMC insertion polling timer.
|
|
||||||
*/
|
|
||||||
VirtualTimer vt;
|
|
||||||
/**
|
|
||||||
* @brief Insertion counter.
|
|
||||||
*/
|
|
||||||
uint_fast8_t cnt;
|
|
||||||
/***
|
/***
|
||||||
* @brief Addresses use blocks instead of bytes.
|
* @brief Addresses use blocks instead of bytes.
|
||||||
*/
|
*/
|
||||||
|
@ -193,6 +163,22 @@ typedef struct {
|
||||||
*/
|
*/
|
||||||
#define mmcGetDriverState(mmcp) ((mmcp)->state)
|
#define mmcGetDriverState(mmcp) ((mmcp)->state)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the card insertion status.
|
||||||
|
* @note This macro wraps a low level function named
|
||||||
|
* @p sdc_lld_is_card_inserted(), this function must be
|
||||||
|
* provided by the application because it is not part of the
|
||||||
|
* SDC driver.
|
||||||
|
*
|
||||||
|
* @param[in] mmcp pointer to the @p MMCDriver object
|
||||||
|
* @return The card state.
|
||||||
|
* @retval FALSE card not inserted.
|
||||||
|
* @retval TRUE card inserted.
|
||||||
|
*
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
#define mmcIsCardInserted(mmcp) mmc_lld_is_card_inserted(mmcp)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the write protect status.
|
* @brief Returns the write protect status.
|
||||||
*
|
*
|
||||||
|
|
|
@ -49,10 +49,10 @@
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/* Forward declarations required by mmc_vmt.*/
|
/* Forward declarations required by mmc_vmt.*/
|
||||||
bool_t mmc_read(void *instance, uint32_t startblk,
|
static bool_t mmc_read(void *instance, uint32_t startblk,
|
||||||
uint8_t *buffer, uint32_t n);
|
uint8_t *buffer, uint32_t n);
|
||||||
bool_t mmc_write(void *instance, uint32_t startblk,
|
static bool_t mmc_write(void *instance, uint32_t startblk,
|
||||||
const uint8_t *buffer, uint32_t n);
|
const uint8_t *buffer, uint32_t n);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Virtual methods table.
|
* @brief Virtual methods table.
|
||||||
|
@ -100,36 +100,36 @@ static const uint8_t crc7_lookup_table[256] = {
|
||||||
/* Driver local functions. */
|
/* Driver local functions. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
bool_t mmc_read(void *instance, uint32_t startblk,
|
static bool_t mmc_read(void *instance, uint32_t startblk,
|
||||||
uint8_t *buffer, uint32_t n) {
|
uint8_t *buffer, uint32_t n) {
|
||||||
|
|
||||||
if (mmcStartSequentialRead((MMCDriver *)instance, startblk))
|
if (mmcStartSequentialRead((MMCDriver *)instance, startblk))
|
||||||
return TRUE;
|
return CH_FAILED;
|
||||||
while (n > 0) {
|
while (n > 0) {
|
||||||
if (mmcSequentialRead((MMCDriver *)instance, buffer))
|
if (mmcSequentialRead((MMCDriver *)instance, buffer))
|
||||||
return TRUE;
|
return CH_FAILED;
|
||||||
buffer += MMCSD_BLOCK_SIZE;
|
buffer += MMCSD_BLOCK_SIZE;
|
||||||
n--;
|
n--;
|
||||||
}
|
}
|
||||||
if (mmcStopSequentialRead((MMCDriver *)instance))
|
if (mmcStopSequentialRead((MMCDriver *)instance))
|
||||||
return TRUE;
|
return CH_FAILED;
|
||||||
return FALSE;
|
return CH_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool_t mmc_write(void *instance, uint32_t startblk,
|
static bool_t mmc_write(void *instance, uint32_t startblk,
|
||||||
const uint8_t *buffer, uint32_t n) {
|
const uint8_t *buffer, uint32_t n) {
|
||||||
|
|
||||||
if (mmcStartSequentialWrite((MMCDriver *)instance, startblk))
|
if (mmcStartSequentialWrite((MMCDriver *)instance, startblk))
|
||||||
return TRUE;
|
return CH_FAILED;
|
||||||
while (n > 0) {
|
while (n > 0) {
|
||||||
if (mmcSequentialWrite((MMCDriver *)instance, buffer))
|
if (mmcSequentialWrite((MMCDriver *)instance, buffer))
|
||||||
return TRUE;
|
return CH_FAILED;
|
||||||
buffer += MMCSD_BLOCK_SIZE;
|
buffer += MMCSD_BLOCK_SIZE;
|
||||||
n--;
|
n--;
|
||||||
}
|
}
|
||||||
if (mmcStopSequentialWrite((MMCDriver *)instance))
|
if (mmcStopSequentialWrite((MMCDriver *)instance))
|
||||||
return TRUE;
|
return CH_FAILED;
|
||||||
return FALSE;
|
return CH_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -147,38 +147,6 @@ static uint8_t crc7(uint8_t crc, const uint8_t *buffer, size_t len) {
|
||||||
return crc;
|
return crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Insertion monitor timer callback function.
|
|
||||||
*
|
|
||||||
* @param[in] p pointer to the @p MMCDriver object
|
|
||||||
*
|
|
||||||
* @notapi
|
|
||||||
*/
|
|
||||||
static void tmrfunc(void *p) {
|
|
||||||
MMCDriver *mmcp = p;
|
|
||||||
|
|
||||||
chSysLockFromIsr();
|
|
||||||
if (mmcp->cnt > 0) {
|
|
||||||
if (mmc_lld_is_card_inserted(mmcp)) {
|
|
||||||
if (--mmcp->cnt == 0) {
|
|
||||||
mmcp->state = MMC_INSERTED;
|
|
||||||
chEvtBroadcastI(&mmcp->inserted_event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
mmcp->cnt = MMC_POLLING_INTERVAL;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (!mmc_lld_is_card_inserted(mmcp)) {
|
|
||||||
mmcp->state = MMC_WAIT;
|
|
||||||
mmcp->cnt = MMC_POLLING_INTERVAL;
|
|
||||||
chEvtBroadcastI(&mmcp->removed_event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
chVTSetI(&mmcp->vt, MS2ST(MMC_POLLING_DELAY), tmrfunc, mmcp);
|
|
||||||
chSysUnlockFromIsr();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Waits an idle condition.
|
* @brief Waits an idle condition.
|
||||||
*
|
*
|
||||||
|
@ -325,8 +293,8 @@ static uint8_t send_command_R3(MMCDriver *mmcp, uint8_t cmd, uint32_t arg,
|
||||||
* @param[out] csd pointer to the CSD buffer
|
* @param[out] csd pointer to the CSD buffer
|
||||||
*
|
*
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval FALSE the operation succeeded.
|
* @retval CH_FAILED the operation succeeded.
|
||||||
* @retval TRUE the operation failed.
|
* @retval CH_SUCCESS the operation failed.
|
||||||
*
|
*
|
||||||
* @notapi
|
* @notapi
|
||||||
*/
|
*/
|
||||||
|
@ -338,7 +306,7 @@ static bool_t read_CxD(MMCDriver *mmcp, uint8_t cmd, uint32_t cxd[4]) {
|
||||||
send_hdr(mmcp, cmd, 0);
|
send_hdr(mmcp, cmd, 0);
|
||||||
if (recvr1(mmcp) != 0x00) {
|
if (recvr1(mmcp) != 0x00) {
|
||||||
spiUnselect(mmcp->config->spip);
|
spiUnselect(mmcp->config->spip);
|
||||||
return TRUE;
|
return CH_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wait for data availability.*/
|
/* Wait for data availability.*/
|
||||||
|
@ -359,10 +327,10 @@ static bool_t read_CxD(MMCDriver *mmcp, uint8_t cmd, uint32_t cxd[4]) {
|
||||||
spiIgnore(mmcp->config->spip, 2);
|
spiIgnore(mmcp->config->spip, 2);
|
||||||
spiUnselect(mmcp->config->spip);
|
spiUnselect(mmcp->config->spip);
|
||||||
|
|
||||||
return FALSE;
|
return CH_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return TRUE;
|
return CH_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -415,8 +383,6 @@ void mmcObjectInit(MMCDriver *mmcp) {
|
||||||
mmcp->state = MMC_STOP;
|
mmcp->state = MMC_STOP;
|
||||||
mmcp->config = NULL;
|
mmcp->config = NULL;
|
||||||
mmcp->block_addresses = FALSE;
|
mmcp->block_addresses = FALSE;
|
||||||
chEvtInit(&mmcp->inserted_event);
|
|
||||||
chEvtInit(&mmcp->removed_event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -432,11 +398,10 @@ void mmcStart(MMCDriver *mmcp, const MMCConfig *config) {
|
||||||
chDbgCheck((mmcp != NULL) && (config != NULL), "mmcStart");
|
chDbgCheck((mmcp != NULL) && (config != NULL), "mmcStart");
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
chDbgAssert(mmcp->state == MMC_STOP, "mmcStart(), #1", "invalid state");
|
chDbgAssert((mmcp->state == MMC_STOP) || (mmcp->state == MMC_READY),
|
||||||
|
"mmcStart(), #1", "invalid state");
|
||||||
mmcp->config = config;
|
mmcp->config = config;
|
||||||
mmcp->state = MMC_WAIT;
|
mmcp->state = MMC_READY;
|
||||||
mmcp->cnt = MMC_POLLING_INTERVAL;
|
|
||||||
chVTSetI(&mmcp->vt, MS2ST(MMC_POLLING_DELAY), tmrfunc, mmcp);
|
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,14 +417,9 @@ void mmcStop(MMCDriver *mmcp) {
|
||||||
chDbgCheck(mmcp != NULL, "mmcStop");
|
chDbgCheck(mmcp != NULL, "mmcStop");
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
chDbgAssert((mmcp->state != MMC_UNINIT) &&
|
chDbgAssert((mmcp->state == MMC_STOP) || (mmcp->state == MMC_READY),
|
||||||
(mmcp->state != MMC_READING) &&
|
|
||||||
(mmcp->state != MMC_WRITING),
|
|
||||||
"mmcStop(), #1", "invalid state");
|
"mmcStop(), #1", "invalid state");
|
||||||
if (mmcp->state != MMC_STOP) {
|
mmcp->state = MMC_STOP;
|
||||||
mmcp->state = MMC_STOP;
|
|
||||||
chVTResetI(&mmcp->vt);
|
|
||||||
}
|
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
spiStop(mmcp->config->spip);
|
spiStop(mmcp->config->spip);
|
||||||
}
|
}
|
||||||
|
@ -475,111 +435,102 @@ void mmcStop(MMCDriver *mmcp) {
|
||||||
* @param[in] mmcp pointer to the @p MMCDriver object
|
* @param[in] mmcp pointer to the @p MMCDriver object
|
||||||
*
|
*
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval FALSE the operation succeeded and the driver is now
|
* @retval CH_FAILED the operation succeeded and the driver is now
|
||||||
* in the @p MMC_READY state.
|
* in the @p MMC_READY state.
|
||||||
* @retval TRUE the operation failed.
|
* @retval CH_SUCCESS the operation failed.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
bool_t mmcConnect(MMCDriver *mmcp) {
|
bool_t mmcConnect(MMCDriver *mmcp) {
|
||||||
unsigned i;
|
unsigned i;
|
||||||
bool_t result;
|
|
||||||
|
|
||||||
chDbgCheck(mmcp != NULL, "mmcConnect");
|
chDbgCheck(mmcp != NULL, "mmcConnect");
|
||||||
|
|
||||||
chDbgAssert((mmcp->state != MMC_UNINIT) && (mmcp->state != MMC_STOP),
|
chSysLock();
|
||||||
|
chDbgAssert((mmcp->state == MMC_READY) || (mmcp->state == MMC_ACTIVE),
|
||||||
"mmcConnect(), #1", "invalid state");
|
"mmcConnect(), #1", "invalid state");
|
||||||
|
mmcp->state = MMC_CONNECTING;
|
||||||
|
chSysUnlock();
|
||||||
|
|
||||||
if (mmcp->state == MMC_INSERTED) {
|
/* Slow clock mode and 128 clock pulses.*/
|
||||||
/* Slow clock mode and 128 clock pulses.*/
|
spiStart(mmcp->config->spip, mmcp->config->lscfg);
|
||||||
spiStart(mmcp->config->spip, mmcp->config->lscfg);
|
spiIgnore(mmcp->config->spip, 16);
|
||||||
spiIgnore(mmcp->config->spip, 16);
|
|
||||||
|
|
||||||
/* SPI mode selection.*/
|
/* SPI mode selection.*/
|
||||||
i = 0;
|
i = 0;
|
||||||
while (TRUE) {
|
while (TRUE) {
|
||||||
if (send_command_R1(mmcp, MMCSD_CMD_GO_IDLE_STATE, 0) == 0x01)
|
if (send_command_R1(mmcp, MMCSD_CMD_GO_IDLE_STATE, 0) == 0x01)
|
||||||
break;
|
break;
|
||||||
if (++i >= MMC_CMD0_RETRY)
|
if (++i >= MMC_CMD0_RETRY)
|
||||||
return TRUE;
|
goto failed;
|
||||||
chThdSleepMilliseconds(10);
|
chThdSleepMilliseconds(10);
|
||||||
}
|
|
||||||
|
|
||||||
/* Try to detect if this is a high capacity card and switch to block
|
|
||||||
addresses if possible.
|
|
||||||
This method is based on "How to support SDC Ver2 and high capacity cards"
|
|
||||||
by ElmChan.*/
|
|
||||||
uint8_t r3[4];
|
|
||||||
if (send_command_R3(mmcp, MMCSD_CMD_SEND_IF_COND,
|
|
||||||
MMCSD_CMD8_PATTERN, r3) != 0x05) {
|
|
||||||
|
|
||||||
/* Switch to SDHC mode.*/
|
|
||||||
i = 0;
|
|
||||||
while (TRUE) {
|
|
||||||
if ((send_command_R1(mmcp, MMCSD_CMD_APP_CMD, 0) == 0x01) &&
|
|
||||||
(send_command_R3(mmcp, MMCSD_CMD_APP_OP_COND,
|
|
||||||
0x400001aa, r3) == 0x00))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (++i >= MMC_ACMD41_RETRY)
|
|
||||||
return TRUE;
|
|
||||||
chThdSleepMilliseconds(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Execute dedicated read on OCR register */
|
|
||||||
send_command_R3(mmcp, MMCSD_CMD_READ_OCR, 0, r3);
|
|
||||||
|
|
||||||
/* Check if CCS is set in response. Card operates in block mode if set.*/
|
|
||||||
if(r3[0] & 0x40)
|
|
||||||
mmcp->block_addresses = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialization.*/
|
|
||||||
i = 0;
|
|
||||||
while (TRUE) {
|
|
||||||
uint8_t b = send_command_R1(mmcp, MMCSD_CMD_INIT, 0);
|
|
||||||
if (b == 0x00)
|
|
||||||
break;
|
|
||||||
if (b != 0x01)
|
|
||||||
return TRUE;
|
|
||||||
if (++i >= MMC_CMD1_RETRY)
|
|
||||||
return TRUE;
|
|
||||||
chThdSleepMilliseconds(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialization complete, full speed.*/
|
|
||||||
spiStart(mmcp->config->spip, mmcp->config->hscfg);
|
|
||||||
|
|
||||||
/* Setting block size.*/
|
|
||||||
if (send_command_R1(mmcp, MMCSD_CMD_SET_BLOCKLEN,
|
|
||||||
MMCSD_BLOCK_SIZE) != 0x00)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
/* Determine capacity.*/
|
|
||||||
if (read_CxD(mmcp, MMCSD_CMD_SEND_CSD, mmcp->csd))
|
|
||||||
return TRUE;
|
|
||||||
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) {
|
|
||||||
mmcp->state = MMC_READY;
|
|
||||||
result = FALSE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
result = TRUE;
|
|
||||||
chSysUnlock();
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
if (mmcp->state == MMC_READY)
|
|
||||||
return FALSE;
|
/* Try to detect if this is a high capacity card and switch to block
|
||||||
/* Any other state is invalid.*/
|
addresses if possible.
|
||||||
return TRUE;
|
This method is based on "How to support SDC Ver2 and high capacity cards"
|
||||||
|
by ElmChan.*/
|
||||||
|
uint8_t r3[4];
|
||||||
|
if (send_command_R3(mmcp, MMCSD_CMD_SEND_IF_COND,
|
||||||
|
MMCSD_CMD8_PATTERN, r3) != 0x05) {
|
||||||
|
|
||||||
|
/* Switch to SDHC mode.*/
|
||||||
|
i = 0;
|
||||||
|
while (TRUE) {
|
||||||
|
if ((send_command_R1(mmcp, MMCSD_CMD_APP_CMD, 0) == 0x01) &&
|
||||||
|
(send_command_R3(mmcp, MMCSD_CMD_APP_OP_COND,
|
||||||
|
0x400001aa, r3) == 0x00))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (++i >= MMC_ACMD41_RETRY)
|
||||||
|
goto failed;
|
||||||
|
chThdSleepMilliseconds(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Execute dedicated read on OCR register */
|
||||||
|
send_command_R3(mmcp, MMCSD_CMD_READ_OCR, 0, r3);
|
||||||
|
|
||||||
|
/* Check if CCS is set in response. Card operates in block mode if set.*/
|
||||||
|
if(r3[0] & 0x40)
|
||||||
|
mmcp->block_addresses = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialization.*/
|
||||||
|
i = 0;
|
||||||
|
while (TRUE) {
|
||||||
|
uint8_t b = send_command_R1(mmcp, MMCSD_CMD_INIT, 0);
|
||||||
|
if (b == 0x00)
|
||||||
|
break;
|
||||||
|
if (b != 0x01)
|
||||||
|
goto failed;
|
||||||
|
if (++i >= MMC_CMD1_RETRY)
|
||||||
|
goto failed;
|
||||||
|
chThdSleepMilliseconds(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialization complete, full speed.*/
|
||||||
|
spiStart(mmcp->config->spip, mmcp->config->hscfg);
|
||||||
|
|
||||||
|
/* Setting block size.*/
|
||||||
|
if (send_command_R1(mmcp, MMCSD_CMD_SET_BLOCKLEN,
|
||||||
|
MMCSD_BLOCK_SIZE) != 0x00)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
/* Determine capacity.*/
|
||||||
|
if (read_CxD(mmcp, MMCSD_CMD_SEND_CSD, mmcp->csd))
|
||||||
|
goto failed;
|
||||||
|
mmcp->capacity = mmcsdGetCapacity(mmcp->csd);
|
||||||
|
if (mmcp->capacity == 0)
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
if (read_CxD(mmcp, MMCSD_CMD_SEND_CID, mmcp->cid))
|
||||||
|
goto failed;
|
||||||
|
|
||||||
|
mmcp->state = MMC_READY;
|
||||||
|
return CH_SUCCESS;
|
||||||
|
failed:
|
||||||
|
mmcp->state = MMC_READY;
|
||||||
|
return CH_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -588,34 +539,32 @@ bool_t mmcConnect(MMCDriver *mmcp) {
|
||||||
* @param[in] mmcp pointer to the @p MMCDriver object
|
* @param[in] mmcp pointer to the @p MMCDriver object
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
*
|
*
|
||||||
* @retval FALSE the operation succeeded and the driver is now
|
* @retval CH_FAILED the operation succeeded and the driver is now
|
||||||
* in the @p MMC_INSERTED state.
|
* in the @p MMC_INSERTED state.
|
||||||
* @retval TRUE the operation failed.
|
* @retval CH_SUCCESS the operation failed.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
bool_t mmcDisconnect(MMCDriver *mmcp) {
|
bool_t mmcDisconnect(MMCDriver *mmcp) {
|
||||||
bool_t status;
|
|
||||||
|
|
||||||
chDbgCheck(mmcp != NULL, "mmcDisconnect");
|
chDbgCheck(mmcp != NULL, "mmcDisconnect");
|
||||||
|
|
||||||
chDbgAssert((mmcp->state != MMC_UNINIT) && (mmcp->state != MMC_STOP),
|
chSysLock();
|
||||||
|
chDbgAssert((mmcp->state == MMC_READY) || (mmcp->state == MMC_ACTIVE),
|
||||||
"mmcDisconnect(), #1", "invalid state");
|
"mmcDisconnect(), #1", "invalid state");
|
||||||
switch (mmcp->state) {
|
if (mmcp->state == MMC_READY) {
|
||||||
case MMC_READY:
|
|
||||||
/* Wait for the pending write operations to complete.*/
|
|
||||||
sync(mmcp);
|
|
||||||
chSysLock();
|
|
||||||
if (mmcp->state == MMC_READY)
|
|
||||||
mmcp->state = MMC_INSERTED;
|
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
case MMC_INSERTED:
|
return CH_SUCCESS;
|
||||||
status = FALSE;
|
|
||||||
default:
|
|
||||||
status = TRUE;
|
|
||||||
}
|
}
|
||||||
|
mmcp->state = MMC_DISCONNECTING;
|
||||||
|
chSysUnlock();
|
||||||
|
|
||||||
|
/* Wait for the pending write operations to complete.*/
|
||||||
|
sync(mmcp);
|
||||||
spiStop(mmcp->config->spip);
|
spiStop(mmcp->config->spip);
|
||||||
return status;
|
|
||||||
|
mmcp->state = MMC_READY;
|
||||||
|
return CH_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -625,8 +574,8 @@ bool_t mmcDisconnect(MMCDriver *mmcp) {
|
||||||
* @param[in] startblk first block to read
|
* @param[in] startblk first block to read
|
||||||
*
|
*
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval FALSE the operation succeeded.
|
* @retval CH_FAILED the operation succeeded.
|
||||||
* @retval TRUE the operation failed.
|
* @retval CH_SUCCESS the operation failed.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
|
@ -635,13 +584,13 @@ bool_t mmcStartSequentialRead(MMCDriver *mmcp, uint32_t startblk) {
|
||||||
chDbgCheck(mmcp != NULL, "mmcStartSequentialRead");
|
chDbgCheck(mmcp != NULL, "mmcStartSequentialRead");
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
if (mmcp->state != MMC_READY) {
|
chDbgAssert(mmcp->state == MMC_ACTIVE,
|
||||||
chSysUnlock();
|
"mmcStartSequentialRead(), #1", "invalid state");
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
mmcp->state = MMC_READING;
|
mmcp->state = MMC_READING;
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
|
|
||||||
|
/* (Re)starting the SPI in case it has been reprogrammed externally, it can
|
||||||
|
happen if the SPI bus is shared among multiple peripherals.*/
|
||||||
spiStart(mmcp->config->spip, mmcp->config->hscfg);
|
spiStart(mmcp->config->spip, mmcp->config->hscfg);
|
||||||
spiSelect(mmcp->config->spip);
|
spiSelect(mmcp->config->spip);
|
||||||
|
|
||||||
|
@ -651,14 +600,10 @@ bool_t mmcStartSequentialRead(MMCDriver *mmcp, uint32_t startblk) {
|
||||||
send_hdr(mmcp, MMCSD_CMD_READ_MULTIPLE_BLOCK, startblk * MMCSD_BLOCK_SIZE);
|
send_hdr(mmcp, MMCSD_CMD_READ_MULTIPLE_BLOCK, startblk * MMCSD_BLOCK_SIZE);
|
||||||
|
|
||||||
if (recvr1(mmcp) != 0x00) {
|
if (recvr1(mmcp) != 0x00) {
|
||||||
spiUnselect(mmcp->config->spip);
|
mmcp->state = MMC_READY;
|
||||||
chSysLock();
|
return CH_FAILED;
|
||||||
if (mmcp->state == MMC_READING)
|
|
||||||
mmcp->state = MMC_READY;
|
|
||||||
chSysUnlock();
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
return FALSE;
|
return CH_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -668,8 +613,8 @@ bool_t mmcStartSequentialRead(MMCDriver *mmcp, uint32_t startblk) {
|
||||||
* @param[out] buffer pointer to the read buffer
|
* @param[out] buffer pointer to the read buffer
|
||||||
*
|
*
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval FALSE the operation succeeded.
|
* @retval CH_FAILED the operation succeeded.
|
||||||
* @retval TRUE the operation failed.
|
* @retval CH_SUCCESS the operation failed.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
|
@ -678,12 +623,8 @@ bool_t mmcSequentialRead(MMCDriver *mmcp, uint8_t *buffer) {
|
||||||
|
|
||||||
chDbgCheck((mmcp != NULL) && (buffer != NULL), "mmcSequentialRead");
|
chDbgCheck((mmcp != NULL) && (buffer != NULL), "mmcSequentialRead");
|
||||||
|
|
||||||
chSysLock();
|
if (mmcp->state != MMC_READING)
|
||||||
if (mmcp->state != MMC_READING) {
|
return CH_FAILED;
|
||||||
chSysUnlock();
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
chSysUnlock();
|
|
||||||
|
|
||||||
for (i = 0; i < MMC_WAIT_DATA; i++) {
|
for (i = 0; i < MMC_WAIT_DATA; i++) {
|
||||||
spiReceive(mmcp->config->spip, 1, buffer);
|
spiReceive(mmcp->config->spip, 1, buffer);
|
||||||
|
@ -691,16 +632,13 @@ bool_t mmcSequentialRead(MMCDriver *mmcp, uint8_t *buffer) {
|
||||||
spiReceive(mmcp->config->spip, MMCSD_BLOCK_SIZE, buffer);
|
spiReceive(mmcp->config->spip, MMCSD_BLOCK_SIZE, buffer);
|
||||||
/* CRC ignored. */
|
/* CRC ignored. */
|
||||||
spiIgnore(mmcp->config->spip, 2);
|
spiIgnore(mmcp->config->spip, 2);
|
||||||
return FALSE;
|
return CH_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Timeout.*/
|
/* Timeout.*/
|
||||||
spiUnselect(mmcp->config->spip);
|
spiUnselect(mmcp->config->spip);
|
||||||
chSysLock();
|
mmcp->state = MMC_READY;
|
||||||
if (mmcp->state == MMC_READING)
|
return CH_FAILED;
|
||||||
mmcp->state = MMC_READY;
|
|
||||||
chSysUnlock();
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -709,37 +647,28 @@ bool_t mmcSequentialRead(MMCDriver *mmcp, uint8_t *buffer) {
|
||||||
* @param[in] mmcp pointer to the @p MMCDriver object
|
* @param[in] mmcp pointer to the @p MMCDriver object
|
||||||
*
|
*
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval FALSE the operation succeeded.
|
* @retval CH_FAILED the operation succeeded.
|
||||||
* @retval TRUE the operation failed.
|
* @retval CH_SUCCESS the operation failed.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
bool_t mmcStopSequentialRead(MMCDriver *mmcp) {
|
bool_t mmcStopSequentialRead(MMCDriver *mmcp) {
|
||||||
static const uint8_t stopcmd[] = {0x40 | MMCSD_CMD_STOP_TRANSMISSION,
|
static const uint8_t stopcmd[] = {0x40 | MMCSD_CMD_STOP_TRANSMISSION,
|
||||||
0, 0, 0, 0, 1, 0xFF};
|
0, 0, 0, 0, 1, 0xFF};
|
||||||
bool_t result;
|
|
||||||
|
|
||||||
chDbgCheck(mmcp != NULL, "mmcStopSequentialRead");
|
chDbgCheck(mmcp != NULL, "mmcStopSequentialRead");
|
||||||
|
|
||||||
chSysLock();
|
if (mmcp->state != MMC_READING)
|
||||||
if (mmcp->state != MMC_READING) {
|
return CH_FAILED;
|
||||||
chSysUnlock();
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
chSysUnlock();
|
|
||||||
|
|
||||||
spiSend(mmcp->config->spip, sizeof(stopcmd), stopcmd);
|
spiSend(mmcp->config->spip, sizeof(stopcmd), stopcmd);
|
||||||
/* result = recvr1(mmcp) != 0x00;*/
|
/* result = recvr1(mmcp) != 0x00;*/
|
||||||
/* Note, ignored r1 response, it can be not zero, unknown issue.*/
|
/* Note, ignored r1 response, it can be not zero, unknown issue.*/
|
||||||
recvr1(mmcp);
|
(void) recvr1(mmcp);
|
||||||
result = FALSE;
|
|
||||||
spiUnselect(mmcp->config->spip);
|
|
||||||
|
|
||||||
chSysLock();
|
spiUnselect(mmcp->config->spip);
|
||||||
if (mmcp->state == MMC_READING)
|
mmcp->state = MMC_READY;
|
||||||
mmcp->state = MMC_READY;
|
return CH_SUCCESS;
|
||||||
chSysUnlock();
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -749,8 +678,8 @@ bool_t mmcStopSequentialRead(MMCDriver *mmcp) {
|
||||||
* @param[in] startblk first block to write
|
* @param[in] startblk first block to write
|
||||||
*
|
*
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval FALSE the operation succeeded.
|
* @retval CH_FAILED the operation succeeded.
|
||||||
* @retval TRUE the operation failed.
|
* @retval CH_SUCCESS the operation failed.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
|
@ -759,10 +688,8 @@ bool_t mmcStartSequentialWrite(MMCDriver *mmcp, uint32_t startblk) {
|
||||||
chDbgCheck(mmcp != NULL, "mmcStartSequentialWrite");
|
chDbgCheck(mmcp != NULL, "mmcStartSequentialWrite");
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
if (mmcp->state != MMC_READY) {
|
chDbgAssert(mmcp->state == MMC_ACTIVE,
|
||||||
chSysUnlock();
|
"mmcStartSequentialWrite(), #1", "invalid state");
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
mmcp->state = MMC_WRITING;
|
mmcp->state = MMC_WRITING;
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
|
|
||||||
|
@ -774,16 +701,11 @@ bool_t mmcStartSequentialWrite(MMCDriver *mmcp, uint32_t startblk) {
|
||||||
send_hdr(mmcp, MMCSD_CMD_WRITE_MULTIPLE_BLOCK,
|
send_hdr(mmcp, MMCSD_CMD_WRITE_MULTIPLE_BLOCK,
|
||||||
startblk * MMCSD_BLOCK_SIZE);
|
startblk * MMCSD_BLOCK_SIZE);
|
||||||
|
|
||||||
|
|
||||||
if (recvr1(mmcp) != 0x00) {
|
if (recvr1(mmcp) != 0x00) {
|
||||||
spiUnselect(mmcp->config->spip);
|
mmcp->state = MMC_READY;
|
||||||
chSysLock();
|
return CH_FAILED;
|
||||||
if (mmcp->state == MMC_WRITING)
|
|
||||||
mmcp->state = MMC_READY;
|
|
||||||
chSysUnlock();
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
return FALSE;
|
return CH_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -793,8 +715,8 @@ bool_t mmcStartSequentialWrite(MMCDriver *mmcp, uint32_t startblk) {
|
||||||
* @param[out] buffer pointer to the write buffer
|
* @param[out] buffer pointer to the write buffer
|
||||||
*
|
*
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval FALSE the operation succeeded.
|
* @retval CH_FAILED the operation succeeded.
|
||||||
* @retval TRUE the operation failed.
|
* @retval CH_SUCCESS the operation failed.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
|
@ -804,12 +726,8 @@ bool_t mmcSequentialWrite(MMCDriver *mmcp, const uint8_t *buffer) {
|
||||||
|
|
||||||
chDbgCheck((mmcp != NULL) && (buffer != NULL), "mmcSequentialWrite");
|
chDbgCheck((mmcp != NULL) && (buffer != NULL), "mmcSequentialWrite");
|
||||||
|
|
||||||
chSysLock();
|
if (mmcp->state != MMC_WRITING)
|
||||||
if (mmcp->state != MMC_WRITING) {
|
return CH_FAILED;
|
||||||
chSysUnlock();
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
chSysUnlock();
|
|
||||||
|
|
||||||
spiSend(mmcp->config->spip, sizeof(start), start); /* Data prologue. */
|
spiSend(mmcp->config->spip, sizeof(start), start); /* Data prologue. */
|
||||||
spiSend(mmcp->config->spip, MMCSD_BLOCK_SIZE, buffer);/* Data. */
|
spiSend(mmcp->config->spip, MMCSD_BLOCK_SIZE, buffer);/* Data. */
|
||||||
|
@ -817,16 +735,13 @@ bool_t mmcSequentialWrite(MMCDriver *mmcp, const uint8_t *buffer) {
|
||||||
spiReceive(mmcp->config->spip, 1, b);
|
spiReceive(mmcp->config->spip, 1, b);
|
||||||
if ((b[0] & 0x1F) == 0x05) {
|
if ((b[0] & 0x1F) == 0x05) {
|
||||||
wait(mmcp);
|
wait(mmcp);
|
||||||
return FALSE;
|
return CH_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Error.*/
|
/* Error.*/
|
||||||
spiUnselect(mmcp->config->spip);
|
spiUnselect(mmcp->config->spip);
|
||||||
chSysLock();
|
mmcp->state = MMC_READY;
|
||||||
if (mmcp->state == MMC_WRITING)
|
return CH_FAILED;
|
||||||
mmcp->state = MMC_READY;
|
|
||||||
chSysUnlock();
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -835,8 +750,8 @@ bool_t mmcSequentialWrite(MMCDriver *mmcp, const uint8_t *buffer) {
|
||||||
* @param[in] mmcp pointer to the @p MMCDriver object
|
* @param[in] mmcp pointer to the @p MMCDriver object
|
||||||
*
|
*
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval FALSE the operation succeeded.
|
* @retval CH_FAILED the operation succeeded.
|
||||||
* @retval TRUE the operation failed.
|
* @retval CH_SUCCESS the operation failed.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
|
@ -845,24 +760,15 @@ bool_t mmcStopSequentialWrite(MMCDriver *mmcp) {
|
||||||
|
|
||||||
chDbgCheck(mmcp != NULL, "mmcStopSequentialWrite");
|
chDbgCheck(mmcp != NULL, "mmcStopSequentialWrite");
|
||||||
|
|
||||||
chSysLock();
|
if (mmcp->state != MMC_WRITING)
|
||||||
if (mmcp->state != MMC_WRITING) {
|
return CH_FAILED;
|
||||||
chSysUnlock();
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
chSysUnlock();
|
|
||||||
|
|
||||||
spiSend(mmcp->config->spip, sizeof(stop), stop);
|
spiSend(mmcp->config->spip, sizeof(stop), stop);
|
||||||
spiUnselect(mmcp->config->spip);
|
spiUnselect(mmcp->config->spip);
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
if (mmcp->state == MMC_WRITING) {
|
mmcp->state = MMC_READY;
|
||||||
mmcp->state = MMC_READY;
|
return CH_SUCCESS;
|
||||||
chSysUnlock();
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
chSysUnlock();
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -871,8 +777,8 @@ bool_t mmcStopSequentialWrite(MMCDriver *mmcp) {
|
||||||
* @param[in] mmcp pointer to the @p MMCDriver object
|
* @param[in] mmcp pointer to the @p MMCDriver object
|
||||||
*
|
*
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval FALSE the operation succeeded.
|
* @retval CH_FAILED the operation succeeded.
|
||||||
* @retval TRUE the operation failed.
|
* @retval CH_SUCCESS the operation failed.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
|
@ -880,16 +786,11 @@ bool_t mmcSync(MMCDriver *mmcp) {
|
||||||
|
|
||||||
chDbgCheck(mmcp != NULL, "mmcSync");
|
chDbgCheck(mmcp != NULL, "mmcSync");
|
||||||
|
|
||||||
chSysLock();
|
if (mmcp->state != MMC_READY)
|
||||||
if (mmcp->state != MMC_READY) {
|
return CH_FAILED;
|
||||||
chSysUnlock();
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
chSysUnlock();
|
|
||||||
|
|
||||||
sync(mmcp);
|
sync(mmcp);
|
||||||
|
return CH_SUCCESS;
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -899,27 +800,21 @@ bool_t mmcSync(MMCDriver *mmcp) {
|
||||||
* @param[out] bdip pointer to a @p BlockDeviceInfo structure
|
* @param[out] bdip pointer to a @p BlockDeviceInfo structure
|
||||||
*
|
*
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval FALSE the operation succeeded.
|
* @retval CH_FAILED the operation succeeded.
|
||||||
* @retval TRUE the operation failed.
|
* @retval CH_SUCCESS the operation failed.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
bool_t mmcGetInfo(MMCDriver *mmcp, BlockDeviceInfo *bdip) {
|
bool_t mmcGetInfo(MMCDriver *mmcp, BlockDeviceInfo *bdip) {
|
||||||
|
|
||||||
|
|
||||||
chDbgCheck((mmcp != NULL) && (bdip != NULL), "mmcGetInfo");
|
chDbgCheck((mmcp != NULL) && (bdip != NULL), "mmcGetInfo");
|
||||||
|
|
||||||
chSysLock();
|
if (mmcp->state != MMC_READY)
|
||||||
if (mmcp->state != MMC_READY) {
|
return CH_FAILED;
|
||||||
chSysUnlock();
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
chSysUnlock();
|
|
||||||
|
|
||||||
bdip->blk_num = mmcp->capacity;
|
bdip->blk_num = mmcp->capacity;
|
||||||
bdip->blk_size = MMCSD_BLOCK_SIZE;
|
bdip->blk_size = MMCSD_BLOCK_SIZE;
|
||||||
|
return CH_SUCCESS;
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -930,8 +825,8 @@ bool_t mmcGetInfo(MMCDriver *mmcp, BlockDeviceInfo *bdip) {
|
||||||
* @param[in] endblk ending block number
|
* @param[in] endblk ending block number
|
||||||
*
|
*
|
||||||
* @return The operation status.
|
* @return The operation status.
|
||||||
* @retval FALSE the operation succeeded.
|
* @retval CH_FAILED the operation succeeded.
|
||||||
* @retval TRUE the operation failed.
|
* @retval CH_SUCCESS the operation failed.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
|
@ -940,15 +835,15 @@ bool_t mmcErase(MMCDriver *mmcp, uint32_t startblk, uint32_t endblk) {
|
||||||
chDbgCheck((mmcp != NULL), "mmcErase");
|
chDbgCheck((mmcp != NULL), "mmcErase");
|
||||||
|
|
||||||
if (send_command_R1(mmcp, MMCSD_CMD_ERASE_RW_BLK_START, startblk))
|
if (send_command_R1(mmcp, MMCSD_CMD_ERASE_RW_BLK_START, startblk))
|
||||||
return TRUE;
|
return CH_FAILED;
|
||||||
|
|
||||||
if (send_command_R1(mmcp, MMCSD_CMD_ERASE_RW_BLK_END, endblk))
|
if (send_command_R1(mmcp, MMCSD_CMD_ERASE_RW_BLK_END, endblk))
|
||||||
return TRUE;
|
return CH_FAILED;
|
||||||
|
|
||||||
if (send_command_R1(mmcp, MMCSD_CMD_ERASE, 0))
|
if (send_command_R1(mmcp, MMCSD_CMD_ERASE, 0))
|
||||||
return TRUE;
|
return CH_FAILED;
|
||||||
|
|
||||||
return FALSE;
|
return CH_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -230,7 +230,7 @@ bool_t sdcConnect(SDCDriver *sdcp) {
|
||||||
#if SDC_MMC_SUPPORT
|
#if SDC_MMC_SUPPORT
|
||||||
if ((sdcp->cardmode & SDC_MODE_CARDTYPE_MASK) == SDC_MODE_CARDTYPE_MMC) {
|
if ((sdcp->cardmode & SDC_MODE_CARDTYPE_MASK) == SDC_MODE_CARDTYPE_MMC) {
|
||||||
/* TODO: MMC initialization.*/
|
/* TODO: MMC initialization.*/
|
||||||
return CH_FAILED;
|
goto failed;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif /* SDC_MMC_SUPPORT */
|
#endif /* SDC_MMC_SUPPORT */
|
||||||
|
@ -337,7 +337,7 @@ bool_t sdcDisconnect(SDCDriver *sdcp) {
|
||||||
chDbgCheck(sdcp != NULL, "sdcDisconnect");
|
chDbgCheck(sdcp != NULL, "sdcDisconnect");
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
chDbgAssert(sdcp->state == SDC_ACTIVE,
|
chDbgAssert((sdcp->state == SDC_READY) || (sdcp->state == SDC_ACTIVE),
|
||||||
"sdcDisconnect(), #1", "invalid state");
|
"sdcDisconnect(), #1", "invalid state");
|
||||||
if (sdcp->state == SDC_READY) {
|
if (sdcp->state == SDC_READY) {
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
|
|
Loading…
Reference in New Issue