From 9492ff4976cb9e8af40c9a6715b7d9f7ef5f9428 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 26 Jun 2012 18:18:14 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4349 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- demos/ARMCM3-STM32F103ZG-FATFS/main.c | 50 ++++++++------- os/hal/include/sdc.h | 34 ----------- os/hal/platforms/STM32/sdc_lld.c | 10 +-- os/hal/platforms/STM32/sdc_lld.h | 4 -- os/hal/src/sdc.c | 111 +++++++++++++++++----------------- 5 files changed, 91 insertions(+), 118 deletions(-) diff --git a/demos/ARMCM3-STM32F103ZG-FATFS/main.c b/demos/ARMCM3-STM32F103ZG-FATFS/main.c index b21e7a864..b44612091 100644 --- a/demos/ARMCM3-STM32F103ZG-FATFS/main.c +++ b/demos/ARMCM3-STM32F103ZG-FATFS/main.c @@ -34,8 +34,8 @@ /* Card insertion monitor. */ /*===========================================================================*/ -#define SDC_POLLING_INTERVAL 10 -#define SDC_POLLING_DELAY 10 +#define POLLING_INTERVAL 10 +#define POLLING_DELAY 10 /** * @brief Card monitor timer. @@ -55,47 +55,55 @@ static EventSource inserted_event, removed_event; /** * @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 */ 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(); - if (cnt > 0) { - if (sdcIsCardInserted(sdcp)) { - if (--cnt == 0) { - chEvtBroadcastI(&inserted_event); + if ((state != BLK_READING) && (state != BLK_WRITING)) { + /* Safe to perform the check.*/ + if (cnt > 0) { + if (blkIsInserted(bbdp)) { + if (--cnt == 0) { + chEvtBroadcastI(&inserted_event); + } } + else + cnt = POLLING_INTERVAL; } - else - cnt = SDC_POLLING_INTERVAL; - } - else { - if (!sdcIsCardInserted(sdcp)) { - cnt = SDC_POLLING_INTERVAL; - chEvtBroadcastI(&removed_event); + else { + if (!blkIsInserted(bbdp)) { + cnt = POLLING_INTERVAL; + chEvtBroadcastI(&removed_event); + } } } - chVTSetI(&tmr, MS2ST(SDC_POLLING_DELAY), tmrfunc, sdcp); + chVTSetI(&tmr, MS2ST(POLLING_DELAY), tmrfunc, bbdp); chSysUnlockFromIsr(); } /** * @brief Polling monitor start. * - * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] p pointer to an object implementing @p BaseBlockDevice * * @notapi */ -static void tmr_init(SDCDriver *sdcp) { +static void tmr_init(void *p) { chEvtInit(&inserted_event); chEvtInit(&removed_event); chSysLock(); - cnt = SDC_POLLING_INTERVAL; - chVTSetI(&tmr, MS2ST(SDC_POLLING_DELAY), tmrfunc, sdcp); + cnt = POLLING_INTERVAL; + chVTSetI(&tmr, MS2ST(POLLING_DELAY), tmrfunc, p); chSysUnlock(); } @@ -276,8 +284,6 @@ static void InsertHandler(eventid_t id) { static void RemoveHandler(eventid_t id) { (void)id; - if (sdcGetDriverState(&SDCD1) == SDC_ACTIVE) - sdcDisconnect(&SDCD1); fs_ready = FALSE; } diff --git a/os/hal/include/sdc.h b/os/hal/include/sdc.h index d2624d306..0b2098dc5 100644 --- a/os/hal/include/sdc.h +++ b/os/hal/include/sdc.h @@ -106,20 +106,6 @@ /* 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" /*===========================================================================*/ @@ -130,16 +116,6 @@ typedef enum { * @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. * @note This macro wraps a low level function named @@ -171,16 +147,6 @@ typedef enum { * @api */ #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) /** @} */ /*===========================================================================*/ diff --git a/os/hal/platforms/STM32/sdc_lld.c b/os/hal/platforms/STM32/sdc_lld.c index 84eb66b0b..77b20d242 100644 --- a/os/hal/platforms/STM32/sdc_lld.c +++ b/os/hal/platforms/STM32/sdc_lld.c @@ -41,8 +41,8 @@ /* Driver local definitions. */ /*===========================================================================*/ -#define DMA_CHANNEL \ - STM32_DMA_GETCHANNEL(STM32_SDC_SDIO_DMA_STREAM, \ +#define DMA_CHANNEL \ + STM32_DMA_GETCHANNEL(STM32_SDC_SDIO_DMA_STREAM, \ STM32_SDC_SDIO_DMA_CHN) /*===========================================================================*/ @@ -346,7 +346,7 @@ void sdc_lld_start(SDCDriver *sdcp) { STM32_DMA_CR_MBURST_INCR4; #endif - if (sdcp->state == SDC_STOP) { + if (sdcp->state == BLK_STOP) { /* Note, the DMA must be enabled before the IRQs.*/ bool_t b; 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) { - if ((sdcp->state == SDC_READY) || (sdcp->state == SDC_ACTIVE)) { + if (sdcp->state != BLK_STOP) { + + /* SDIO deactivation.*/ SDIO->POWER = 0; SDIO->CLKCR = 0; SDIO->DCTRL = 0; diff --git a/os/hal/platforms/STM32/sdc_lld.h b/os/hal/platforms/STM32/sdc_lld.h index 79eac638a..0312b011d 100644 --- a/os/hal/platforms/STM32/sdc_lld.h +++ b/os/hal/platforms/STM32/sdc_lld.h @@ -229,10 +229,6 @@ struct SDCDriver { */ const struct SDCDriverVMT *vmt; _mmcsd_block_device_data - /** - * @brief Driver state. - */ - sdcstate_t state; /** * @brief Current configuration data. */ diff --git a/os/hal/src/sdc.c b/os/hal/src/sdc.c index 19829f9b8..2773ab79c 100644 --- a/os/hal/src/sdc.c +++ b/os/hal/src/sdc.c @@ -125,10 +125,10 @@ void sdcInit(void) { */ void sdcObjectInit(SDCDriver *sdcp) { - sdcp->vmt = &sdc_vmt; - sdcp->state = SDC_STOP; - sdcp->errors = SDC_NO_ERROR; - sdcp->config = NULL; + sdcp->vmt = &sdc_vmt; + sdcp->state = BLK_STOP; + sdcp->errors = SDC_NO_ERROR; + sdcp->config = NULL; sdcp->capacity = 0; } @@ -147,11 +147,11 @@ void sdcStart(SDCDriver *sdcp, const SDCConfig *config) { chDbgCheck(sdcp != NULL, "sdcStart"); chSysLock(); - chDbgAssert((sdcp->state == SDC_STOP) || (sdcp->state == SDC_READY), + chDbgAssert((sdcp->state == BLK_STOP) || (sdcp->state == BLK_ACTIVE), "sdcStart(), #1", "invalid state"); sdcp->config = config; sdc_lld_start(sdcp); - sdcp->state = SDC_READY; + sdcp->state = BLK_ACTIVE; chSysUnlock(); } @@ -167,17 +167,17 @@ void sdcStop(SDCDriver *sdcp) { chDbgCheck(sdcp != NULL, "sdcStop"); chSysLock(); - chDbgAssert((sdcp->state == SDC_STOP) || (sdcp->state == SDC_READY), + chDbgAssert((sdcp->state == BLK_STOP) || (sdcp->state == BLK_ACTIVE), "sdcStop(), #1", "invalid state"); sdc_lld_stop(sdcp); - sdcp->state = SDC_STOP; + sdcp->state = BLK_STOP; chSysUnlock(); } /** * @brief Performs the initialization procedure on the inserted card. * @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. * * @param[in] sdcp pointer to the @p SDCDriver object @@ -192,12 +192,11 @@ bool_t sdcConnect(SDCDriver *sdcp) { uint32_t resp[1]; chDbgCheck(sdcp != NULL, "sdcConnect"); - - chSysLock(); - chDbgAssert((sdcp->state == SDC_READY) || (sdcp->state == SDC_ACTIVE), + chDbgAssert((sdcp->state == BLK_ACTIVE) || (sdcp->state == BLK_READY), "mmcConnect(), #1", "invalid state"); - sdcp->state = SDC_CONNECTING; - chSysUnlock(); + + /* Connection procedure in progress.*/ + sdcp->state = BLK_CONNECTING; /* Card clock initialization.*/ sdc_lld_start_clk(sdcp); @@ -228,7 +227,7 @@ bool_t sdcConnect(SDCDriver *sdcp) { } #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.*/ goto failed; } @@ -311,13 +310,13 @@ bool_t sdcConnect(SDCDriver *sdcp) { goto failed; /* Initialization complete.*/ - sdcp->state = SDC_ACTIVE; + sdcp->state = BLK_READY; return CH_SUCCESS; - /* Initialization failed.*/ + /* Connection failed, state reset to BLK_ACTIVE.*/ failed: sdc_lld_stop_clk(sdcp); - sdcp->state = SDC_READY; + sdcp->state = BLK_ACTIVE; return CH_FAILED; } @@ -337,29 +336,31 @@ bool_t sdcDisconnect(SDCDriver *sdcp) { chDbgCheck(sdcp != NULL, "sdcDisconnect"); chSysLock(); - chDbgAssert((sdcp->state == SDC_READY) || (sdcp->state == SDC_ACTIVE), + chDbgAssert((sdcp->state == BLK_ACTIVE) || (sdcp->state == BLK_READY), "sdcDisconnect(), #1", "invalid state"); - if (sdcp->state == SDC_READY) { + if (sdcp->state == BLK_ACTIVE) { chSysUnlock(); return CH_SUCCESS; } - sdcp->state = SDC_DISCONNECTING; + sdcp->state = BLK_DISCONNECTING; chSysUnlock(); /* 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; + } /* Card clock stopped.*/ sdc_lld_stop_clk(sdcp); - - sdcp->state = SDC_READY; + sdcp->state = BLK_ACTIVE; return CH_SUCCESS; } /** * @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. * * @param[in] sdcp pointer to the @p SDCDriver object @@ -378,25 +379,26 @@ bool_t sdcRead(SDCDriver *sdcp, uint32_t startblk, bool_t status; chDbgCheck((sdcp != NULL) && (buf != NULL) && (n > 0), "sdcRead"); + chDbgAssert(sdcp->state == BLK_READY, "sdcRead(), #1", "invalid state"); if ((startblk + n - 1) > sdcp->capacity){ sdcp->errors |= SDC_OVERFLOW_ERROR; return CH_FAILED; } - chSysLock(); - chDbgAssert(sdcp->state == SDC_ACTIVE, "sdcRead(), #1", "invalid state"); - sdcp->state = SDC_READING; - chSysUnlock(); + /* Read operation in progress.*/ + sdcp->state = BLK_READING; status = sdc_lld_read(sdcp, startblk, buf, n); - sdcp->state = SDC_ACTIVE; + + /* Read operation finished.*/ + sdcp->state = BLK_READY; return status; } /** * @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. * * @param[in] sdcp pointer to the @p SDCDriver object @@ -415,19 +417,20 @@ bool_t sdcWrite(SDCDriver *sdcp, uint32_t startblk, bool_t status; chDbgCheck((sdcp != NULL) && (buf != NULL) && (n > 0), "sdcWrite"); + chDbgAssert(sdcp->state == BLK_READY, "sdcWrite(), #1", "invalid state"); if ((startblk + n - 1) > sdcp->capacity){ sdcp->errors |= SDC_OVERFLOW_ERROR; return CH_FAILED; } - chSysLock(); - chDbgAssert(sdcp->state == SDC_ACTIVE, "sdcWrite(), #1", "invalid state"); - sdcp->state = SDC_WRITING; - chSysUnlock(); + /* Write operation in progress.*/ + sdcp->state = BLK_WRITING; status = sdc_lld_write(sdcp, startblk, buf, n); - sdcp->state = SDC_ACTIVE; + + /* Write operation finished.*/ + sdcp->state = BLK_READY; return status; } @@ -442,6 +445,8 @@ bool_t sdcWrite(SDCDriver *sdcp, uint32_t startblk, sdcflags_t sdcGetAndClearErrors(SDCDriver *sdcp) { chDbgCheck(sdcp != NULL, "sdcGetAndClearErrors"); + chDbgAssert(sdcp->state == BLK_READY, + "sdcGetAndClearErrors(), #1", "invalid state"); chSysLock(); sdcflags_t flags = sdcp->errors; @@ -465,12 +470,8 @@ bool_t sdcSync(SDCDriver *sdcp) { chDbgCheck(sdcp != NULL, "sdcSync"); - chSysLock(); - if (sdcp->state != SDC_READY) { - chSysUnlock(); + if (sdcp->state != BLK_READY) return CH_FAILED; - } - chSysUnlock(); return sdc_lld_sync(sdcp); } @@ -489,15 +490,10 @@ bool_t sdcSync(SDCDriver *sdcp) { */ bool_t sdcGetInfo(SDCDriver *sdcp, BlockDeviceInfo *bdip) { - chDbgCheck((sdcp != NULL) && (bdip != NULL), "sdcGetInfo"); - chSysLock(); - if (sdcp->state != SDC_READY) { - chSysUnlock(); + if (sdcp->state != BLK_READY) return CH_FAILED; - } - chSysUnlock(); bdip->blk_num = sdcp->capacity; 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]; 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 - have not HC card than we must convert address from blocks to bytes.*/ + /* Handling command differences between HC and normal cards.*/ if (!(sdcp->cardmode & SDC_MODE_HIGH_CAPACITY)) { startblk *= 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; - 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; - 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; /* 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 */ - _sdc_wait_for_transfer_state( sdcp ); + _sdc_wait_for_transfer_state(sdcp); return CH_SUCCESS; } -- cgit v1.2.3