git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4349 35acf78f-673a-0410-8e92-d51de3d6d3f4
parent
853b0fd51c
commit
9492ff4976
|
@ -34,8 +34,8 @@
|
||||||
/* Card insertion monitor. */
|
/* Card insertion monitor. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
#define SDC_POLLING_INTERVAL 10
|
#define POLLING_INTERVAL 10
|
||||||
#define SDC_POLLING_DELAY 10
|
#define POLLING_DELAY 10
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Card monitor timer.
|
* @brief Card monitor timer.
|
||||||
|
@ -55,47 +55,55 @@ static EventSource inserted_event, removed_event;
|
||||||
/**
|
/**
|
||||||
* @brief Insertion monitor timer callback function.
|
* @brief Insertion monitor timer callback function.
|
||||||
*
|
*
|
||||||
* @param[in] p pointer to the @p SDCDriver object
|
* @param[in] p pointer to the @p BaseBlockDevice object
|
||||||
*
|
*
|
||||||
* @notapi
|
* @notapi
|
||||||
*/
|
*/
|
||||||
static void tmrfunc(void *p) {
|
static void tmrfunc(void *p) {
|
||||||
SDCDriver *sdcp = p;
|
BaseBlockDevice *bbdp = p;
|
||||||
|
|
||||||
|
/* The presence check is performed only while the driver is not in a
|
||||||
|
transfer state because it is often performed by changing the mode of
|
||||||
|
the pin connected to the CS/D3 contact of the card, this could disturb
|
||||||
|
the transfer.*/
|
||||||
|
blkstate_t state = blkGetDriverState(bbdp);
|
||||||
chSysLockFromIsr();
|
chSysLockFromIsr();
|
||||||
if (cnt > 0) {
|
if ((state != BLK_READING) && (state != BLK_WRITING)) {
|
||||||
if (sdcIsCardInserted(sdcp)) {
|
/* Safe to perform the check.*/
|
||||||
if (--cnt == 0) {
|
if (cnt > 0) {
|
||||||
chEvtBroadcastI(&inserted_event);
|
if (blkIsInserted(bbdp)) {
|
||||||
|
if (--cnt == 0) {
|
||||||
|
chEvtBroadcastI(&inserted_event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
cnt = POLLING_INTERVAL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!blkIsInserted(bbdp)) {
|
||||||
|
cnt = POLLING_INTERVAL;
|
||||||
|
chEvtBroadcastI(&removed_event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
cnt = SDC_POLLING_INTERVAL;
|
|
||||||
}
|
}
|
||||||
else {
|
chVTSetI(&tmr, MS2ST(POLLING_DELAY), tmrfunc, bbdp);
|
||||||
if (!sdcIsCardInserted(sdcp)) {
|
|
||||||
cnt = SDC_POLLING_INTERVAL;
|
|
||||||
chEvtBroadcastI(&removed_event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
chVTSetI(&tmr, MS2ST(SDC_POLLING_DELAY), tmrfunc, sdcp);
|
|
||||||
chSysUnlockFromIsr();
|
chSysUnlockFromIsr();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Polling monitor start.
|
* @brief Polling monitor start.
|
||||||
*
|
*
|
||||||
* @param[in] sdcp pointer to the @p SDCDriver object
|
* @param[in] p pointer to an object implementing @p BaseBlockDevice
|
||||||
*
|
*
|
||||||
* @notapi
|
* @notapi
|
||||||
*/
|
*/
|
||||||
static void tmr_init(SDCDriver *sdcp) {
|
static void tmr_init(void *p) {
|
||||||
|
|
||||||
chEvtInit(&inserted_event);
|
chEvtInit(&inserted_event);
|
||||||
chEvtInit(&removed_event);
|
chEvtInit(&removed_event);
|
||||||
chSysLock();
|
chSysLock();
|
||||||
cnt = SDC_POLLING_INTERVAL;
|
cnt = POLLING_INTERVAL;
|
||||||
chVTSetI(&tmr, MS2ST(SDC_POLLING_DELAY), tmrfunc, sdcp);
|
chVTSetI(&tmr, MS2ST(POLLING_DELAY), tmrfunc, p);
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,8 +284,6 @@ static void InsertHandler(eventid_t id) {
|
||||||
static void RemoveHandler(eventid_t id) {
|
static void RemoveHandler(eventid_t id) {
|
||||||
|
|
||||||
(void)id;
|
(void)id;
|
||||||
if (sdcGetDriverState(&SDCD1) == SDC_ACTIVE)
|
|
||||||
sdcDisconnect(&SDCD1);
|
|
||||||
fs_ready = FALSE;
|
fs_ready = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -106,20 +106,6 @@
|
||||||
/* Driver data structures and types. */
|
/* Driver data structures and types. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Driver state machine possible states.
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
SDC_UNINIT = 0, /**< Not initialized. */
|
|
||||||
SDC_STOP = 1, /**< Stopped. */
|
|
||||||
SDC_READY = 2, /**< Ready. */
|
|
||||||
SDC_CONNECTING = 3, /**< Card connection in progress. */
|
|
||||||
SDC_DISCONNECTING = 4, /**< Card disconnection in progress. */
|
|
||||||
SDC_ACTIVE = 5, /**< Cart initialized. */
|
|
||||||
SDC_READING = 6, /**< Read operation in progress. */
|
|
||||||
SDC_WRITING = 7, /**< Write operation in progress. */
|
|
||||||
} sdcstate_t;
|
|
||||||
|
|
||||||
#include "sdc_lld.h"
|
#include "sdc_lld.h"
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -130,16 +116,6 @@ typedef enum {
|
||||||
* @name Macro Functions
|
* @name Macro Functions
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/**
|
|
||||||
* @brief Returns the driver state.
|
|
||||||
*
|
|
||||||
* @param[in] sdcp pointer to the @p SDCDriver object
|
|
||||||
* @return The driver state.
|
|
||||||
*
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
#define sdcGetDriverState(sdcp) ((sdcp)->state)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the card insertion status.
|
* @brief Returns the card insertion status.
|
||||||
* @note This macro wraps a low level function named
|
* @note This macro wraps a low level function named
|
||||||
|
@ -171,16 +147,6 @@ typedef enum {
|
||||||
* @api
|
* @api
|
||||||
*/
|
*/
|
||||||
#define sdcIsWriteProtected(sdcp) (sdc_lld_is_write_protected(sdcp))
|
#define sdcIsWriteProtected(sdcp) (sdc_lld_is_write_protected(sdcp))
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Returns the card capacity in blocks.
|
|
||||||
*
|
|
||||||
* @param[in] sdcp pointer to the @p SDCDriver object
|
|
||||||
* @return The card capacity.
|
|
||||||
*
|
|
||||||
* @api
|
|
||||||
*/
|
|
||||||
#define sdcGetCardCapacity(sdcp) ((sdcp)->capacity)
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
|
@ -41,8 +41,8 @@
|
||||||
/* Driver local definitions. */
|
/* Driver local definitions. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
#define DMA_CHANNEL \
|
#define DMA_CHANNEL \
|
||||||
STM32_DMA_GETCHANNEL(STM32_SDC_SDIO_DMA_STREAM, \
|
STM32_DMA_GETCHANNEL(STM32_SDC_SDIO_DMA_STREAM, \
|
||||||
STM32_SDC_SDIO_DMA_CHN)
|
STM32_SDC_SDIO_DMA_CHN)
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -346,7 +346,7 @@ void sdc_lld_start(SDCDriver *sdcp) {
|
||||||
STM32_DMA_CR_MBURST_INCR4;
|
STM32_DMA_CR_MBURST_INCR4;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (sdcp->state == SDC_STOP) {
|
if (sdcp->state == BLK_STOP) {
|
||||||
/* Note, the DMA must be enabled before the IRQs.*/
|
/* Note, the DMA must be enabled before the IRQs.*/
|
||||||
bool_t b;
|
bool_t b;
|
||||||
b = dmaStreamAllocate(sdcp->dma, STM32_SDC_SDIO_IRQ_PRIORITY, NULL, NULL);
|
b = dmaStreamAllocate(sdcp->dma, STM32_SDC_SDIO_IRQ_PRIORITY, NULL, NULL);
|
||||||
|
@ -376,7 +376,9 @@ void sdc_lld_start(SDCDriver *sdcp) {
|
||||||
*/
|
*/
|
||||||
void sdc_lld_stop(SDCDriver *sdcp) {
|
void sdc_lld_stop(SDCDriver *sdcp) {
|
||||||
|
|
||||||
if ((sdcp->state == SDC_READY) || (sdcp->state == SDC_ACTIVE)) {
|
if (sdcp->state != BLK_STOP) {
|
||||||
|
|
||||||
|
/* SDIO deactivation.*/
|
||||||
SDIO->POWER = 0;
|
SDIO->POWER = 0;
|
||||||
SDIO->CLKCR = 0;
|
SDIO->CLKCR = 0;
|
||||||
SDIO->DCTRL = 0;
|
SDIO->DCTRL = 0;
|
||||||
|
|
|
@ -229,10 +229,6 @@ struct SDCDriver {
|
||||||
*/
|
*/
|
||||||
const struct SDCDriverVMT *vmt;
|
const struct SDCDriverVMT *vmt;
|
||||||
_mmcsd_block_device_data
|
_mmcsd_block_device_data
|
||||||
/**
|
|
||||||
* @brief Driver state.
|
|
||||||
*/
|
|
||||||
sdcstate_t state;
|
|
||||||
/**
|
/**
|
||||||
* @brief Current configuration data.
|
* @brief Current configuration data.
|
||||||
*/
|
*/
|
||||||
|
|
111
os/hal/src/sdc.c
111
os/hal/src/sdc.c
|
@ -125,10 +125,10 @@ void sdcInit(void) {
|
||||||
*/
|
*/
|
||||||
void sdcObjectInit(SDCDriver *sdcp) {
|
void sdcObjectInit(SDCDriver *sdcp) {
|
||||||
|
|
||||||
sdcp->vmt = &sdc_vmt;
|
sdcp->vmt = &sdc_vmt;
|
||||||
sdcp->state = SDC_STOP;
|
sdcp->state = BLK_STOP;
|
||||||
sdcp->errors = SDC_NO_ERROR;
|
sdcp->errors = SDC_NO_ERROR;
|
||||||
sdcp->config = NULL;
|
sdcp->config = NULL;
|
||||||
sdcp->capacity = 0;
|
sdcp->capacity = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,11 +147,11 @@ void sdcStart(SDCDriver *sdcp, const SDCConfig *config) {
|
||||||
chDbgCheck(sdcp != NULL, "sdcStart");
|
chDbgCheck(sdcp != NULL, "sdcStart");
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
chDbgAssert((sdcp->state == SDC_STOP) || (sdcp->state == SDC_READY),
|
chDbgAssert((sdcp->state == BLK_STOP) || (sdcp->state == BLK_ACTIVE),
|
||||||
"sdcStart(), #1", "invalid state");
|
"sdcStart(), #1", "invalid state");
|
||||||
sdcp->config = config;
|
sdcp->config = config;
|
||||||
sdc_lld_start(sdcp);
|
sdc_lld_start(sdcp);
|
||||||
sdcp->state = SDC_READY;
|
sdcp->state = BLK_ACTIVE;
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,17 +167,17 @@ void sdcStop(SDCDriver *sdcp) {
|
||||||
chDbgCheck(sdcp != NULL, "sdcStop");
|
chDbgCheck(sdcp != NULL, "sdcStop");
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
chDbgAssert((sdcp->state == SDC_STOP) || (sdcp->state == SDC_READY),
|
chDbgAssert((sdcp->state == BLK_STOP) || (sdcp->state == BLK_ACTIVE),
|
||||||
"sdcStop(), #1", "invalid state");
|
"sdcStop(), #1", "invalid state");
|
||||||
sdc_lld_stop(sdcp);
|
sdc_lld_stop(sdcp);
|
||||||
sdcp->state = SDC_STOP;
|
sdcp->state = BLK_STOP;
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Performs the initialization procedure on the inserted card.
|
* @brief Performs the initialization procedure on the inserted card.
|
||||||
* @details This function should be invoked when a card is inserted and
|
* @details This function should be invoked when a card is inserted and
|
||||||
* brings the driver in the @p SDC_ACTIVE state where it is possible
|
* brings the driver in the @p BLK_READY state where it is possible
|
||||||
* to perform read and write operations.
|
* to perform read and write operations.
|
||||||
*
|
*
|
||||||
* @param[in] sdcp pointer to the @p SDCDriver object
|
* @param[in] sdcp pointer to the @p SDCDriver object
|
||||||
|
@ -192,12 +192,11 @@ bool_t sdcConnect(SDCDriver *sdcp) {
|
||||||
uint32_t resp[1];
|
uint32_t resp[1];
|
||||||
|
|
||||||
chDbgCheck(sdcp != NULL, "sdcConnect");
|
chDbgCheck(sdcp != NULL, "sdcConnect");
|
||||||
|
chDbgAssert((sdcp->state == BLK_ACTIVE) || (sdcp->state == BLK_READY),
|
||||||
chSysLock();
|
|
||||||
chDbgAssert((sdcp->state == SDC_READY) || (sdcp->state == SDC_ACTIVE),
|
|
||||||
"mmcConnect(), #1", "invalid state");
|
"mmcConnect(), #1", "invalid state");
|
||||||
sdcp->state = SDC_CONNECTING;
|
|
||||||
chSysUnlock();
|
/* Connection procedure in progress.*/
|
||||||
|
sdcp->state = BLK_CONNECTING;
|
||||||
|
|
||||||
/* Card clock initialization.*/
|
/* Card clock initialization.*/
|
||||||
sdc_lld_start_clk(sdcp);
|
sdc_lld_start_clk(sdcp);
|
||||||
|
@ -228,7 +227,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.*/
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
@ -311,13 +310,13 @@ bool_t sdcConnect(SDCDriver *sdcp) {
|
||||||
goto failed;
|
goto failed;
|
||||||
|
|
||||||
/* Initialization complete.*/
|
/* Initialization complete.*/
|
||||||
sdcp->state = SDC_ACTIVE;
|
sdcp->state = BLK_READY;
|
||||||
return CH_SUCCESS;
|
return CH_SUCCESS;
|
||||||
|
|
||||||
/* Initialization failed.*/
|
/* Connection failed, state reset to BLK_ACTIVE.*/
|
||||||
failed:
|
failed:
|
||||||
sdc_lld_stop_clk(sdcp);
|
sdc_lld_stop_clk(sdcp);
|
||||||
sdcp->state = SDC_READY;
|
sdcp->state = BLK_ACTIVE;
|
||||||
return CH_FAILED;
|
return CH_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,29 +336,31 @@ bool_t sdcDisconnect(SDCDriver *sdcp) {
|
||||||
chDbgCheck(sdcp != NULL, "sdcDisconnect");
|
chDbgCheck(sdcp != NULL, "sdcDisconnect");
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
chDbgAssert((sdcp->state == SDC_READY) || (sdcp->state == SDC_ACTIVE),
|
chDbgAssert((sdcp->state == BLK_ACTIVE) || (sdcp->state == BLK_READY),
|
||||||
"sdcDisconnect(), #1", "invalid state");
|
"sdcDisconnect(), #1", "invalid state");
|
||||||
if (sdcp->state == SDC_READY) {
|
if (sdcp->state == BLK_ACTIVE) {
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
return CH_SUCCESS;
|
return CH_SUCCESS;
|
||||||
}
|
}
|
||||||
sdcp->state = SDC_DISCONNECTING;
|
sdcp->state = BLK_DISCONNECTING;
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
|
|
||||||
/* Waits for eventual pending operations completion.*/
|
/* Waits for eventual pending operations completion.*/
|
||||||
if (_sdc_wait_for_transfer_state(sdcp))
|
if (_sdc_wait_for_transfer_state(sdcp)) {
|
||||||
|
sdc_lld_stop_clk(sdcp);
|
||||||
|
sdcp->state = BLK_ACTIVE;
|
||||||
return CH_FAILED;
|
return CH_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
/* Card clock stopped.*/
|
/* Card clock stopped.*/
|
||||||
sdc_lld_stop_clk(sdcp);
|
sdc_lld_stop_clk(sdcp);
|
||||||
|
sdcp->state = BLK_ACTIVE;
|
||||||
sdcp->state = SDC_READY;
|
|
||||||
return CH_SUCCESS;
|
return CH_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Reads one or more blocks.
|
* @brief Reads one or more blocks.
|
||||||
* @pre The driver must be in the @p SDC_ACTIVE state after a successful
|
* @pre The driver must be in the @p BLK_READY state after a successful
|
||||||
* sdcConnect() invocation.
|
* sdcConnect() invocation.
|
||||||
*
|
*
|
||||||
* @param[in] sdcp pointer to the @p SDCDriver object
|
* @param[in] sdcp pointer to the @p SDCDriver object
|
||||||
|
@ -378,25 +379,26 @@ bool_t sdcRead(SDCDriver *sdcp, uint32_t startblk,
|
||||||
bool_t status;
|
bool_t status;
|
||||||
|
|
||||||
chDbgCheck((sdcp != NULL) && (buf != NULL) && (n > 0), "sdcRead");
|
chDbgCheck((sdcp != NULL) && (buf != NULL) && (n > 0), "sdcRead");
|
||||||
|
chDbgAssert(sdcp->state == BLK_READY, "sdcRead(), #1", "invalid state");
|
||||||
|
|
||||||
if ((startblk + n - 1) > sdcp->capacity){
|
if ((startblk + n - 1) > sdcp->capacity){
|
||||||
sdcp->errors |= SDC_OVERFLOW_ERROR;
|
sdcp->errors |= SDC_OVERFLOW_ERROR;
|
||||||
return CH_FAILED;
|
return CH_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
chSysLock();
|
/* Read operation in progress.*/
|
||||||
chDbgAssert(sdcp->state == SDC_ACTIVE, "sdcRead(), #1", "invalid state");
|
sdcp->state = BLK_READING;
|
||||||
sdcp->state = SDC_READING;
|
|
||||||
chSysUnlock();
|
|
||||||
|
|
||||||
status = sdc_lld_read(sdcp, startblk, buf, n);
|
status = sdc_lld_read(sdcp, startblk, buf, n);
|
||||||
sdcp->state = SDC_ACTIVE;
|
|
||||||
|
/* Read operation finished.*/
|
||||||
|
sdcp->state = BLK_READY;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Writes one or more blocks.
|
* @brief Writes one or more blocks.
|
||||||
* @pre The driver must be in the @p SDC_ACTIVE state after a successful
|
* @pre The driver must be in the @p BLK_READY state after a successful
|
||||||
* sdcConnect() invocation.
|
* sdcConnect() invocation.
|
||||||
*
|
*
|
||||||
* @param[in] sdcp pointer to the @p SDCDriver object
|
* @param[in] sdcp pointer to the @p SDCDriver object
|
||||||
|
@ -415,19 +417,20 @@ bool_t sdcWrite(SDCDriver *sdcp, uint32_t startblk,
|
||||||
bool_t status;
|
bool_t status;
|
||||||
|
|
||||||
chDbgCheck((sdcp != NULL) && (buf != NULL) && (n > 0), "sdcWrite");
|
chDbgCheck((sdcp != NULL) && (buf != NULL) && (n > 0), "sdcWrite");
|
||||||
|
chDbgAssert(sdcp->state == BLK_READY, "sdcWrite(), #1", "invalid state");
|
||||||
|
|
||||||
if ((startblk + n - 1) > sdcp->capacity){
|
if ((startblk + n - 1) > sdcp->capacity){
|
||||||
sdcp->errors |= SDC_OVERFLOW_ERROR;
|
sdcp->errors |= SDC_OVERFLOW_ERROR;
|
||||||
return CH_FAILED;
|
return CH_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
chSysLock();
|
/* Write operation in progress.*/
|
||||||
chDbgAssert(sdcp->state == SDC_ACTIVE, "sdcWrite(), #1", "invalid state");
|
sdcp->state = BLK_WRITING;
|
||||||
sdcp->state = SDC_WRITING;
|
|
||||||
chSysUnlock();
|
|
||||||
|
|
||||||
status = sdc_lld_write(sdcp, startblk, buf, n);
|
status = sdc_lld_write(sdcp, startblk, buf, n);
|
||||||
sdcp->state = SDC_ACTIVE;
|
|
||||||
|
/* Write operation finished.*/
|
||||||
|
sdcp->state = BLK_READY;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,6 +445,8 @@ bool_t sdcWrite(SDCDriver *sdcp, uint32_t startblk,
|
||||||
sdcflags_t sdcGetAndClearErrors(SDCDriver *sdcp) {
|
sdcflags_t sdcGetAndClearErrors(SDCDriver *sdcp) {
|
||||||
|
|
||||||
chDbgCheck(sdcp != NULL, "sdcGetAndClearErrors");
|
chDbgCheck(sdcp != NULL, "sdcGetAndClearErrors");
|
||||||
|
chDbgAssert(sdcp->state == BLK_READY,
|
||||||
|
"sdcGetAndClearErrors(), #1", "invalid state");
|
||||||
|
|
||||||
chSysLock();
|
chSysLock();
|
||||||
sdcflags_t flags = sdcp->errors;
|
sdcflags_t flags = sdcp->errors;
|
||||||
|
@ -465,12 +470,8 @@ bool_t sdcSync(SDCDriver *sdcp) {
|
||||||
|
|
||||||
chDbgCheck(sdcp != NULL, "sdcSync");
|
chDbgCheck(sdcp != NULL, "sdcSync");
|
||||||
|
|
||||||
chSysLock();
|
if (sdcp->state != BLK_READY)
|
||||||
if (sdcp->state != SDC_READY) {
|
|
||||||
chSysUnlock();
|
|
||||||
return CH_FAILED;
|
return CH_FAILED;
|
||||||
}
|
|
||||||
chSysUnlock();
|
|
||||||
|
|
||||||
return sdc_lld_sync(sdcp);
|
return sdc_lld_sync(sdcp);
|
||||||
}
|
}
|
||||||
|
@ -489,15 +490,10 @@ bool_t sdcSync(SDCDriver *sdcp) {
|
||||||
*/
|
*/
|
||||||
bool_t sdcGetInfo(SDCDriver *sdcp, BlockDeviceInfo *bdip) {
|
bool_t sdcGetInfo(SDCDriver *sdcp, BlockDeviceInfo *bdip) {
|
||||||
|
|
||||||
|
|
||||||
chDbgCheck((sdcp != NULL) && (bdip != NULL), "sdcGetInfo");
|
chDbgCheck((sdcp != NULL) && (bdip != NULL), "sdcGetInfo");
|
||||||
|
|
||||||
chSysLock();
|
if (sdcp->state != BLK_READY)
|
||||||
if (sdcp->state != SDC_READY) {
|
|
||||||
chSysUnlock();
|
|
||||||
return CH_FAILED;
|
return CH_FAILED;
|
||||||
}
|
|
||||||
chSysUnlock();
|
|
||||||
|
|
||||||
bdip->blk_num = sdcp->capacity;
|
bdip->blk_num = sdcp->capacity;
|
||||||
bdip->blk_size = MMCSD_BLOCK_SIZE;
|
bdip->blk_size = MMCSD_BLOCK_SIZE;
|
||||||
|
@ -523,29 +519,36 @@ bool_t sdcErase(SDCDriver *sdcp, uint32_t startblk, uint32_t endblk) {
|
||||||
uint32_t resp[1];
|
uint32_t resp[1];
|
||||||
|
|
||||||
chDbgCheck((sdcp != NULL), "sdcErase");
|
chDbgCheck((sdcp != NULL), "sdcErase");
|
||||||
|
chDbgAssert(sdcp->state == BLK_READY, "sdcErase(), #1", "invalid state");
|
||||||
|
|
||||||
/* Driver handles data in 512 bytes blocks (just like HC cards). But if we
|
/* Handling command differences between HC and normal cards.*/
|
||||||
have not HC card than we must convert address from blocks to bytes.*/
|
|
||||||
if (!(sdcp->cardmode & SDC_MODE_HIGH_CAPACITY)) {
|
if (!(sdcp->cardmode & SDC_MODE_HIGH_CAPACITY)) {
|
||||||
startblk *= MMCSD_BLOCK_SIZE;
|
startblk *= MMCSD_BLOCK_SIZE;
|
||||||
endblk *= MMCSD_BLOCK_SIZE;
|
endblk *= MMCSD_BLOCK_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
_sdc_wait_for_transfer_state( sdcp );
|
_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]))
|
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;
|
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]))
|
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;
|
return CH_FAILED;
|
||||||
|
|
||||||
if (sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_ERASE, 0, resp) != CH_SUCCESS || MMCSD_R1_ERROR(resp[0]))
|
if ((sdc_lld_send_cmd_short_crc(sdcp, MMCSD_CMD_ERASE,
|
||||||
|
0, resp) != CH_SUCCESS) ||
|
||||||
|
MMCSD_R1_ERROR(resp[0]))
|
||||||
return CH_FAILED;
|
return CH_FAILED;
|
||||||
|
|
||||||
/* Quick sleep to allow it to transition to programming or receiving state */
|
/* Quick sleep to allow it to transition to programming or receiving state */
|
||||||
|
/* TODO: ??????????????????????????? */
|
||||||
|
|
||||||
/* Wait for it to return to transfer state to indicate it has finished erasing */
|
/* Wait for it to return to transfer state to indicate it has finished erasing */
|
||||||
_sdc_wait_for_transfer_state( sdcp );
|
_sdc_wait_for_transfer_state(sdcp);
|
||||||
|
|
||||||
return CH_SUCCESS;
|
return CH_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue