001

Committer:
ganlikun
Date:
Sun Jun 12 14:02:44 2022 +0000
Revision:
0:13413ea9a877
00

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ganlikun 0:13413ea9a877 1 /**
ganlikun 0:13413ea9a877 2 ******************************************************************************
ganlikun 0:13413ea9a877 3 * @file stm32f4xx_ll_sdmmc.c
ganlikun 0:13413ea9a877 4 * @author MCD Application Team
ganlikun 0:13413ea9a877 5 * @version V1.7.1
ganlikun 0:13413ea9a877 6 * @date 14-April-2017
ganlikun 0:13413ea9a877 7 * @brief SDMMC Low Layer HAL module driver.
ganlikun 0:13413ea9a877 8 *
ganlikun 0:13413ea9a877 9 * This file provides firmware functions to manage the following
ganlikun 0:13413ea9a877 10 * functionalities of the SDMMC peripheral:
ganlikun 0:13413ea9a877 11 * + Initialization/de-initialization functions
ganlikun 0:13413ea9a877 12 * + I/O operation functions
ganlikun 0:13413ea9a877 13 * + Peripheral Control functions
ganlikun 0:13413ea9a877 14 * + Peripheral State functions
ganlikun 0:13413ea9a877 15 *
ganlikun 0:13413ea9a877 16 @verbatim
ganlikun 0:13413ea9a877 17 ==============================================================================
ganlikun 0:13413ea9a877 18 ##### SDMMC peripheral features #####
ganlikun 0:13413ea9a877 19 ==============================================================================
ganlikun 0:13413ea9a877 20 [..] The SD/SDMMC MMC card host interface (SDMMC) provides an interface between the APB2
ganlikun 0:13413ea9a877 21 peripheral bus and MultiMedia cards (MMCs), SD memory cards, SDMMC cards and CE-ATA
ganlikun 0:13413ea9a877 22 devices.
ganlikun 0:13413ea9a877 23
ganlikun 0:13413ea9a877 24 [..] The SDMMC features include the following:
ganlikun 0:13413ea9a877 25 (+) Full compliance with MultiMedia Card System Specification Version 4.2. Card support
ganlikun 0:13413ea9a877 26 for three different databus modes: 1-bit (default), 4-bit and 8-bit
ganlikun 0:13413ea9a877 27 (+) Full compatibility with previous versions of MultiMedia Cards (forward compatibility)
ganlikun 0:13413ea9a877 28 (+) Full compliance with SD Memory Card Specifications Version 2.0
ganlikun 0:13413ea9a877 29 (+) Full compliance with SD I/O Card Specification Version 2.0: card support for two
ganlikun 0:13413ea9a877 30 different data bus modes: 1-bit (default) and 4-bit
ganlikun 0:13413ea9a877 31 (+) Full support of the CE-ATA features (full compliance with CE-ATA digital protocol
ganlikun 0:13413ea9a877 32 Rev1.1)
ganlikun 0:13413ea9a877 33 (+) Data transfer up to 48 MHz for the 8 bit mode
ganlikun 0:13413ea9a877 34 (+) Data and command output enable signals to control external bidirectional drivers.
ganlikun 0:13413ea9a877 35
ganlikun 0:13413ea9a877 36
ganlikun 0:13413ea9a877 37 ##### How to use this driver #####
ganlikun 0:13413ea9a877 38 ==============================================================================
ganlikun 0:13413ea9a877 39 [..]
ganlikun 0:13413ea9a877 40 This driver is a considered as a driver of service for external devices drivers
ganlikun 0:13413ea9a877 41 that interfaces with the SDMMC peripheral.
ganlikun 0:13413ea9a877 42 According to the device used (SD card/ MMC card / SDMMC card ...), a set of APIs
ganlikun 0:13413ea9a877 43 is used in the device's driver to perform SDMMC operations and functionalities.
ganlikun 0:13413ea9a877 44
ganlikun 0:13413ea9a877 45 This driver is almost transparent for the final user, it is only used to implement other
ganlikun 0:13413ea9a877 46 functionalities of the external device.
ganlikun 0:13413ea9a877 47
ganlikun 0:13413ea9a877 48 [..]
ganlikun 0:13413ea9a877 49 (+) The SDMMC clock (SDMMCCLK = 48 MHz) is coming from a specific output of PLL
ganlikun 0:13413ea9a877 50 (PLL48CLK). Before start working with SDMMC peripheral make sure that the
ganlikun 0:13413ea9a877 51 PLL is well configured.
ganlikun 0:13413ea9a877 52 The SDMMC peripheral uses two clock signals:
ganlikun 0:13413ea9a877 53 (++) SDMMC adapter clock (SDMMCCLK = 48 MHz)
ganlikun 0:13413ea9a877 54 (++) APB2 bus clock (PCLK2)
ganlikun 0:13413ea9a877 55
ganlikun 0:13413ea9a877 56 -@@- PCLK2 and SDMMC_CK clock frequencies must respect the following condition:
ganlikun 0:13413ea9a877 57 Frequency(PCLK2) >= (3 / 8 x Frequency(SDMMC_CK))
ganlikun 0:13413ea9a877 58
ganlikun 0:13413ea9a877 59 (+) Enable/Disable peripheral clock using RCC peripheral macros related to SDMMC
ganlikun 0:13413ea9a877 60 peripheral.
ganlikun 0:13413ea9a877 61
ganlikun 0:13413ea9a877 62 (+) Enable the Power ON State using the SDIO_PowerState_ON(SDIOx)
ganlikun 0:13413ea9a877 63 function and disable it using the function SDIO_PowerState_ON(SDIOx).
ganlikun 0:13413ea9a877 64
ganlikun 0:13413ea9a877 65 (+) Enable/Disable the clock using the __SDIO_ENABLE()/__SDIO_DISABLE() macros.
ganlikun 0:13413ea9a877 66
ganlikun 0:13413ea9a877 67 (+) Enable/Disable the peripheral interrupts using the macros __SDIO_ENABLE_IT(hSDIO, IT)
ganlikun 0:13413ea9a877 68 and __SDIO_DISABLE_IT(hSDIO, IT) if you need to use interrupt mode.
ganlikun 0:13413ea9a877 69
ganlikun 0:13413ea9a877 70 (+) When using the DMA mode
ganlikun 0:13413ea9a877 71 (++) Configure the DMA in the MSP layer of the external device
ganlikun 0:13413ea9a877 72 (++) Active the needed channel Request
ganlikun 0:13413ea9a877 73 (++) Enable the DMA using __SDIO_DMA_ENABLE() macro or Disable it using the macro
ganlikun 0:13413ea9a877 74 __SDIO_DMA_DISABLE().
ganlikun 0:13413ea9a877 75
ganlikun 0:13413ea9a877 76 (+) To control the CPSM (Command Path State Machine) and send
ganlikun 0:13413ea9a877 77 commands to the card use the SDIO_SendCommand(),
ganlikun 0:13413ea9a877 78 SDIO_GetCommandResponse() and SDIO_GetResponse() functions. First, user has
ganlikun 0:13413ea9a877 79 to fill the command structure (pointer to SDIO_CmdInitTypeDef) according
ganlikun 0:13413ea9a877 80 to the selected command to be sent.
ganlikun 0:13413ea9a877 81 The parameters that should be filled are:
ganlikun 0:13413ea9a877 82 (++) Command Argument
ganlikun 0:13413ea9a877 83 (++) Command Index
ganlikun 0:13413ea9a877 84 (++) Command Response type
ganlikun 0:13413ea9a877 85 (++) Command Wait
ganlikun 0:13413ea9a877 86 (++) CPSM Status (Enable or Disable).
ganlikun 0:13413ea9a877 87
ganlikun 0:13413ea9a877 88 -@@- To check if the command is well received, read the SDIO_CMDRESP
ganlikun 0:13413ea9a877 89 register using the SDIO_GetCommandResponse().
ganlikun 0:13413ea9a877 90 The SDMMC responses registers (SDIO_RESP1 to SDIO_RESP2), use the
ganlikun 0:13413ea9a877 91 SDIO_GetResponse() function.
ganlikun 0:13413ea9a877 92
ganlikun 0:13413ea9a877 93 (+) To control the DPSM (Data Path State Machine) and send/receive
ganlikun 0:13413ea9a877 94 data to/from the card use the SDIO_ConfigData(), SDIO_GetDataCounter(),
ganlikun 0:13413ea9a877 95 SDIO_ReadFIFO(), SDIO_WriteFIFO() and SDIO_GetFIFOCount() functions.
ganlikun 0:13413ea9a877 96
ganlikun 0:13413ea9a877 97 *** Read Operations ***
ganlikun 0:13413ea9a877 98 =======================
ganlikun 0:13413ea9a877 99 [..]
ganlikun 0:13413ea9a877 100 (#) First, user has to fill the data structure (pointer to
ganlikun 0:13413ea9a877 101 SDIO_DataInitTypeDef) according to the selected data type to be received.
ganlikun 0:13413ea9a877 102 The parameters that should be filled are:
ganlikun 0:13413ea9a877 103 (++) Data TimeOut
ganlikun 0:13413ea9a877 104 (++) Data Length
ganlikun 0:13413ea9a877 105 (++) Data Block size
ganlikun 0:13413ea9a877 106 (++) Data Transfer direction: should be from card (To SDMMC)
ganlikun 0:13413ea9a877 107 (++) Data Transfer mode
ganlikun 0:13413ea9a877 108 (++) DPSM Status (Enable or Disable)
ganlikun 0:13413ea9a877 109
ganlikun 0:13413ea9a877 110 (#) Configure the SDMMC resources to receive the data from the card
ganlikun 0:13413ea9a877 111 according to selected transfer mode (Refer to Step 8, 9 and 10).
ganlikun 0:13413ea9a877 112
ganlikun 0:13413ea9a877 113 (#) Send the selected Read command (refer to step 11).
ganlikun 0:13413ea9a877 114
ganlikun 0:13413ea9a877 115 (#) Use the SDIO flags/interrupts to check the transfer status.
ganlikun 0:13413ea9a877 116
ganlikun 0:13413ea9a877 117 *** Write Operations ***
ganlikun 0:13413ea9a877 118 ========================
ganlikun 0:13413ea9a877 119 [..]
ganlikun 0:13413ea9a877 120 (#) First, user has to fill the data structure (pointer to
ganlikun 0:13413ea9a877 121 SDIO_DataInitTypeDef) according to the selected data type to be received.
ganlikun 0:13413ea9a877 122 The parameters that should be filled are:
ganlikun 0:13413ea9a877 123 (++) Data TimeOut
ganlikun 0:13413ea9a877 124 (++) Data Length
ganlikun 0:13413ea9a877 125 (++) Data Block size
ganlikun 0:13413ea9a877 126 (++) Data Transfer direction: should be to card (To CARD)
ganlikun 0:13413ea9a877 127 (++) Data Transfer mode
ganlikun 0:13413ea9a877 128 (++) DPSM Status (Enable or Disable)
ganlikun 0:13413ea9a877 129
ganlikun 0:13413ea9a877 130 (#) Configure the SDMMC resources to send the data to the card according to
ganlikun 0:13413ea9a877 131 selected transfer mode.
ganlikun 0:13413ea9a877 132
ganlikun 0:13413ea9a877 133 (#) Send the selected Write command.
ganlikun 0:13413ea9a877 134
ganlikun 0:13413ea9a877 135 (#) Use the SDIO flags/interrupts to check the transfer status.
ganlikun 0:13413ea9a877 136
ganlikun 0:13413ea9a877 137 *** Command management operations ***
ganlikun 0:13413ea9a877 138 =====================================
ganlikun 0:13413ea9a877 139 [..]
ganlikun 0:13413ea9a877 140 (#) The commands used for Read/Write/Erase operations are managed in
ganlikun 0:13413ea9a877 141 separate functions.
ganlikun 0:13413ea9a877 142 Each function allows to send the needed command with the related argument,
ganlikun 0:13413ea9a877 143 then check the response.
ganlikun 0:13413ea9a877 144 By the same approach, you could implement a command and check the response.
ganlikun 0:13413ea9a877 145
ganlikun 0:13413ea9a877 146 @endverbatim
ganlikun 0:13413ea9a877 147 ******************************************************************************
ganlikun 0:13413ea9a877 148 * @attention
ganlikun 0:13413ea9a877 149 *
ganlikun 0:13413ea9a877 150 * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
ganlikun 0:13413ea9a877 151 *
ganlikun 0:13413ea9a877 152 * Redistribution and use in source and binary forms, with or without modification,
ganlikun 0:13413ea9a877 153 * are permitted provided that the following conditions are met:
ganlikun 0:13413ea9a877 154 * 1. Redistributions of source code must retain the above copyright notice,
ganlikun 0:13413ea9a877 155 * this list of conditions and the following disclaimer.
ganlikun 0:13413ea9a877 156 * 2. Redistributions in binary form must reproduce the above copyright notice,
ganlikun 0:13413ea9a877 157 * this list of conditions and the following disclaimer in the documentation
ganlikun 0:13413ea9a877 158 * and/or other materials provided with the distribution.
ganlikun 0:13413ea9a877 159 * 3. Neither the name of STMicroelectronics nor the names of its contributors
ganlikun 0:13413ea9a877 160 * may be used to endorse or promote products derived from this software
ganlikun 0:13413ea9a877 161 * without specific prior written permission.
ganlikun 0:13413ea9a877 162 *
ganlikun 0:13413ea9a877 163 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
ganlikun 0:13413ea9a877 164 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
ganlikun 0:13413ea9a877 165 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
ganlikun 0:13413ea9a877 166 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
ganlikun 0:13413ea9a877 167 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
ganlikun 0:13413ea9a877 168 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
ganlikun 0:13413ea9a877 169 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
ganlikun 0:13413ea9a877 170 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
ganlikun 0:13413ea9a877 171 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
ganlikun 0:13413ea9a877 172 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ganlikun 0:13413ea9a877 173 *
ganlikun 0:13413ea9a877 174 ******************************************************************************
ganlikun 0:13413ea9a877 175 */
ganlikun 0:13413ea9a877 176
ganlikun 0:13413ea9a877 177 /* Includes ------------------------------------------------------------------*/
ganlikun 0:13413ea9a877 178 #include "stm32f4xx_hal.h"
ganlikun 0:13413ea9a877 179
ganlikun 0:13413ea9a877 180 /** @addtogroup STM32F4xx_HAL_Driver
ganlikun 0:13413ea9a877 181 * @{
ganlikun 0:13413ea9a877 182 */
ganlikun 0:13413ea9a877 183
ganlikun 0:13413ea9a877 184 /** @defgroup SDMMC_LL SDMMC Low Layer
ganlikun 0:13413ea9a877 185 * @brief Low layer module for SD
ganlikun 0:13413ea9a877 186 * @{
ganlikun 0:13413ea9a877 187 */
ganlikun 0:13413ea9a877 188
ganlikun 0:13413ea9a877 189 #if defined(HAL_SD_MODULE_ENABLED) || defined(HAL_MMC_MODULE_ENABLED)
ganlikun 0:13413ea9a877 190 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || \
ganlikun 0:13413ea9a877 191 defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || \
ganlikun 0:13413ea9a877 192 defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) || \
ganlikun 0:13413ea9a877 193 defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || \
ganlikun 0:13413ea9a877 194 defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
ganlikun 0:13413ea9a877 195
ganlikun 0:13413ea9a877 196 /* Private typedef -----------------------------------------------------------*/
ganlikun 0:13413ea9a877 197 /* Private define ------------------------------------------------------------*/
ganlikun 0:13413ea9a877 198 /* Private macro -------------------------------------------------------------*/
ganlikun 0:13413ea9a877 199 /* Private variables ---------------------------------------------------------*/
ganlikun 0:13413ea9a877 200 /* Private function prototypes -----------------------------------------------*/
ganlikun 0:13413ea9a877 201 static uint32_t SDMMC_GetCmdError(SDIO_TypeDef *SDIOx);
ganlikun 0:13413ea9a877 202 static uint32_t SDMMC_GetCmdResp1(SDIO_TypeDef *SDIOx, uint8_t SD_CMD, uint32_t Timeout);
ganlikun 0:13413ea9a877 203 static uint32_t SDMMC_GetCmdResp2(SDIO_TypeDef *SDIOx);
ganlikun 0:13413ea9a877 204 static uint32_t SDMMC_GetCmdResp3(SDIO_TypeDef *SDIOx);
ganlikun 0:13413ea9a877 205 static uint32_t SDMMC_GetCmdResp7(SDIO_TypeDef *SDIOx);
ganlikun 0:13413ea9a877 206 static uint32_t SDMMC_GetCmdResp6(SDIO_TypeDef *SDIOx, uint8_t SD_CMD, uint16_t *pRCA);
ganlikun 0:13413ea9a877 207
ganlikun 0:13413ea9a877 208 /* Exported functions --------------------------------------------------------*/
ganlikun 0:13413ea9a877 209
ganlikun 0:13413ea9a877 210 /** @defgroup SDMMC_LL_Exported_Functions SDMMC Low Layer Exported Functions
ganlikun 0:13413ea9a877 211 * @{
ganlikun 0:13413ea9a877 212 */
ganlikun 0:13413ea9a877 213
ganlikun 0:13413ea9a877 214 /** @defgroup HAL_SDMMC_LL_Group1 Initialization de-initialization functions
ganlikun 0:13413ea9a877 215 * @brief Initialization and Configuration functions
ganlikun 0:13413ea9a877 216 *
ganlikun 0:13413ea9a877 217 @verbatim
ganlikun 0:13413ea9a877 218 ===============================================================================
ganlikun 0:13413ea9a877 219 ##### Initialization/de-initialization functions #####
ganlikun 0:13413ea9a877 220 ===============================================================================
ganlikun 0:13413ea9a877 221 [..] This section provides functions allowing to:
ganlikun 0:13413ea9a877 222
ganlikun 0:13413ea9a877 223 @endverbatim
ganlikun 0:13413ea9a877 224 * @{
ganlikun 0:13413ea9a877 225 */
ganlikun 0:13413ea9a877 226
ganlikun 0:13413ea9a877 227 /**
ganlikun 0:13413ea9a877 228 * @brief Initializes the SDMMC according to the specified
ganlikun 0:13413ea9a877 229 * parameters in the SDMMC_InitTypeDef and create the associated handle.
ganlikun 0:13413ea9a877 230 * @param SDIOx: Pointer to SDMMC register base
ganlikun 0:13413ea9a877 231 * @param Init: SDMMC initialization structure
ganlikun 0:13413ea9a877 232 * @retval HAL status
ganlikun 0:13413ea9a877 233 */
ganlikun 0:13413ea9a877 234 HAL_StatusTypeDef SDIO_Init(SDIO_TypeDef *SDIOx, SDIO_InitTypeDef Init)
ganlikun 0:13413ea9a877 235 {
ganlikun 0:13413ea9a877 236 uint32_t tmpreg = 0U;
ganlikun 0:13413ea9a877 237
ganlikun 0:13413ea9a877 238 /* Check the parameters */
ganlikun 0:13413ea9a877 239 assert_param(IS_SDIO_ALL_INSTANCE(SDIOx));
ganlikun 0:13413ea9a877 240 assert_param(IS_SDIO_CLOCK_EDGE(Init.ClockEdge));
ganlikun 0:13413ea9a877 241 assert_param(IS_SDIO_CLOCK_BYPASS(Init.ClockBypass));
ganlikun 0:13413ea9a877 242 assert_param(IS_SDIO_CLOCK_POWER_SAVE(Init.ClockPowerSave));
ganlikun 0:13413ea9a877 243 assert_param(IS_SDIO_BUS_WIDE(Init.BusWide));
ganlikun 0:13413ea9a877 244 assert_param(IS_SDIO_HARDWARE_FLOW_CONTROL(Init.HardwareFlowControl));
ganlikun 0:13413ea9a877 245 assert_param(IS_SDIO_CLKDIV(Init.ClockDiv));
ganlikun 0:13413ea9a877 246
ganlikun 0:13413ea9a877 247 /* Set SDMMC configuration parameters */
ganlikun 0:13413ea9a877 248 tmpreg |= (Init.ClockEdge |\
ganlikun 0:13413ea9a877 249 Init.ClockBypass |\
ganlikun 0:13413ea9a877 250 Init.ClockPowerSave |\
ganlikun 0:13413ea9a877 251 Init.BusWide |\
ganlikun 0:13413ea9a877 252 Init.HardwareFlowControl |\
ganlikun 0:13413ea9a877 253 Init.ClockDiv
ganlikun 0:13413ea9a877 254 );
ganlikun 0:13413ea9a877 255
ganlikun 0:13413ea9a877 256 /* Write to SDMMC CLKCR */
ganlikun 0:13413ea9a877 257 MODIFY_REG(SDIOx->CLKCR, CLKCR_CLEAR_MASK, tmpreg);
ganlikun 0:13413ea9a877 258
ganlikun 0:13413ea9a877 259 return HAL_OK;
ganlikun 0:13413ea9a877 260 }
ganlikun 0:13413ea9a877 261
ganlikun 0:13413ea9a877 262
ganlikun 0:13413ea9a877 263 /**
ganlikun 0:13413ea9a877 264 * @}
ganlikun 0:13413ea9a877 265 */
ganlikun 0:13413ea9a877 266
ganlikun 0:13413ea9a877 267 /** @defgroup HAL_SDMMC_LL_Group2 IO operation functions
ganlikun 0:13413ea9a877 268 * @brief Data transfers functions
ganlikun 0:13413ea9a877 269 *
ganlikun 0:13413ea9a877 270 @verbatim
ganlikun 0:13413ea9a877 271 ===============================================================================
ganlikun 0:13413ea9a877 272 ##### I/O operation functions #####
ganlikun 0:13413ea9a877 273 ===============================================================================
ganlikun 0:13413ea9a877 274 [..]
ganlikun 0:13413ea9a877 275 This subsection provides a set of functions allowing to manage the SDMMC data
ganlikun 0:13413ea9a877 276 transfers.
ganlikun 0:13413ea9a877 277
ganlikun 0:13413ea9a877 278 @endverbatim
ganlikun 0:13413ea9a877 279 * @{
ganlikun 0:13413ea9a877 280 */
ganlikun 0:13413ea9a877 281
ganlikun 0:13413ea9a877 282 /**
ganlikun 0:13413ea9a877 283 * @brief Read data (word) from Rx FIFO in blocking mode (polling)
ganlikun 0:13413ea9a877 284 * @param SDIOx: Pointer to SDMMC register base
ganlikun 0:13413ea9a877 285 * @retval HAL status
ganlikun 0:13413ea9a877 286 */
ganlikun 0:13413ea9a877 287 uint32_t SDIO_ReadFIFO(SDIO_TypeDef *SDIOx)
ganlikun 0:13413ea9a877 288 {
ganlikun 0:13413ea9a877 289 /* Read data from Rx FIFO */
ganlikun 0:13413ea9a877 290 return (SDIOx->FIFO);
ganlikun 0:13413ea9a877 291 }
ganlikun 0:13413ea9a877 292
ganlikun 0:13413ea9a877 293 /**
ganlikun 0:13413ea9a877 294 * @brief Write data (word) to Tx FIFO in blocking mode (polling)
ganlikun 0:13413ea9a877 295 * @param SDIOx: Pointer to SDMMC register base
ganlikun 0:13413ea9a877 296 * @param pWriteData: pointer to data to write
ganlikun 0:13413ea9a877 297 * @retval HAL status
ganlikun 0:13413ea9a877 298 */
ganlikun 0:13413ea9a877 299 HAL_StatusTypeDef SDIO_WriteFIFO(SDIO_TypeDef *SDIOx, uint32_t *pWriteData)
ganlikun 0:13413ea9a877 300 {
ganlikun 0:13413ea9a877 301 /* Write data to FIFO */
ganlikun 0:13413ea9a877 302 SDIOx->FIFO = *pWriteData;
ganlikun 0:13413ea9a877 303
ganlikun 0:13413ea9a877 304 return HAL_OK;
ganlikun 0:13413ea9a877 305 }
ganlikun 0:13413ea9a877 306
ganlikun 0:13413ea9a877 307 /**
ganlikun 0:13413ea9a877 308 * @}
ganlikun 0:13413ea9a877 309 */
ganlikun 0:13413ea9a877 310
ganlikun 0:13413ea9a877 311 /** @defgroup HAL_SDMMC_LL_Group3 Peripheral Control functions
ganlikun 0:13413ea9a877 312 * @brief management functions
ganlikun 0:13413ea9a877 313 *
ganlikun 0:13413ea9a877 314 @verbatim
ganlikun 0:13413ea9a877 315 ===============================================================================
ganlikun 0:13413ea9a877 316 ##### Peripheral Control functions #####
ganlikun 0:13413ea9a877 317 ===============================================================================
ganlikun 0:13413ea9a877 318 [..]
ganlikun 0:13413ea9a877 319 This subsection provides a set of functions allowing to control the SDMMC data
ganlikun 0:13413ea9a877 320 transfers.
ganlikun 0:13413ea9a877 321
ganlikun 0:13413ea9a877 322 @endverbatim
ganlikun 0:13413ea9a877 323 * @{
ganlikun 0:13413ea9a877 324 */
ganlikun 0:13413ea9a877 325
ganlikun 0:13413ea9a877 326 /**
ganlikun 0:13413ea9a877 327 * @brief Set SDMMC Power state to ON.
ganlikun 0:13413ea9a877 328 * @param SDIOx: Pointer to SDMMC register base
ganlikun 0:13413ea9a877 329 * @retval HAL status
ganlikun 0:13413ea9a877 330 */
ganlikun 0:13413ea9a877 331 HAL_StatusTypeDef SDIO_PowerState_ON(SDIO_TypeDef *SDIOx)
ganlikun 0:13413ea9a877 332 {
ganlikun 0:13413ea9a877 333 /* Set power state to ON */
ganlikun 0:13413ea9a877 334 SDIOx->POWER = SDIO_POWER_PWRCTRL;
ganlikun 0:13413ea9a877 335
ganlikun 0:13413ea9a877 336 return HAL_OK;
ganlikun 0:13413ea9a877 337 }
ganlikun 0:13413ea9a877 338
ganlikun 0:13413ea9a877 339 /**
ganlikun 0:13413ea9a877 340 * @brief Set SDMMC Power state to OFF.
ganlikun 0:13413ea9a877 341 * @param SDIOx: Pointer to SDMMC register base
ganlikun 0:13413ea9a877 342 * @retval HAL status
ganlikun 0:13413ea9a877 343 */
ganlikun 0:13413ea9a877 344 HAL_StatusTypeDef SDIO_PowerState_OFF(SDIO_TypeDef *SDIOx)
ganlikun 0:13413ea9a877 345 {
ganlikun 0:13413ea9a877 346 /* Set power state to OFF */
ganlikun 0:13413ea9a877 347 SDIOx->POWER = 0x00000000U;
ganlikun 0:13413ea9a877 348
ganlikun 0:13413ea9a877 349 return HAL_OK;
ganlikun 0:13413ea9a877 350 }
ganlikun 0:13413ea9a877 351
ganlikun 0:13413ea9a877 352 /**
ganlikun 0:13413ea9a877 353 * @brief Get SDMMC Power state.
ganlikun 0:13413ea9a877 354 * @param SDIOx: Pointer to SDMMC register base
ganlikun 0:13413ea9a877 355 * @retval Power status of the controller. The returned value can be one of the
ganlikun 0:13413ea9a877 356 * following values:
ganlikun 0:13413ea9a877 357 * - 0x00: Power OFF
ganlikun 0:13413ea9a877 358 * - 0x02: Power UP
ganlikun 0:13413ea9a877 359 * - 0x03: Power ON
ganlikun 0:13413ea9a877 360 */
ganlikun 0:13413ea9a877 361 uint32_t SDIO_GetPowerState(SDIO_TypeDef *SDIOx)
ganlikun 0:13413ea9a877 362 {
ganlikun 0:13413ea9a877 363 return (SDIOx->POWER & SDIO_POWER_PWRCTRL);
ganlikun 0:13413ea9a877 364 }
ganlikun 0:13413ea9a877 365
ganlikun 0:13413ea9a877 366 /**
ganlikun 0:13413ea9a877 367 * @brief Configure the SDMMC command path according to the specified parameters in
ganlikun 0:13413ea9a877 368 * SDIO_CmdInitTypeDef structure and send the command
ganlikun 0:13413ea9a877 369 * @param SDIOx: Pointer to SDMMC register base
ganlikun 0:13413ea9a877 370 * @param Command: pointer to a SDIO_CmdInitTypeDef structure that contains
ganlikun 0:13413ea9a877 371 * the configuration information for the SDMMC command
ganlikun 0:13413ea9a877 372 * @retval HAL status
ganlikun 0:13413ea9a877 373 */
ganlikun 0:13413ea9a877 374 HAL_StatusTypeDef SDIO_SendCommand(SDIO_TypeDef *SDIOx, SDIO_CmdInitTypeDef *Command)
ganlikun 0:13413ea9a877 375 {
ganlikun 0:13413ea9a877 376 uint32_t tmpreg = 0U;
ganlikun 0:13413ea9a877 377
ganlikun 0:13413ea9a877 378 /* Check the parameters */
ganlikun 0:13413ea9a877 379 assert_param(IS_SDIO_CMD_INDEX(Command->CmdIndex));
ganlikun 0:13413ea9a877 380 assert_param(IS_SDIO_RESPONSE(Command->Response));
ganlikun 0:13413ea9a877 381 assert_param(IS_SDIO_WAIT(Command->WaitForInterrupt));
ganlikun 0:13413ea9a877 382 assert_param(IS_SDIO_CPSM(Command->CPSM));
ganlikun 0:13413ea9a877 383
ganlikun 0:13413ea9a877 384 /* Set the SDMMC Argument value */
ganlikun 0:13413ea9a877 385 SDIOx->ARG = Command->Argument;
ganlikun 0:13413ea9a877 386
ganlikun 0:13413ea9a877 387 /* Set SDMMC command parameters */
ganlikun 0:13413ea9a877 388 tmpreg |= (uint32_t)(Command->CmdIndex |\
ganlikun 0:13413ea9a877 389 Command->Response |\
ganlikun 0:13413ea9a877 390 Command->WaitForInterrupt |\
ganlikun 0:13413ea9a877 391 Command->CPSM);
ganlikun 0:13413ea9a877 392
ganlikun 0:13413ea9a877 393 /* Write to SDMMC CMD register */
ganlikun 0:13413ea9a877 394 MODIFY_REG(SDIOx->CMD, CMD_CLEAR_MASK, tmpreg);
ganlikun 0:13413ea9a877 395
ganlikun 0:13413ea9a877 396 return HAL_OK;
ganlikun 0:13413ea9a877 397 }
ganlikun 0:13413ea9a877 398
ganlikun 0:13413ea9a877 399 /**
ganlikun 0:13413ea9a877 400 * @brief Return the command index of last command for which response received
ganlikun 0:13413ea9a877 401 * @param SDIOx: Pointer to SDMMC register base
ganlikun 0:13413ea9a877 402 * @retval Command index of the last command response received
ganlikun 0:13413ea9a877 403 */
ganlikun 0:13413ea9a877 404 uint8_t SDIO_GetCommandResponse(SDIO_TypeDef *SDIOx)
ganlikun 0:13413ea9a877 405 {
ganlikun 0:13413ea9a877 406 return (uint8_t)(SDIOx->RESPCMD);
ganlikun 0:13413ea9a877 407 }
ganlikun 0:13413ea9a877 408
ganlikun 0:13413ea9a877 409
ganlikun 0:13413ea9a877 410 /**
ganlikun 0:13413ea9a877 411 * @brief Return the response received from the card for the last command
ganlikun 0:13413ea9a877 412 * @param SDIOx: Pointer to SDMMC register base
ganlikun 0:13413ea9a877 413 * @param Response: Specifies the SDMMC response register.
ganlikun 0:13413ea9a877 414 * This parameter can be one of the following values:
ganlikun 0:13413ea9a877 415 * @arg SDIO_RESP1: Response Register 1
ganlikun 0:13413ea9a877 416 * @arg SDIO_RESP1: Response Register 2
ganlikun 0:13413ea9a877 417 * @arg SDIO_RESP1: Response Register 3
ganlikun 0:13413ea9a877 418 * @arg SDIO_RESP1: Response Register 4
ganlikun 0:13413ea9a877 419 * @retval The Corresponding response register value
ganlikun 0:13413ea9a877 420 */
ganlikun 0:13413ea9a877 421 uint32_t SDIO_GetResponse(SDIO_TypeDef *SDIOx, uint32_t Response)
ganlikun 0:13413ea9a877 422 {
ganlikun 0:13413ea9a877 423 __IO uint32_t tmp = 0U;
ganlikun 0:13413ea9a877 424
ganlikun 0:13413ea9a877 425 /* Check the parameters */
ganlikun 0:13413ea9a877 426 assert_param(IS_SDIO_RESP(Response));
ganlikun 0:13413ea9a877 427
ganlikun 0:13413ea9a877 428 /* Get the response */
ganlikun 0:13413ea9a877 429 tmp = (uint32_t)&(SDIOx->RESP1) + Response;
ganlikun 0:13413ea9a877 430
ganlikun 0:13413ea9a877 431 return (*(__IO uint32_t *) tmp);
ganlikun 0:13413ea9a877 432 }
ganlikun 0:13413ea9a877 433
ganlikun 0:13413ea9a877 434 /**
ganlikun 0:13413ea9a877 435 * @brief Configure the SDMMC data path according to the specified
ganlikun 0:13413ea9a877 436 * parameters in the SDIO_DataInitTypeDef.
ganlikun 0:13413ea9a877 437 * @param SDIOx: Pointer to SDMMC register base
ganlikun 0:13413ea9a877 438 * @param Data : pointer to a SDIO_DataInitTypeDef structure
ganlikun 0:13413ea9a877 439 * that contains the configuration information for the SDMMC data.
ganlikun 0:13413ea9a877 440 * @retval HAL status
ganlikun 0:13413ea9a877 441 */
ganlikun 0:13413ea9a877 442 HAL_StatusTypeDef SDIO_ConfigData(SDIO_TypeDef *SDIOx, SDIO_DataInitTypeDef* Data)
ganlikun 0:13413ea9a877 443 {
ganlikun 0:13413ea9a877 444 uint32_t tmpreg = 0U;
ganlikun 0:13413ea9a877 445
ganlikun 0:13413ea9a877 446 /* Check the parameters */
ganlikun 0:13413ea9a877 447 assert_param(IS_SDIO_DATA_LENGTH(Data->DataLength));
ganlikun 0:13413ea9a877 448 assert_param(IS_SDIO_BLOCK_SIZE(Data->DataBlockSize));
ganlikun 0:13413ea9a877 449 assert_param(IS_SDIO_TRANSFER_DIR(Data->TransferDir));
ganlikun 0:13413ea9a877 450 assert_param(IS_SDIO_TRANSFER_MODE(Data->TransferMode));
ganlikun 0:13413ea9a877 451 assert_param(IS_SDIO_DPSM(Data->DPSM));
ganlikun 0:13413ea9a877 452
ganlikun 0:13413ea9a877 453 /* Set the SDMMC Data TimeOut value */
ganlikun 0:13413ea9a877 454 SDIOx->DTIMER = Data->DataTimeOut;
ganlikun 0:13413ea9a877 455
ganlikun 0:13413ea9a877 456 /* Set the SDMMC DataLength value */
ganlikun 0:13413ea9a877 457 SDIOx->DLEN = Data->DataLength;
ganlikun 0:13413ea9a877 458
ganlikun 0:13413ea9a877 459 /* Set the SDMMC data configuration parameters */
ganlikun 0:13413ea9a877 460 tmpreg |= (uint32_t)(Data->DataBlockSize |\
ganlikun 0:13413ea9a877 461 Data->TransferDir |\
ganlikun 0:13413ea9a877 462 Data->TransferMode |\
ganlikun 0:13413ea9a877 463 Data->DPSM);
ganlikun 0:13413ea9a877 464
ganlikun 0:13413ea9a877 465 /* Write to SDMMC DCTRL */
ganlikun 0:13413ea9a877 466 MODIFY_REG(SDIOx->DCTRL, DCTRL_CLEAR_MASK, tmpreg);
ganlikun 0:13413ea9a877 467
ganlikun 0:13413ea9a877 468 return HAL_OK;
ganlikun 0:13413ea9a877 469
ganlikun 0:13413ea9a877 470 }
ganlikun 0:13413ea9a877 471
ganlikun 0:13413ea9a877 472 /**
ganlikun 0:13413ea9a877 473 * @brief Returns number of remaining data bytes to be transferred.
ganlikun 0:13413ea9a877 474 * @param SDIOx: Pointer to SDMMC register base
ganlikun 0:13413ea9a877 475 * @retval Number of remaining data bytes to be transferred
ganlikun 0:13413ea9a877 476 */
ganlikun 0:13413ea9a877 477 uint32_t SDIO_GetDataCounter(SDIO_TypeDef *SDIOx)
ganlikun 0:13413ea9a877 478 {
ganlikun 0:13413ea9a877 479 return (SDIOx->DCOUNT);
ganlikun 0:13413ea9a877 480 }
ganlikun 0:13413ea9a877 481
ganlikun 0:13413ea9a877 482 /**
ganlikun 0:13413ea9a877 483 * @brief Get the FIFO data
ganlikun 0:13413ea9a877 484 * @param SDIOx: Pointer to SDMMC register base
ganlikun 0:13413ea9a877 485 * @retval Data received
ganlikun 0:13413ea9a877 486 */
ganlikun 0:13413ea9a877 487 uint32_t SDIO_GetFIFOCount(SDIO_TypeDef *SDIOx)
ganlikun 0:13413ea9a877 488 {
ganlikun 0:13413ea9a877 489 return (SDIOx->FIFO);
ganlikun 0:13413ea9a877 490 }
ganlikun 0:13413ea9a877 491
ganlikun 0:13413ea9a877 492 /**
ganlikun 0:13413ea9a877 493 * @brief Sets one of the two options of inserting read wait interval.
ganlikun 0:13413ea9a877 494 * @param SDIOx: Pointer to SDMMC register base
ganlikun 0:13413ea9a877 495 * @param SDIO_ReadWaitMode: SDMMC Read Wait operation mode.
ganlikun 0:13413ea9a877 496 * This parameter can be:
ganlikun 0:13413ea9a877 497 * @arg SDIO_READ_WAIT_MODE_CLK: Read Wait control by stopping SDMMCCLK
ganlikun 0:13413ea9a877 498 * @arg SDIO_READ_WAIT_MODE_DATA2: Read Wait control using SDMMC_DATA2
ganlikun 0:13413ea9a877 499 * @retval None
ganlikun 0:13413ea9a877 500 */
ganlikun 0:13413ea9a877 501 HAL_StatusTypeDef SDIO_SetSDMMCReadWaitMode(SDIO_TypeDef *SDIOx, uint32_t SDIO_ReadWaitMode)
ganlikun 0:13413ea9a877 502 {
ganlikun 0:13413ea9a877 503 /* Check the parameters */
ganlikun 0:13413ea9a877 504 assert_param(IS_SDIO_READWAIT_MODE(SDIO_ReadWaitMode));
ganlikun 0:13413ea9a877 505
ganlikun 0:13413ea9a877 506 /* Set SDMMC read wait mode */
ganlikun 0:13413ea9a877 507 MODIFY_REG(SDIOx->DCTRL, SDIO_DCTRL_RWMOD, SDIO_ReadWaitMode);
ganlikun 0:13413ea9a877 508
ganlikun 0:13413ea9a877 509 return HAL_OK;
ganlikun 0:13413ea9a877 510 }
ganlikun 0:13413ea9a877 511
ganlikun 0:13413ea9a877 512 /**
ganlikun 0:13413ea9a877 513 * @}
ganlikun 0:13413ea9a877 514 */
ganlikun 0:13413ea9a877 515
ganlikun 0:13413ea9a877 516
ganlikun 0:13413ea9a877 517 /** @defgroup HAL_SDMMC_LL_Group4 Command management functions
ganlikun 0:13413ea9a877 518 * @brief Data transfers functions
ganlikun 0:13413ea9a877 519 *
ganlikun 0:13413ea9a877 520 @verbatim
ganlikun 0:13413ea9a877 521 ===============================================================================
ganlikun 0:13413ea9a877 522 ##### Commands management functions #####
ganlikun 0:13413ea9a877 523 ===============================================================================
ganlikun 0:13413ea9a877 524 [..]
ganlikun 0:13413ea9a877 525 This subsection provides a set of functions allowing to manage the needed commands.
ganlikun 0:13413ea9a877 526
ganlikun 0:13413ea9a877 527 @endverbatim
ganlikun 0:13413ea9a877 528 * @{
ganlikun 0:13413ea9a877 529 */
ganlikun 0:13413ea9a877 530
ganlikun 0:13413ea9a877 531 /**
ganlikun 0:13413ea9a877 532 * @brief Send the Data Block Lenght command and check the response
ganlikun 0:13413ea9a877 533 * @param SDIOx: Pointer to SDMMC register base
ganlikun 0:13413ea9a877 534 * @retval HAL status
ganlikun 0:13413ea9a877 535 */
ganlikun 0:13413ea9a877 536 uint32_t SDMMC_CmdBlockLength(SDIO_TypeDef *SDIOx, uint32_t BlockSize)
ganlikun 0:13413ea9a877 537 {
ganlikun 0:13413ea9a877 538 SDIO_CmdInitTypeDef sdmmc_cmdinit;
ganlikun 0:13413ea9a877 539 uint32_t errorstate = SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 540
ganlikun 0:13413ea9a877 541 /* Set Block Size for Card */
ganlikun 0:13413ea9a877 542 sdmmc_cmdinit.Argument = (uint32_t)BlockSize;
ganlikun 0:13413ea9a877 543 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SET_BLOCKLEN;
ganlikun 0:13413ea9a877 544 sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
ganlikun 0:13413ea9a877 545 sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
ganlikun 0:13413ea9a877 546 sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
ganlikun 0:13413ea9a877 547 SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
ganlikun 0:13413ea9a877 548
ganlikun 0:13413ea9a877 549 /* Check for error conditions */
ganlikun 0:13413ea9a877 550 errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SET_BLOCKLEN, SDIO_CMDTIMEOUT);
ganlikun 0:13413ea9a877 551
ganlikun 0:13413ea9a877 552 return errorstate;
ganlikun 0:13413ea9a877 553 }
ganlikun 0:13413ea9a877 554
ganlikun 0:13413ea9a877 555 /**
ganlikun 0:13413ea9a877 556 * @brief Send the Read Single Block command and check the response
ganlikun 0:13413ea9a877 557 * @param SDIOx: Pointer to SDMMC register base
ganlikun 0:13413ea9a877 558 * @retval HAL status
ganlikun 0:13413ea9a877 559 */
ganlikun 0:13413ea9a877 560 uint32_t SDMMC_CmdReadSingleBlock(SDIO_TypeDef *SDIOx, uint32_t ReadAdd)
ganlikun 0:13413ea9a877 561 {
ganlikun 0:13413ea9a877 562 SDIO_CmdInitTypeDef sdmmc_cmdinit;
ganlikun 0:13413ea9a877 563 uint32_t errorstate = SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 564
ganlikun 0:13413ea9a877 565 /* Set Block Size for Card */
ganlikun 0:13413ea9a877 566 sdmmc_cmdinit.Argument = (uint32_t)ReadAdd;
ganlikun 0:13413ea9a877 567 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_READ_SINGLE_BLOCK;
ganlikun 0:13413ea9a877 568 sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
ganlikun 0:13413ea9a877 569 sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
ganlikun 0:13413ea9a877 570 sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
ganlikun 0:13413ea9a877 571 SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
ganlikun 0:13413ea9a877 572
ganlikun 0:13413ea9a877 573 /* Check for error conditions */
ganlikun 0:13413ea9a877 574 errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_READ_SINGLE_BLOCK, SDIO_CMDTIMEOUT);
ganlikun 0:13413ea9a877 575
ganlikun 0:13413ea9a877 576 return errorstate;
ganlikun 0:13413ea9a877 577 }
ganlikun 0:13413ea9a877 578
ganlikun 0:13413ea9a877 579 /**
ganlikun 0:13413ea9a877 580 * @brief Send the Read Multi Block command and check the response
ganlikun 0:13413ea9a877 581 * @param SDIOx: Pointer to SDIO register base
ganlikun 0:13413ea9a877 582 * @retval HAL status
ganlikun 0:13413ea9a877 583 */
ganlikun 0:13413ea9a877 584 uint32_t SDMMC_CmdReadMultiBlock(SDIO_TypeDef *SDIOx, uint32_t ReadAdd)
ganlikun 0:13413ea9a877 585 {
ganlikun 0:13413ea9a877 586 SDIO_CmdInitTypeDef sdmmc_cmdinit;
ganlikun 0:13413ea9a877 587 uint32_t errorstate = SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 588
ganlikun 0:13413ea9a877 589 /* Set Block Size for Card */
ganlikun 0:13413ea9a877 590 sdmmc_cmdinit.Argument = (uint32_t)ReadAdd;
ganlikun 0:13413ea9a877 591 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_READ_MULT_BLOCK;
ganlikun 0:13413ea9a877 592 sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
ganlikun 0:13413ea9a877 593 sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
ganlikun 0:13413ea9a877 594 sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
ganlikun 0:13413ea9a877 595 SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
ganlikun 0:13413ea9a877 596
ganlikun 0:13413ea9a877 597 /* Check for error conditions */
ganlikun 0:13413ea9a877 598 errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_READ_MULT_BLOCK, SDIO_CMDTIMEOUT);
ganlikun 0:13413ea9a877 599
ganlikun 0:13413ea9a877 600 return errorstate;
ganlikun 0:13413ea9a877 601 }
ganlikun 0:13413ea9a877 602
ganlikun 0:13413ea9a877 603 /**
ganlikun 0:13413ea9a877 604 * @brief Send the Write Single Block command and check the response
ganlikun 0:13413ea9a877 605 * @param SDIOx: Pointer to SDIO register base
ganlikun 0:13413ea9a877 606 * @retval HAL status
ganlikun 0:13413ea9a877 607 */
ganlikun 0:13413ea9a877 608 uint32_t SDMMC_CmdWriteSingleBlock(SDIO_TypeDef *SDIOx, uint32_t WriteAdd)
ganlikun 0:13413ea9a877 609 {
ganlikun 0:13413ea9a877 610 SDIO_CmdInitTypeDef sdmmc_cmdinit;
ganlikun 0:13413ea9a877 611 uint32_t errorstate = SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 612
ganlikun 0:13413ea9a877 613 /* Set Block Size for Card */
ganlikun 0:13413ea9a877 614 sdmmc_cmdinit.Argument = (uint32_t)WriteAdd;
ganlikun 0:13413ea9a877 615 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_WRITE_SINGLE_BLOCK;
ganlikun 0:13413ea9a877 616 sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
ganlikun 0:13413ea9a877 617 sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
ganlikun 0:13413ea9a877 618 sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
ganlikun 0:13413ea9a877 619 SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
ganlikun 0:13413ea9a877 620
ganlikun 0:13413ea9a877 621 /* Check for error conditions */
ganlikun 0:13413ea9a877 622 errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_WRITE_SINGLE_BLOCK, SDIO_CMDTIMEOUT);
ganlikun 0:13413ea9a877 623
ganlikun 0:13413ea9a877 624 return errorstate;
ganlikun 0:13413ea9a877 625 }
ganlikun 0:13413ea9a877 626
ganlikun 0:13413ea9a877 627 /**
ganlikun 0:13413ea9a877 628 * @brief Send the Write Multi Block command and check the response
ganlikun 0:13413ea9a877 629 * @param SDIOx: Pointer to SDIO register base
ganlikun 0:13413ea9a877 630 * @retval HAL status
ganlikun 0:13413ea9a877 631 */
ganlikun 0:13413ea9a877 632 uint32_t SDMMC_CmdWriteMultiBlock(SDIO_TypeDef *SDIOx, uint32_t WriteAdd)
ganlikun 0:13413ea9a877 633 {
ganlikun 0:13413ea9a877 634 SDIO_CmdInitTypeDef sdmmc_cmdinit;
ganlikun 0:13413ea9a877 635 uint32_t errorstate = SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 636
ganlikun 0:13413ea9a877 637 /* Set Block Size for Card */
ganlikun 0:13413ea9a877 638 sdmmc_cmdinit.Argument = (uint32_t)WriteAdd;
ganlikun 0:13413ea9a877 639 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_WRITE_MULT_BLOCK;
ganlikun 0:13413ea9a877 640 sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
ganlikun 0:13413ea9a877 641 sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
ganlikun 0:13413ea9a877 642 sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
ganlikun 0:13413ea9a877 643 SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
ganlikun 0:13413ea9a877 644
ganlikun 0:13413ea9a877 645 /* Check for error conditions */
ganlikun 0:13413ea9a877 646 errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_WRITE_MULT_BLOCK, SDIO_CMDTIMEOUT);
ganlikun 0:13413ea9a877 647
ganlikun 0:13413ea9a877 648 return errorstate;
ganlikun 0:13413ea9a877 649 }
ganlikun 0:13413ea9a877 650
ganlikun 0:13413ea9a877 651 /**
ganlikun 0:13413ea9a877 652 * @brief Send the Start Address Erase command for SD and check the response
ganlikun 0:13413ea9a877 653 * @param SDIOx: Pointer to SDIO register base
ganlikun 0:13413ea9a877 654 * @retval HAL status
ganlikun 0:13413ea9a877 655 */
ganlikun 0:13413ea9a877 656 uint32_t SDMMC_CmdSDEraseStartAdd(SDIO_TypeDef *SDIOx, uint32_t StartAdd)
ganlikun 0:13413ea9a877 657 {
ganlikun 0:13413ea9a877 658 SDIO_CmdInitTypeDef sdmmc_cmdinit;
ganlikun 0:13413ea9a877 659 uint32_t errorstate = SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 660
ganlikun 0:13413ea9a877 661 /* Set Block Size for Card */
ganlikun 0:13413ea9a877 662 sdmmc_cmdinit.Argument = (uint32_t)StartAdd;
ganlikun 0:13413ea9a877 663 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_ERASE_GRP_START;
ganlikun 0:13413ea9a877 664 sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
ganlikun 0:13413ea9a877 665 sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
ganlikun 0:13413ea9a877 666 sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
ganlikun 0:13413ea9a877 667 SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
ganlikun 0:13413ea9a877 668
ganlikun 0:13413ea9a877 669 /* Check for error conditions */
ganlikun 0:13413ea9a877 670 errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SD_ERASE_GRP_START, SDIO_CMDTIMEOUT);
ganlikun 0:13413ea9a877 671
ganlikun 0:13413ea9a877 672 return errorstate;
ganlikun 0:13413ea9a877 673 }
ganlikun 0:13413ea9a877 674
ganlikun 0:13413ea9a877 675 /**
ganlikun 0:13413ea9a877 676 * @brief Send the End Address Erase command for SD and check the response
ganlikun 0:13413ea9a877 677 * @param SDIOx: Pointer to SDIO register base
ganlikun 0:13413ea9a877 678 * @retval HAL status
ganlikun 0:13413ea9a877 679 */
ganlikun 0:13413ea9a877 680 uint32_t SDMMC_CmdSDEraseEndAdd(SDIO_TypeDef *SDIOx, uint32_t EndAdd)
ganlikun 0:13413ea9a877 681 {
ganlikun 0:13413ea9a877 682 SDIO_CmdInitTypeDef sdmmc_cmdinit;
ganlikun 0:13413ea9a877 683 uint32_t errorstate = SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 684
ganlikun 0:13413ea9a877 685 /* Set Block Size for Card */
ganlikun 0:13413ea9a877 686 sdmmc_cmdinit.Argument = (uint32_t)EndAdd;
ganlikun 0:13413ea9a877 687 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_ERASE_GRP_END;
ganlikun 0:13413ea9a877 688 sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
ganlikun 0:13413ea9a877 689 sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
ganlikun 0:13413ea9a877 690 sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
ganlikun 0:13413ea9a877 691 SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
ganlikun 0:13413ea9a877 692
ganlikun 0:13413ea9a877 693 /* Check for error conditions */
ganlikun 0:13413ea9a877 694 errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SD_ERASE_GRP_END, SDIO_CMDTIMEOUT);
ganlikun 0:13413ea9a877 695
ganlikun 0:13413ea9a877 696 return errorstate;
ganlikun 0:13413ea9a877 697 }
ganlikun 0:13413ea9a877 698
ganlikun 0:13413ea9a877 699 /**
ganlikun 0:13413ea9a877 700 * @brief Send the Start Address Erase command and check the response
ganlikun 0:13413ea9a877 701 * @param SDIOx: Pointer to SDIO register base
ganlikun 0:13413ea9a877 702 * @retval HAL status
ganlikun 0:13413ea9a877 703 */
ganlikun 0:13413ea9a877 704 uint32_t SDMMC_CmdEraseStartAdd(SDIO_TypeDef *SDIOx, uint32_t StartAdd)
ganlikun 0:13413ea9a877 705 {
ganlikun 0:13413ea9a877 706 SDIO_CmdInitTypeDef sdmmc_cmdinit;
ganlikun 0:13413ea9a877 707 uint32_t errorstate = SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 708
ganlikun 0:13413ea9a877 709 /* Set Block Size for Card */
ganlikun 0:13413ea9a877 710 sdmmc_cmdinit.Argument = (uint32_t)StartAdd;
ganlikun 0:13413ea9a877 711 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ERASE_GRP_START;
ganlikun 0:13413ea9a877 712 sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
ganlikun 0:13413ea9a877 713 sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
ganlikun 0:13413ea9a877 714 sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
ganlikun 0:13413ea9a877 715 SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
ganlikun 0:13413ea9a877 716
ganlikun 0:13413ea9a877 717 /* Check for error conditions */
ganlikun 0:13413ea9a877 718 errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_ERASE_GRP_START, SDIO_CMDTIMEOUT);
ganlikun 0:13413ea9a877 719
ganlikun 0:13413ea9a877 720 return errorstate;
ganlikun 0:13413ea9a877 721 }
ganlikun 0:13413ea9a877 722
ganlikun 0:13413ea9a877 723 /**
ganlikun 0:13413ea9a877 724 * @brief Send the End Address Erase command and check the response
ganlikun 0:13413ea9a877 725 * @param SDIOx: Pointer to SDIO register base
ganlikun 0:13413ea9a877 726 * @retval HAL status
ganlikun 0:13413ea9a877 727 */
ganlikun 0:13413ea9a877 728 uint32_t SDMMC_CmdEraseEndAdd(SDIO_TypeDef *SDIOx, uint32_t EndAdd)
ganlikun 0:13413ea9a877 729 {
ganlikun 0:13413ea9a877 730 SDIO_CmdInitTypeDef sdmmc_cmdinit;
ganlikun 0:13413ea9a877 731 uint32_t errorstate = SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 732
ganlikun 0:13413ea9a877 733 /* Set Block Size for Card */
ganlikun 0:13413ea9a877 734 sdmmc_cmdinit.Argument = (uint32_t)EndAdd;
ganlikun 0:13413ea9a877 735 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ERASE_GRP_END;
ganlikun 0:13413ea9a877 736 sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
ganlikun 0:13413ea9a877 737 sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
ganlikun 0:13413ea9a877 738 sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
ganlikun 0:13413ea9a877 739 SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
ganlikun 0:13413ea9a877 740
ganlikun 0:13413ea9a877 741 /* Check for error conditions */
ganlikun 0:13413ea9a877 742 errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_ERASE_GRP_END, SDIO_CMDTIMEOUT);
ganlikun 0:13413ea9a877 743
ganlikun 0:13413ea9a877 744 return errorstate;
ganlikun 0:13413ea9a877 745 }
ganlikun 0:13413ea9a877 746
ganlikun 0:13413ea9a877 747 /**
ganlikun 0:13413ea9a877 748 * @brief Send the Erase command and check the response
ganlikun 0:13413ea9a877 749 * @param SDIOx: Pointer to SDIO register base
ganlikun 0:13413ea9a877 750 * @retval HAL status
ganlikun 0:13413ea9a877 751 */
ganlikun 0:13413ea9a877 752 uint32_t SDMMC_CmdErase(SDIO_TypeDef *SDIOx)
ganlikun 0:13413ea9a877 753 {
ganlikun 0:13413ea9a877 754 SDIO_CmdInitTypeDef sdmmc_cmdinit;
ganlikun 0:13413ea9a877 755 uint32_t errorstate = SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 756
ganlikun 0:13413ea9a877 757 /* Set Block Size for Card */
ganlikun 0:13413ea9a877 758 sdmmc_cmdinit.Argument = 0U;
ganlikun 0:13413ea9a877 759 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ERASE;
ganlikun 0:13413ea9a877 760 sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
ganlikun 0:13413ea9a877 761 sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
ganlikun 0:13413ea9a877 762 sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
ganlikun 0:13413ea9a877 763 SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
ganlikun 0:13413ea9a877 764
ganlikun 0:13413ea9a877 765 /* Check for error conditions */
ganlikun 0:13413ea9a877 766 errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_ERASE, SDIO_MAXERASETIMEOUT);
ganlikun 0:13413ea9a877 767
ganlikun 0:13413ea9a877 768 return errorstate;
ganlikun 0:13413ea9a877 769 }
ganlikun 0:13413ea9a877 770
ganlikun 0:13413ea9a877 771 /**
ganlikun 0:13413ea9a877 772 * @brief Send the Stop Transfer command and check the response.
ganlikun 0:13413ea9a877 773 * @param SDIOx: Pointer to SDIO register base
ganlikun 0:13413ea9a877 774 * @retval HAL status
ganlikun 0:13413ea9a877 775 */
ganlikun 0:13413ea9a877 776 uint32_t SDMMC_CmdStopTransfer(SDIO_TypeDef *SDIOx)
ganlikun 0:13413ea9a877 777 {
ganlikun 0:13413ea9a877 778 SDIO_CmdInitTypeDef sdmmc_cmdinit;
ganlikun 0:13413ea9a877 779 uint32_t errorstate = SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 780
ganlikun 0:13413ea9a877 781 /* Send CMD12 STOP_TRANSMISSION */
ganlikun 0:13413ea9a877 782 sdmmc_cmdinit.Argument = 0U;
ganlikun 0:13413ea9a877 783 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_STOP_TRANSMISSION;
ganlikun 0:13413ea9a877 784 sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
ganlikun 0:13413ea9a877 785 sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
ganlikun 0:13413ea9a877 786 sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
ganlikun 0:13413ea9a877 787 SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
ganlikun 0:13413ea9a877 788
ganlikun 0:13413ea9a877 789 /* Check for error conditions */
ganlikun 0:13413ea9a877 790 errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_STOP_TRANSMISSION, 100000000U);
ganlikun 0:13413ea9a877 791
ganlikun 0:13413ea9a877 792 return errorstate;
ganlikun 0:13413ea9a877 793 }
ganlikun 0:13413ea9a877 794
ganlikun 0:13413ea9a877 795 /**
ganlikun 0:13413ea9a877 796 * @brief Send the Select Deselect command and check the response.
ganlikun 0:13413ea9a877 797 * @param SDIOx: Pointer to SDIO register base
ganlikun 0:13413ea9a877 798 * @param addr: Address of the card to be selected
ganlikun 0:13413ea9a877 799 * @retval HAL status
ganlikun 0:13413ea9a877 800 */
ganlikun 0:13413ea9a877 801 uint32_t SDMMC_CmdSelDesel(SDIO_TypeDef *SDIOx, uint64_t Addr)
ganlikun 0:13413ea9a877 802 {
ganlikun 0:13413ea9a877 803 SDIO_CmdInitTypeDef sdmmc_cmdinit;
ganlikun 0:13413ea9a877 804 uint32_t errorstate = SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 805
ganlikun 0:13413ea9a877 806 /* Send CMD7 SDMMC_SEL_DESEL_CARD */
ganlikun 0:13413ea9a877 807 sdmmc_cmdinit.Argument = (uint32_t)Addr;
ganlikun 0:13413ea9a877 808 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEL_DESEL_CARD;
ganlikun 0:13413ea9a877 809 sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
ganlikun 0:13413ea9a877 810 sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
ganlikun 0:13413ea9a877 811 sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
ganlikun 0:13413ea9a877 812 SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
ganlikun 0:13413ea9a877 813
ganlikun 0:13413ea9a877 814 /* Check for error conditions */
ganlikun 0:13413ea9a877 815 errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SEL_DESEL_CARD, SDIO_CMDTIMEOUT);
ganlikun 0:13413ea9a877 816
ganlikun 0:13413ea9a877 817 return errorstate;
ganlikun 0:13413ea9a877 818 }
ganlikun 0:13413ea9a877 819
ganlikun 0:13413ea9a877 820 /**
ganlikun 0:13413ea9a877 821 * @brief Send the Go Idle State command and check the response.
ganlikun 0:13413ea9a877 822 * @param SDIOx: Pointer to SDIO register base
ganlikun 0:13413ea9a877 823 * @retval HAL status
ganlikun 0:13413ea9a877 824 */
ganlikun 0:13413ea9a877 825 uint32_t SDMMC_CmdGoIdleState(SDIO_TypeDef *SDIOx)
ganlikun 0:13413ea9a877 826 {
ganlikun 0:13413ea9a877 827 SDIO_CmdInitTypeDef sdmmc_cmdinit;
ganlikun 0:13413ea9a877 828 uint32_t errorstate = SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 829
ganlikun 0:13413ea9a877 830 sdmmc_cmdinit.Argument = 0U;
ganlikun 0:13413ea9a877 831 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_GO_IDLE_STATE;
ganlikun 0:13413ea9a877 832 sdmmc_cmdinit.Response = SDIO_RESPONSE_NO;
ganlikun 0:13413ea9a877 833 sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
ganlikun 0:13413ea9a877 834 sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
ganlikun 0:13413ea9a877 835 SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
ganlikun 0:13413ea9a877 836
ganlikun 0:13413ea9a877 837 /* Check for error conditions */
ganlikun 0:13413ea9a877 838 errorstate = SDMMC_GetCmdError(SDIOx);
ganlikun 0:13413ea9a877 839
ganlikun 0:13413ea9a877 840 return errorstate;
ganlikun 0:13413ea9a877 841 }
ganlikun 0:13413ea9a877 842
ganlikun 0:13413ea9a877 843 /**
ganlikun 0:13413ea9a877 844 * @brief Send the Operating Condition command and check the response.
ganlikun 0:13413ea9a877 845 * @param SDIOx: Pointer to SDIO register base
ganlikun 0:13413ea9a877 846 * @retval HAL status
ganlikun 0:13413ea9a877 847 */
ganlikun 0:13413ea9a877 848 uint32_t SDMMC_CmdOperCond(SDIO_TypeDef *SDIOx)
ganlikun 0:13413ea9a877 849 {
ganlikun 0:13413ea9a877 850 SDIO_CmdInitTypeDef sdmmc_cmdinit;
ganlikun 0:13413ea9a877 851 uint32_t errorstate = SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 852
ganlikun 0:13413ea9a877 853 /* Send CMD8 to verify SD card interface operating condition */
ganlikun 0:13413ea9a877 854 /* Argument: - [31:12]: Reserved (shall be set to '0')
ganlikun 0:13413ea9a877 855 - [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V)
ganlikun 0:13413ea9a877 856 - [7:0]: Check Pattern (recommended 0xAA) */
ganlikun 0:13413ea9a877 857 /* CMD Response: R7 */
ganlikun 0:13413ea9a877 858 sdmmc_cmdinit.Argument = SDMMC_CHECK_PATTERN;
ganlikun 0:13413ea9a877 859 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_HS_SEND_EXT_CSD;
ganlikun 0:13413ea9a877 860 sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
ganlikun 0:13413ea9a877 861 sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
ganlikun 0:13413ea9a877 862 sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
ganlikun 0:13413ea9a877 863 SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
ganlikun 0:13413ea9a877 864
ganlikun 0:13413ea9a877 865 /* Check for error conditions */
ganlikun 0:13413ea9a877 866 errorstate = SDMMC_GetCmdResp7(SDIOx);
ganlikun 0:13413ea9a877 867
ganlikun 0:13413ea9a877 868 return errorstate;
ganlikun 0:13413ea9a877 869 }
ganlikun 0:13413ea9a877 870
ganlikun 0:13413ea9a877 871 /**
ganlikun 0:13413ea9a877 872 * @brief Send the Application command to verify that that the next command
ganlikun 0:13413ea9a877 873 * is an application specific com-mand rather than a standard command
ganlikun 0:13413ea9a877 874 * and check the response.
ganlikun 0:13413ea9a877 875 * @param SDIOx: Pointer to SDIO register base
ganlikun 0:13413ea9a877 876 * @retval HAL status
ganlikun 0:13413ea9a877 877 */
ganlikun 0:13413ea9a877 878 uint32_t SDMMC_CmdAppCommand(SDIO_TypeDef *SDIOx, uint32_t Argument)
ganlikun 0:13413ea9a877 879 {
ganlikun 0:13413ea9a877 880 SDIO_CmdInitTypeDef sdmmc_cmdinit;
ganlikun 0:13413ea9a877 881 uint32_t errorstate = SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 882
ganlikun 0:13413ea9a877 883 sdmmc_cmdinit.Argument = (uint32_t)Argument;
ganlikun 0:13413ea9a877 884 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_APP_CMD;
ganlikun 0:13413ea9a877 885 sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
ganlikun 0:13413ea9a877 886 sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
ganlikun 0:13413ea9a877 887 sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
ganlikun 0:13413ea9a877 888 SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
ganlikun 0:13413ea9a877 889
ganlikun 0:13413ea9a877 890 /* Check for error conditions */
ganlikun 0:13413ea9a877 891 /* If there is a HAL_ERROR, it is a MMC card, else
ganlikun 0:13413ea9a877 892 it is a SD card: SD card 2.0 (voltage range mismatch)
ganlikun 0:13413ea9a877 893 or SD card 1.x */
ganlikun 0:13413ea9a877 894 errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_APP_CMD, SDIO_CMDTIMEOUT);
ganlikun 0:13413ea9a877 895
ganlikun 0:13413ea9a877 896 return errorstate;
ganlikun 0:13413ea9a877 897 }
ganlikun 0:13413ea9a877 898
ganlikun 0:13413ea9a877 899 /**
ganlikun 0:13413ea9a877 900 * @brief Send the command asking the accessed card to send its operating
ganlikun 0:13413ea9a877 901 * condition register (OCR)
ganlikun 0:13413ea9a877 902 * @param SDIOx: Pointer to SDIO register base
ganlikun 0:13413ea9a877 903 * @retval HAL status
ganlikun 0:13413ea9a877 904 */
ganlikun 0:13413ea9a877 905 uint32_t SDMMC_CmdAppOperCommand(SDIO_TypeDef *SDIOx, uint32_t SdType)
ganlikun 0:13413ea9a877 906 {
ganlikun 0:13413ea9a877 907 SDIO_CmdInitTypeDef sdmmc_cmdinit;
ganlikun 0:13413ea9a877 908 uint32_t errorstate = SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 909
ganlikun 0:13413ea9a877 910 sdmmc_cmdinit.Argument = SDMMC_VOLTAGE_WINDOW_SD | SdType;
ganlikun 0:13413ea9a877 911 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_OP_COND;
ganlikun 0:13413ea9a877 912 sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
ganlikun 0:13413ea9a877 913 sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
ganlikun 0:13413ea9a877 914 sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
ganlikun 0:13413ea9a877 915 SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
ganlikun 0:13413ea9a877 916
ganlikun 0:13413ea9a877 917 /* Check for error conditions */
ganlikun 0:13413ea9a877 918 errorstate = SDMMC_GetCmdResp3(SDIOx);
ganlikun 0:13413ea9a877 919
ganlikun 0:13413ea9a877 920 return errorstate;
ganlikun 0:13413ea9a877 921 }
ganlikun 0:13413ea9a877 922
ganlikun 0:13413ea9a877 923 /**
ganlikun 0:13413ea9a877 924 * @brief Send the Bus Width command and check the response.
ganlikun 0:13413ea9a877 925 * @param SDIOx: Pointer to SDIO register base
ganlikun 0:13413ea9a877 926 * @retval HAL status
ganlikun 0:13413ea9a877 927 */
ganlikun 0:13413ea9a877 928 uint32_t SDMMC_CmdBusWidth(SDIO_TypeDef *SDIOx, uint32_t BusWidth)
ganlikun 0:13413ea9a877 929 {
ganlikun 0:13413ea9a877 930 SDIO_CmdInitTypeDef sdmmc_cmdinit;
ganlikun 0:13413ea9a877 931 uint32_t errorstate = SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 932
ganlikun 0:13413ea9a877 933 sdmmc_cmdinit.Argument = (uint32_t)BusWidth;
ganlikun 0:13413ea9a877 934 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_APP_SD_SET_BUSWIDTH;
ganlikun 0:13413ea9a877 935 sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
ganlikun 0:13413ea9a877 936 sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
ganlikun 0:13413ea9a877 937 sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
ganlikun 0:13413ea9a877 938 SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
ganlikun 0:13413ea9a877 939
ganlikun 0:13413ea9a877 940 /* Check for error conditions */
ganlikun 0:13413ea9a877 941 errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_APP_SD_SET_BUSWIDTH, SDIO_CMDTIMEOUT);
ganlikun 0:13413ea9a877 942
ganlikun 0:13413ea9a877 943 return errorstate;
ganlikun 0:13413ea9a877 944 }
ganlikun 0:13413ea9a877 945
ganlikun 0:13413ea9a877 946 /**
ganlikun 0:13413ea9a877 947 * @brief Send the Send SCR command and check the response.
ganlikun 0:13413ea9a877 948 * @param SDIOx: Pointer to SDMMC register base
ganlikun 0:13413ea9a877 949 * @retval HAL status
ganlikun 0:13413ea9a877 950 */
ganlikun 0:13413ea9a877 951 uint32_t SDMMC_CmdSendSCR(SDIO_TypeDef *SDIOx)
ganlikun 0:13413ea9a877 952 {
ganlikun 0:13413ea9a877 953 SDIO_CmdInitTypeDef sdmmc_cmdinit;
ganlikun 0:13413ea9a877 954 uint32_t errorstate = SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 955
ganlikun 0:13413ea9a877 956 /* Send CMD51 SD_APP_SEND_SCR */
ganlikun 0:13413ea9a877 957 sdmmc_cmdinit.Argument = 0U;
ganlikun 0:13413ea9a877 958 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_SEND_SCR;
ganlikun 0:13413ea9a877 959 sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
ganlikun 0:13413ea9a877 960 sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
ganlikun 0:13413ea9a877 961 sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
ganlikun 0:13413ea9a877 962 SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
ganlikun 0:13413ea9a877 963
ganlikun 0:13413ea9a877 964 /* Check for error conditions */
ganlikun 0:13413ea9a877 965 errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SD_APP_SEND_SCR, SDIO_CMDTIMEOUT);
ganlikun 0:13413ea9a877 966
ganlikun 0:13413ea9a877 967 return errorstate;
ganlikun 0:13413ea9a877 968 }
ganlikun 0:13413ea9a877 969
ganlikun 0:13413ea9a877 970 /**
ganlikun 0:13413ea9a877 971 * @brief Send the Send CID command and check the response.
ganlikun 0:13413ea9a877 972 * @param SDIOx: Pointer to SDIO register base
ganlikun 0:13413ea9a877 973 * @retval HAL status
ganlikun 0:13413ea9a877 974 */
ganlikun 0:13413ea9a877 975 uint32_t SDMMC_CmdSendCID(SDIO_TypeDef *SDIOx)
ganlikun 0:13413ea9a877 976 {
ganlikun 0:13413ea9a877 977 SDIO_CmdInitTypeDef sdmmc_cmdinit;
ganlikun 0:13413ea9a877 978 uint32_t errorstate = SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 979
ganlikun 0:13413ea9a877 980 /* Send CMD2 ALL_SEND_CID */
ganlikun 0:13413ea9a877 981 sdmmc_cmdinit.Argument = 0U;
ganlikun 0:13413ea9a877 982 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_ALL_SEND_CID;
ganlikun 0:13413ea9a877 983 sdmmc_cmdinit.Response = SDIO_RESPONSE_LONG;
ganlikun 0:13413ea9a877 984 sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
ganlikun 0:13413ea9a877 985 sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
ganlikun 0:13413ea9a877 986 SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
ganlikun 0:13413ea9a877 987
ganlikun 0:13413ea9a877 988 /* Check for error conditions */
ganlikun 0:13413ea9a877 989 errorstate = SDMMC_GetCmdResp2(SDIOx);
ganlikun 0:13413ea9a877 990
ganlikun 0:13413ea9a877 991 return errorstate;
ganlikun 0:13413ea9a877 992 }
ganlikun 0:13413ea9a877 993
ganlikun 0:13413ea9a877 994 /**
ganlikun 0:13413ea9a877 995 * @brief Send the Send CSD command and check the response.
ganlikun 0:13413ea9a877 996 * @param SDIOx: Pointer to SDIO register base
ganlikun 0:13413ea9a877 997 * @retval HAL status
ganlikun 0:13413ea9a877 998 */
ganlikun 0:13413ea9a877 999 uint32_t SDMMC_CmdSendCSD(SDIO_TypeDef *SDIOx, uint32_t Argument)
ganlikun 0:13413ea9a877 1000 {
ganlikun 0:13413ea9a877 1001 SDIO_CmdInitTypeDef sdmmc_cmdinit;
ganlikun 0:13413ea9a877 1002 uint32_t errorstate = SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 1003
ganlikun 0:13413ea9a877 1004 /* Send CMD9 SEND_CSD */
ganlikun 0:13413ea9a877 1005 sdmmc_cmdinit.Argument = (uint32_t)Argument;
ganlikun 0:13413ea9a877 1006 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEND_CSD;
ganlikun 0:13413ea9a877 1007 sdmmc_cmdinit.Response = SDIO_RESPONSE_LONG;
ganlikun 0:13413ea9a877 1008 sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
ganlikun 0:13413ea9a877 1009 sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
ganlikun 0:13413ea9a877 1010 SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
ganlikun 0:13413ea9a877 1011
ganlikun 0:13413ea9a877 1012 /* Check for error conditions */
ganlikun 0:13413ea9a877 1013 errorstate = SDMMC_GetCmdResp2(SDIOx);
ganlikun 0:13413ea9a877 1014
ganlikun 0:13413ea9a877 1015 return errorstate;
ganlikun 0:13413ea9a877 1016 }
ganlikun 0:13413ea9a877 1017
ganlikun 0:13413ea9a877 1018 /**
ganlikun 0:13413ea9a877 1019 * @brief Send the Send CSD command and check the response.
ganlikun 0:13413ea9a877 1020 * @param SDIOx: Pointer to SDIO register base
ganlikun 0:13413ea9a877 1021 * @retval HAL status
ganlikun 0:13413ea9a877 1022 */
ganlikun 0:13413ea9a877 1023 uint32_t SDMMC_CmdSetRelAdd(SDIO_TypeDef *SDIOx, uint16_t *pRCA)
ganlikun 0:13413ea9a877 1024 {
ganlikun 0:13413ea9a877 1025 SDIO_CmdInitTypeDef sdmmc_cmdinit;
ganlikun 0:13413ea9a877 1026 uint32_t errorstate = SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 1027
ganlikun 0:13413ea9a877 1028 /* Send CMD3 SD_CMD_SET_REL_ADDR */
ganlikun 0:13413ea9a877 1029 sdmmc_cmdinit.Argument = 0U;
ganlikun 0:13413ea9a877 1030 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SET_REL_ADDR;
ganlikun 0:13413ea9a877 1031 sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
ganlikun 0:13413ea9a877 1032 sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
ganlikun 0:13413ea9a877 1033 sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
ganlikun 0:13413ea9a877 1034 SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
ganlikun 0:13413ea9a877 1035
ganlikun 0:13413ea9a877 1036 /* Check for error conditions */
ganlikun 0:13413ea9a877 1037 errorstate = SDMMC_GetCmdResp6(SDIOx, SDMMC_CMD_SET_REL_ADDR, pRCA);
ganlikun 0:13413ea9a877 1038
ganlikun 0:13413ea9a877 1039 return errorstate;
ganlikun 0:13413ea9a877 1040 }
ganlikun 0:13413ea9a877 1041
ganlikun 0:13413ea9a877 1042 /**
ganlikun 0:13413ea9a877 1043 * @brief Send the Status command and check the response.
ganlikun 0:13413ea9a877 1044 * @param SDIOx: Pointer to SDIO register base
ganlikun 0:13413ea9a877 1045 * @retval HAL status
ganlikun 0:13413ea9a877 1046 */
ganlikun 0:13413ea9a877 1047 uint32_t SDMMC_CmdSendStatus(SDIO_TypeDef *SDIOx, uint32_t Argument)
ganlikun 0:13413ea9a877 1048 {
ganlikun 0:13413ea9a877 1049 SDIO_CmdInitTypeDef sdmmc_cmdinit;
ganlikun 0:13413ea9a877 1050 uint32_t errorstate = SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 1051
ganlikun 0:13413ea9a877 1052 sdmmc_cmdinit.Argument = (uint32_t)Argument;
ganlikun 0:13413ea9a877 1053 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEND_STATUS;
ganlikun 0:13413ea9a877 1054 sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
ganlikun 0:13413ea9a877 1055 sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
ganlikun 0:13413ea9a877 1056 sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
ganlikun 0:13413ea9a877 1057 SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
ganlikun 0:13413ea9a877 1058
ganlikun 0:13413ea9a877 1059 /* Check for error conditions */
ganlikun 0:13413ea9a877 1060 errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SEND_STATUS, SDIO_CMDTIMEOUT);
ganlikun 0:13413ea9a877 1061
ganlikun 0:13413ea9a877 1062 return errorstate;
ganlikun 0:13413ea9a877 1063 }
ganlikun 0:13413ea9a877 1064
ganlikun 0:13413ea9a877 1065 /**
ganlikun 0:13413ea9a877 1066 * @brief Send the Status register command and check the response.
ganlikun 0:13413ea9a877 1067 * @param SDIOx: Pointer to SDIO register base
ganlikun 0:13413ea9a877 1068 * @retval HAL status
ganlikun 0:13413ea9a877 1069 */
ganlikun 0:13413ea9a877 1070 uint32_t SDMMC_CmdStatusRegister(SDIO_TypeDef *SDIOx)
ganlikun 0:13413ea9a877 1071 {
ganlikun 0:13413ea9a877 1072 SDIO_CmdInitTypeDef sdmmc_cmdinit;
ganlikun 0:13413ea9a877 1073 uint32_t errorstate = SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 1074
ganlikun 0:13413ea9a877 1075 sdmmc_cmdinit.Argument = 0U;
ganlikun 0:13413ea9a877 1076 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SD_APP_STATUS;
ganlikun 0:13413ea9a877 1077 sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
ganlikun 0:13413ea9a877 1078 sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
ganlikun 0:13413ea9a877 1079 sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
ganlikun 0:13413ea9a877 1080 SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
ganlikun 0:13413ea9a877 1081
ganlikun 0:13413ea9a877 1082 /* Check for error conditions */
ganlikun 0:13413ea9a877 1083 errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_SD_APP_STATUS, SDIO_CMDTIMEOUT);
ganlikun 0:13413ea9a877 1084
ganlikun 0:13413ea9a877 1085 return errorstate;
ganlikun 0:13413ea9a877 1086 }
ganlikun 0:13413ea9a877 1087
ganlikun 0:13413ea9a877 1088 /**
ganlikun 0:13413ea9a877 1089 * @brief Sends host capacity support information and activates the card's
ganlikun 0:13413ea9a877 1090 * initialization process. Send SDMMC_CMD_SEND_OP_COND command
ganlikun 0:13413ea9a877 1091 * @param SDIOx: Pointer to SDIO register base
ganlikun 0:13413ea9a877 1092 * @parame Argument: Argument used for the command
ganlikun 0:13413ea9a877 1093 * @retval HAL status
ganlikun 0:13413ea9a877 1094 */
ganlikun 0:13413ea9a877 1095 uint32_t SDMMC_CmdOpCondition(SDIO_TypeDef *SDIOx, uint32_t Argument)
ganlikun 0:13413ea9a877 1096 {
ganlikun 0:13413ea9a877 1097 SDIO_CmdInitTypeDef sdmmc_cmdinit;
ganlikun 0:13413ea9a877 1098 uint32_t errorstate = SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 1099
ganlikun 0:13413ea9a877 1100 sdmmc_cmdinit.Argument = Argument;
ganlikun 0:13413ea9a877 1101 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_SEND_OP_COND;
ganlikun 0:13413ea9a877 1102 sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
ganlikun 0:13413ea9a877 1103 sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
ganlikun 0:13413ea9a877 1104 sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
ganlikun 0:13413ea9a877 1105 SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
ganlikun 0:13413ea9a877 1106
ganlikun 0:13413ea9a877 1107 /* Check for error conditions */
ganlikun 0:13413ea9a877 1108 errorstate = SDMMC_GetCmdResp3(SDIOx);
ganlikun 0:13413ea9a877 1109
ganlikun 0:13413ea9a877 1110 return errorstate;
ganlikun 0:13413ea9a877 1111 }
ganlikun 0:13413ea9a877 1112
ganlikun 0:13413ea9a877 1113 /**
ganlikun 0:13413ea9a877 1114 * @brief Checks switchable function and switch card function. SDMMC_CMD_HS_SWITCH comand
ganlikun 0:13413ea9a877 1115 * @param SDIOx: Pointer to SDIO register base
ganlikun 0:13413ea9a877 1116 * @parame Argument: Argument used for the command
ganlikun 0:13413ea9a877 1117 * @retval HAL status
ganlikun 0:13413ea9a877 1118 */
ganlikun 0:13413ea9a877 1119 uint32_t SDMMC_CmdSwitch(SDIO_TypeDef *SDIOx, uint32_t Argument)
ganlikun 0:13413ea9a877 1120 {
ganlikun 0:13413ea9a877 1121 SDIO_CmdInitTypeDef sdmmc_cmdinit;
ganlikun 0:13413ea9a877 1122 uint32_t errorstate = SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 1123
ganlikun 0:13413ea9a877 1124 sdmmc_cmdinit.Argument = Argument;
ganlikun 0:13413ea9a877 1125 sdmmc_cmdinit.CmdIndex = SDMMC_CMD_HS_SWITCH;
ganlikun 0:13413ea9a877 1126 sdmmc_cmdinit.Response = SDIO_RESPONSE_SHORT;
ganlikun 0:13413ea9a877 1127 sdmmc_cmdinit.WaitForInterrupt = SDIO_WAIT_NO;
ganlikun 0:13413ea9a877 1128 sdmmc_cmdinit.CPSM = SDIO_CPSM_ENABLE;
ganlikun 0:13413ea9a877 1129 SDIO_SendCommand(SDIOx, &sdmmc_cmdinit);
ganlikun 0:13413ea9a877 1130
ganlikun 0:13413ea9a877 1131 /* Check for error conditions */
ganlikun 0:13413ea9a877 1132 errorstate = SDMMC_GetCmdResp1(SDIOx, SDMMC_CMD_HS_SWITCH, SDIO_CMDTIMEOUT);
ganlikun 0:13413ea9a877 1133
ganlikun 0:13413ea9a877 1134 return errorstate;
ganlikun 0:13413ea9a877 1135 }
ganlikun 0:13413ea9a877 1136
ganlikun 0:13413ea9a877 1137 /**
ganlikun 0:13413ea9a877 1138 * @}
ganlikun 0:13413ea9a877 1139 */
ganlikun 0:13413ea9a877 1140
ganlikun 0:13413ea9a877 1141 /* Private function ----------------------------------------------------------*/
ganlikun 0:13413ea9a877 1142 /** @addtogroup SD_Private_Functions
ganlikun 0:13413ea9a877 1143 * @{
ganlikun 0:13413ea9a877 1144 */
ganlikun 0:13413ea9a877 1145
ganlikun 0:13413ea9a877 1146 /**
ganlikun 0:13413ea9a877 1147 * @brief Checks for error conditions for CMD0.
ganlikun 0:13413ea9a877 1148 * @param hsd: SD handle
ganlikun 0:13413ea9a877 1149 * @retval SD Card error state
ganlikun 0:13413ea9a877 1150 */
ganlikun 0:13413ea9a877 1151 static uint32_t SDMMC_GetCmdError(SDIO_TypeDef *SDIOx)
ganlikun 0:13413ea9a877 1152 {
ganlikun 0:13413ea9a877 1153 /* 8 is the number of required instructions cycles for the below loop statement.
ganlikun 0:13413ea9a877 1154 The SDMMC_CMDTIMEOUT is expressed in ms */
ganlikun 0:13413ea9a877 1155 register uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
ganlikun 0:13413ea9a877 1156
ganlikun 0:13413ea9a877 1157 do
ganlikun 0:13413ea9a877 1158 {
ganlikun 0:13413ea9a877 1159 if (count-- == 0U)
ganlikun 0:13413ea9a877 1160 {
ganlikun 0:13413ea9a877 1161 return SDMMC_ERROR_TIMEOUT;
ganlikun 0:13413ea9a877 1162 }
ganlikun 0:13413ea9a877 1163
ganlikun 0:13413ea9a877 1164 }while(!__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CMDSENT));
ganlikun 0:13413ea9a877 1165
ganlikun 0:13413ea9a877 1166 /* Clear all the static flags */
ganlikun 0:13413ea9a877 1167 __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_FLAGS);
ganlikun 0:13413ea9a877 1168
ganlikun 0:13413ea9a877 1169 return SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 1170 }
ganlikun 0:13413ea9a877 1171
ganlikun 0:13413ea9a877 1172 /**
ganlikun 0:13413ea9a877 1173 * @brief Checks for error conditions for R1 response.
ganlikun 0:13413ea9a877 1174 * @param hsd: SD handle
ganlikun 0:13413ea9a877 1175 * @param SD_CMD: The sent command index
ganlikun 0:13413ea9a877 1176 * @retval SD Card error state
ganlikun 0:13413ea9a877 1177 */
ganlikun 0:13413ea9a877 1178 static uint32_t SDMMC_GetCmdResp1(SDIO_TypeDef *SDIOx, uint8_t SD_CMD, uint32_t Timeout)
ganlikun 0:13413ea9a877 1179 {
ganlikun 0:13413ea9a877 1180 uint32_t response_r1;
ganlikun 0:13413ea9a877 1181
ganlikun 0:13413ea9a877 1182 /* 8 is the number of required instructions cycles for the below loop statement.
ganlikun 0:13413ea9a877 1183 The Timeout is expressed in ms */
ganlikun 0:13413ea9a877 1184 register uint32_t count = Timeout * (SystemCoreClock / 8U /1000U);
ganlikun 0:13413ea9a877 1185
ganlikun 0:13413ea9a877 1186 do
ganlikun 0:13413ea9a877 1187 {
ganlikun 0:13413ea9a877 1188 if (count-- == 0U)
ganlikun 0:13413ea9a877 1189 {
ganlikun 0:13413ea9a877 1190 return SDMMC_ERROR_TIMEOUT;
ganlikun 0:13413ea9a877 1191 }
ganlikun 0:13413ea9a877 1192
ganlikun 0:13413ea9a877 1193 }while(!__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT));
ganlikun 0:13413ea9a877 1194
ganlikun 0:13413ea9a877 1195 if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
ganlikun 0:13413ea9a877 1196 {
ganlikun 0:13413ea9a877 1197 __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT);
ganlikun 0:13413ea9a877 1198
ganlikun 0:13413ea9a877 1199 return SDMMC_ERROR_CMD_RSP_TIMEOUT;
ganlikun 0:13413ea9a877 1200 }
ganlikun 0:13413ea9a877 1201 else if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL))
ganlikun 0:13413ea9a877 1202 {
ganlikun 0:13413ea9a877 1203 __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL);
ganlikun 0:13413ea9a877 1204
ganlikun 0:13413ea9a877 1205 return SDMMC_ERROR_CMD_CRC_FAIL;
ganlikun 0:13413ea9a877 1206 }
ganlikun 0:13413ea9a877 1207
ganlikun 0:13413ea9a877 1208 /* Check response received is of desired command */
ganlikun 0:13413ea9a877 1209 if(SDIO_GetCommandResponse(SDIOx) != SD_CMD)
ganlikun 0:13413ea9a877 1210 {
ganlikun 0:13413ea9a877 1211 return SDMMC_ERROR_CMD_CRC_FAIL;
ganlikun 0:13413ea9a877 1212 }
ganlikun 0:13413ea9a877 1213
ganlikun 0:13413ea9a877 1214 /* Clear all the static flags */
ganlikun 0:13413ea9a877 1215 __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_FLAGS);
ganlikun 0:13413ea9a877 1216
ganlikun 0:13413ea9a877 1217 /* We have received response, retrieve it for analysis */
ganlikun 0:13413ea9a877 1218 response_r1 = SDIO_GetResponse(SDIOx, SDIO_RESP1);
ganlikun 0:13413ea9a877 1219
ganlikun 0:13413ea9a877 1220 if((response_r1 & SDMMC_OCR_ERRORBITS) == SDMMC_ALLZERO)
ganlikun 0:13413ea9a877 1221 {
ganlikun 0:13413ea9a877 1222 return SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 1223 }
ganlikun 0:13413ea9a877 1224 else if((response_r1 & SDMMC_OCR_ADDR_OUT_OF_RANGE) == SDMMC_OCR_ADDR_OUT_OF_RANGE)
ganlikun 0:13413ea9a877 1225 {
ganlikun 0:13413ea9a877 1226 return SDMMC_ERROR_ADDR_OUT_OF_RANGE;
ganlikun 0:13413ea9a877 1227 }
ganlikun 0:13413ea9a877 1228 else if((response_r1 & SDMMC_OCR_ADDR_MISALIGNED) == SDMMC_OCR_ADDR_MISALIGNED)
ganlikun 0:13413ea9a877 1229 {
ganlikun 0:13413ea9a877 1230 return SDMMC_ERROR_ADDR_MISALIGNED;
ganlikun 0:13413ea9a877 1231 }
ganlikun 0:13413ea9a877 1232 else if((response_r1 & SDMMC_OCR_BLOCK_LEN_ERR) == SDMMC_OCR_BLOCK_LEN_ERR)
ganlikun 0:13413ea9a877 1233 {
ganlikun 0:13413ea9a877 1234 return SDMMC_ERROR_BLOCK_LEN_ERR;
ganlikun 0:13413ea9a877 1235 }
ganlikun 0:13413ea9a877 1236 else if((response_r1 & SDMMC_OCR_ERASE_SEQ_ERR) == SDMMC_OCR_ERASE_SEQ_ERR)
ganlikun 0:13413ea9a877 1237 {
ganlikun 0:13413ea9a877 1238 return SDMMC_ERROR_ERASE_SEQ_ERR;
ganlikun 0:13413ea9a877 1239 }
ganlikun 0:13413ea9a877 1240 else if((response_r1 & SDMMC_OCR_BAD_ERASE_PARAM) == SDMMC_OCR_BAD_ERASE_PARAM)
ganlikun 0:13413ea9a877 1241 {
ganlikun 0:13413ea9a877 1242 return SDMMC_ERROR_BAD_ERASE_PARAM;
ganlikun 0:13413ea9a877 1243 }
ganlikun 0:13413ea9a877 1244 else if((response_r1 & SDMMC_OCR_WRITE_PROT_VIOLATION) == SDMMC_OCR_WRITE_PROT_VIOLATION)
ganlikun 0:13413ea9a877 1245 {
ganlikun 0:13413ea9a877 1246 return SDMMC_ERROR_WRITE_PROT_VIOLATION;
ganlikun 0:13413ea9a877 1247 }
ganlikun 0:13413ea9a877 1248 else if((response_r1 & SDMMC_OCR_LOCK_UNLOCK_FAILED) == SDMMC_OCR_LOCK_UNLOCK_FAILED)
ganlikun 0:13413ea9a877 1249 {
ganlikun 0:13413ea9a877 1250 return SDMMC_ERROR_LOCK_UNLOCK_FAILED;
ganlikun 0:13413ea9a877 1251 }
ganlikun 0:13413ea9a877 1252 else if((response_r1 & SDMMC_OCR_COM_CRC_FAILED) == SDMMC_OCR_COM_CRC_FAILED)
ganlikun 0:13413ea9a877 1253 {
ganlikun 0:13413ea9a877 1254 return SDMMC_ERROR_COM_CRC_FAILED;
ganlikun 0:13413ea9a877 1255 }
ganlikun 0:13413ea9a877 1256 else if((response_r1 & SDMMC_OCR_ILLEGAL_CMD) == SDMMC_OCR_ILLEGAL_CMD)
ganlikun 0:13413ea9a877 1257 {
ganlikun 0:13413ea9a877 1258 return SDMMC_ERROR_ILLEGAL_CMD;
ganlikun 0:13413ea9a877 1259 }
ganlikun 0:13413ea9a877 1260 else if((response_r1 & SDMMC_OCR_CARD_ECC_FAILED) == SDMMC_OCR_CARD_ECC_FAILED)
ganlikun 0:13413ea9a877 1261 {
ganlikun 0:13413ea9a877 1262 return SDMMC_ERROR_CARD_ECC_FAILED;
ganlikun 0:13413ea9a877 1263 }
ganlikun 0:13413ea9a877 1264 else if((response_r1 & SDMMC_OCR_CC_ERROR) == SDMMC_OCR_CC_ERROR)
ganlikun 0:13413ea9a877 1265 {
ganlikun 0:13413ea9a877 1266 return SDMMC_ERROR_CC_ERR;
ganlikun 0:13413ea9a877 1267 }
ganlikun 0:13413ea9a877 1268 else if((response_r1 & SDMMC_OCR_STREAM_READ_UNDERRUN) == SDMMC_OCR_STREAM_READ_UNDERRUN)
ganlikun 0:13413ea9a877 1269 {
ganlikun 0:13413ea9a877 1270 return SDMMC_ERROR_STREAM_READ_UNDERRUN;
ganlikun 0:13413ea9a877 1271 }
ganlikun 0:13413ea9a877 1272 else if((response_r1 & SDMMC_OCR_STREAM_WRITE_OVERRUN) == SDMMC_OCR_STREAM_WRITE_OVERRUN)
ganlikun 0:13413ea9a877 1273 {
ganlikun 0:13413ea9a877 1274 return SDMMC_ERROR_STREAM_WRITE_OVERRUN;
ganlikun 0:13413ea9a877 1275 }
ganlikun 0:13413ea9a877 1276 else if((response_r1 & SDMMC_OCR_CID_CSD_OVERWRITE) == SDMMC_OCR_CID_CSD_OVERWRITE)
ganlikun 0:13413ea9a877 1277 {
ganlikun 0:13413ea9a877 1278 return SDMMC_ERROR_CID_CSD_OVERWRITE;
ganlikun 0:13413ea9a877 1279 }
ganlikun 0:13413ea9a877 1280 else if((response_r1 & SDMMC_OCR_WP_ERASE_SKIP) == SDMMC_OCR_WP_ERASE_SKIP)
ganlikun 0:13413ea9a877 1281 {
ganlikun 0:13413ea9a877 1282 return SDMMC_ERROR_WP_ERASE_SKIP;
ganlikun 0:13413ea9a877 1283 }
ganlikun 0:13413ea9a877 1284 else if((response_r1 & SDMMC_OCR_CARD_ECC_DISABLED) == SDMMC_OCR_CARD_ECC_DISABLED)
ganlikun 0:13413ea9a877 1285 {
ganlikun 0:13413ea9a877 1286 return SDMMC_ERROR_CARD_ECC_DISABLED;
ganlikun 0:13413ea9a877 1287 }
ganlikun 0:13413ea9a877 1288 else if((response_r1 & SDMMC_OCR_ERASE_RESET) == SDMMC_OCR_ERASE_RESET)
ganlikun 0:13413ea9a877 1289 {
ganlikun 0:13413ea9a877 1290 return SDMMC_ERROR_ERASE_RESET;
ganlikun 0:13413ea9a877 1291 }
ganlikun 0:13413ea9a877 1292 else if((response_r1 & SDMMC_OCR_AKE_SEQ_ERROR) == SDMMC_OCR_AKE_SEQ_ERROR)
ganlikun 0:13413ea9a877 1293 {
ganlikun 0:13413ea9a877 1294 return SDMMC_ERROR_AKE_SEQ_ERR;
ganlikun 0:13413ea9a877 1295 }
ganlikun 0:13413ea9a877 1296 else
ganlikun 0:13413ea9a877 1297 {
ganlikun 0:13413ea9a877 1298 return SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
ganlikun 0:13413ea9a877 1299 }
ganlikun 0:13413ea9a877 1300 }
ganlikun 0:13413ea9a877 1301
ganlikun 0:13413ea9a877 1302 /**
ganlikun 0:13413ea9a877 1303 * @brief Checks for error conditions for R2 (CID or CSD) response.
ganlikun 0:13413ea9a877 1304 * @param hsd: SD handle
ganlikun 0:13413ea9a877 1305 * @retval SD Card error state
ganlikun 0:13413ea9a877 1306 */
ganlikun 0:13413ea9a877 1307 static uint32_t SDMMC_GetCmdResp2(SDIO_TypeDef *SDIOx)
ganlikun 0:13413ea9a877 1308 {
ganlikun 0:13413ea9a877 1309 /* 8 is the number of required instructions cycles for the below loop statement.
ganlikun 0:13413ea9a877 1310 The SDMMC_CMDTIMEOUT is expressed in ms */
ganlikun 0:13413ea9a877 1311 register uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
ganlikun 0:13413ea9a877 1312
ganlikun 0:13413ea9a877 1313 do
ganlikun 0:13413ea9a877 1314 {
ganlikun 0:13413ea9a877 1315 if (count-- == 0U)
ganlikun 0:13413ea9a877 1316 {
ganlikun 0:13413ea9a877 1317 return SDMMC_ERROR_TIMEOUT;
ganlikun 0:13413ea9a877 1318 }
ganlikun 0:13413ea9a877 1319
ganlikun 0:13413ea9a877 1320 }while(!__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT));
ganlikun 0:13413ea9a877 1321
ganlikun 0:13413ea9a877 1322 if (__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
ganlikun 0:13413ea9a877 1323 {
ganlikun 0:13413ea9a877 1324 __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT);
ganlikun 0:13413ea9a877 1325
ganlikun 0:13413ea9a877 1326 return SDMMC_ERROR_CMD_RSP_TIMEOUT;
ganlikun 0:13413ea9a877 1327 }
ganlikun 0:13413ea9a877 1328 else if (__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL))
ganlikun 0:13413ea9a877 1329 {
ganlikun 0:13413ea9a877 1330 __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL);
ganlikun 0:13413ea9a877 1331
ganlikun 0:13413ea9a877 1332 return SDMMC_ERROR_CMD_CRC_FAIL;
ganlikun 0:13413ea9a877 1333 }
ganlikun 0:13413ea9a877 1334 else
ganlikun 0:13413ea9a877 1335 {
ganlikun 0:13413ea9a877 1336 /* No error flag set */
ganlikun 0:13413ea9a877 1337 /* Clear all the static flags */
ganlikun 0:13413ea9a877 1338 __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_FLAGS);
ganlikun 0:13413ea9a877 1339 }
ganlikun 0:13413ea9a877 1340
ganlikun 0:13413ea9a877 1341 return SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 1342 }
ganlikun 0:13413ea9a877 1343
ganlikun 0:13413ea9a877 1344 /**
ganlikun 0:13413ea9a877 1345 * @brief Checks for error conditions for R3 (OCR) response.
ganlikun 0:13413ea9a877 1346 * @param hsd: SD handle
ganlikun 0:13413ea9a877 1347 * @retval SD Card error state
ganlikun 0:13413ea9a877 1348 */
ganlikun 0:13413ea9a877 1349 static uint32_t SDMMC_GetCmdResp3(SDIO_TypeDef *SDIOx)
ganlikun 0:13413ea9a877 1350 {
ganlikun 0:13413ea9a877 1351 /* 8 is the number of required instructions cycles for the below loop statement.
ganlikun 0:13413ea9a877 1352 The SDMMC_CMDTIMEOUT is expressed in ms */
ganlikun 0:13413ea9a877 1353 register uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
ganlikun 0:13413ea9a877 1354
ganlikun 0:13413ea9a877 1355 do
ganlikun 0:13413ea9a877 1356 {
ganlikun 0:13413ea9a877 1357 if (count-- == 0U)
ganlikun 0:13413ea9a877 1358 {
ganlikun 0:13413ea9a877 1359 return SDMMC_ERROR_TIMEOUT;
ganlikun 0:13413ea9a877 1360 }
ganlikun 0:13413ea9a877 1361
ganlikun 0:13413ea9a877 1362 }while(!__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT));
ganlikun 0:13413ea9a877 1363
ganlikun 0:13413ea9a877 1364 if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
ganlikun 0:13413ea9a877 1365 {
ganlikun 0:13413ea9a877 1366 __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT);
ganlikun 0:13413ea9a877 1367
ganlikun 0:13413ea9a877 1368 return SDMMC_ERROR_CMD_RSP_TIMEOUT;
ganlikun 0:13413ea9a877 1369 }
ganlikun 0:13413ea9a877 1370 else
ganlikun 0:13413ea9a877 1371
ganlikun 0:13413ea9a877 1372 {
ganlikun 0:13413ea9a877 1373 /* Clear all the static flags */
ganlikun 0:13413ea9a877 1374 __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_FLAGS);
ganlikun 0:13413ea9a877 1375 }
ganlikun 0:13413ea9a877 1376
ganlikun 0:13413ea9a877 1377 return SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 1378 }
ganlikun 0:13413ea9a877 1379
ganlikun 0:13413ea9a877 1380 /**
ganlikun 0:13413ea9a877 1381 * @brief Checks for error conditions for R6 (RCA) response.
ganlikun 0:13413ea9a877 1382 * @param hsd: SD handle
ganlikun 0:13413ea9a877 1383 * @param SD_CMD: The sent command index
ganlikun 0:13413ea9a877 1384 * @param pRCA: Pointer to the variable that will contain the SD card relative
ganlikun 0:13413ea9a877 1385 * address RCA
ganlikun 0:13413ea9a877 1386 * @retval SD Card error state
ganlikun 0:13413ea9a877 1387 */
ganlikun 0:13413ea9a877 1388 static uint32_t SDMMC_GetCmdResp6(SDIO_TypeDef *SDIOx, uint8_t SD_CMD, uint16_t *pRCA)
ganlikun 0:13413ea9a877 1389 {
ganlikun 0:13413ea9a877 1390 uint32_t response_r1;
ganlikun 0:13413ea9a877 1391
ganlikun 0:13413ea9a877 1392 /* 8 is the number of required instructions cycles for the below loop statement.
ganlikun 0:13413ea9a877 1393 The SDMMC_CMDTIMEOUT is expressed in ms */
ganlikun 0:13413ea9a877 1394 register uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
ganlikun 0:13413ea9a877 1395
ganlikun 0:13413ea9a877 1396 do
ganlikun 0:13413ea9a877 1397 {
ganlikun 0:13413ea9a877 1398 if (count-- == 0U)
ganlikun 0:13413ea9a877 1399 {
ganlikun 0:13413ea9a877 1400 return SDMMC_ERROR_TIMEOUT;
ganlikun 0:13413ea9a877 1401 }
ganlikun 0:13413ea9a877 1402
ganlikun 0:13413ea9a877 1403 }while(!__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT));
ganlikun 0:13413ea9a877 1404
ganlikun 0:13413ea9a877 1405 if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
ganlikun 0:13413ea9a877 1406 {
ganlikun 0:13413ea9a877 1407 __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT);
ganlikun 0:13413ea9a877 1408
ganlikun 0:13413ea9a877 1409 return SDMMC_ERROR_CMD_RSP_TIMEOUT;
ganlikun 0:13413ea9a877 1410 }
ganlikun 0:13413ea9a877 1411 else if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL))
ganlikun 0:13413ea9a877 1412 {
ganlikun 0:13413ea9a877 1413 __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL);
ganlikun 0:13413ea9a877 1414
ganlikun 0:13413ea9a877 1415 return SDMMC_ERROR_CMD_CRC_FAIL;
ganlikun 0:13413ea9a877 1416 }
ganlikun 0:13413ea9a877 1417
ganlikun 0:13413ea9a877 1418 /* Check response received is of desired command */
ganlikun 0:13413ea9a877 1419 if(SDIO_GetCommandResponse(SDIOx) != SD_CMD)
ganlikun 0:13413ea9a877 1420 {
ganlikun 0:13413ea9a877 1421 return SDMMC_ERROR_CMD_CRC_FAIL;
ganlikun 0:13413ea9a877 1422 }
ganlikun 0:13413ea9a877 1423
ganlikun 0:13413ea9a877 1424 /* Clear all the static flags */
ganlikun 0:13413ea9a877 1425 __SDIO_CLEAR_FLAG(SDIOx, SDIO_STATIC_FLAGS);
ganlikun 0:13413ea9a877 1426
ganlikun 0:13413ea9a877 1427 /* We have received response, retrieve it. */
ganlikun 0:13413ea9a877 1428 response_r1 = SDIO_GetResponse(SDIOx, SDIO_RESP1);
ganlikun 0:13413ea9a877 1429
ganlikun 0:13413ea9a877 1430 if((response_r1 & (SDMMC_R6_GENERAL_UNKNOWN_ERROR | SDMMC_R6_ILLEGAL_CMD | SDMMC_R6_COM_CRC_FAILED)) == SDMMC_ALLZERO)
ganlikun 0:13413ea9a877 1431 {
ganlikun 0:13413ea9a877 1432 *pRCA = (uint16_t) (response_r1 >> 16);
ganlikun 0:13413ea9a877 1433
ganlikun 0:13413ea9a877 1434 return SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 1435 }
ganlikun 0:13413ea9a877 1436 else if((response_r1 & SDMMC_R6_ILLEGAL_CMD) == SDMMC_R6_ILLEGAL_CMD)
ganlikun 0:13413ea9a877 1437 {
ganlikun 0:13413ea9a877 1438 return SDMMC_ERROR_ILLEGAL_CMD;
ganlikun 0:13413ea9a877 1439 }
ganlikun 0:13413ea9a877 1440 else if((response_r1 & SDMMC_R6_COM_CRC_FAILED) == SDMMC_R6_COM_CRC_FAILED)
ganlikun 0:13413ea9a877 1441 {
ganlikun 0:13413ea9a877 1442 return SDMMC_ERROR_COM_CRC_FAILED;
ganlikun 0:13413ea9a877 1443 }
ganlikun 0:13413ea9a877 1444 else
ganlikun 0:13413ea9a877 1445 {
ganlikun 0:13413ea9a877 1446 return SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
ganlikun 0:13413ea9a877 1447 }
ganlikun 0:13413ea9a877 1448 }
ganlikun 0:13413ea9a877 1449
ganlikun 0:13413ea9a877 1450 /**
ganlikun 0:13413ea9a877 1451 * @brief Checks for error conditions for R7 response.
ganlikun 0:13413ea9a877 1452 * @param hsd: SD handle
ganlikun 0:13413ea9a877 1453 * @retval SD Card error state
ganlikun 0:13413ea9a877 1454 */
ganlikun 0:13413ea9a877 1455 static uint32_t SDMMC_GetCmdResp7(SDIO_TypeDef *SDIOx)
ganlikun 0:13413ea9a877 1456 {
ganlikun 0:13413ea9a877 1457 /* 8 is the number of required instructions cycles for the below loop statement.
ganlikun 0:13413ea9a877 1458 The SDIO_CMDTIMEOUT is expressed in ms */
ganlikun 0:13413ea9a877 1459 register uint32_t count = SDIO_CMDTIMEOUT * (SystemCoreClock / 8U /1000U);
ganlikun 0:13413ea9a877 1460
ganlikun 0:13413ea9a877 1461 do
ganlikun 0:13413ea9a877 1462 {
ganlikun 0:13413ea9a877 1463 if (count-- == 0U)
ganlikun 0:13413ea9a877 1464 {
ganlikun 0:13413ea9a877 1465 return SDMMC_ERROR_TIMEOUT;
ganlikun 0:13413ea9a877 1466 }
ganlikun 0:13413ea9a877 1467
ganlikun 0:13413ea9a877 1468 }while(!__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT));
ganlikun 0:13413ea9a877 1469
ganlikun 0:13413ea9a877 1470 if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CTIMEOUT))
ganlikun 0:13413ea9a877 1471 {
ganlikun 0:13413ea9a877 1472 /* Card is SD V2.0 compliant */
ganlikun 0:13413ea9a877 1473 __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CMDREND);
ganlikun 0:13413ea9a877 1474
ganlikun 0:13413ea9a877 1475 return SDMMC_ERROR_CMD_RSP_TIMEOUT;
ganlikun 0:13413ea9a877 1476 }
ganlikun 0:13413ea9a877 1477
ganlikun 0:13413ea9a877 1478 if(__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CMDREND))
ganlikun 0:13413ea9a877 1479 {
ganlikun 0:13413ea9a877 1480 /* Card is SD V2.0 compliant */
ganlikun 0:13413ea9a877 1481 __SDIO_CLEAR_FLAG(SDIOx, SDIO_FLAG_CMDREND);
ganlikun 0:13413ea9a877 1482 }
ganlikun 0:13413ea9a877 1483
ganlikun 0:13413ea9a877 1484 return SDMMC_ERROR_NONE;
ganlikun 0:13413ea9a877 1485
ganlikun 0:13413ea9a877 1486 }
ganlikun 0:13413ea9a877 1487
ganlikun 0:13413ea9a877 1488 /**
ganlikun 0:13413ea9a877 1489 * @}
ganlikun 0:13413ea9a877 1490 */
ganlikun 0:13413ea9a877 1491
ganlikun 0:13413ea9a877 1492 /**
ganlikun 0:13413ea9a877 1493 * @}
ganlikun 0:13413ea9a877 1494 */
ganlikun 0:13413ea9a877 1495
ganlikun 0:13413ea9a877 1496 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx ||
ganlikun 0:13413ea9a877 1497 STM32F401xC || STM32F401xE || STM32F411xE || STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx ||
ganlikun 0:13413ea9a877 1498 STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */
ganlikun 0:13413ea9a877 1499 #endif /* (HAL_SD_MODULE_ENABLED) || (HAL_MMC_MODULE_ENABLED) */
ganlikun 0:13413ea9a877 1500
ganlikun 0:13413ea9a877 1501 /**
ganlikun 0:13413ea9a877 1502 * @}
ganlikun 0:13413ea9a877 1503 */
ganlikun 0:13413ea9a877 1504
ganlikun 0:13413ea9a877 1505 /**
ganlikun 0:13413ea9a877 1506 * @}
ganlikun 0:13413ea9a877 1507 */
ganlikun 0:13413ea9a877 1508
ganlikun 0:13413ea9a877 1509 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
ganlikun 0:13413ea9a877 1510