diff options
author | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2011-07-23 07:38:56 +0000 |
---|---|---|
committer | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2011-07-23 07:38:56 +0000 |
commit | f9229daa87c2b60b0a9e6be6e1cb4ebf8c8ad85f (patch) | |
tree | 5d802a9734a64dd11332c9eb3d12392110c692b7 /os/hal/platforms/STM32/sdc_lld.c | |
parent | d115445582b5b65c22e445c0101f817ba75547c5 (diff) | |
download | ChibiOS-f9229daa87c2b60b0a9e6be6e1cb4ebf8c8ad85f.tar.gz ChibiOS-f9229daa87c2b60b0a9e6be6e1cb4ebf8c8ad85f.tar.bz2 ChibiOS-f9229daa87c2b60b0a9e6be6e1cb4ebf8c8ad85f.zip |
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3170 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal/platforms/STM32/sdc_lld.c')
-rw-r--r-- | os/hal/platforms/STM32/sdc_lld.c | 722 |
1 files changed, 0 insertions, 722 deletions
diff --git a/os/hal/platforms/STM32/sdc_lld.c b/os/hal/platforms/STM32/sdc_lld.c deleted file mode 100644 index a88ad53fa..000000000 --- a/os/hal/platforms/STM32/sdc_lld.c +++ /dev/null @@ -1,722 +0,0 @@ -/*
- ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
- 2011 Giovanni Di Sirio.
-
- This file is part of ChibiOS/RT.
-
- ChibiOS/RT is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- ChibiOS/RT is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/**
- * @file STM32/sdc_lld.c
- * @brief STM32 SDC subsystem low level driver source.
- *
- * @addtogroup SDC
- * @{
- */
-
-#include <string.h>
-
-#include "ch.h"
-#include "hal.h"
-
-#if HAL_USE_SDC || defined(__DOXYGEN__)
-
-/*===========================================================================*/
-/* Driver exported variables. */
-/*===========================================================================*/
-
-/** @brief SDCD1 driver identifier.*/
-SDCDriver SDCD1;
-
-/*===========================================================================*/
-/* Driver local variables. */
-/*===========================================================================*/
-
-#if STM32_SDC_UNALIGNED_SUPPORT
-/**
- * @brief Buffer for temporary storage during unaligned transfers.
- */
-static union {
- uint32_t alignment;
- uint8_t buf[SDC_BLOCK_SIZE];
-} u;
-#endif
-
-/*===========================================================================*/
-/* Driver local functions. */
-/*===========================================================================*/
-
-/**
- * @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, it must be aligned to
- * four bytes boundary
- * @param[in] n number of blocks to read
- * @return The operation status.
- * @retval FALSE operation succeeded, the requested blocks have been
- * read.
- * @retval TRUE operation failed, the state of the buffer is uncertain.
- *
- * @notapi
- */
-static bool_t sdc_lld_read_multiple(SDCDriver *sdcp, uint32_t startblk,
- uint8_t *buf, uint32_t n) {
- uint32_t resp[1];
-
- /* Checks for errors and waits for the card to be ready for reading.*/
- if (sdc_wait_for_transfer_state(sdcp))
- return TRUE;
-
- /* Prepares the DMA channel for reading.*/
- dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4],
- (n * SDC_BLOCK_SIZE) / sizeof (uint32_t), buf,
- (STM32_SDC_SDIO_DMA_PRIORITY << 12) |
- DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 |
- DMA_CCR1_MINC);
-
- /* Setting up data transfer.
- Options: Card to Controller, Block mode, DMA mode, 512 bytes blocks.*/
- SDIO->ICR = 0xFFFFFFFF;
- SDIO->MASK = SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE |
- SDIO_MASK_DATAENDIE | SDIO_MASK_STBITERRIE;
- SDIO->DLEN = n * SDC_BLOCK_SIZE;
- SDIO->DCTRL = SDIO_DCTRL_DTDIR |
- SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0 |
- SDIO_DCTRL_DMAEN |
- SDIO_DCTRL_DTEN;
-
- /* DMA channel activation.*/
- dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
-
- /* Read multiple blocks command.*/
- if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0)
- startblk *= SDC_BLOCK_SIZE;
- if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_READ_MULTIPLE_BLOCK,
- startblk, resp) ||
- SDC_R1_ERROR(resp[0]))
- goto error;
-
- chSysLock();
- if (SDIO->MASK != 0) {
- chDbgAssert(sdcp->thread == NULL,
- "sdc_lld_read_multiple(), #1", "not NULL");
- sdcp->thread = chThdSelf();
- chSchGoSleepS(THD_STATE_SUSPENDED);
- chDbgAssert(sdcp->thread == NULL,
- "sdc_lld_read_multiple(), #2", "not NULL");
- }
- if ((SDIO->STA & SDIO_STA_DATAEND) == 0) {
- chSysUnlock();
- goto error;
- }
- dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
- SDIO->ICR = 0xFFFFFFFF;
- SDIO->DCTRL = 0;
- chSysUnlock();
-
- return sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, 0, resp);
-error:
- dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
- SDIO->ICR = 0xFFFFFFFF;
- SDIO->MASK = 0;
- SDIO->DCTRL = 0;
- return TRUE;
-}
-
-/**
- * @brief Reads one block.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] startblk first block to read
- * @param[out] buf pointer to the read buffer, it must be aligned to
- * four bytes boundary
- * @return The operation status.
- * @retval FALSE operation succeeded, the requested blocks have been
- * read.
- * @retval TRUE operation failed, the state of the buffer is uncertain.
- *
- * @notapi
- */
-static bool_t sdc_lld_read_single(SDCDriver *sdcp, uint32_t startblk,
- uint8_t *buf) {
- uint32_t resp[1];
-
- /* Checks for errors and waits for the card to be ready for reading.*/
- if (sdc_wait_for_transfer_state(sdcp))
- return TRUE;
-
- /* Prepares the DMA channel for reading.*/
- dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4],
- SDC_BLOCK_SIZE / sizeof (uint32_t), buf,
- (STM32_SDC_SDIO_DMA_PRIORITY << 12) |
- DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 |
- DMA_CCR1_MINC);
-
- /* Setting up data transfer.
- Options: Card to Controller, Block mode, DMA mode, 512 bytes blocks.*/
- SDIO->ICR = 0xFFFFFFFF;
- SDIO->MASK = SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE |
- SDIO_MASK_DATAENDIE | SDIO_MASK_STBITERRIE;
- SDIO->DLEN = SDC_BLOCK_SIZE;
- SDIO->DCTRL = SDIO_DCTRL_DTDIR |
- SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0 |
- SDIO_DCTRL_DMAEN |
- SDIO_DCTRL_DTEN;
-
- /* DMA channel activation.*/
- dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
-
- /* Read single block command.*/
- if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0)
- startblk *= SDC_BLOCK_SIZE;
- if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_READ_SINGLE_BLOCK,
- startblk, resp) ||
- SDC_R1_ERROR(resp[0]))
- goto error;
-
- chSysLock();
- if (SDIO->MASK != 0) {
- chDbgAssert(sdcp->thread == NULL,
- "sdc_lld_read_single(), #1", "not NULL");
- sdcp->thread = chThdSelf();
- chSchGoSleepS(THD_STATE_SUSPENDED);
- chDbgAssert(sdcp->thread == NULL,
- "sdc_lld_read_single(), #2", "not NULL");
- }
- if ((SDIO->STA & SDIO_STA_DATAEND) == 0) {
- chSysUnlock();
- goto error;
- }
- dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
- SDIO->ICR = 0xFFFFFFFF;
- SDIO->DCTRL = 0;
- chSysUnlock();
-
- return FALSE;
-error:
- dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
- SDIO->ICR = 0xFFFFFFFF;
- SDIO->MASK = 0;
- SDIO->DCTRL = 0;
- return TRUE;
-}
-
-/**
- * @brief Writes one or more blocks.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] startblk first block to write
- * @param[out] buf pointer to the write buffer, it must be aligned to
- * four bytes boundary
- * @param[in] n number of blocks to write
- * @return The operation status.
- * @retval FALSE operation succeeded, the requested blocks have been
- * written.
- * @retval TRUE operation failed.
- *
- * @notapi
- */
-static bool_t sdc_lld_write_multiple(SDCDriver *sdcp, uint32_t startblk,
- const uint8_t *buf, uint32_t n) {
- uint32_t resp[1];
-
- /* Checks for errors and waits for the card to be ready for writing.*/
- if (sdc_wait_for_transfer_state(sdcp))
- return TRUE;
-
- /* Prepares the DMA channel for writing.*/
- dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4],
- (n * SDC_BLOCK_SIZE) / sizeof (uint32_t), buf,
- (STM32_SDC_SDIO_DMA_PRIORITY << 12) |
- DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 |
- DMA_CCR1_MINC | DMA_CCR1_DIR);
-
- /* Write multiple blocks command.*/
- if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0)
- startblk *= SDC_BLOCK_SIZE;
- if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_WRITE_MULTIPLE_BLOCK,
- startblk, resp) ||
- SDC_R1_ERROR(resp[0]))
- return TRUE;
-
- /* Setting up data transfer.
- Options: Controller to Card, Block mode, DMA mode, 512 bytes blocks.*/
- SDIO->ICR = 0xFFFFFFFF;
- SDIO->MASK = SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE |
- SDIO_MASK_DATAENDIE | SDIO_MASK_TXUNDERRIE |
- SDIO_MASK_STBITERRIE;
- SDIO->DLEN = n * SDC_BLOCK_SIZE;
- SDIO->DCTRL = SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0 |
- SDIO_DCTRL_DMAEN |
- SDIO_DCTRL_DTEN;
-
- /* DMA channel activation.*/
- dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
-
- /* Note the mask is checked before going to sleep because the interrupt
- may have occurred before reaching the critical zone.*/
- chSysLock();
- if (SDIO->MASK != 0) {
- chDbgAssert(sdcp->thread == NULL,
- "sdc_lld_write_multiple(), #1", "not NULL");
- sdcp->thread = chThdSelf();
- chSchGoSleepS(THD_STATE_SUSPENDED);
- chDbgAssert(sdcp->thread == NULL,
- "sdc_lld_write_multiple(), #2", "not NULL");
- }
- if ((SDIO->STA & SDIO_STA_DATAEND) == 0) {
- chSysUnlock();
- goto error;
- }
- dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
- SDIO->ICR = 0xFFFFFFFF;
- SDIO->DCTRL = 0;
- chSysUnlock();
-
- return sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_STOP_TRANSMISSION, 0, resp);
-error:
- dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
- SDIO->ICR = 0xFFFFFFFF;
- SDIO->MASK = 0;
- SDIO->DCTRL = 0;
- return TRUE;
-}
-
-/**
- * @brief Writes one block.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] startblk first block to write
- * @param[out] buf pointer to the write buffer, it must be aligned to
- * four bytes boundary
- * @param[in] n number of blocks to write
- * @return The operation status.
- * @retval FALSE operation succeeded, the requested blocks have been
- * written.
- * @retval TRUE operation failed.
- *
- * @notapi
- */
-static bool_t sdc_lld_write_single(SDCDriver *sdcp, uint32_t startblk,
- const uint8_t *buf) {
- uint32_t resp[1];
-
- /* Checks for errors and waits for the card to be ready for writing.*/
- if (sdc_wait_for_transfer_state(sdcp))
- return TRUE;
-
- /* Prepares the DMA channel for writing.*/
- dmaChannelSetup(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4],
- SDC_BLOCK_SIZE / sizeof (uint32_t), buf,
- (STM32_SDC_SDIO_DMA_PRIORITY << 12) |
- DMA_CCR1_PSIZE_1 | DMA_CCR1_MSIZE_1 |
- DMA_CCR1_MINC | DMA_CCR1_DIR);
-
- /* Write single block command.*/
- if ((sdcp->cardmode & SDC_MODE_HIGH_CAPACITY) == 0)
- startblk *= SDC_BLOCK_SIZE;
- if (sdc_lld_send_cmd_short_crc(sdcp, SDC_CMD_WRITE_BLOCK,
- startblk, resp) ||
- SDC_R1_ERROR(resp[0]))
- return TRUE;
-
- /* Setting up data transfer.
- Options: Controller to Card, Block mode, DMA mode, 512 bytes blocks.*/
- SDIO->ICR = 0xFFFFFFFF;
- SDIO->MASK = SDIO_MASK_DCRCFAILIE | SDIO_MASK_DTIMEOUTIE |
- SDIO_MASK_DATAENDIE | SDIO_MASK_TXUNDERRIE |
- SDIO_MASK_STBITERRIE;
- SDIO->DLEN = SDC_BLOCK_SIZE;
- SDIO->DCTRL = SDIO_DCTRL_DBLOCKSIZE_3 | SDIO_DCTRL_DBLOCKSIZE_0 |
- SDIO_DCTRL_DMAEN |
- SDIO_DCTRL_DTEN;
-
- /* DMA channel activation.*/
- dmaEnableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
-
- /* Note the mask is checked before going to sleep because the interrupt
- may have occurred before reaching the critical zone.*/
- chSysLock();
- if (SDIO->MASK != 0) {
- chDbgAssert(sdcp->thread == NULL,
- "sdc_lld_write_single(), #1", "not NULL");
- sdcp->thread = chThdSelf();
- chSchGoSleepS(THD_STATE_SUSPENDED);
- chDbgAssert(sdcp->thread == NULL,
- "sdc_lld_write_single(), #2", "not NULL");
- }
- if ((SDIO->STA & SDIO_STA_DATAEND) == 0) {
- chSysUnlock();
- goto error;
- }
- dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
- SDIO->ICR = 0xFFFFFFFF;
- SDIO->DCTRL = 0;
- chSysUnlock();
-
- return FALSE;
-error:
- dmaDisableChannel(STM32_DMA2, STM32_DMA_CHANNEL_4);
- SDIO->ICR = 0xFFFFFFFF;
- SDIO->MASK = 0;
- SDIO->DCTRL = 0;
- return TRUE;
-}
-
-/*===========================================================================*/
-/* Driver interrupt handlers. */
-/*===========================================================================*/
-
-/**
- * @brief SDIO IRQ handler.
- *
- * @isr
- */
-CH_IRQ_HANDLER(SDIO_IRQHandler) {
-
- CH_IRQ_PROLOGUE();
-
- chSysLockFromIsr();
- if (SDCD1.thread != NULL) {
- chSchReadyI(SDCD1.thread);
- SDCD1.thread = NULL;
- }
- chSysUnlockFromIsr();
-
- /* Disables the source but the status flags are not reset because the
- read/write functions need to check them.*/
- SDIO->MASK = 0;
-
- CH_IRQ_EPILOGUE();
-}
-
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
-/**
- * @brief Low level SDC driver initialization.
- *
- * @notapi
- */
-void sdc_lld_init(void) {
-
- sdcObjectInit(&SDCD1);
- SDCD1.thread = NULL;
-}
-
-/**
- * @brief Configures and activates the SDC peripheral.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object, must be @p NULL,
- * this driver does not require any configuration
- *
- * @notapi
- */
-void sdc_lld_start(SDCDriver *sdcp) {
-
- if (sdcp->state == SDC_STOP) {
- /* Note, the DMA must be enabled before the IRQs.*/
- dmaAllocate(STM32_DMA2_ID, STM32_DMA_CHANNEL_4, NULL, NULL);
- dmaChannelSetPeripheral(&STM32_DMA2->channels[STM32_DMA_CHANNEL_4], &SDIO->FIFO);
- NVICEnableVector(SDIO_IRQn,
- CORTEX_PRIORITY_MASK(STM32_SDC_SDIO_IRQ_PRIORITY));
- RCC->AHBENR |= RCC_AHBENR_SDIOEN;
- }
- /* Configuration, card clock is initially stopped.*/
- SDIO->POWER = 0;
- SDIO->CLKCR = 0;
- SDIO->DCTRL = 0;
- SDIO->DTIMER = STM32_SDC_DATATIMEOUT;
-}
-
-/**
- * @brief Deactivates the SDC peripheral.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- *
- * @notapi
- */
-void sdc_lld_stop(SDCDriver *sdcp) {
-
- if ((sdcp->state == SDC_READY) || (sdcp->state == SDC_ACTIVE)) {
- SDIO->POWER = 0;
- SDIO->CLKCR = 0;
- SDIO->DCTRL = 0;
- SDIO->DTIMER = 0;
-
- /* Clock deactivation.*/
- NVICDisableVector(SDIO_IRQn);
- dmaRelease(STM32_DMA2_ID, STM32_DMA_CHANNEL_4);
- }
-}
-
-/**
- * @brief Starts the SDIO clock and sets it to init mode (400KHz or less).
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- *
- * @notapi
- */
-void sdc_lld_start_clk(SDCDriver *sdcp) {
-
- (void)sdcp;
- /* Initial clock setting: 400KHz, 1bit mode.*/
- SDIO->CLKCR = STM32_SDIO_DIV_LS;
- SDIO->POWER |= SDIO_POWER_PWRCTRL_0 | SDIO_POWER_PWRCTRL_1;
- SDIO->CLKCR |= SDIO_CLKCR_CLKEN;
-}
-
-/**
- * @brief Sets the SDIO clock to data mode (25MHz or less).
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- *
- * @notapi
- */
-void sdc_lld_set_data_clk(SDCDriver *sdcp) {
-
- (void)sdcp;
- SDIO->CLKCR = (SDIO->CLKCR & 0xFFFFFF00) | STM32_SDIO_DIV_HS;
-}
-
-/**
- * @brief Stops the SDIO clock.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- *
- * @notapi
- */
-void sdc_lld_stop_clk(SDCDriver *sdcp) {
-
- (void)sdcp;
- SDIO->CLKCR = 0;
- SDIO->POWER = 0;
-}
-
-/**
- * @brief Switches the bus to 4 bits mode.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] mode bus mode
- *
- * @notapi
- */
-void sdc_lld_set_bus_mode(SDCDriver *sdcp, sdcbusmode_t mode) {
- uint32_t clk = SDIO->CLKCR & ~SDIO_CLKCR_WIDBUS;
-
- (void)sdcp;
- switch (mode) {
- case SDC_MODE_1BIT:
- SDIO->CLKCR = clk;
- break;
- case SDC_MODE_4BIT:
- SDIO->CLKCR = clk | SDIO_CLKCR_WIDBUS_0;
- break;
- case SDC_MODE_8BIT:
- SDIO->CLKCR = clk | SDIO_CLKCR_WIDBUS_1;
- }
-}
-
-/**
- * @brief Sends an SDIO command with no response expected.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] cmd card command
- * @param[in] arg command argument
- *
- * @notapi
- */
-void sdc_lld_send_cmd_none(SDCDriver *sdcp, uint8_t cmd, uint32_t arg) {
-
- (void)sdcp;
- SDIO->ARG = arg;
- SDIO->CMD = (uint32_t)cmd | SDIO_CMD_CPSMEN;
- while ((SDIO->STA & SDIO_STA_CMDSENT) == 0)
- ;
- SDIO->ICR = SDIO_ICR_CMDSENTC;
-}
-
-/**
- * @brief Sends an SDIO command with a short response expected.
- * @note The CRC is not verified.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] cmd card command
- * @param[in] arg command argument
- * @param[out] resp pointer to the response buffer (one word)
- * @return The operation status.
- * @retval FALSE the operation succeeded.
- * @retval TRUE the operation failed because timeout, CRC check or
- * other errors.
- *
- * @notapi
- */
-bool_t sdc_lld_send_cmd_short(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
- uint32_t *resp) {
- uint32_t sta;
-
- (void)sdcp;
- SDIO->ARG = arg;
- SDIO->CMD = (uint32_t)cmd | SDIO_CMD_WAITRESP_0 | SDIO_CMD_CPSMEN;
- while (((sta = SDIO->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT |
- SDIO_STA_CCRCFAIL)) == 0)
- ;
- SDIO->ICR = SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC;
- if ((sta & (SDIO_STA_CTIMEOUT)) != 0)
- return TRUE;
- *resp = SDIO->RESP1;
- return FALSE;
-}
-
-/**
- * @brief Sends an SDIO command with a short response expected and CRC.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] cmd card command
- * @param[in] arg command argument
- * @param[out] resp pointer to the response buffer (one word)
- * @return The operation status.
- * @retval FALSE the operation succeeded.
- * @retval TRUE the operation failed because timeout, CRC check or
- * other errors.
- *
- * @notapi
- */
-bool_t sdc_lld_send_cmd_short_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
- uint32_t *resp) {
- uint32_t sta;
-
- (void)sdcp;
- SDIO->ARG = arg;
- SDIO->CMD = (uint32_t)cmd | SDIO_CMD_WAITRESP_0 | SDIO_CMD_CPSMEN;
- while (((sta = SDIO->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT |
- SDIO_STA_CCRCFAIL)) == 0)
- ;
- SDIO->ICR = SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC;
- if ((sta & (SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL)) != 0)
- return TRUE;
- *resp = SDIO->RESP1;
- return FALSE;
-}
-
-/**
- * @brief Sends an SDIO command with a long response expected and CRC.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] cmd card command
- * @param[in] arg command argument
- * @param[out] resp pointer to the response buffer (four words)
- * @return The operation status.
- * @retval FALSE the operation succeeded.
- * @retval TRUE the operation failed because timeout, CRC check or
- * other errors.
- *
- * @notapi
- */
-bool_t sdc_lld_send_cmd_long_crc(SDCDriver *sdcp, uint8_t cmd, uint32_t arg,
- uint32_t *resp) {
-
- uint32_t sta;
-
- (void)sdcp;
- SDIO->ARG = arg;
- SDIO->CMD = (uint32_t)cmd | SDIO_CMD_WAITRESP_0 | SDIO_CMD_WAITRESP_1 |
- SDIO_CMD_CPSMEN;
- while (((sta = SDIO->STA) & (SDIO_STA_CMDREND | SDIO_STA_CTIMEOUT |
- SDIO_STA_CCRCFAIL)) == 0)
- ;
- SDIO->ICR = SDIO_ICR_CMDRENDC | SDIO_ICR_CTIMEOUTC | SDIO_ICR_CCRCFAILC;
- if ((sta & (SDIO_STA_CTIMEOUT | SDIO_STA_CCRCFAIL)) != 0)
- return TRUE;
- *resp = SDIO->RESP1;
- return FALSE;
-}
-
-/**
- * @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] n number of blocks to read
- * @return The operation status.
- * @retval FALSE operation succeeded, the requested blocks have been
- * read.
- * @retval TRUE operation failed, the state of the buffer is uncertain.
- *
- * @notapi
- */
-bool_t sdc_lld_read(SDCDriver *sdcp, uint32_t startblk,
- uint8_t *buf, uint32_t n) {
-
-#if STM32_SDC_UNALIGNED_SUPPORT
- if (((unsigned)buf & 3) != 0) {
- uint32_t i;
- for (i = 0; i < n; i++) {
- if (sdc_lld_read_single(sdcp, startblk, u.buf))
- return TRUE;
- memcpy(buf, u.buf, SDC_BLOCK_SIZE);
- buf += SDC_BLOCK_SIZE;
- startblk++;
- }
- return FALSE;
- }
-#endif
- if (n == 1)
- return sdc_lld_read_single(sdcp, startblk, buf);
- return sdc_lld_read_multiple(sdcp, startblk, buf, n);
-}
-
-/**
- * @brief Writes one or more blocks.
- *
- * @param[in] sdcp pointer to the @p SDCDriver object
- * @param[in] startblk first block to write
- * @param[out] buf pointer to the write buffer
- * @param[in] n number of blocks to write
- * @return The operation status.
- * @retval FALSE operation succeeded, the requested blocks have been
- * written.
- * @retval TRUE operation failed.
- *
- * @notapi
- */
-bool_t sdc_lld_write(SDCDriver *sdcp, uint32_t startblk,
- const uint8_t *buf, uint32_t n) {
-
- #if STM32_SDC_UNALIGNED_SUPPORT
- if (((unsigned)buf & 3) != 0) {
- uint32_t i;
- for (i = 0; i < n; i++) {
- memcpy(u.buf, buf, SDC_BLOCK_SIZE);
- buf += SDC_BLOCK_SIZE;
- if (sdc_lld_write_single(sdcp, startblk, u.buf))
- return TRUE;
- startblk++;
- }
- return FALSE;
- }
-#endif
- if (n == 1)
- return sdc_lld_write_single(sdcp, startblk, buf);
- return sdc_lld_write_multiple(sdcp, startblk, buf, n);
-}
-
-#endif /* HAL_USE_SDC */
-
-/** @} */
|