From 3922b69fc1605a95758d8bf259753929dbb3f9f7 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Mon, 11 May 2015 14:33:14 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@7960 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/ports/STM32/LLD/sdc_lld.c | 133 +++++++++++++++++---------------------- os/hal/ports/STM32/LLD/sdc_lld.h | 4 ++ 2 files changed, 60 insertions(+), 77 deletions(-) diff --git a/os/hal/ports/STM32/LLD/sdc_lld.c b/os/hal/ports/STM32/LLD/sdc_lld.c index 3e53b2b0f..948c22afc 100644 --- a/os/hal/ports/STM32/LLD/sdc_lld.c +++ b/os/hal/ports/STM32/LLD/sdc_lld.c @@ -71,57 +71,7 @@ static const SDCConfig sdc_default_cfg = { /*===========================================================================*/ /** - * @brief Prepares MCU to handle read transaction. - * - * @param[in] sdcp pointer to the @p SDCDriver object - * @param[out] buf pointer to the read buffer - * @param[in] n number of blocks to read - * - * @return The operation status. - * @retval HAL_SUCCESS operation succeeded. - * @retval HAL_FAILED operation failed. - * - * @notapi - */ -static bool sdc_lld_prepare_read_mcu_blocks(SDCDriver *sdcp, - uint8_t *buf, uint32_t blocks) { - - osalDbgCheck(blocks < 0x1000000 / MMCSD_BLOCK_SIZE); - - SDIO->DTIMER = STM32_SDC_READ_TIMEOUT; - - /* Checks for errors and waits for the card to be ready for reading.*/ - if (_sdc_wait_for_transfer_state(sdcp)) - return HAL_FAILED; - - /* Prepares the DMA channel for writing.*/ - dmaStreamSetMemory0(sdcp->dma, buf); - dmaStreamSetTransactionSize(sdcp->dma, - (blocks * MMCSD_BLOCK_SIZE) / sizeof (uint32_t)); - dmaStreamSetMode(sdcp->dma, sdcp->dmamode | STM32_DMA_CR_DIR_P2M); - dmaStreamEnable(sdcp->dma); - - /* Setting up data transfer.*/ - SDIO->ICR = STM32_SDIO_ICR_ALL_FLAGS; - SDIO->MASK = SDIO_MASK_DCRCFAILIE | - SDIO_MASK_DTIMEOUTIE | - SDIO_MASK_STBITERRIE | - SDIO_MASK_RXOVERRIE | - SDIO_MASK_DATAENDIE; - SDIO->DLEN = blocks * MMCSD_BLOCK_SIZE; - - /* Transaction starts just after DTEN bit setting.*/ - SDIO->DCTRL = SDIO_DCTRL_DTDIR | - SDIO_DCTRL_DBLOCKSIZE_3 | - SDIO_DCTRL_DBLOCKSIZE_0 | - SDIO_DCTRL_DMAEN | - SDIO_DCTRL_DTEN; - - return HAL_SUCCESS; -} - -/** - * @brief Prepares MCU to handle read transaction. + * @brief Prepares to handle read transaction. * @details Designed for read special registers from card. * * @param[in] sdcp pointer to the @p SDCDriver object @@ -134,8 +84,8 @@ static bool sdc_lld_prepare_read_mcu_blocks(SDCDriver *sdcp, * * @notapi */ -static bool sdc_lld_prepare_read_mcu_bytes(SDCDriver *sdcp, - uint8_t *buf, uint32_t bytes) { +static bool sdc_lld_prepare_read_bytes(SDCDriver *sdcp, + uint8_t *buf, uint32_t bytes) { osalDbgCheck(bytes < 0x1000000); SDIO->DTIMER = STM32_SDC_READ_TIMEOUT; @@ -182,8 +132,8 @@ static bool sdc_lld_prepare_read_mcu_bytes(SDCDriver *sdcp, * * @notapi */ -static bool sdc_lld_prepare_read_card(SDCDriver *sdcp, uint32_t startblk, - uint32_t n, uint32_t *resp) { +static bool sdc_lld_prepare_read(SDCDriver *sdcp, uint32_t startblk, + uint32_t n, uint32_t *resp) { /* 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.*/ @@ -683,12 +633,14 @@ bool sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, } /** - * @brief Reads one or more blocks. + * @brief Reads special registers using data bus. + * @details Needs only during card detection procedure. * * @param[in] sdcp pointer to the @p SDCDriver object - * @param[in] startblk first block to read * @param[out] buf pointer to the read buffer - * @param[in] blocks number of blocks to read + * @param[in] bytes number of bytes to read + * @param[in] cmd card command + * @param[in] arg argument for command * * @return The operation status. * @retval HAL_SUCCESS operation succeeded. @@ -696,35 +648,34 @@ bool sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg, * * @notapi */ -bool sdc_lld_read_aligned(SDCDriver *sdcp, uint32_t startblk, - uint8_t *buf, uint32_t blocks) { +bool sdc_lld_read_special(SDCDriver *sdcp, uint8_t *buf, size_t bytes, + uint8_t cmd, uint32_t arg) { uint32_t resp[1]; - if(sdc_lld_prepare_read_mcu_blocks(sdcp, buf, blocks)) + if(sdc_lld_prepare_read_bytes(sdcp, buf, bytes)) goto error; - if (sdc_lld_prepare_read_card(sdcp, startblk, blocks, resp) == TRUE) + if (sdc_lld_send_cmd_short_crc(sdcp, cmd, arg, resp) + || MMCSD_R1_ERROR(resp[0])) goto error; - if (sdc_lld_wait_transaction_end(sdcp, blocks, resp) == TRUE) + if (sdc_lld_wait_transaction_end(sdcp, 1, resp)) goto error; return HAL_SUCCESS; error: - sdc_lld_error_cleanup(sdcp, blocks, resp); + sdc_lld_error_cleanup(sdcp, 1, resp); return HAL_FAILED; } /** - * @brief Reads special registers using data bus. - * @details Needs only during card detection procedure. + * @brief Reads one or more blocks. * * @param[in] sdcp pointer to the @p SDCDriver object + * @param[in] startblk first block to read * @param[out] buf pointer to the read buffer - * @param[in] bytes number of bytes to read - * @param[in] cmd card command - * @param[in] arg argument for command + * @param[in] blocks number of blocks to read * * @return The operation status. * @retval HAL_SUCCESS operation succeeded. @@ -732,24 +683,51 @@ error: * * @notapi */ -bool sdc_lld_read_special(SDCDriver *sdcp, uint8_t *buf, size_t bytes, - uint8_t cmd, uint32_t arg) { +bool sdc_lld_read_aligned(SDCDriver *sdcp, uint32_t startblk, + uint8_t *buf, uint32_t blocks) { uint32_t resp[1]; - if(sdc_lld_prepare_read_mcu_bytes(sdcp, buf, bytes)) - goto error; + osalDbgCheck(blocks < 0x1000000 / MMCSD_BLOCK_SIZE); - if (sdc_lld_send_cmd_short_crc(sdcp, cmd, arg, resp) - || MMCSD_R1_ERROR(resp[0])) + SDIO->DTIMER = STM32_SDC_READ_TIMEOUT; + + /* Checks for errors and waits for the card to be ready for reading.*/ + if (_sdc_wait_for_transfer_state(sdcp)) + return HAL_FAILED; + + /* Prepares the DMA channel for writing.*/ + dmaStreamSetMemory0(sdcp->dma, buf); + dmaStreamSetTransactionSize(sdcp->dma, + (blocks * MMCSD_BLOCK_SIZE) / sizeof (uint32_t)); + dmaStreamSetMode(sdcp->dma, sdcp->dmamode | STM32_DMA_CR_DIR_P2M); + dmaStreamEnable(sdcp->dma); + + /* Setting up data transfer.*/ + SDIO->ICR = STM32_SDIO_ICR_ALL_FLAGS; + SDIO->MASK = SDIO_MASK_DCRCFAILIE | + SDIO_MASK_DTIMEOUTIE | + SDIO_MASK_STBITERRIE | + SDIO_MASK_RXOVERRIE | + SDIO_MASK_DATAENDIE; + SDIO->DLEN = blocks * MMCSD_BLOCK_SIZE; + + /* Transaction starts just after DTEN bit setting.*/ + SDIO->DCTRL = SDIO_DCTRL_DTDIR | + SDIO_DCTRL_DBLOCKSIZE_3 | + SDIO_DCTRL_DBLOCKSIZE_0 | + SDIO_DCTRL_DMAEN | + SDIO_DCTRL_DTEN; + + if (sdc_lld_prepare_read(sdcp, startblk, blocks, resp) == TRUE) goto error; - if (sdc_lld_wait_transaction_end(sdcp, 1, resp)) + if (sdc_lld_wait_transaction_end(sdcp, blocks, resp) == TRUE) goto error; return HAL_SUCCESS; error: - sdc_lld_error_cleanup(sdcp, 1, resp); + sdc_lld_error_cleanup(sdcp, blocks, resp); return HAL_FAILED; } @@ -804,6 +782,7 @@ bool sdc_lld_write_aligned(SDCDriver *sdcp, uint32_t startblk, SDIO_DCTRL_DBLOCKSIZE_0 | SDIO_DCTRL_DMAEN | SDIO_DCTRL_DTEN; + if (sdc_lld_wait_transaction_end(sdcp, blocks, resp) == TRUE) goto error; diff --git a/os/hal/ports/STM32/LLD/sdc_lld.h b/os/hal/ports/STM32/LLD/sdc_lld.h index 8b960fb97..ae258e5f1 100644 --- a/os/hal/ports/STM32/LLD/sdc_lld.h +++ b/os/hal/ports/STM32/LLD/sdc_lld.h @@ -159,6 +159,10 @@ #error "SDIO requires STM32_CLOCK48_REQUIRED to be enabled" #endif +#if STM32_PLL48CLK != 48000000 +#error "invalid STM32_PLL48CLK clock value" +#endif + #define STM32_SDC_WRITE_TIMEOUT \ (((STM32_PLL48CLK / (STM32_SDIO_DIV_HS + 2)) / 1000) * \ STM32_SDC_WRITE_TIMEOUT_MS) -- cgit v1.2.3