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_hal_mmc.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 MMC card HAL module driver.
ganlikun 0:13413ea9a877 8 * This file provides firmware functions to manage the following
ganlikun 0:13413ea9a877 9 * functionalities of the Secure Digital (MMC) peripheral:
ganlikun 0:13413ea9a877 10 * + Initialization and de-initialization functions
ganlikun 0:13413ea9a877 11 * + IO operation functions
ganlikun 0:13413ea9a877 12 * + Peripheral Control functions
ganlikun 0:13413ea9a877 13 * + MMC card Control functions
ganlikun 0:13413ea9a877 14 *
ganlikun 0:13413ea9a877 15 @verbatim
ganlikun 0:13413ea9a877 16 ==============================================================================
ganlikun 0:13413ea9a877 17 ##### How to use this driver #####
ganlikun 0:13413ea9a877 18 ==============================================================================
ganlikun 0:13413ea9a877 19 [..]
ganlikun 0:13413ea9a877 20 This driver implements a high level communication layer for read and write from/to
ganlikun 0:13413ea9a877 21 this memory. The needed STM32 hardware resources (SDMMC and GPIO) are performed by
ganlikun 0:13413ea9a877 22 the user in HAL_MMC_MspInit() function (MSP layer).
ganlikun 0:13413ea9a877 23 Basically, the MSP layer configuration should be the same as we provide in the
ganlikun 0:13413ea9a877 24 examples.
ganlikun 0:13413ea9a877 25 You can easily tailor this configuration according to hardware resources.
ganlikun 0:13413ea9a877 26
ganlikun 0:13413ea9a877 27 [..]
ganlikun 0:13413ea9a877 28 This driver is a generic layered driver for SDMMC memories which uses the HAL
ganlikun 0:13413ea9a877 29 SDMMC driver functions to interface with MMC and eMMC cards devices.
ganlikun 0:13413ea9a877 30 It is used as follows:
ganlikun 0:13413ea9a877 31
ganlikun 0:13413ea9a877 32 (#)Initialize the SDMMC low level resources by implement the HAL_MMC_MspInit() API:
ganlikun 0:13413ea9a877 33 (##) Enable the SDMMC interface clock using __HAL_RCC_SDMMC_CLK_ENABLE();
ganlikun 0:13413ea9a877 34 (##) SDMMC pins configuration for MMC card
ganlikun 0:13413ea9a877 35 (+++) Enable the clock for the SDMMC GPIOs using the functions __HAL_RCC_GPIOx_CLK_ENABLE();
ganlikun 0:13413ea9a877 36 (+++) Configure these SDMMC pins as alternate function pull-up using HAL_GPIO_Init()
ganlikun 0:13413ea9a877 37 and according to your pin assignment;
ganlikun 0:13413ea9a877 38 (##) DMA Configuration if you need to use DMA process (HAL_MMC_ReadBlocks_DMA()
ganlikun 0:13413ea9a877 39 and HAL_MMC_WriteBlocks_DMA() APIs).
ganlikun 0:13413ea9a877 40 (+++) Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE();
ganlikun 0:13413ea9a877 41 (+++) Configure the DMA using the function HAL_DMA_Init() with predeclared and filled.
ganlikun 0:13413ea9a877 42 (##) NVIC configuration if you need to use interrupt process when using DMA transfer.
ganlikun 0:13413ea9a877 43 (+++) Configure the SDMMC and DMA interrupt priorities using functions
ganlikun 0:13413ea9a877 44 HAL_NVIC_SetPriority(); DMA priority is superior to SDMMC's priority
ganlikun 0:13413ea9a877 45 (+++) Enable the NVIC DMA and SDMMC IRQs using function HAL_NVIC_EnableIRQ()
ganlikun 0:13413ea9a877 46 (+++) SDMMC interrupts are managed using the macros __HAL_MMC_ENABLE_IT()
ganlikun 0:13413ea9a877 47 and __HAL_MMC_DISABLE_IT() inside the communication process.
ganlikun 0:13413ea9a877 48 (+++) SDMMC interrupts pending bits are managed using the macros __HAL_MMC_GET_IT()
ganlikun 0:13413ea9a877 49 and __HAL_MMC_CLEAR_IT()
ganlikun 0:13413ea9a877 50 (##) NVIC configuration if you need to use interrupt process (HAL_MMC_ReadBlocks_IT()
ganlikun 0:13413ea9a877 51 and HAL_MMC_WriteBlocks_IT() APIs).
ganlikun 0:13413ea9a877 52 (+++) Configure the SDMMC interrupt priorities using function
ganlikun 0:13413ea9a877 53 HAL_NVIC_SetPriority();
ganlikun 0:13413ea9a877 54 (+++) Enable the NVIC SDMMC IRQs using function HAL_NVIC_EnableIRQ()
ganlikun 0:13413ea9a877 55 (+++) SDMMC interrupts are managed using the macros __HAL_MMC_ENABLE_IT()
ganlikun 0:13413ea9a877 56 and __HAL_MMC_DISABLE_IT() inside the communication process.
ganlikun 0:13413ea9a877 57 (+++) SDMMC interrupts pending bits are managed using the macros __HAL_MMC_GET_IT()
ganlikun 0:13413ea9a877 58 and __HAL_MMC_CLEAR_IT()
ganlikun 0:13413ea9a877 59 (#) At this stage, you can perform MMC read/write/erase operations after MMC card initialization
ganlikun 0:13413ea9a877 60
ganlikun 0:13413ea9a877 61
ganlikun 0:13413ea9a877 62 *** MMC Card Initialization and configuration ***
ganlikun 0:13413ea9a877 63 ================================================
ganlikun 0:13413ea9a877 64 [..]
ganlikun 0:13413ea9a877 65 To initialize the MMC Card, use the HAL_MMC_Init() function. It Initializes
ganlikun 0:13413ea9a877 66 SDMMC IP (STM32 side) and the MMC Card, and put it into StandBy State (Ready for data transfer).
ganlikun 0:13413ea9a877 67 This function provide the following operations:
ganlikun 0:13413ea9a877 68
ganlikun 0:13413ea9a877 69 (#) Initialize the SDMMC peripheral interface with defaullt configuration.
ganlikun 0:13413ea9a877 70 The initialization process is done at 400KHz. You can change or adapt
ganlikun 0:13413ea9a877 71 this frequency by adjusting the "ClockDiv" field.
ganlikun 0:13413ea9a877 72 The MMC Card frequency (SDMMC_CK) is computed as follows:
ganlikun 0:13413ea9a877 73
ganlikun 0:13413ea9a877 74 SDMMC_CK = SDMMCCLK / (ClockDiv + 2)
ganlikun 0:13413ea9a877 75
ganlikun 0:13413ea9a877 76 In initialization mode and according to the MMC Card standard,
ganlikun 0:13413ea9a877 77 make sure that the SDMMC_CK frequency doesn't exceed 400KHz.
ganlikun 0:13413ea9a877 78
ganlikun 0:13413ea9a877 79 This phase of initialization is done through SDMMC_Init() and
ganlikun 0:13413ea9a877 80 SDMMC_PowerState_ON() SDMMC low level APIs.
ganlikun 0:13413ea9a877 81
ganlikun 0:13413ea9a877 82 (#) Initialize the MMC card. The API used is HAL_MMC_InitCard().
ganlikun 0:13413ea9a877 83 This phase allows the card initialization and identification
ganlikun 0:13413ea9a877 84 and check the MMC Card type (Standard Capacity or High Capacity)
ganlikun 0:13413ea9a877 85 The initialization flow is compatible with MMC standard.
ganlikun 0:13413ea9a877 86
ganlikun 0:13413ea9a877 87 This API (HAL_MMC_InitCard()) could be used also to reinitialize the card in case
ganlikun 0:13413ea9a877 88 of plug-off plug-in.
ganlikun 0:13413ea9a877 89
ganlikun 0:13413ea9a877 90 (#) Configure the MMC Card Data transfer frequency. By Default, the card transfer
ganlikun 0:13413ea9a877 91 frequency is set to 24MHz. You can change or adapt this frequency by adjusting
ganlikun 0:13413ea9a877 92 the "ClockDiv" field.
ganlikun 0:13413ea9a877 93 In transfer mode and according to the MMC Card standard, make sure that the
ganlikun 0:13413ea9a877 94 SDMMC_CK frequency doesn't exceed 25MHz and 50MHz in High-speed mode switch.
ganlikun 0:13413ea9a877 95 To be able to use a frequency higher than 24MHz, you should use the SDMMC
ganlikun 0:13413ea9a877 96 peripheral in bypass mode. Refer to the corresponding reference manual
ganlikun 0:13413ea9a877 97 for more details.
ganlikun 0:13413ea9a877 98
ganlikun 0:13413ea9a877 99 (#) Select the corresponding MMC Card according to the address read with the step 2.
ganlikun 0:13413ea9a877 100
ganlikun 0:13413ea9a877 101 (#) Configure the MMC Card in wide bus mode: 4-bits data.
ganlikun 0:13413ea9a877 102
ganlikun 0:13413ea9a877 103 *** MMC Card Read operation ***
ganlikun 0:13413ea9a877 104 ==============================
ganlikun 0:13413ea9a877 105 [..]
ganlikun 0:13413ea9a877 106 (+) You can read from MMC card in polling mode by using function HAL_MMC_ReadBlocks().
ganlikun 0:13413ea9a877 107 This function allows the read of 512 bytes blocks.
ganlikun 0:13413ea9a877 108 You can choose either one block read operation or multiple block read operation
ganlikun 0:13413ea9a877 109 by adjusting the "NumberOfBlocks" parameter.
ganlikun 0:13413ea9a877 110 After this, you have to ensure that the transfer is done correctly. The check is done
ganlikun 0:13413ea9a877 111 through HAL_MMC_GetCardState() function for MMC card state.
ganlikun 0:13413ea9a877 112
ganlikun 0:13413ea9a877 113 (+) You can read from MMC card in DMA mode by using function HAL_MMC_ReadBlocks_DMA().
ganlikun 0:13413ea9a877 114 This function allows the read of 512 bytes blocks.
ganlikun 0:13413ea9a877 115 You can choose either one block read operation or multiple block read operation
ganlikun 0:13413ea9a877 116 by adjusting the "NumberOfBlocks" parameter.
ganlikun 0:13413ea9a877 117 After this, you have to ensure that the transfer is done correctly. The check is done
ganlikun 0:13413ea9a877 118 through HAL_MMC_GetCardState() function for MMC card state.
ganlikun 0:13413ea9a877 119 You could also check the DMA transfer process through the MMC Rx interrupt event.
ganlikun 0:13413ea9a877 120
ganlikun 0:13413ea9a877 121 (+) You can read from MMC card in Interrupt mode by using function HAL_MMC_ReadBlocks_IT().
ganlikun 0:13413ea9a877 122 This function allows the read of 512 bytes blocks.
ganlikun 0:13413ea9a877 123 You can choose either one block read operation or multiple block read operation
ganlikun 0:13413ea9a877 124 by adjusting the "NumberOfBlocks" parameter.
ganlikun 0:13413ea9a877 125 After this, you have to ensure that the transfer is done correctly. The check is done
ganlikun 0:13413ea9a877 126 through HAL_MMC_GetCardState() function for MMC card state.
ganlikun 0:13413ea9a877 127 You could also check the IT transfer process through the MMC Rx interrupt event.
ganlikun 0:13413ea9a877 128
ganlikun 0:13413ea9a877 129 *** MMC Card Write operation ***
ganlikun 0:13413ea9a877 130 ===============================
ganlikun 0:13413ea9a877 131 [..]
ganlikun 0:13413ea9a877 132 (+) You can write to MMC card in polling mode by using function HAL_MMC_WriteBlocks().
ganlikun 0:13413ea9a877 133 This function allows the read of 512 bytes blocks.
ganlikun 0:13413ea9a877 134 You can choose either one block read operation or multiple block read operation
ganlikun 0:13413ea9a877 135 by adjusting the "NumberOfBlocks" parameter.
ganlikun 0:13413ea9a877 136 After this, you have to ensure that the transfer is done correctly. The check is done
ganlikun 0:13413ea9a877 137 through HAL_MMC_GetCardState() function for MMC card state.
ganlikun 0:13413ea9a877 138
ganlikun 0:13413ea9a877 139 (+) You can write to MMC card in DMA mode by using function HAL_MMC_WriteBlocks_DMA().
ganlikun 0:13413ea9a877 140 This function allows the read of 512 bytes blocks.
ganlikun 0:13413ea9a877 141 You can choose either one block read operation or multiple block read operation
ganlikun 0:13413ea9a877 142 by adjusting the "NumberOfBlocks" parameter.
ganlikun 0:13413ea9a877 143 After this, you have to ensure that the transfer is done correctly. The check is done
ganlikun 0:13413ea9a877 144 through HAL_MMC_GetCardState() function for MMC card state.
ganlikun 0:13413ea9a877 145 You could also check the DMA transfer process through the MMC Tx interrupt event.
ganlikun 0:13413ea9a877 146
ganlikun 0:13413ea9a877 147 (+) You can write to MMC card in Interrupt mode by using function HAL_MMC_WriteBlocks_IT().
ganlikun 0:13413ea9a877 148 This function allows the read of 512 bytes blocks.
ganlikun 0:13413ea9a877 149 You can choose either one block read operation or multiple block read operation
ganlikun 0:13413ea9a877 150 by adjusting the "NumberOfBlocks" parameter.
ganlikun 0:13413ea9a877 151 After this, you have to ensure that the transfer is done correctly. The check is done
ganlikun 0:13413ea9a877 152 through HAL_MMC_GetCardState() function for MMC card state.
ganlikun 0:13413ea9a877 153 You could also check the IT transfer process through the MMC Tx interrupt event.
ganlikun 0:13413ea9a877 154
ganlikun 0:13413ea9a877 155 *** MMC card status ***
ganlikun 0:13413ea9a877 156 ======================
ganlikun 0:13413ea9a877 157 [..]
ganlikun 0:13413ea9a877 158 (+) The MMC Status contains status bits that are related to the MMC Memory
ganlikun 0:13413ea9a877 159 Card proprietary features. To get MMC card status use the HAL_MMC_GetCardStatus().
ganlikun 0:13413ea9a877 160
ganlikun 0:13413ea9a877 161 *** MMC card information ***
ganlikun 0:13413ea9a877 162 ===========================
ganlikun 0:13413ea9a877 163 [..]
ganlikun 0:13413ea9a877 164 (+) To get MMC card information, you can use the function HAL_MMC_GetCardInfo().
ganlikun 0:13413ea9a877 165 It returns useful information about the MMC card such as block size, card type,
ganlikun 0:13413ea9a877 166 block number ...
ganlikun 0:13413ea9a877 167
ganlikun 0:13413ea9a877 168 *** MMC card CSD register ***
ganlikun 0:13413ea9a877 169 ============================
ganlikun 0:13413ea9a877 170 [..]
ganlikun 0:13413ea9a877 171 (+) The HAL_MMC_GetCardCSD() API allows to get the parameters of the CSD register.
ganlikun 0:13413ea9a877 172 Some of the CSD parameters are useful for card initialization and identification.
ganlikun 0:13413ea9a877 173
ganlikun 0:13413ea9a877 174 *** MMC card CID register ***
ganlikun 0:13413ea9a877 175 ============================
ganlikun 0:13413ea9a877 176 [..]
ganlikun 0:13413ea9a877 177 (+) The HAL_MMC_GetCardCID() API allows to get the parameters of the CID register.
ganlikun 0:13413ea9a877 178 Some of the CID parameters are useful for card initialization and identification.
ganlikun 0:13413ea9a877 179
ganlikun 0:13413ea9a877 180 *** MMC HAL driver macros list ***
ganlikun 0:13413ea9a877 181 ==================================
ganlikun 0:13413ea9a877 182 [..]
ganlikun 0:13413ea9a877 183 Below the list of most used macros in MMC HAL driver.
ganlikun 0:13413ea9a877 184
ganlikun 0:13413ea9a877 185 (+) __HAL_MMC_ENABLE : Enable the MMC device
ganlikun 0:13413ea9a877 186 (+) __HAL_MMC_DISABLE : Disable the MMC device
ganlikun 0:13413ea9a877 187 (+) __HAL_MMC_DMA_ENABLE: Enable the SDMMC DMA transfer
ganlikun 0:13413ea9a877 188 (+) __HAL_MMC_DMA_DISABLE: Disable the SDMMC DMA transfer
ganlikun 0:13413ea9a877 189 (+) __HAL_MMC_ENABLE_IT: Enable the MMC device interrupt
ganlikun 0:13413ea9a877 190 (+) __HAL_MMC_DISABLE_IT: Disable the MMC device interrupt
ganlikun 0:13413ea9a877 191 (+) __HAL_MMC_GET_FLAG:Check whether the specified MMC flag is set or not
ganlikun 0:13413ea9a877 192 (+) __HAL_MMC_CLEAR_FLAG: Clear the MMC's pending flags
ganlikun 0:13413ea9a877 193
ganlikun 0:13413ea9a877 194 [..]
ganlikun 0:13413ea9a877 195 (@) You can refer to the MMC HAL driver header file for more useful macros
ganlikun 0:13413ea9a877 196
ganlikun 0:13413ea9a877 197 @endverbatim
ganlikun 0:13413ea9a877 198 ******************************************************************************
ganlikun 0:13413ea9a877 199 * @attention
ganlikun 0:13413ea9a877 200 *
ganlikun 0:13413ea9a877 201 * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
ganlikun 0:13413ea9a877 202 *
ganlikun 0:13413ea9a877 203 * Redistribution and use in source and binary forms, with or without modification,
ganlikun 0:13413ea9a877 204 * are permitted provided that the following conditions are met:
ganlikun 0:13413ea9a877 205 * 1. Redistributions of source code must retain the above copyright notice,
ganlikun 0:13413ea9a877 206 * this list of conditions and the following disclaimer.
ganlikun 0:13413ea9a877 207 * 2. Redistributions in binary form must reproduce the above copyright notice,
ganlikun 0:13413ea9a877 208 * this list of conditions and the following disclaimer in the documentation
ganlikun 0:13413ea9a877 209 * and/or other materials provided with the distribution.
ganlikun 0:13413ea9a877 210 * 3. Neither the name of STMicroelectronics nor the names of its contributors
ganlikun 0:13413ea9a877 211 * may be used to endorse or promote products derived from this software
ganlikun 0:13413ea9a877 212 * without specific prior written permission.
ganlikun 0:13413ea9a877 213 *
ganlikun 0:13413ea9a877 214 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
ganlikun 0:13413ea9a877 215 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
ganlikun 0:13413ea9a877 216 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
ganlikun 0:13413ea9a877 217 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
ganlikun 0:13413ea9a877 218 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
ganlikun 0:13413ea9a877 219 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
ganlikun 0:13413ea9a877 220 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
ganlikun 0:13413ea9a877 221 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
ganlikun 0:13413ea9a877 222 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
ganlikun 0:13413ea9a877 223 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
ganlikun 0:13413ea9a877 224 *
ganlikun 0:13413ea9a877 225 ******************************************************************************
ganlikun 0:13413ea9a877 226 */
ganlikun 0:13413ea9a877 227
ganlikun 0:13413ea9a877 228 /* Includes ------------------------------------------------------------------*/
ganlikun 0:13413ea9a877 229 #include "stm32f4xx_hal.h"
ganlikun 0:13413ea9a877 230
ganlikun 0:13413ea9a877 231 /** @addtogroup STM32F4xx_HAL_Driver
ganlikun 0:13413ea9a877 232 * @{
ganlikun 0:13413ea9a877 233 */
ganlikun 0:13413ea9a877 234
ganlikun 0:13413ea9a877 235 /** @addtogroup MMC
ganlikun 0:13413ea9a877 236 * @{
ganlikun 0:13413ea9a877 237 */
ganlikun 0:13413ea9a877 238
ganlikun 0:13413ea9a877 239 #ifdef HAL_MMC_MODULE_ENABLED
ganlikun 0:13413ea9a877 240
ganlikun 0:13413ea9a877 241 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || \
ganlikun 0:13413ea9a877 242 defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || \
ganlikun 0:13413ea9a877 243 defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) || \
ganlikun 0:13413ea9a877 244 defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || \
ganlikun 0:13413ea9a877 245 defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
ganlikun 0:13413ea9a877 246
ganlikun 0:13413ea9a877 247 /* Private typedef -----------------------------------------------------------*/
ganlikun 0:13413ea9a877 248 /* Private define ------------------------------------------------------------*/
ganlikun 0:13413ea9a877 249 /** @addtogroup MMC_Private_Defines
ganlikun 0:13413ea9a877 250 * @{
ganlikun 0:13413ea9a877 251 */
ganlikun 0:13413ea9a877 252
ganlikun 0:13413ea9a877 253 /**
ganlikun 0:13413ea9a877 254 * @}
ganlikun 0:13413ea9a877 255 */
ganlikun 0:13413ea9a877 256
ganlikun 0:13413ea9a877 257 /* Private macro -------------------------------------------------------------*/
ganlikun 0:13413ea9a877 258 /* Private variables ---------------------------------------------------------*/
ganlikun 0:13413ea9a877 259 /* Private function prototypes -----------------------------------------------*/
ganlikun 0:13413ea9a877 260 /* Private functions ---------------------------------------------------------*/
ganlikun 0:13413ea9a877 261 /** @defgroup MMC_Private_Functions MMC Private Functions
ganlikun 0:13413ea9a877 262 * @{
ganlikun 0:13413ea9a877 263 */
ganlikun 0:13413ea9a877 264 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc);
ganlikun 0:13413ea9a877 265 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc);
ganlikun 0:13413ea9a877 266 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus);
ganlikun 0:13413ea9a877 267 static HAL_StatusTypeDef MMC_PowerOFF(MMC_HandleTypeDef *hmmc);
ganlikun 0:13413ea9a877 268 static HAL_StatusTypeDef MMC_Write_IT(MMC_HandleTypeDef *hmmc);
ganlikun 0:13413ea9a877 269 static HAL_StatusTypeDef MMC_Read_IT(MMC_HandleTypeDef *hmmc);
ganlikun 0:13413ea9a877 270 static void MMC_DMATransmitCplt(DMA_HandleTypeDef *hdma);
ganlikun 0:13413ea9a877 271 static void MMC_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
ganlikun 0:13413ea9a877 272 static void MMC_DMAError(DMA_HandleTypeDef *hdma);
ganlikun 0:13413ea9a877 273 static void MMC_DMATxAbort(DMA_HandleTypeDef *hdma);
ganlikun 0:13413ea9a877 274 static void MMC_DMARxAbort(DMA_HandleTypeDef *hdma);
ganlikun 0:13413ea9a877 275 /**
ganlikun 0:13413ea9a877 276 * @}
ganlikun 0:13413ea9a877 277 */
ganlikun 0:13413ea9a877 278
ganlikun 0:13413ea9a877 279 /* Exported functions --------------------------------------------------------*/
ganlikun 0:13413ea9a877 280 /** @addtogroup MMC_Exported_Functions
ganlikun 0:13413ea9a877 281 * @{
ganlikun 0:13413ea9a877 282 */
ganlikun 0:13413ea9a877 283
ganlikun 0:13413ea9a877 284 /** @addtogroup MMC_Exported_Functions_Group1
ganlikun 0:13413ea9a877 285 * @brief Initialization and de-initialization functions
ganlikun 0:13413ea9a877 286 *
ganlikun 0:13413ea9a877 287 @verbatim
ganlikun 0:13413ea9a877 288 ==============================================================================
ganlikun 0:13413ea9a877 289 ##### Initialization and de-initialization functions #####
ganlikun 0:13413ea9a877 290 ==============================================================================
ganlikun 0:13413ea9a877 291 [..]
ganlikun 0:13413ea9a877 292 This section provides functions allowing to initialize/de-initialize the MMC
ganlikun 0:13413ea9a877 293 card device to be ready for use.
ganlikun 0:13413ea9a877 294
ganlikun 0:13413ea9a877 295 @endverbatim
ganlikun 0:13413ea9a877 296 * @{
ganlikun 0:13413ea9a877 297 */
ganlikun 0:13413ea9a877 298
ganlikun 0:13413ea9a877 299 /**
ganlikun 0:13413ea9a877 300 * @brief Initializes the MMC according to the specified parameters in the
ganlikun 0:13413ea9a877 301 MMC_HandleTypeDef and create the associated handle.
ganlikun 0:13413ea9a877 302 * @param hmmc: Pointer to the MMC handle
ganlikun 0:13413ea9a877 303 * @retval HAL status
ganlikun 0:13413ea9a877 304 */
ganlikun 0:13413ea9a877 305 HAL_StatusTypeDef HAL_MMC_Init(MMC_HandleTypeDef *hmmc)
ganlikun 0:13413ea9a877 306 {
ganlikun 0:13413ea9a877 307 /* Check the MMC handle allocation */
ganlikun 0:13413ea9a877 308 if(hmmc == NULL)
ganlikun 0:13413ea9a877 309 {
ganlikun 0:13413ea9a877 310 return HAL_ERROR;
ganlikun 0:13413ea9a877 311 }
ganlikun 0:13413ea9a877 312
ganlikun 0:13413ea9a877 313 /* Check the parameters */
ganlikun 0:13413ea9a877 314 assert_param(IS_SDIO_ALL_INSTANCE(hmmc->Instance));
ganlikun 0:13413ea9a877 315 assert_param(IS_SDIO_CLOCK_EDGE(hmmc->Init.ClockEdge));
ganlikun 0:13413ea9a877 316 assert_param(IS_SDIO_CLOCK_BYPASS(hmmc->Init.ClockBypass));
ganlikun 0:13413ea9a877 317 assert_param(IS_SDIO_CLOCK_POWER_SAVE(hmmc->Init.ClockPowerSave));
ganlikun 0:13413ea9a877 318 assert_param(IS_SDIO_BUS_WIDE(hmmc->Init.BusWide));
ganlikun 0:13413ea9a877 319 assert_param(IS_SDIO_HARDWARE_FLOW_CONTROL(hmmc->Init.HardwareFlowControl));
ganlikun 0:13413ea9a877 320 assert_param(IS_SDIO_CLKDIV(hmmc->Init.ClockDiv));
ganlikun 0:13413ea9a877 321
ganlikun 0:13413ea9a877 322 if(hmmc->State == HAL_MMC_STATE_RESET)
ganlikun 0:13413ea9a877 323 {
ganlikun 0:13413ea9a877 324 /* Allocate lock resource and initialize it */
ganlikun 0:13413ea9a877 325 hmmc->Lock = HAL_UNLOCKED;
ganlikun 0:13413ea9a877 326 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
ganlikun 0:13413ea9a877 327 HAL_MMC_MspInit(hmmc);
ganlikun 0:13413ea9a877 328 }
ganlikun 0:13413ea9a877 329
ganlikun 0:13413ea9a877 330 hmmc->State = HAL_MMC_STATE_BUSY;
ganlikun 0:13413ea9a877 331
ganlikun 0:13413ea9a877 332 /* Initialize the Card parameters */
ganlikun 0:13413ea9a877 333 HAL_MMC_InitCard(hmmc);
ganlikun 0:13413ea9a877 334
ganlikun 0:13413ea9a877 335 /* Initialize the error code */
ganlikun 0:13413ea9a877 336 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
ganlikun 0:13413ea9a877 337
ganlikun 0:13413ea9a877 338 /* Initialize the MMC operation */
ganlikun 0:13413ea9a877 339 hmmc->Context = MMC_CONTEXT_NONE;
ganlikun 0:13413ea9a877 340
ganlikun 0:13413ea9a877 341 /* Initialize the MMC state */
ganlikun 0:13413ea9a877 342 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 343
ganlikun 0:13413ea9a877 344 return HAL_OK;
ganlikun 0:13413ea9a877 345 }
ganlikun 0:13413ea9a877 346
ganlikun 0:13413ea9a877 347 /**
ganlikun 0:13413ea9a877 348 * @brief Initializes the MMC Card.
ganlikun 0:13413ea9a877 349 * @param hmmc: Pointer to MMC handle
ganlikun 0:13413ea9a877 350 * @note This function initializes the MMC card. It could be used when a card
ganlikun 0:13413ea9a877 351 re-initialization is needed.
ganlikun 0:13413ea9a877 352 * @retval HAL status
ganlikun 0:13413ea9a877 353 */
ganlikun 0:13413ea9a877 354 HAL_StatusTypeDef HAL_MMC_InitCard(MMC_HandleTypeDef *hmmc)
ganlikun 0:13413ea9a877 355 {
ganlikun 0:13413ea9a877 356 uint32_t errorstate = HAL_MMC_ERROR_NONE;
ganlikun 0:13413ea9a877 357 MMC_InitTypeDef Init;
ganlikun 0:13413ea9a877 358
ganlikun 0:13413ea9a877 359 /* Default SDMMC peripheral configuration for MMC card initialization */
ganlikun 0:13413ea9a877 360 Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
ganlikun 0:13413ea9a877 361 Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
ganlikun 0:13413ea9a877 362 Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
ganlikun 0:13413ea9a877 363 Init.BusWide = SDIO_BUS_WIDE_1B;
ganlikun 0:13413ea9a877 364 Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
ganlikun 0:13413ea9a877 365 Init.ClockDiv = SDIO_INIT_CLK_DIV;
ganlikun 0:13413ea9a877 366
ganlikun 0:13413ea9a877 367 /* Initialize SDMMC peripheral interface with default configuration */
ganlikun 0:13413ea9a877 368 SDIO_Init(hmmc->Instance, Init);
ganlikun 0:13413ea9a877 369
ganlikun 0:13413ea9a877 370 /* Disable SDMMC Clock */
ganlikun 0:13413ea9a877 371 __HAL_MMC_DISABLE(hmmc);
ganlikun 0:13413ea9a877 372
ganlikun 0:13413ea9a877 373 /* Set Power State to ON */
ganlikun 0:13413ea9a877 374 SDIO_PowerState_ON(hmmc->Instance);
ganlikun 0:13413ea9a877 375
ganlikun 0:13413ea9a877 376 /* Enable SDMMC Clock */
ganlikun 0:13413ea9a877 377 __HAL_MMC_ENABLE(hmmc);
ganlikun 0:13413ea9a877 378
ganlikun 0:13413ea9a877 379 /* Required power up waiting time before starting the SD initialization
ganlikun 0:13413ea9a877 380 sequence */
ganlikun 0:13413ea9a877 381 HAL_Delay(2U);
ganlikun 0:13413ea9a877 382
ganlikun 0:13413ea9a877 383 /* Identify card operating voltage */
ganlikun 0:13413ea9a877 384 errorstate = MMC_PowerON(hmmc);
ganlikun 0:13413ea9a877 385 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 386 {
ganlikun 0:13413ea9a877 387 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 388 hmmc->ErrorCode |= errorstate;
ganlikun 0:13413ea9a877 389 return HAL_ERROR;
ganlikun 0:13413ea9a877 390 }
ganlikun 0:13413ea9a877 391
ganlikun 0:13413ea9a877 392 /* Card initialization */
ganlikun 0:13413ea9a877 393 errorstate = MMC_InitCard(hmmc);
ganlikun 0:13413ea9a877 394 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 395 {
ganlikun 0:13413ea9a877 396 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 397 hmmc->ErrorCode |= errorstate;
ganlikun 0:13413ea9a877 398 return HAL_ERROR;
ganlikun 0:13413ea9a877 399 }
ganlikun 0:13413ea9a877 400
ganlikun 0:13413ea9a877 401 return HAL_OK;
ganlikun 0:13413ea9a877 402 }
ganlikun 0:13413ea9a877 403
ganlikun 0:13413ea9a877 404 /**
ganlikun 0:13413ea9a877 405 * @brief De-Initializes the MMC card.
ganlikun 0:13413ea9a877 406 * @param hmmc: Pointer to MMC handle
ganlikun 0:13413ea9a877 407 * @retval HAL status
ganlikun 0:13413ea9a877 408 */
ganlikun 0:13413ea9a877 409 HAL_StatusTypeDef HAL_MMC_DeInit(MMC_HandleTypeDef *hmmc)
ganlikun 0:13413ea9a877 410 {
ganlikun 0:13413ea9a877 411 /* Check the MMC handle allocation */
ganlikun 0:13413ea9a877 412 if(hmmc == NULL)
ganlikun 0:13413ea9a877 413 {
ganlikun 0:13413ea9a877 414 return HAL_ERROR;
ganlikun 0:13413ea9a877 415 }
ganlikun 0:13413ea9a877 416
ganlikun 0:13413ea9a877 417 /* Check the parameters */
ganlikun 0:13413ea9a877 418 assert_param(IS_SDIO_ALL_INSTANCE(hmmc->Instance));
ganlikun 0:13413ea9a877 419
ganlikun 0:13413ea9a877 420 hmmc->State = HAL_MMC_STATE_BUSY;
ganlikun 0:13413ea9a877 421
ganlikun 0:13413ea9a877 422 /* Set SD power state to off */
ganlikun 0:13413ea9a877 423 MMC_PowerOFF(hmmc);
ganlikun 0:13413ea9a877 424
ganlikun 0:13413ea9a877 425 /* De-Initialize the MSP layer */
ganlikun 0:13413ea9a877 426 HAL_MMC_MspDeInit(hmmc);
ganlikun 0:13413ea9a877 427
ganlikun 0:13413ea9a877 428 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
ganlikun 0:13413ea9a877 429 hmmc->State = HAL_MMC_STATE_RESET;
ganlikun 0:13413ea9a877 430
ganlikun 0:13413ea9a877 431 return HAL_OK;
ganlikun 0:13413ea9a877 432 }
ganlikun 0:13413ea9a877 433
ganlikun 0:13413ea9a877 434
ganlikun 0:13413ea9a877 435 /**
ganlikun 0:13413ea9a877 436 * @brief Initializes the MMC MSP.
ganlikun 0:13413ea9a877 437 * @param hmmc: Pointer to MMC handle
ganlikun 0:13413ea9a877 438 * @retval None
ganlikun 0:13413ea9a877 439 */
ganlikun 0:13413ea9a877 440 __weak void HAL_MMC_MspInit(MMC_HandleTypeDef *hmmc)
ganlikun 0:13413ea9a877 441 {
ganlikun 0:13413ea9a877 442 /* Prevent unused argument(s) compilation warning */
ganlikun 0:13413ea9a877 443 UNUSED(hmmc);
ganlikun 0:13413ea9a877 444
ganlikun 0:13413ea9a877 445 /* NOTE : This function Should not be modified, when the callback is needed,
ganlikun 0:13413ea9a877 446 the HAL_MMC_MspInit could be implemented in the user file
ganlikun 0:13413ea9a877 447 */
ganlikun 0:13413ea9a877 448 }
ganlikun 0:13413ea9a877 449
ganlikun 0:13413ea9a877 450 /**
ganlikun 0:13413ea9a877 451 * @brief De-Initialize MMC MSP.
ganlikun 0:13413ea9a877 452 * @param hmmc: Pointer to MMC handle
ganlikun 0:13413ea9a877 453 * @retval None
ganlikun 0:13413ea9a877 454 */
ganlikun 0:13413ea9a877 455 __weak void HAL_MMC_MspDeInit(MMC_HandleTypeDef *hmmc)
ganlikun 0:13413ea9a877 456 {
ganlikun 0:13413ea9a877 457 /* Prevent unused argument(s) compilation warning */
ganlikun 0:13413ea9a877 458 UNUSED(hmmc);
ganlikun 0:13413ea9a877 459
ganlikun 0:13413ea9a877 460 /* NOTE : This function Should not be modified, when the callback is needed,
ganlikun 0:13413ea9a877 461 the HAL_MMC_MspDeInit could be implemented in the user file
ganlikun 0:13413ea9a877 462 */
ganlikun 0:13413ea9a877 463 }
ganlikun 0:13413ea9a877 464
ganlikun 0:13413ea9a877 465 /**
ganlikun 0:13413ea9a877 466 * @}
ganlikun 0:13413ea9a877 467 */
ganlikun 0:13413ea9a877 468
ganlikun 0:13413ea9a877 469 /** @addtogroup MMC_Exported_Functions_Group2
ganlikun 0:13413ea9a877 470 * @brief Data transfer functions
ganlikun 0:13413ea9a877 471 *
ganlikun 0:13413ea9a877 472 @verbatim
ganlikun 0:13413ea9a877 473 ==============================================================================
ganlikun 0:13413ea9a877 474 ##### IO operation functions #####
ganlikun 0:13413ea9a877 475 ==============================================================================
ganlikun 0:13413ea9a877 476 [..]
ganlikun 0:13413ea9a877 477 This subsection provides a set of functions allowing to manage the data
ganlikun 0:13413ea9a877 478 transfer from/to MMC card.
ganlikun 0:13413ea9a877 479
ganlikun 0:13413ea9a877 480 @endverbatim
ganlikun 0:13413ea9a877 481 * @{
ganlikun 0:13413ea9a877 482 */
ganlikun 0:13413ea9a877 483
ganlikun 0:13413ea9a877 484 /**
ganlikun 0:13413ea9a877 485 * @brief Reads block(s) from a specified address in a card. The Data transfer
ganlikun 0:13413ea9a877 486 * is managed by polling mode.
ganlikun 0:13413ea9a877 487 * @note This API should be followed by a check on the card state through
ganlikun 0:13413ea9a877 488 * HAL_MMC_GetCardState().
ganlikun 0:13413ea9a877 489 * @param hmmc: Pointer to MMC handle
ganlikun 0:13413ea9a877 490 * @param pData: pointer to the buffer that will contain the received data
ganlikun 0:13413ea9a877 491 * @param BlockAdd: Block Address from where data is to be read
ganlikun 0:13413ea9a877 492 * @param NumberOfBlocks: Number of MMC blocks to read
ganlikun 0:13413ea9a877 493 * @param Timeout: Specify timeout value
ganlikun 0:13413ea9a877 494 * @retval HAL status
ganlikun 0:13413ea9a877 495 */
ganlikun 0:13413ea9a877 496 HAL_StatusTypeDef HAL_MMC_ReadBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
ganlikun 0:13413ea9a877 497 {
ganlikun 0:13413ea9a877 498 SDIO_DataInitTypeDef config;
ganlikun 0:13413ea9a877 499 uint32_t errorstate = HAL_MMC_ERROR_NONE;
ganlikun 0:13413ea9a877 500 uint32_t tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 501 uint32_t count = 0U, *tempbuff = (uint32_t *)pData;
ganlikun 0:13413ea9a877 502
ganlikun 0:13413ea9a877 503 if(NULL == pData)
ganlikun 0:13413ea9a877 504 {
ganlikun 0:13413ea9a877 505 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
ganlikun 0:13413ea9a877 506 return HAL_ERROR;
ganlikun 0:13413ea9a877 507 }
ganlikun 0:13413ea9a877 508
ganlikun 0:13413ea9a877 509 if(hmmc->State == HAL_MMC_STATE_READY)
ganlikun 0:13413ea9a877 510 {
ganlikun 0:13413ea9a877 511 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
ganlikun 0:13413ea9a877 512
ganlikun 0:13413ea9a877 513 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
ganlikun 0:13413ea9a877 514 {
ganlikun 0:13413ea9a877 515 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
ganlikun 0:13413ea9a877 516 return HAL_ERROR;
ganlikun 0:13413ea9a877 517 }
ganlikun 0:13413ea9a877 518
ganlikun 0:13413ea9a877 519 hmmc->State = HAL_MMC_STATE_BUSY;
ganlikun 0:13413ea9a877 520
ganlikun 0:13413ea9a877 521 /* Initialize data control register */
ganlikun 0:13413ea9a877 522 hmmc->Instance->DCTRL = 0U;
ganlikun 0:13413ea9a877 523
ganlikun 0:13413ea9a877 524 /* Check the Card capacity in term of Logical number of blocks */
ganlikun 0:13413ea9a877 525 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
ganlikun 0:13413ea9a877 526 {
ganlikun 0:13413ea9a877 527 BlockAdd *= 512U;
ganlikun 0:13413ea9a877 528 }
ganlikun 0:13413ea9a877 529
ganlikun 0:13413ea9a877 530 /* Set Block Size for Card */
ganlikun 0:13413ea9a877 531 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
ganlikun 0:13413ea9a877 532 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 533 {
ganlikun 0:13413ea9a877 534 /* Clear all the static flags */
ganlikun 0:13413ea9a877 535 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
ganlikun 0:13413ea9a877 536 hmmc->ErrorCode |= errorstate;
ganlikun 0:13413ea9a877 537 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 538 return HAL_ERROR;
ganlikun 0:13413ea9a877 539 }
ganlikun 0:13413ea9a877 540
ganlikun 0:13413ea9a877 541 /* Configure the MMC DPSM (Data Path State Machine) */
ganlikun 0:13413ea9a877 542 config.DataTimeOut = SDMMC_DATATIMEOUT;
ganlikun 0:13413ea9a877 543 config.DataLength = NumberOfBlocks * BLOCKSIZE;
ganlikun 0:13413ea9a877 544 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
ganlikun 0:13413ea9a877 545 config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
ganlikun 0:13413ea9a877 546 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
ganlikun 0:13413ea9a877 547 config.DPSM = SDIO_DPSM_ENABLE;
ganlikun 0:13413ea9a877 548 SDIO_ConfigData(hmmc->Instance, &config);
ganlikun 0:13413ea9a877 549
ganlikun 0:13413ea9a877 550 /* Read block(s) in polling mode */
ganlikun 0:13413ea9a877 551 if(NumberOfBlocks > 1U)
ganlikun 0:13413ea9a877 552 {
ganlikun 0:13413ea9a877 553 hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
ganlikun 0:13413ea9a877 554
ganlikun 0:13413ea9a877 555 /* Read Multi Block command */
ganlikun 0:13413ea9a877 556 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, BlockAdd);
ganlikun 0:13413ea9a877 557 }
ganlikun 0:13413ea9a877 558 else
ganlikun 0:13413ea9a877 559 {
ganlikun 0:13413ea9a877 560 hmmc->Context = MMC_CONTEXT_READ_SINGLE_BLOCK;
ganlikun 0:13413ea9a877 561
ganlikun 0:13413ea9a877 562 /* Read Single Block command */
ganlikun 0:13413ea9a877 563 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, BlockAdd);
ganlikun 0:13413ea9a877 564 }
ganlikun 0:13413ea9a877 565 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 566 {
ganlikun 0:13413ea9a877 567 /* Clear all the static flags */
ganlikun 0:13413ea9a877 568 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
ganlikun 0:13413ea9a877 569 hmmc->ErrorCode |= errorstate;
ganlikun 0:13413ea9a877 570 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 571 return HAL_ERROR;
ganlikun 0:13413ea9a877 572 }
ganlikun 0:13413ea9a877 573
ganlikun 0:13413ea9a877 574 /* Poll on SDMMC flags */
ganlikun 0:13413ea9a877 575 #ifdef SDIO_STA_STBITERR
ganlikun 0:13413ea9a877 576 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_STA_STBITERR))
ganlikun 0:13413ea9a877 577 #else /* SDIO_STA_STBITERR not defined */
ganlikun 0:13413ea9a877 578 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND))
ganlikun 0:13413ea9a877 579 #endif /* SDIO_STA_STBITERR */
ganlikun 0:13413ea9a877 580 {
ganlikun 0:13413ea9a877 581 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXFIFOHF))
ganlikun 0:13413ea9a877 582 {
ganlikun 0:13413ea9a877 583 /* Read data from SDMMC Rx FIFO */
ganlikun 0:13413ea9a877 584 for(count = 0U; count < 8U; count++)
ganlikun 0:13413ea9a877 585 {
ganlikun 0:13413ea9a877 586 *(tempbuff + count) = SDIO_ReadFIFO(hmmc->Instance);
ganlikun 0:13413ea9a877 587 }
ganlikun 0:13413ea9a877 588 tempbuff += 8U;
ganlikun 0:13413ea9a877 589 }
ganlikun 0:13413ea9a877 590
ganlikun 0:13413ea9a877 591 if((Timeout == 0U)||((HAL_GetTick()-tickstart) >= Timeout))
ganlikun 0:13413ea9a877 592 {
ganlikun 0:13413ea9a877 593 /* Clear all the static flags */
ganlikun 0:13413ea9a877 594 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
ganlikun 0:13413ea9a877 595 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
ganlikun 0:13413ea9a877 596 hmmc->State= HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 597 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 598 }
ganlikun 0:13413ea9a877 599 }
ganlikun 0:13413ea9a877 600
ganlikun 0:13413ea9a877 601 /* Send stop transmission command in case of multiblock read */
ganlikun 0:13413ea9a877 602 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1U))
ganlikun 0:13413ea9a877 603 {
ganlikun 0:13413ea9a877 604 /* Send stop transmission command */
ganlikun 0:13413ea9a877 605 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
ganlikun 0:13413ea9a877 606 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 607 {
ganlikun 0:13413ea9a877 608 /* Clear all the static flags */
ganlikun 0:13413ea9a877 609 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
ganlikun 0:13413ea9a877 610 hmmc->ErrorCode |= errorstate;
ganlikun 0:13413ea9a877 611 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 612 return HAL_ERROR;
ganlikun 0:13413ea9a877 613 }
ganlikun 0:13413ea9a877 614 }
ganlikun 0:13413ea9a877 615
ganlikun 0:13413ea9a877 616 /* Get error state */
ganlikun 0:13413ea9a877 617 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DTIMEOUT))
ganlikun 0:13413ea9a877 618 {
ganlikun 0:13413ea9a877 619 /* Clear all the static flags */
ganlikun 0:13413ea9a877 620 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
ganlikun 0:13413ea9a877 621 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
ganlikun 0:13413ea9a877 622 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 623 return HAL_ERROR;
ganlikun 0:13413ea9a877 624 }
ganlikun 0:13413ea9a877 625 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL))
ganlikun 0:13413ea9a877 626 {
ganlikun 0:13413ea9a877 627 /* Clear all the static flags */
ganlikun 0:13413ea9a877 628 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
ganlikun 0:13413ea9a877 629 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
ganlikun 0:13413ea9a877 630 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 631 return HAL_ERROR;
ganlikun 0:13413ea9a877 632 }
ganlikun 0:13413ea9a877 633 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR))
ganlikun 0:13413ea9a877 634 {
ganlikun 0:13413ea9a877 635 /* Clear all the static flags */
ganlikun 0:13413ea9a877 636 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
ganlikun 0:13413ea9a877 637 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
ganlikun 0:13413ea9a877 638 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 639 return HAL_ERROR;
ganlikun 0:13413ea9a877 640 }
ganlikun 0:13413ea9a877 641
ganlikun 0:13413ea9a877 642 /* Empty FIFO if there is still any data */
ganlikun 0:13413ea9a877 643 while ((__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXDAVL)))
ganlikun 0:13413ea9a877 644 {
ganlikun 0:13413ea9a877 645 *tempbuff = SDIO_ReadFIFO(hmmc->Instance);
ganlikun 0:13413ea9a877 646 tempbuff++;
ganlikun 0:13413ea9a877 647
ganlikun 0:13413ea9a877 648 if((Timeout == 0U)||((HAL_GetTick()-tickstart) >= Timeout))
ganlikun 0:13413ea9a877 649 {
ganlikun 0:13413ea9a877 650 /* Clear all the static flags */
ganlikun 0:13413ea9a877 651 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
ganlikun 0:13413ea9a877 652 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
ganlikun 0:13413ea9a877 653 hmmc->State= HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 654 return HAL_ERROR;
ganlikun 0:13413ea9a877 655 }
ganlikun 0:13413ea9a877 656 }
ganlikun 0:13413ea9a877 657
ganlikun 0:13413ea9a877 658 /* Clear all the static flags */
ganlikun 0:13413ea9a877 659 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
ganlikun 0:13413ea9a877 660
ganlikun 0:13413ea9a877 661 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 662
ganlikun 0:13413ea9a877 663 return HAL_OK;
ganlikun 0:13413ea9a877 664 }
ganlikun 0:13413ea9a877 665 else
ganlikun 0:13413ea9a877 666 {
ganlikun 0:13413ea9a877 667 hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
ganlikun 0:13413ea9a877 668 return HAL_ERROR;
ganlikun 0:13413ea9a877 669 }
ganlikun 0:13413ea9a877 670 }
ganlikun 0:13413ea9a877 671
ganlikun 0:13413ea9a877 672 /**
ganlikun 0:13413ea9a877 673 * @brief Allows to write block(s) to a specified address in a card. The Data
ganlikun 0:13413ea9a877 674 * transfer is managed by polling mode.
ganlikun 0:13413ea9a877 675 * @note This API should be followed by a check on the card state through
ganlikun 0:13413ea9a877 676 * HAL_MMC_GetCardState().
ganlikun 0:13413ea9a877 677 * @param hmmc: Pointer to MMC handle
ganlikun 0:13413ea9a877 678 * @param pData: pointer to the buffer that will contain the data to transmit
ganlikun 0:13413ea9a877 679 * @param BlockAdd: Block Address where data will be written
ganlikun 0:13413ea9a877 680 * @param NumberOfBlocks: Number of MMC blocks to write
ganlikun 0:13413ea9a877 681 * @param Timeout: Specify timeout value
ganlikun 0:13413ea9a877 682 * @retval HAL status
ganlikun 0:13413ea9a877 683 */
ganlikun 0:13413ea9a877 684 HAL_StatusTypeDef HAL_MMC_WriteBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
ganlikun 0:13413ea9a877 685 {
ganlikun 0:13413ea9a877 686 SDIO_DataInitTypeDef config;
ganlikun 0:13413ea9a877 687 uint32_t errorstate = HAL_MMC_ERROR_NONE;
ganlikun 0:13413ea9a877 688 uint32_t tickstart = HAL_GetTick();
ganlikun 0:13413ea9a877 689 uint32_t count = 0U;
ganlikun 0:13413ea9a877 690 uint32_t *tempbuff = (uint32_t *)pData;
ganlikun 0:13413ea9a877 691
ganlikun 0:13413ea9a877 692 if(NULL == pData)
ganlikun 0:13413ea9a877 693 {
ganlikun 0:13413ea9a877 694 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
ganlikun 0:13413ea9a877 695 return HAL_ERROR;
ganlikun 0:13413ea9a877 696 }
ganlikun 0:13413ea9a877 697
ganlikun 0:13413ea9a877 698 if(hmmc->State == HAL_MMC_STATE_READY)
ganlikun 0:13413ea9a877 699 {
ganlikun 0:13413ea9a877 700 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
ganlikun 0:13413ea9a877 701
ganlikun 0:13413ea9a877 702 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
ganlikun 0:13413ea9a877 703 {
ganlikun 0:13413ea9a877 704 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
ganlikun 0:13413ea9a877 705 return HAL_ERROR;
ganlikun 0:13413ea9a877 706 }
ganlikun 0:13413ea9a877 707
ganlikun 0:13413ea9a877 708 hmmc->State = HAL_MMC_STATE_BUSY;
ganlikun 0:13413ea9a877 709
ganlikun 0:13413ea9a877 710 /* Initialize data control register */
ganlikun 0:13413ea9a877 711 hmmc->Instance->DCTRL = 0U;
ganlikun 0:13413ea9a877 712
ganlikun 0:13413ea9a877 713 /* Check the Card capacity in term of Logical number of blocks */
ganlikun 0:13413ea9a877 714 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
ganlikun 0:13413ea9a877 715 {
ganlikun 0:13413ea9a877 716 BlockAdd *= 512U;
ganlikun 0:13413ea9a877 717 }
ganlikun 0:13413ea9a877 718
ganlikun 0:13413ea9a877 719 /* Set Block Size for Card */
ganlikun 0:13413ea9a877 720 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
ganlikun 0:13413ea9a877 721 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 722 {
ganlikun 0:13413ea9a877 723 /* Clear all the static flags */
ganlikun 0:13413ea9a877 724 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
ganlikun 0:13413ea9a877 725 hmmc->ErrorCode |= errorstate;
ganlikun 0:13413ea9a877 726 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 727 return HAL_ERROR;
ganlikun 0:13413ea9a877 728 }
ganlikun 0:13413ea9a877 729
ganlikun 0:13413ea9a877 730 /* Write Blocks in Polling mode */
ganlikun 0:13413ea9a877 731 if(NumberOfBlocks > 1U)
ganlikun 0:13413ea9a877 732 {
ganlikun 0:13413ea9a877 733 hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
ganlikun 0:13413ea9a877 734
ganlikun 0:13413ea9a877 735 /* Write Multi Block command */
ganlikun 0:13413ea9a877 736 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, BlockAdd);
ganlikun 0:13413ea9a877 737 }
ganlikun 0:13413ea9a877 738 else
ganlikun 0:13413ea9a877 739 {
ganlikun 0:13413ea9a877 740 hmmc->Context = MMC_CONTEXT_WRITE_SINGLE_BLOCK;
ganlikun 0:13413ea9a877 741
ganlikun 0:13413ea9a877 742 /* Write Single Block command */
ganlikun 0:13413ea9a877 743 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, BlockAdd);
ganlikun 0:13413ea9a877 744 }
ganlikun 0:13413ea9a877 745 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 746 {
ganlikun 0:13413ea9a877 747 /* Clear all the static flags */
ganlikun 0:13413ea9a877 748 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
ganlikun 0:13413ea9a877 749 hmmc->ErrorCode |= errorstate;
ganlikun 0:13413ea9a877 750 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 751 return HAL_ERROR;
ganlikun 0:13413ea9a877 752 }
ganlikun 0:13413ea9a877 753
ganlikun 0:13413ea9a877 754 /* Configure the MMC DPSM (Data Path State Machine) */
ganlikun 0:13413ea9a877 755 config.DataTimeOut = SDMMC_DATATIMEOUT;
ganlikun 0:13413ea9a877 756 config.DataLength = NumberOfBlocks * BLOCKSIZE;
ganlikun 0:13413ea9a877 757 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
ganlikun 0:13413ea9a877 758 config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
ganlikun 0:13413ea9a877 759 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
ganlikun 0:13413ea9a877 760 config.DPSM = SDIO_DPSM_ENABLE;
ganlikun 0:13413ea9a877 761 SDIO_ConfigData(hmmc->Instance, &config);
ganlikun 0:13413ea9a877 762
ganlikun 0:13413ea9a877 763 /* Write block(s) in polling mode */
ganlikun 0:13413ea9a877 764 #ifdef SDIO_STA_STBITERR
ganlikun 0:13413ea9a877 765 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_FLAG_STBITERR))
ganlikun 0:13413ea9a877 766 #else /* SDIO_STA_STBITERR not defined */
ganlikun 0:13413ea9a877 767 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND))
ganlikun 0:13413ea9a877 768 #endif /* SDIO_STA_STBITERR */
ganlikun 0:13413ea9a877 769 {
ganlikun 0:13413ea9a877 770 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXFIFOHE))
ganlikun 0:13413ea9a877 771 {
ganlikun 0:13413ea9a877 772 /* Write data to SDIO Tx FIFO */
ganlikun 0:13413ea9a877 773 for(count = 0U; count < 8U; count++)
ganlikun 0:13413ea9a877 774 {
ganlikun 0:13413ea9a877 775 SDIO_WriteFIFO(hmmc->Instance, (tempbuff + count));
ganlikun 0:13413ea9a877 776 }
ganlikun 0:13413ea9a877 777 tempbuff += 8U;
ganlikun 0:13413ea9a877 778 }
ganlikun 0:13413ea9a877 779
ganlikun 0:13413ea9a877 780 if((Timeout == 0U)||((HAL_GetTick()-tickstart) >= Timeout))
ganlikun 0:13413ea9a877 781 {
ganlikun 0:13413ea9a877 782 /* Clear all the static flags */
ganlikun 0:13413ea9a877 783 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
ganlikun 0:13413ea9a877 784 hmmc->ErrorCode |= errorstate;
ganlikun 0:13413ea9a877 785 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 786 return HAL_TIMEOUT;
ganlikun 0:13413ea9a877 787 }
ganlikun 0:13413ea9a877 788 }
ganlikun 0:13413ea9a877 789
ganlikun 0:13413ea9a877 790 /* Send stop transmission command in case of multiblock write */
ganlikun 0:13413ea9a877 791 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1U))
ganlikun 0:13413ea9a877 792 {
ganlikun 0:13413ea9a877 793 /* Send stop transmission command */
ganlikun 0:13413ea9a877 794 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
ganlikun 0:13413ea9a877 795 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 796 {
ganlikun 0:13413ea9a877 797 /* Clear all the static flags */
ganlikun 0:13413ea9a877 798 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
ganlikun 0:13413ea9a877 799 hmmc->ErrorCode |= errorstate;
ganlikun 0:13413ea9a877 800 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 801 return HAL_ERROR;
ganlikun 0:13413ea9a877 802 }
ganlikun 0:13413ea9a877 803 }
ganlikun 0:13413ea9a877 804
ganlikun 0:13413ea9a877 805 /* Get error state */
ganlikun 0:13413ea9a877 806 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DTIMEOUT))
ganlikun 0:13413ea9a877 807 {
ganlikun 0:13413ea9a877 808 /* Clear all the static flags */
ganlikun 0:13413ea9a877 809 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
ganlikun 0:13413ea9a877 810 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
ganlikun 0:13413ea9a877 811 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 812 return HAL_ERROR;
ganlikun 0:13413ea9a877 813 }
ganlikun 0:13413ea9a877 814 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL))
ganlikun 0:13413ea9a877 815 {
ganlikun 0:13413ea9a877 816 /* Clear all the static flags */
ganlikun 0:13413ea9a877 817 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
ganlikun 0:13413ea9a877 818 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
ganlikun 0:13413ea9a877 819 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 820 return HAL_ERROR;
ganlikun 0:13413ea9a877 821 }
ganlikun 0:13413ea9a877 822 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR))
ganlikun 0:13413ea9a877 823 {
ganlikun 0:13413ea9a877 824 /* Clear all the static flags */
ganlikun 0:13413ea9a877 825 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
ganlikun 0:13413ea9a877 826 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
ganlikun 0:13413ea9a877 827 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 828 return HAL_ERROR;
ganlikun 0:13413ea9a877 829 }
ganlikun 0:13413ea9a877 830
ganlikun 0:13413ea9a877 831 /* Clear all the static flags */
ganlikun 0:13413ea9a877 832 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
ganlikun 0:13413ea9a877 833
ganlikun 0:13413ea9a877 834 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 835
ganlikun 0:13413ea9a877 836 return HAL_OK;
ganlikun 0:13413ea9a877 837 }
ganlikun 0:13413ea9a877 838 else
ganlikun 0:13413ea9a877 839 {
ganlikun 0:13413ea9a877 840 hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
ganlikun 0:13413ea9a877 841 return HAL_ERROR;
ganlikun 0:13413ea9a877 842 }
ganlikun 0:13413ea9a877 843 }
ganlikun 0:13413ea9a877 844
ganlikun 0:13413ea9a877 845 /**
ganlikun 0:13413ea9a877 846 * @brief Reads block(s) from a specified address in a card. The Data transfer
ganlikun 0:13413ea9a877 847 * is managed in interrupt mode.
ganlikun 0:13413ea9a877 848 * @note This API should be followed by a check on the card state through
ganlikun 0:13413ea9a877 849 * HAL_MMC_GetCardState().
ganlikun 0:13413ea9a877 850 * @note You could also check the IT transfer process through the MMC Rx
ganlikun 0:13413ea9a877 851 * interrupt event.
ganlikun 0:13413ea9a877 852 * @param hmmc: Pointer to MMC handle
ganlikun 0:13413ea9a877 853 * @param pData: Pointer to the buffer that will contain the received data
ganlikun 0:13413ea9a877 854 * @param BlockAdd: Block Address from where data is to be read
ganlikun 0:13413ea9a877 855 * @param NumberOfBlocks: Number of blocks to read.
ganlikun 0:13413ea9a877 856 * @retval HAL status
ganlikun 0:13413ea9a877 857 */
ganlikun 0:13413ea9a877 858 HAL_StatusTypeDef HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
ganlikun 0:13413ea9a877 859 {
ganlikun 0:13413ea9a877 860 SDIO_DataInitTypeDef config;
ganlikun 0:13413ea9a877 861 uint32_t errorstate = HAL_MMC_ERROR_NONE;
ganlikun 0:13413ea9a877 862
ganlikun 0:13413ea9a877 863 if(NULL == pData)
ganlikun 0:13413ea9a877 864 {
ganlikun 0:13413ea9a877 865 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
ganlikun 0:13413ea9a877 866 return HAL_ERROR;
ganlikun 0:13413ea9a877 867 }
ganlikun 0:13413ea9a877 868
ganlikun 0:13413ea9a877 869 if(hmmc->State == HAL_MMC_STATE_READY)
ganlikun 0:13413ea9a877 870 {
ganlikun 0:13413ea9a877 871 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
ganlikun 0:13413ea9a877 872
ganlikun 0:13413ea9a877 873 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
ganlikun 0:13413ea9a877 874 {
ganlikun 0:13413ea9a877 875 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
ganlikun 0:13413ea9a877 876 return HAL_ERROR;
ganlikun 0:13413ea9a877 877 }
ganlikun 0:13413ea9a877 878
ganlikun 0:13413ea9a877 879 hmmc->State = HAL_MMC_STATE_BUSY;
ganlikun 0:13413ea9a877 880
ganlikun 0:13413ea9a877 881 /* Initialize data control register */
ganlikun 0:13413ea9a877 882 hmmc->Instance->DCTRL = 0U;
ganlikun 0:13413ea9a877 883
ganlikun 0:13413ea9a877 884 hmmc->pRxBuffPtr = (uint32_t *)pData;
ganlikun 0:13413ea9a877 885 hmmc->RxXferSize = BLOCKSIZE * NumberOfBlocks;
ganlikun 0:13413ea9a877 886
ganlikun 0:13413ea9a877 887 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_FLAG_RXFIFOHF));
ganlikun 0:13413ea9a877 888
ganlikun 0:13413ea9a877 889 /* Check the Card capacity in term of Logical number of blocks */
ganlikun 0:13413ea9a877 890 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
ganlikun 0:13413ea9a877 891 {
ganlikun 0:13413ea9a877 892 BlockAdd *= 512U;
ganlikun 0:13413ea9a877 893 }
ganlikun 0:13413ea9a877 894
ganlikun 0:13413ea9a877 895 /* Configure the MMC DPSM (Data Path State Machine) */
ganlikun 0:13413ea9a877 896 config.DataTimeOut = SDMMC_DATATIMEOUT;
ganlikun 0:13413ea9a877 897 config.DataLength = BLOCKSIZE * NumberOfBlocks;
ganlikun 0:13413ea9a877 898 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
ganlikun 0:13413ea9a877 899 config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
ganlikun 0:13413ea9a877 900 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
ganlikun 0:13413ea9a877 901 config.DPSM = SDIO_DPSM_ENABLE;
ganlikun 0:13413ea9a877 902 SDIO_ConfigData(hmmc->Instance, &config);
ganlikun 0:13413ea9a877 903
ganlikun 0:13413ea9a877 904 /* Set Block Size for Card */
ganlikun 0:13413ea9a877 905 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
ganlikun 0:13413ea9a877 906 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 907 {
ganlikun 0:13413ea9a877 908 /* Clear all the static flags */
ganlikun 0:13413ea9a877 909 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
ganlikun 0:13413ea9a877 910 hmmc->ErrorCode |= errorstate;
ganlikun 0:13413ea9a877 911 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 912 return HAL_ERROR;
ganlikun 0:13413ea9a877 913 }
ganlikun 0:13413ea9a877 914
ganlikun 0:13413ea9a877 915 /* Read Blocks in IT mode */
ganlikun 0:13413ea9a877 916 if(NumberOfBlocks > 1U)
ganlikun 0:13413ea9a877 917 {
ganlikun 0:13413ea9a877 918 hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_IT);
ganlikun 0:13413ea9a877 919
ganlikun 0:13413ea9a877 920 /* Read Multi Block command */
ganlikun 0:13413ea9a877 921 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, BlockAdd);
ganlikun 0:13413ea9a877 922 }
ganlikun 0:13413ea9a877 923 else
ganlikun 0:13413ea9a877 924 {
ganlikun 0:13413ea9a877 925 hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_IT);
ganlikun 0:13413ea9a877 926
ganlikun 0:13413ea9a877 927 /* Read Single Block command */
ganlikun 0:13413ea9a877 928 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, BlockAdd);
ganlikun 0:13413ea9a877 929 }
ganlikun 0:13413ea9a877 930 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 931 {
ganlikun 0:13413ea9a877 932 /* Clear all the static flags */
ganlikun 0:13413ea9a877 933 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
ganlikun 0:13413ea9a877 934 hmmc->ErrorCode |= errorstate;
ganlikun 0:13413ea9a877 935 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 936 return HAL_ERROR;
ganlikun 0:13413ea9a877 937 }
ganlikun 0:13413ea9a877 938
ganlikun 0:13413ea9a877 939 return HAL_OK;
ganlikun 0:13413ea9a877 940 }
ganlikun 0:13413ea9a877 941 else
ganlikun 0:13413ea9a877 942 {
ganlikun 0:13413ea9a877 943 return HAL_BUSY;
ganlikun 0:13413ea9a877 944 }
ganlikun 0:13413ea9a877 945 }
ganlikun 0:13413ea9a877 946
ganlikun 0:13413ea9a877 947 /**
ganlikun 0:13413ea9a877 948 * @brief Writes block(s) to a specified address in a card. The Data transfer
ganlikun 0:13413ea9a877 949 * is managed in interrupt mode.
ganlikun 0:13413ea9a877 950 * @note This API should be followed by a check on the card state through
ganlikun 0:13413ea9a877 951 * HAL_MMC_GetCardState().
ganlikun 0:13413ea9a877 952 * @note You could also check the IT transfer process through the MMC Tx
ganlikun 0:13413ea9a877 953 * interrupt event.
ganlikun 0:13413ea9a877 954 * @param hmmc: Pointer to MMC handle
ganlikun 0:13413ea9a877 955 * @param pData: Pointer to the buffer that will contain the data to transmit
ganlikun 0:13413ea9a877 956 * @param BlockAdd: Block Address where data will be written
ganlikun 0:13413ea9a877 957 * @param NumberOfBlocks: Number of blocks to write
ganlikun 0:13413ea9a877 958 * @retval HAL status
ganlikun 0:13413ea9a877 959 */
ganlikun 0:13413ea9a877 960 HAL_StatusTypeDef HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
ganlikun 0:13413ea9a877 961 {
ganlikun 0:13413ea9a877 962 SDIO_DataInitTypeDef config;
ganlikun 0:13413ea9a877 963 uint32_t errorstate = HAL_MMC_ERROR_NONE;
ganlikun 0:13413ea9a877 964
ganlikun 0:13413ea9a877 965 if(NULL == pData)
ganlikun 0:13413ea9a877 966 {
ganlikun 0:13413ea9a877 967 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
ganlikun 0:13413ea9a877 968 return HAL_ERROR;
ganlikun 0:13413ea9a877 969 }
ganlikun 0:13413ea9a877 970
ganlikun 0:13413ea9a877 971 if(hmmc->State == HAL_MMC_STATE_READY)
ganlikun 0:13413ea9a877 972 {
ganlikun 0:13413ea9a877 973 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
ganlikun 0:13413ea9a877 974
ganlikun 0:13413ea9a877 975 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
ganlikun 0:13413ea9a877 976 {
ganlikun 0:13413ea9a877 977 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
ganlikun 0:13413ea9a877 978 return HAL_ERROR;
ganlikun 0:13413ea9a877 979 }
ganlikun 0:13413ea9a877 980
ganlikun 0:13413ea9a877 981 hmmc->State = HAL_MMC_STATE_BUSY;
ganlikun 0:13413ea9a877 982
ganlikun 0:13413ea9a877 983 /* Initialize data control register */
ganlikun 0:13413ea9a877 984 hmmc->Instance->DCTRL = 0U;
ganlikun 0:13413ea9a877 985
ganlikun 0:13413ea9a877 986 hmmc->pTxBuffPtr = (uint32_t *)pData;
ganlikun 0:13413ea9a877 987 hmmc->TxXferSize = BLOCKSIZE * NumberOfBlocks;
ganlikun 0:13413ea9a877 988
ganlikun 0:13413ea9a877 989 /* Enable transfer interrupts */
ganlikun 0:13413ea9a877 990 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_DATAEND | SDIO_FLAG_TXFIFOHE));
ganlikun 0:13413ea9a877 991
ganlikun 0:13413ea9a877 992 /* Check the Card capacity in term of Logical number of blocks */
ganlikun 0:13413ea9a877 993 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
ganlikun 0:13413ea9a877 994 {
ganlikun 0:13413ea9a877 995 BlockAdd *= 512U;
ganlikun 0:13413ea9a877 996 }
ganlikun 0:13413ea9a877 997
ganlikun 0:13413ea9a877 998 /* Set Block Size for Card */
ganlikun 0:13413ea9a877 999 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
ganlikun 0:13413ea9a877 1000 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 1001 {
ganlikun 0:13413ea9a877 1002 /* Clear all the static flags */
ganlikun 0:13413ea9a877 1003 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
ganlikun 0:13413ea9a877 1004 hmmc->ErrorCode |= errorstate;
ganlikun 0:13413ea9a877 1005 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 1006 return HAL_ERROR;
ganlikun 0:13413ea9a877 1007 }
ganlikun 0:13413ea9a877 1008
ganlikun 0:13413ea9a877 1009 /* Write Blocks in Polling mode */
ganlikun 0:13413ea9a877 1010 if(NumberOfBlocks > 1U)
ganlikun 0:13413ea9a877 1011 {
ganlikun 0:13413ea9a877 1012 hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK| MMC_CONTEXT_IT);
ganlikun 0:13413ea9a877 1013
ganlikun 0:13413ea9a877 1014 /* Write Multi Block command */
ganlikun 0:13413ea9a877 1015 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, BlockAdd);
ganlikun 0:13413ea9a877 1016 }
ganlikun 0:13413ea9a877 1017 else
ganlikun 0:13413ea9a877 1018 {
ganlikun 0:13413ea9a877 1019 hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_IT);
ganlikun 0:13413ea9a877 1020
ganlikun 0:13413ea9a877 1021 /* Write Single Block command */
ganlikun 0:13413ea9a877 1022 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, BlockAdd);
ganlikun 0:13413ea9a877 1023 }
ganlikun 0:13413ea9a877 1024 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 1025 {
ganlikun 0:13413ea9a877 1026 /* Clear all the static flags */
ganlikun 0:13413ea9a877 1027 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
ganlikun 0:13413ea9a877 1028 hmmc->ErrorCode |= errorstate;
ganlikun 0:13413ea9a877 1029 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 1030 return HAL_ERROR;
ganlikun 0:13413ea9a877 1031 }
ganlikun 0:13413ea9a877 1032
ganlikun 0:13413ea9a877 1033 /* Configure the MMC DPSM (Data Path State Machine) */
ganlikun 0:13413ea9a877 1034 config.DataTimeOut = SDMMC_DATATIMEOUT;
ganlikun 0:13413ea9a877 1035 config.DataLength = BLOCKSIZE * NumberOfBlocks;
ganlikun 0:13413ea9a877 1036 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
ganlikun 0:13413ea9a877 1037 config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
ganlikun 0:13413ea9a877 1038 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
ganlikun 0:13413ea9a877 1039 config.DPSM = SDIO_DPSM_ENABLE;
ganlikun 0:13413ea9a877 1040 SDIO_ConfigData(hmmc->Instance, &config);
ganlikun 0:13413ea9a877 1041
ganlikun 0:13413ea9a877 1042 return HAL_OK;
ganlikun 0:13413ea9a877 1043 }
ganlikun 0:13413ea9a877 1044 else
ganlikun 0:13413ea9a877 1045 {
ganlikun 0:13413ea9a877 1046 return HAL_BUSY;
ganlikun 0:13413ea9a877 1047 }
ganlikun 0:13413ea9a877 1048 }
ganlikun 0:13413ea9a877 1049
ganlikun 0:13413ea9a877 1050 /**
ganlikun 0:13413ea9a877 1051 * @brief Reads block(s) from a specified address in a card. The Data transfer
ganlikun 0:13413ea9a877 1052 * is managed by DMA mode.
ganlikun 0:13413ea9a877 1053 * @note This API should be followed by a check on the card state through
ganlikun 0:13413ea9a877 1054 * HAL_MMC_GetCardState().
ganlikun 0:13413ea9a877 1055 * @note You could also check the DMA transfer process through the MMC Rx
ganlikun 0:13413ea9a877 1056 * interrupt event.
ganlikun 0:13413ea9a877 1057 * @param hmmc: Pointer MMC handle
ganlikun 0:13413ea9a877 1058 * @param pData: Pointer to the buffer that will contain the received data
ganlikun 0:13413ea9a877 1059 * @param BlockAdd: Block Address from where data is to be read
ganlikun 0:13413ea9a877 1060 * @param NumberOfBlocks: Number of blocks to read.
ganlikun 0:13413ea9a877 1061 * @retval HAL status
ganlikun 0:13413ea9a877 1062 */
ganlikun 0:13413ea9a877 1063 HAL_StatusTypeDef HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
ganlikun 0:13413ea9a877 1064 {
ganlikun 0:13413ea9a877 1065 SDIO_DataInitTypeDef config;
ganlikun 0:13413ea9a877 1066 uint32_t errorstate = HAL_MMC_ERROR_NONE;
ganlikun 0:13413ea9a877 1067
ganlikun 0:13413ea9a877 1068 if(NULL == pData)
ganlikun 0:13413ea9a877 1069 {
ganlikun 0:13413ea9a877 1070 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
ganlikun 0:13413ea9a877 1071 return HAL_ERROR;
ganlikun 0:13413ea9a877 1072 }
ganlikun 0:13413ea9a877 1073
ganlikun 0:13413ea9a877 1074 if(hmmc->State == HAL_MMC_STATE_READY)
ganlikun 0:13413ea9a877 1075 {
ganlikun 0:13413ea9a877 1076 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
ganlikun 0:13413ea9a877 1077
ganlikun 0:13413ea9a877 1078 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
ganlikun 0:13413ea9a877 1079 {
ganlikun 0:13413ea9a877 1080 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
ganlikun 0:13413ea9a877 1081 return HAL_ERROR;
ganlikun 0:13413ea9a877 1082 }
ganlikun 0:13413ea9a877 1083
ganlikun 0:13413ea9a877 1084 hmmc->State = HAL_MMC_STATE_BUSY;
ganlikun 0:13413ea9a877 1085
ganlikun 0:13413ea9a877 1086 /* Initialize data control register */
ganlikun 0:13413ea9a877 1087 hmmc->Instance->DCTRL = 0U;
ganlikun 0:13413ea9a877 1088
ganlikun 0:13413ea9a877 1089 #ifdef SDIO_STA_STBITER
ganlikun 0:13413ea9a877 1090 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_IT_STBITERR));
ganlikun 0:13413ea9a877 1091 #else /* SDIO_STA_STBITERR not defined */
ganlikun 0:13413ea9a877 1092 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND));
ganlikun 0:13413ea9a877 1093 #endif /* SDIO_STA_STBITERR */
ganlikun 0:13413ea9a877 1094
ganlikun 0:13413ea9a877 1095 /* Set the DMA transfer complete callback */
ganlikun 0:13413ea9a877 1096 hmmc->hdmarx->XferCpltCallback = MMC_DMAReceiveCplt;
ganlikun 0:13413ea9a877 1097
ganlikun 0:13413ea9a877 1098 /* Set the DMA error callback */
ganlikun 0:13413ea9a877 1099 hmmc->hdmarx->XferErrorCallback = MMC_DMAError;
ganlikun 0:13413ea9a877 1100
ganlikun 0:13413ea9a877 1101 /* Set the DMA Abort callback */
ganlikun 0:13413ea9a877 1102 hmmc->hdmarx->XferAbortCallback = NULL;
ganlikun 0:13413ea9a877 1103
ganlikun 0:13413ea9a877 1104 /* Enable the DMA Channel */
ganlikun 0:13413ea9a877 1105 HAL_DMA_Start_IT(hmmc->hdmarx, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)pData, (uint32_t)(BLOCKSIZE * NumberOfBlocks)/4);
ganlikun 0:13413ea9a877 1106
ganlikun 0:13413ea9a877 1107 /* Enable MMC DMA transfer */
ganlikun 0:13413ea9a877 1108 __HAL_MMC_DMA_ENABLE(hmmc);
ganlikun 0:13413ea9a877 1109
ganlikun 0:13413ea9a877 1110 /* Check the Card capacity in term of Logical number of blocks */
ganlikun 0:13413ea9a877 1111 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
ganlikun 0:13413ea9a877 1112 {
ganlikun 0:13413ea9a877 1113 BlockAdd *= 512U;
ganlikun 0:13413ea9a877 1114 }
ganlikun 0:13413ea9a877 1115
ganlikun 0:13413ea9a877 1116 /* Configure the MMC DPSM (Data Path State Machine) */
ganlikun 0:13413ea9a877 1117 config.DataTimeOut = SDMMC_DATATIMEOUT;
ganlikun 0:13413ea9a877 1118 config.DataLength = BLOCKSIZE * NumberOfBlocks;
ganlikun 0:13413ea9a877 1119 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
ganlikun 0:13413ea9a877 1120 config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
ganlikun 0:13413ea9a877 1121 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
ganlikun 0:13413ea9a877 1122 config.DPSM = SDIO_DPSM_ENABLE;
ganlikun 0:13413ea9a877 1123 SDIO_ConfigData(hmmc->Instance, &config);
ganlikun 0:13413ea9a877 1124
ganlikun 0:13413ea9a877 1125 /* Set Block Size for Card */
ganlikun 0:13413ea9a877 1126 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
ganlikun 0:13413ea9a877 1127 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 1128 {
ganlikun 0:13413ea9a877 1129 /* Clear all the static flags */
ganlikun 0:13413ea9a877 1130 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
ganlikun 0:13413ea9a877 1131 hmmc->ErrorCode |= errorstate;
ganlikun 0:13413ea9a877 1132 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 1133 return HAL_ERROR;
ganlikun 0:13413ea9a877 1134 }
ganlikun 0:13413ea9a877 1135
ganlikun 0:13413ea9a877 1136 /* Read Blocks in DMA mode */
ganlikun 0:13413ea9a877 1137 if(NumberOfBlocks > 1U)
ganlikun 0:13413ea9a877 1138 {
ganlikun 0:13413ea9a877 1139 hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
ganlikun 0:13413ea9a877 1140
ganlikun 0:13413ea9a877 1141 /* Read Multi Block command */
ganlikun 0:13413ea9a877 1142 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, BlockAdd);
ganlikun 0:13413ea9a877 1143 }
ganlikun 0:13413ea9a877 1144 else
ganlikun 0:13413ea9a877 1145 {
ganlikun 0:13413ea9a877 1146 hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_DMA);
ganlikun 0:13413ea9a877 1147
ganlikun 0:13413ea9a877 1148 /* Read Single Block command */
ganlikun 0:13413ea9a877 1149 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, BlockAdd);
ganlikun 0:13413ea9a877 1150 }
ganlikun 0:13413ea9a877 1151 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 1152 {
ganlikun 0:13413ea9a877 1153 /* Clear all the static flags */
ganlikun 0:13413ea9a877 1154 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
ganlikun 0:13413ea9a877 1155 hmmc->ErrorCode |= errorstate;
ganlikun 0:13413ea9a877 1156 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 1157 return HAL_ERROR;
ganlikun 0:13413ea9a877 1158 }
ganlikun 0:13413ea9a877 1159
ganlikun 0:13413ea9a877 1160 return HAL_OK;
ganlikun 0:13413ea9a877 1161 }
ganlikun 0:13413ea9a877 1162 else
ganlikun 0:13413ea9a877 1163 {
ganlikun 0:13413ea9a877 1164 return HAL_BUSY;
ganlikun 0:13413ea9a877 1165 }
ganlikun 0:13413ea9a877 1166 }
ganlikun 0:13413ea9a877 1167
ganlikun 0:13413ea9a877 1168 /**
ganlikun 0:13413ea9a877 1169 * @brief Writes block(s) to a specified address in a card. The Data transfer
ganlikun 0:13413ea9a877 1170 * is managed by DMA mode.
ganlikun 0:13413ea9a877 1171 * @note This API should be followed by a check on the card state through
ganlikun 0:13413ea9a877 1172 * HAL_MMC_GetCardState().
ganlikun 0:13413ea9a877 1173 * @note You could also check the DMA transfer process through the MMC Tx
ganlikun 0:13413ea9a877 1174 * interrupt event.
ganlikun 0:13413ea9a877 1175 * @param hmmc: Pointer to MMC handle
ganlikun 0:13413ea9a877 1176 * @param pData: Pointer to the buffer that will contain the data to transmit
ganlikun 0:13413ea9a877 1177 * @param BlockAdd: Block Address where data will be written
ganlikun 0:13413ea9a877 1178 * @param NumberOfBlocks: Number of blocks to write
ganlikun 0:13413ea9a877 1179 * @retval HAL status
ganlikun 0:13413ea9a877 1180 */
ganlikun 0:13413ea9a877 1181 HAL_StatusTypeDef HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
ganlikun 0:13413ea9a877 1182 {
ganlikun 0:13413ea9a877 1183 SDIO_DataInitTypeDef config;
ganlikun 0:13413ea9a877 1184 uint32_t errorstate = HAL_MMC_ERROR_NONE;
ganlikun 0:13413ea9a877 1185
ganlikun 0:13413ea9a877 1186 if(NULL == pData)
ganlikun 0:13413ea9a877 1187 {
ganlikun 0:13413ea9a877 1188 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
ganlikun 0:13413ea9a877 1189 return HAL_ERROR;
ganlikun 0:13413ea9a877 1190 }
ganlikun 0:13413ea9a877 1191
ganlikun 0:13413ea9a877 1192 if(hmmc->State == HAL_MMC_STATE_READY)
ganlikun 0:13413ea9a877 1193 {
ganlikun 0:13413ea9a877 1194 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
ganlikun 0:13413ea9a877 1195
ganlikun 0:13413ea9a877 1196 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
ganlikun 0:13413ea9a877 1197 {
ganlikun 0:13413ea9a877 1198 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
ganlikun 0:13413ea9a877 1199 return HAL_ERROR;
ganlikun 0:13413ea9a877 1200 }
ganlikun 0:13413ea9a877 1201
ganlikun 0:13413ea9a877 1202 hmmc->State = HAL_MMC_STATE_BUSY;
ganlikun 0:13413ea9a877 1203
ganlikun 0:13413ea9a877 1204 /* Initialize data control register */
ganlikun 0:13413ea9a877 1205 hmmc->Instance->DCTRL = 0U;
ganlikun 0:13413ea9a877 1206
ganlikun 0:13413ea9a877 1207 /* Enable MMC Error interrupts */
ganlikun 0:13413ea9a877 1208 #ifdef SDIO_STA_STBITER
ganlikun 0:13413ea9a877 1209 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR));
ganlikun 0:13413ea9a877 1210 #else /* SDIO_STA_STBITERR not defined */
ganlikun 0:13413ea9a877 1211 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR));
ganlikun 0:13413ea9a877 1212 #endif /* SDIO_STA_STBITERR */
ganlikun 0:13413ea9a877 1213
ganlikun 0:13413ea9a877 1214 /* Set the DMA transfer complete callback */
ganlikun 0:13413ea9a877 1215 hmmc->hdmatx->XferCpltCallback = MMC_DMATransmitCplt;
ganlikun 0:13413ea9a877 1216
ganlikun 0:13413ea9a877 1217 /* Set the DMA error callback */
ganlikun 0:13413ea9a877 1218 hmmc->hdmatx->XferErrorCallback = MMC_DMAError;
ganlikun 0:13413ea9a877 1219
ganlikun 0:13413ea9a877 1220 /* Set the DMA Abort callback */
ganlikun 0:13413ea9a877 1221 hmmc->hdmatx->XferAbortCallback = NULL;
ganlikun 0:13413ea9a877 1222
ganlikun 0:13413ea9a877 1223 /* Check the Card capacity in term of Logical number of blocks */
ganlikun 0:13413ea9a877 1224 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
ganlikun 0:13413ea9a877 1225 {
ganlikun 0:13413ea9a877 1226 BlockAdd *= 512U;
ganlikun 0:13413ea9a877 1227 }
ganlikun 0:13413ea9a877 1228
ganlikun 0:13413ea9a877 1229 /* Set Block Size for Card */
ganlikun 0:13413ea9a877 1230 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
ganlikun 0:13413ea9a877 1231 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 1232 {
ganlikun 0:13413ea9a877 1233 /* Clear all the static flags */
ganlikun 0:13413ea9a877 1234 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
ganlikun 0:13413ea9a877 1235 hmmc->ErrorCode |= errorstate;
ganlikun 0:13413ea9a877 1236 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 1237 return HAL_ERROR;
ganlikun 0:13413ea9a877 1238 }
ganlikun 0:13413ea9a877 1239
ganlikun 0:13413ea9a877 1240 /* Write Blocks in Polling mode */
ganlikun 0:13413ea9a877 1241 if(NumberOfBlocks > 1U)
ganlikun 0:13413ea9a877 1242 {
ganlikun 0:13413ea9a877 1243 hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
ganlikun 0:13413ea9a877 1244
ganlikun 0:13413ea9a877 1245 /* Write Multi Block command */
ganlikun 0:13413ea9a877 1246 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, BlockAdd);
ganlikun 0:13413ea9a877 1247 }
ganlikun 0:13413ea9a877 1248 else
ganlikun 0:13413ea9a877 1249 {
ganlikun 0:13413ea9a877 1250 hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_DMA);
ganlikun 0:13413ea9a877 1251
ganlikun 0:13413ea9a877 1252 /* Write Single Block command */
ganlikun 0:13413ea9a877 1253 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, BlockAdd);
ganlikun 0:13413ea9a877 1254 }
ganlikun 0:13413ea9a877 1255 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 1256 {
ganlikun 0:13413ea9a877 1257 /* Clear all the static flags */
ganlikun 0:13413ea9a877 1258 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
ganlikun 0:13413ea9a877 1259 hmmc->ErrorCode |= errorstate;
ganlikun 0:13413ea9a877 1260 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 1261 return HAL_ERROR;
ganlikun 0:13413ea9a877 1262 }
ganlikun 0:13413ea9a877 1263
ganlikun 0:13413ea9a877 1264 /* Enable SDIO DMA transfer */
ganlikun 0:13413ea9a877 1265 __HAL_MMC_DMA_ENABLE(hmmc);
ganlikun 0:13413ea9a877 1266
ganlikun 0:13413ea9a877 1267 /* Enable the DMA Channel */
ganlikun 0:13413ea9a877 1268 HAL_DMA_Start_IT(hmmc->hdmatx, (uint32_t)pData, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)(BLOCKSIZE * NumberOfBlocks)/4);
ganlikun 0:13413ea9a877 1269
ganlikun 0:13413ea9a877 1270 /* Configure the MMC DPSM (Data Path State Machine) */
ganlikun 0:13413ea9a877 1271 config.DataTimeOut = SDMMC_DATATIMEOUT;
ganlikun 0:13413ea9a877 1272 config.DataLength = BLOCKSIZE * NumberOfBlocks;
ganlikun 0:13413ea9a877 1273 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
ganlikun 0:13413ea9a877 1274 config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
ganlikun 0:13413ea9a877 1275 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
ganlikun 0:13413ea9a877 1276 config.DPSM = SDIO_DPSM_ENABLE;
ganlikun 0:13413ea9a877 1277 SDIO_ConfigData(hmmc->Instance, &config);
ganlikun 0:13413ea9a877 1278
ganlikun 0:13413ea9a877 1279 return HAL_OK;
ganlikun 0:13413ea9a877 1280 }
ganlikun 0:13413ea9a877 1281 else
ganlikun 0:13413ea9a877 1282 {
ganlikun 0:13413ea9a877 1283 return HAL_BUSY;
ganlikun 0:13413ea9a877 1284 }
ganlikun 0:13413ea9a877 1285 }
ganlikun 0:13413ea9a877 1286
ganlikun 0:13413ea9a877 1287 /**
ganlikun 0:13413ea9a877 1288 * @brief Erases the specified memory area of the given MMC card.
ganlikun 0:13413ea9a877 1289 * @note This API should be followed by a check on the card state through
ganlikun 0:13413ea9a877 1290 * HAL_MMC_GetCardState().
ganlikun 0:13413ea9a877 1291 * @param hmmc: Pointer to MMC handle
ganlikun 0:13413ea9a877 1292 * @param BlockStartAdd: Start Block address
ganlikun 0:13413ea9a877 1293 * @param BlockEndAdd: End Block address
ganlikun 0:13413ea9a877 1294 * @retval HAL status
ganlikun 0:13413ea9a877 1295 */
ganlikun 0:13413ea9a877 1296 HAL_StatusTypeDef HAL_MMC_Erase(MMC_HandleTypeDef *hmmc, uint32_t BlockStartAdd, uint32_t BlockEndAdd)
ganlikun 0:13413ea9a877 1297 {
ganlikun 0:13413ea9a877 1298 uint32_t errorstate = HAL_MMC_ERROR_NONE;
ganlikun 0:13413ea9a877 1299
ganlikun 0:13413ea9a877 1300 if(hmmc->State == HAL_MMC_STATE_READY)
ganlikun 0:13413ea9a877 1301 {
ganlikun 0:13413ea9a877 1302 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
ganlikun 0:13413ea9a877 1303
ganlikun 0:13413ea9a877 1304 if(BlockEndAdd < BlockStartAdd)
ganlikun 0:13413ea9a877 1305 {
ganlikun 0:13413ea9a877 1306 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
ganlikun 0:13413ea9a877 1307 return HAL_ERROR;
ganlikun 0:13413ea9a877 1308 }
ganlikun 0:13413ea9a877 1309
ganlikun 0:13413ea9a877 1310 if(BlockEndAdd > (hmmc->MmcCard.LogBlockNbr))
ganlikun 0:13413ea9a877 1311 {
ganlikun 0:13413ea9a877 1312 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
ganlikun 0:13413ea9a877 1313 return HAL_ERROR;
ganlikun 0:13413ea9a877 1314 }
ganlikun 0:13413ea9a877 1315
ganlikun 0:13413ea9a877 1316 hmmc->State = HAL_MMC_STATE_BUSY;
ganlikun 0:13413ea9a877 1317
ganlikun 0:13413ea9a877 1318 /* Check if the card command class supports erase command */
ganlikun 0:13413ea9a877 1319 if(((hmmc->MmcCard.Class) & SDIO_CCCC_ERASE) == 0U)
ganlikun 0:13413ea9a877 1320 {
ganlikun 0:13413ea9a877 1321 /* Clear all the static flags */
ganlikun 0:13413ea9a877 1322 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
ganlikun 0:13413ea9a877 1323 hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
ganlikun 0:13413ea9a877 1324 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 1325 return HAL_ERROR;
ganlikun 0:13413ea9a877 1326 }
ganlikun 0:13413ea9a877 1327
ganlikun 0:13413ea9a877 1328 if((SDIO_GetResponse(hmmc->Instance, SDIO_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
ganlikun 0:13413ea9a877 1329 {
ganlikun 0:13413ea9a877 1330 /* Clear all the static flags */
ganlikun 0:13413ea9a877 1331 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
ganlikun 0:13413ea9a877 1332 hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED;
ganlikun 0:13413ea9a877 1333 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 1334 return HAL_ERROR;
ganlikun 0:13413ea9a877 1335 }
ganlikun 0:13413ea9a877 1336
ganlikun 0:13413ea9a877 1337 /* Check the Card capacity in term of Logical number of blocks */
ganlikun 0:13413ea9a877 1338 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
ganlikun 0:13413ea9a877 1339 {
ganlikun 0:13413ea9a877 1340 BlockStartAdd *= 512U;
ganlikun 0:13413ea9a877 1341 BlockEndAdd *= 512U;
ganlikun 0:13413ea9a877 1342 }
ganlikun 0:13413ea9a877 1343
ganlikun 0:13413ea9a877 1344 /* Send CMD35 MMC_ERASE_GRP_START with argument as addr */
ganlikun 0:13413ea9a877 1345 errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, BlockStartAdd);
ganlikun 0:13413ea9a877 1346 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 1347 {
ganlikun 0:13413ea9a877 1348 /* Clear all the static flags */
ganlikun 0:13413ea9a877 1349 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
ganlikun 0:13413ea9a877 1350 hmmc->ErrorCode |= errorstate;
ganlikun 0:13413ea9a877 1351 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 1352 return HAL_ERROR;
ganlikun 0:13413ea9a877 1353 }
ganlikun 0:13413ea9a877 1354
ganlikun 0:13413ea9a877 1355 /* Send CMD36 MMC_ERASE_GRP_END with argument as addr */
ganlikun 0:13413ea9a877 1356 errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, BlockEndAdd);
ganlikun 0:13413ea9a877 1357 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 1358 {
ganlikun 0:13413ea9a877 1359 /* Clear all the static flags */
ganlikun 0:13413ea9a877 1360 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
ganlikun 0:13413ea9a877 1361 hmmc->ErrorCode |= errorstate;
ganlikun 0:13413ea9a877 1362 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 1363 return HAL_ERROR;
ganlikun 0:13413ea9a877 1364 }
ganlikun 0:13413ea9a877 1365
ganlikun 0:13413ea9a877 1366 /* Send CMD38 ERASE */
ganlikun 0:13413ea9a877 1367 errorstate = SDMMC_CmdErase(hmmc->Instance);
ganlikun 0:13413ea9a877 1368 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 1369 {
ganlikun 0:13413ea9a877 1370 /* Clear all the static flags */
ganlikun 0:13413ea9a877 1371 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
ganlikun 0:13413ea9a877 1372 hmmc->ErrorCode |= errorstate;
ganlikun 0:13413ea9a877 1373 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 1374 return HAL_ERROR;
ganlikun 0:13413ea9a877 1375 }
ganlikun 0:13413ea9a877 1376
ganlikun 0:13413ea9a877 1377 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 1378
ganlikun 0:13413ea9a877 1379 return HAL_OK;
ganlikun 0:13413ea9a877 1380 }
ganlikun 0:13413ea9a877 1381 else
ganlikun 0:13413ea9a877 1382 {
ganlikun 0:13413ea9a877 1383 return HAL_BUSY;
ganlikun 0:13413ea9a877 1384 }
ganlikun 0:13413ea9a877 1385 }
ganlikun 0:13413ea9a877 1386
ganlikun 0:13413ea9a877 1387 /**
ganlikun 0:13413ea9a877 1388 * @brief This function handles MMC card interrupt request.
ganlikun 0:13413ea9a877 1389 * @param hmmc: Pointer to MMC handle
ganlikun 0:13413ea9a877 1390 * @retval None
ganlikun 0:13413ea9a877 1391 */
ganlikun 0:13413ea9a877 1392 void HAL_MMC_IRQHandler(MMC_HandleTypeDef *hmmc)
ganlikun 0:13413ea9a877 1393 {
ganlikun 0:13413ea9a877 1394 uint32_t errorstate = HAL_MMC_ERROR_NONE;
ganlikun 0:13413ea9a877 1395
ganlikun 0:13413ea9a877 1396 /* Check for SDIO interrupt flags */
ganlikun 0:13413ea9a877 1397 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DATAEND) != RESET)
ganlikun 0:13413ea9a877 1398 {
ganlikun 0:13413ea9a877 1399 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_FLAG_DATAEND);
ganlikun 0:13413ea9a877 1400
ganlikun 0:13413ea9a877 1401 #ifdef SDIO_STA_STBITERR
ganlikun 0:13413ea9a877 1402 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
ganlikun 0:13413ea9a877 1403 SDIO_IT_TXUNDERR | SDIO_IT_RXOVERR | SDIO_IT_STBITERR);
ganlikun 0:13413ea9a877 1404 #else /* SDIO_STA_STBITERR not defined */
ganlikun 0:13413ea9a877 1405 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
ganlikun 0:13413ea9a877 1406 SDIO_IT_TXUNDERR | SDIO_IT_RXOVERR);
ganlikun 0:13413ea9a877 1407 #endif
ganlikun 0:13413ea9a877 1408
ganlikun 0:13413ea9a877 1409 if((hmmc->Context & MMC_CONTEXT_IT) != RESET)
ganlikun 0:13413ea9a877 1410 {
ganlikun 0:13413ea9a877 1411 if(((hmmc->Context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != RESET) || ((hmmc->Context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != RESET))
ganlikun 0:13413ea9a877 1412 {
ganlikun 0:13413ea9a877 1413 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
ganlikun 0:13413ea9a877 1414 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 1415 {
ganlikun 0:13413ea9a877 1416 hmmc->ErrorCode |= errorstate;
ganlikun 0:13413ea9a877 1417 HAL_MMC_ErrorCallback(hmmc);
ganlikun 0:13413ea9a877 1418 }
ganlikun 0:13413ea9a877 1419 }
ganlikun 0:13413ea9a877 1420
ganlikun 0:13413ea9a877 1421 /* Clear all the static flags */
ganlikun 0:13413ea9a877 1422 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
ganlikun 0:13413ea9a877 1423
ganlikun 0:13413ea9a877 1424 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 1425 if(((hmmc->Context & MMC_CONTEXT_READ_SINGLE_BLOCK) != RESET) || ((hmmc->Context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != RESET))
ganlikun 0:13413ea9a877 1426 {
ganlikun 0:13413ea9a877 1427 HAL_MMC_RxCpltCallback(hmmc);
ganlikun 0:13413ea9a877 1428 }
ganlikun 0:13413ea9a877 1429 else
ganlikun 0:13413ea9a877 1430 {
ganlikun 0:13413ea9a877 1431 HAL_MMC_TxCpltCallback(hmmc);
ganlikun 0:13413ea9a877 1432 }
ganlikun 0:13413ea9a877 1433 }
ganlikun 0:13413ea9a877 1434 else if((hmmc->Context & MMC_CONTEXT_DMA) != RESET)
ganlikun 0:13413ea9a877 1435 {
ganlikun 0:13413ea9a877 1436 if((hmmc->Context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != RESET)
ganlikun 0:13413ea9a877 1437 {
ganlikun 0:13413ea9a877 1438 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
ganlikun 0:13413ea9a877 1439 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 1440 {
ganlikun 0:13413ea9a877 1441 hmmc->ErrorCode |= errorstate;
ganlikun 0:13413ea9a877 1442 HAL_MMC_ErrorCallback(hmmc);
ganlikun 0:13413ea9a877 1443 }
ganlikun 0:13413ea9a877 1444 }
ganlikun 0:13413ea9a877 1445 if(((hmmc->Context & MMC_CONTEXT_READ_SINGLE_BLOCK) == RESET) && ((hmmc->Context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) == RESET))
ganlikun 0:13413ea9a877 1446 {
ganlikun 0:13413ea9a877 1447 /* Disable the DMA transfer for transmit request by setting the DMAEN bit
ganlikun 0:13413ea9a877 1448 in the MMC DCTRL register */
ganlikun 0:13413ea9a877 1449 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
ganlikun 0:13413ea9a877 1450
ganlikun 0:13413ea9a877 1451 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 1452
ganlikun 0:13413ea9a877 1453 HAL_MMC_TxCpltCallback(hmmc);
ganlikun 0:13413ea9a877 1454 }
ganlikun 0:13413ea9a877 1455 }
ganlikun 0:13413ea9a877 1456 }
ganlikun 0:13413ea9a877 1457
ganlikun 0:13413ea9a877 1458 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_TXFIFOHE) != RESET)
ganlikun 0:13413ea9a877 1459 {
ganlikun 0:13413ea9a877 1460 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_FLAG_TXFIFOHE);
ganlikun 0:13413ea9a877 1461
ganlikun 0:13413ea9a877 1462 MMC_Write_IT(hmmc);
ganlikun 0:13413ea9a877 1463 }
ganlikun 0:13413ea9a877 1464
ganlikun 0:13413ea9a877 1465 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_RXFIFOHF) != RESET)
ganlikun 0:13413ea9a877 1466 {
ganlikun 0:13413ea9a877 1467 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_FLAG_RXFIFOHF);
ganlikun 0:13413ea9a877 1468
ganlikun 0:13413ea9a877 1469 MMC_Read_IT(hmmc);
ganlikun 0:13413ea9a877 1470 }
ganlikun 0:13413ea9a877 1471
ganlikun 0:13413ea9a877 1472 #ifdef SDIO_STA_STBITERR
ganlikun 0:13413ea9a877 1473 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR) != RESET)
ganlikun 0:13413ea9a877 1474 {
ganlikun 0:13413ea9a877 1475 /* Set Error code */
ganlikun 0:13413ea9a877 1476 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DCRCFAIL) != RESET)
ganlikun 0:13413ea9a877 1477 {
ganlikun 0:13413ea9a877 1478 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
ganlikun 0:13413ea9a877 1479 }
ganlikun 0:13413ea9a877 1480 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DTIMEOUT) != RESET)
ganlikun 0:13413ea9a877 1481 {
ganlikun 0:13413ea9a877 1482 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
ganlikun 0:13413ea9a877 1483 }
ganlikun 0:13413ea9a877 1484 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_RXOVERR) != RESET)
ganlikun 0:13413ea9a877 1485 {
ganlikun 0:13413ea9a877 1486 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
ganlikun 0:13413ea9a877 1487 }
ganlikun 0:13413ea9a877 1488 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_TXUNDERR) != RESET)
ganlikun 0:13413ea9a877 1489 {
ganlikun 0:13413ea9a877 1490 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
ganlikun 0:13413ea9a877 1491 }
ganlikun 0:13413ea9a877 1492 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_STBITERR) != RESET)
ganlikun 0:13413ea9a877 1493 {
ganlikun 0:13413ea9a877 1494 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
ganlikun 0:13413ea9a877 1495 }
ganlikun 0:13413ea9a877 1496
ganlikun 0:13413ea9a877 1497 /* Clear All flags */
ganlikun 0:13413ea9a877 1498 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS | SDIO_FLAG_STBITERR);
ganlikun 0:13413ea9a877 1499
ganlikun 0:13413ea9a877 1500 /* Disable all interrupts */
ganlikun 0:13413ea9a877 1501 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
ganlikun 0:13413ea9a877 1502 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR |SDIO_IT_STBITERR);
ganlikun 0:13413ea9a877 1503
ganlikun 0:13413ea9a877 1504 if((hmmc->Context & MMC_CONTEXT_DMA) != RESET)
ganlikun 0:13413ea9a877 1505 {
ganlikun 0:13413ea9a877 1506 /* Abort the MMC DMA Streams */
ganlikun 0:13413ea9a877 1507 if(hmmc->hdmatx != NULL)
ganlikun 0:13413ea9a877 1508 {
ganlikun 0:13413ea9a877 1509 /* Set the DMA Tx abort callback */
ganlikun 0:13413ea9a877 1510 hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort;
ganlikun 0:13413ea9a877 1511 /* Abort DMA in IT mode */
ganlikun 0:13413ea9a877 1512 if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
ganlikun 0:13413ea9a877 1513 {
ganlikun 0:13413ea9a877 1514 MMC_DMATxAbort(hmmc->hdmatx);
ganlikun 0:13413ea9a877 1515 }
ganlikun 0:13413ea9a877 1516 }
ganlikun 0:13413ea9a877 1517 else if(hmmc->hdmarx != NULL)
ganlikun 0:13413ea9a877 1518 {
ganlikun 0:13413ea9a877 1519 /* Set the DMA Rx abort callback */
ganlikun 0:13413ea9a877 1520 hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort;
ganlikun 0:13413ea9a877 1521 /* Abort DMA in IT mode */
ganlikun 0:13413ea9a877 1522 if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
ganlikun 0:13413ea9a877 1523 {
ganlikun 0:13413ea9a877 1524 MMC_DMARxAbort(hmmc->hdmarx);
ganlikun 0:13413ea9a877 1525 }
ganlikun 0:13413ea9a877 1526 }
ganlikun 0:13413ea9a877 1527 else
ganlikun 0:13413ea9a877 1528 {
ganlikun 0:13413ea9a877 1529 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
ganlikun 0:13413ea9a877 1530 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 1531 HAL_MMC_AbortCallback(hmmc);
ganlikun 0:13413ea9a877 1532 }
ganlikun 0:13413ea9a877 1533 }
ganlikun 0:13413ea9a877 1534 else if((hmmc->Context & MMC_CONTEXT_IT) != RESET)
ganlikun 0:13413ea9a877 1535 {
ganlikun 0:13413ea9a877 1536 /* Set the MMC state to ready to be able to start again the process */
ganlikun 0:13413ea9a877 1537 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 1538 HAL_MMC_ErrorCallback(hmmc);
ganlikun 0:13413ea9a877 1539 }
ganlikun 0:13413ea9a877 1540 }
ganlikun 0:13413ea9a877 1541 #else /* SDIO_STA_STBITERR not defined */
ganlikun 0:13413ea9a877 1542 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_TXUNDERR) != RESET)
ganlikun 0:13413ea9a877 1543 {
ganlikun 0:13413ea9a877 1544 /* Set Error code */
ganlikun 0:13413ea9a877 1545 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DCRCFAIL) != RESET)
ganlikun 0:13413ea9a877 1546 {
ganlikun 0:13413ea9a877 1547 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
ganlikun 0:13413ea9a877 1548 }
ganlikun 0:13413ea9a877 1549 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DTIMEOUT) != RESET)
ganlikun 0:13413ea9a877 1550 {
ganlikun 0:13413ea9a877 1551 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
ganlikun 0:13413ea9a877 1552 }
ganlikun 0:13413ea9a877 1553 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_RXOVERR) != RESET)
ganlikun 0:13413ea9a877 1554 {
ganlikun 0:13413ea9a877 1555 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
ganlikun 0:13413ea9a877 1556 }
ganlikun 0:13413ea9a877 1557 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_TXUNDERR) != RESET)
ganlikun 0:13413ea9a877 1558 {
ganlikun 0:13413ea9a877 1559 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
ganlikun 0:13413ea9a877 1560 }
ganlikun 0:13413ea9a877 1561
ganlikun 0:13413ea9a877 1562 /* Clear All flags */
ganlikun 0:13413ea9a877 1563 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
ganlikun 0:13413ea9a877 1564
ganlikun 0:13413ea9a877 1565 /* Disable all interrupts */
ganlikun 0:13413ea9a877 1566 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
ganlikun 0:13413ea9a877 1567 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
ganlikun 0:13413ea9a877 1568
ganlikun 0:13413ea9a877 1569 if((hmmc->Context & MMC_CONTEXT_DMA) != RESET)
ganlikun 0:13413ea9a877 1570 {
ganlikun 0:13413ea9a877 1571 /* Abort the MMC DMA Streams */
ganlikun 0:13413ea9a877 1572 if(hmmc->hdmatx != NULL)
ganlikun 0:13413ea9a877 1573 {
ganlikun 0:13413ea9a877 1574 /* Set the DMA Tx abort callback */
ganlikun 0:13413ea9a877 1575 hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort;
ganlikun 0:13413ea9a877 1576 /* Abort DMA in IT mode */
ganlikun 0:13413ea9a877 1577 if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
ganlikun 0:13413ea9a877 1578 {
ganlikun 0:13413ea9a877 1579 MMC_DMATxAbort(hmmc->hdmatx);
ganlikun 0:13413ea9a877 1580 }
ganlikun 0:13413ea9a877 1581 }
ganlikun 0:13413ea9a877 1582 else if(hmmc->hdmarx != NULL)
ganlikun 0:13413ea9a877 1583 {
ganlikun 0:13413ea9a877 1584 /* Set the DMA Rx abort callback */
ganlikun 0:13413ea9a877 1585 hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort;
ganlikun 0:13413ea9a877 1586 /* Abort DMA in IT mode */
ganlikun 0:13413ea9a877 1587 if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
ganlikun 0:13413ea9a877 1588 {
ganlikun 0:13413ea9a877 1589 MMC_DMARxAbort(hmmc->hdmarx);
ganlikun 0:13413ea9a877 1590 }
ganlikun 0:13413ea9a877 1591 }
ganlikun 0:13413ea9a877 1592 else
ganlikun 0:13413ea9a877 1593 {
ganlikun 0:13413ea9a877 1594 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
ganlikun 0:13413ea9a877 1595 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 1596 HAL_MMC_AbortCallback(hmmc);
ganlikun 0:13413ea9a877 1597 }
ganlikun 0:13413ea9a877 1598 }
ganlikun 0:13413ea9a877 1599 else if((hmmc->Context & MMC_CONTEXT_IT) != RESET)
ganlikun 0:13413ea9a877 1600 {
ganlikun 0:13413ea9a877 1601 /* Set the MMC state to ready to be able to start again the process */
ganlikun 0:13413ea9a877 1602 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 1603 HAL_MMC_ErrorCallback(hmmc);
ganlikun 0:13413ea9a877 1604 }
ganlikun 0:13413ea9a877 1605 }
ganlikun 0:13413ea9a877 1606 #endif /* SDIO_STA_STBITERR */
ganlikun 0:13413ea9a877 1607 }
ganlikun 0:13413ea9a877 1608
ganlikun 0:13413ea9a877 1609 /**
ganlikun 0:13413ea9a877 1610 * @brief return the MMC state
ganlikun 0:13413ea9a877 1611 * @param hmmc: Pointer to mmc handle
ganlikun 0:13413ea9a877 1612 * @retval HAL state
ganlikun 0:13413ea9a877 1613 */
ganlikun 0:13413ea9a877 1614 HAL_MMC_StateTypeDef HAL_MMC_GetState(MMC_HandleTypeDef *hmmc)
ganlikun 0:13413ea9a877 1615 {
ganlikun 0:13413ea9a877 1616 return hmmc->State;
ganlikun 0:13413ea9a877 1617 }
ganlikun 0:13413ea9a877 1618
ganlikun 0:13413ea9a877 1619 /**
ganlikun 0:13413ea9a877 1620 * @brief Return the MMC error code
ganlikun 0:13413ea9a877 1621 * @param hmmc : Pointer to a MMC_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 1622 * the configuration information.
ganlikun 0:13413ea9a877 1623 * @retval MMC Error Code
ganlikun 0:13413ea9a877 1624 */
ganlikun 0:13413ea9a877 1625 uint32_t HAL_MMC_GetError(MMC_HandleTypeDef *hmmc)
ganlikun 0:13413ea9a877 1626 {
ganlikun 0:13413ea9a877 1627 return hmmc->ErrorCode;
ganlikun 0:13413ea9a877 1628 }
ganlikun 0:13413ea9a877 1629
ganlikun 0:13413ea9a877 1630 /**
ganlikun 0:13413ea9a877 1631 * @brief Tx Transfer completed callbacks
ganlikun 0:13413ea9a877 1632 * @param hmmc: Pointer to MMC handle
ganlikun 0:13413ea9a877 1633 * @retval None
ganlikun 0:13413ea9a877 1634 */
ganlikun 0:13413ea9a877 1635 __weak void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef *hmmc)
ganlikun 0:13413ea9a877 1636 {
ganlikun 0:13413ea9a877 1637 /* Prevent unused argument(s) compilation warning */
ganlikun 0:13413ea9a877 1638 UNUSED(hmmc);
ganlikun 0:13413ea9a877 1639
ganlikun 0:13413ea9a877 1640 /* NOTE : This function should not be modified, when the callback is needed,
ganlikun 0:13413ea9a877 1641 the HAL_MMC_TxCpltCallback can be implemented in the user file
ganlikun 0:13413ea9a877 1642 */
ganlikun 0:13413ea9a877 1643 }
ganlikun 0:13413ea9a877 1644
ganlikun 0:13413ea9a877 1645 /**
ganlikun 0:13413ea9a877 1646 * @brief Rx Transfer completed callbacks
ganlikun 0:13413ea9a877 1647 * @param hmmc: Pointer MMC handle
ganlikun 0:13413ea9a877 1648 * @retval None
ganlikun 0:13413ea9a877 1649 */
ganlikun 0:13413ea9a877 1650 __weak void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef *hmmc)
ganlikun 0:13413ea9a877 1651 {
ganlikun 0:13413ea9a877 1652 /* Prevent unused argument(s) compilation warning */
ganlikun 0:13413ea9a877 1653 UNUSED(hmmc);
ganlikun 0:13413ea9a877 1654
ganlikun 0:13413ea9a877 1655 /* NOTE : This function should not be modified, when the callback is needed,
ganlikun 0:13413ea9a877 1656 the HAL_MMC_RxCpltCallback can be implemented in the user file
ganlikun 0:13413ea9a877 1657 */
ganlikun 0:13413ea9a877 1658 }
ganlikun 0:13413ea9a877 1659
ganlikun 0:13413ea9a877 1660 /**
ganlikun 0:13413ea9a877 1661 * @brief MMC error callbacks
ganlikun 0:13413ea9a877 1662 * @param hmmc: Pointer MMC handle
ganlikun 0:13413ea9a877 1663 * @retval None
ganlikun 0:13413ea9a877 1664 */
ganlikun 0:13413ea9a877 1665 __weak void HAL_MMC_ErrorCallback(MMC_HandleTypeDef *hmmc)
ganlikun 0:13413ea9a877 1666 {
ganlikun 0:13413ea9a877 1667 /* Prevent unused argument(s) compilation warning */
ganlikun 0:13413ea9a877 1668 UNUSED(hmmc);
ganlikun 0:13413ea9a877 1669
ganlikun 0:13413ea9a877 1670 /* NOTE : This function should not be modified, when the callback is needed,
ganlikun 0:13413ea9a877 1671 the HAL_MMC_ErrorCallback can be implemented in the user file
ganlikun 0:13413ea9a877 1672 */
ganlikun 0:13413ea9a877 1673 }
ganlikun 0:13413ea9a877 1674
ganlikun 0:13413ea9a877 1675 /**
ganlikun 0:13413ea9a877 1676 * @brief MMC Abort callbacks
ganlikun 0:13413ea9a877 1677 * @param hmmc: Pointer MMC handle
ganlikun 0:13413ea9a877 1678 * @retval None
ganlikun 0:13413ea9a877 1679 */
ganlikun 0:13413ea9a877 1680 __weak void HAL_MMC_AbortCallback(MMC_HandleTypeDef *hmmc)
ganlikun 0:13413ea9a877 1681 {
ganlikun 0:13413ea9a877 1682 /* Prevent unused argument(s) compilation warning */
ganlikun 0:13413ea9a877 1683 UNUSED(hmmc);
ganlikun 0:13413ea9a877 1684
ganlikun 0:13413ea9a877 1685 /* NOTE : This function should not be modified, when the callback is needed,
ganlikun 0:13413ea9a877 1686 the HAL_MMC_ErrorCallback can be implemented in the user file
ganlikun 0:13413ea9a877 1687 */
ganlikun 0:13413ea9a877 1688 }
ganlikun 0:13413ea9a877 1689
ganlikun 0:13413ea9a877 1690
ganlikun 0:13413ea9a877 1691 /**
ganlikun 0:13413ea9a877 1692 * @}
ganlikun 0:13413ea9a877 1693 */
ganlikun 0:13413ea9a877 1694
ganlikun 0:13413ea9a877 1695 /** @addtogroup MMC_Exported_Functions_Group3
ganlikun 0:13413ea9a877 1696 * @brief management functions
ganlikun 0:13413ea9a877 1697 *
ganlikun 0:13413ea9a877 1698 @verbatim
ganlikun 0:13413ea9a877 1699 ==============================================================================
ganlikun 0:13413ea9a877 1700 ##### Peripheral Control functions #####
ganlikun 0:13413ea9a877 1701 ==============================================================================
ganlikun 0:13413ea9a877 1702 [..]
ganlikun 0:13413ea9a877 1703 This subsection provides a set of functions allowing to control the MMC card
ganlikun 0:13413ea9a877 1704 operations and get the related information
ganlikun 0:13413ea9a877 1705
ganlikun 0:13413ea9a877 1706 @endverbatim
ganlikun 0:13413ea9a877 1707 * @{
ganlikun 0:13413ea9a877 1708 */
ganlikun 0:13413ea9a877 1709
ganlikun 0:13413ea9a877 1710 /**
ganlikun 0:13413ea9a877 1711 * @brief Returns information the information of the card which are stored on
ganlikun 0:13413ea9a877 1712 * the CID register.
ganlikun 0:13413ea9a877 1713 * @param hmmc: Pointer to MMC handle
ganlikun 0:13413ea9a877 1714 * @param pCID: Pointer to a HAL_MMC_CIDTypedef structure that
ganlikun 0:13413ea9a877 1715 * contains all CID register parameters
ganlikun 0:13413ea9a877 1716 * @retval HAL status
ganlikun 0:13413ea9a877 1717 */
ganlikun 0:13413ea9a877 1718 HAL_StatusTypeDef HAL_MMC_GetCardCID(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCIDTypeDef *pCID)
ganlikun 0:13413ea9a877 1719 {
ganlikun 0:13413ea9a877 1720 uint32_t tmp = 0U;
ganlikun 0:13413ea9a877 1721
ganlikun 0:13413ea9a877 1722 /* Byte 0 */
ganlikun 0:13413ea9a877 1723 tmp = (uint8_t)((hmmc->CID[0U] & 0xFF000000U) >> 24U);
ganlikun 0:13413ea9a877 1724 pCID->ManufacturerID = tmp;
ganlikun 0:13413ea9a877 1725
ganlikun 0:13413ea9a877 1726 /* Byte 1 */
ganlikun 0:13413ea9a877 1727 tmp = (uint8_t)((hmmc->CID[0U] & 0x00FF0000U) >> 16U);
ganlikun 0:13413ea9a877 1728 pCID->OEM_AppliID = tmp << 8U;
ganlikun 0:13413ea9a877 1729
ganlikun 0:13413ea9a877 1730 /* Byte 2 */
ganlikun 0:13413ea9a877 1731 tmp = (uint8_t)((hmmc->CID[0U] & 0x000000FF00U) >> 8U);
ganlikun 0:13413ea9a877 1732 pCID->OEM_AppliID |= tmp;
ganlikun 0:13413ea9a877 1733
ganlikun 0:13413ea9a877 1734 /* Byte 3 */
ganlikun 0:13413ea9a877 1735 tmp = (uint8_t)(hmmc->CID[0U] & 0x000000FFU);
ganlikun 0:13413ea9a877 1736 pCID->ProdName1 = tmp << 24U;
ganlikun 0:13413ea9a877 1737
ganlikun 0:13413ea9a877 1738 /* Byte 4 */
ganlikun 0:13413ea9a877 1739 tmp = (uint8_t)((hmmc->CID[1U] & 0xFF000000U) >> 24U);
ganlikun 0:13413ea9a877 1740 pCID->ProdName1 |= tmp << 16U;
ganlikun 0:13413ea9a877 1741
ganlikun 0:13413ea9a877 1742 /* Byte 5 */
ganlikun 0:13413ea9a877 1743 tmp = (uint8_t)((hmmc->CID[1U] & 0x00FF0000U) >> 16U);
ganlikun 0:13413ea9a877 1744 pCID->ProdName1 |= tmp << 8U;
ganlikun 0:13413ea9a877 1745
ganlikun 0:13413ea9a877 1746 /* Byte 6 */
ganlikun 0:13413ea9a877 1747 tmp = (uint8_t)((hmmc->CID[1U] & 0x0000FF00U) >> 8U);
ganlikun 0:13413ea9a877 1748 pCID->ProdName1 |= tmp;
ganlikun 0:13413ea9a877 1749
ganlikun 0:13413ea9a877 1750 /* Byte 7 */
ganlikun 0:13413ea9a877 1751 tmp = (uint8_t)(hmmc->CID[1U] & 0x000000FFU);
ganlikun 0:13413ea9a877 1752 pCID->ProdName2 = tmp;
ganlikun 0:13413ea9a877 1753
ganlikun 0:13413ea9a877 1754 /* Byte 8 */
ganlikun 0:13413ea9a877 1755 tmp = (uint8_t)((hmmc->CID[2U] & 0xFF000000U) >> 24U);
ganlikun 0:13413ea9a877 1756 pCID->ProdRev = tmp;
ganlikun 0:13413ea9a877 1757
ganlikun 0:13413ea9a877 1758 /* Byte 9 */
ganlikun 0:13413ea9a877 1759 tmp = (uint8_t)((hmmc->CID[2U] & 0x00FF0000U) >> 16U);
ganlikun 0:13413ea9a877 1760 pCID->ProdSN = tmp << 24U;
ganlikun 0:13413ea9a877 1761
ganlikun 0:13413ea9a877 1762 /* Byte 10 */
ganlikun 0:13413ea9a877 1763 tmp = (uint8_t)((hmmc->CID[2U] & 0x0000FF00U) >> 8U);
ganlikun 0:13413ea9a877 1764 pCID->ProdSN |= tmp << 16U;
ganlikun 0:13413ea9a877 1765
ganlikun 0:13413ea9a877 1766 /* Byte 11 */
ganlikun 0:13413ea9a877 1767 tmp = (uint8_t)(hmmc->CID[2U] & 0x000000FFU);
ganlikun 0:13413ea9a877 1768 pCID->ProdSN |= tmp << 8U;
ganlikun 0:13413ea9a877 1769
ganlikun 0:13413ea9a877 1770 /* Byte 12 */
ganlikun 0:13413ea9a877 1771 tmp = (uint8_t)((hmmc->CID[3U] & 0xFF000000U) >> 24U);
ganlikun 0:13413ea9a877 1772 pCID->ProdSN |= tmp;
ganlikun 0:13413ea9a877 1773
ganlikun 0:13413ea9a877 1774 /* Byte 13 */
ganlikun 0:13413ea9a877 1775 tmp = (uint8_t)((hmmc->CID[3U] & 0x00FF0000U) >> 16U);
ganlikun 0:13413ea9a877 1776 pCID->Reserved1 |= (tmp & 0xF0U) >> 4U;
ganlikun 0:13413ea9a877 1777 pCID->ManufactDate = (tmp & 0x0FU) << 8U;
ganlikun 0:13413ea9a877 1778
ganlikun 0:13413ea9a877 1779 /* Byte 14 */
ganlikun 0:13413ea9a877 1780 tmp = (uint8_t)((hmmc->CID[3U] & 0x0000FF00U) >> 8U);
ganlikun 0:13413ea9a877 1781 pCID->ManufactDate |= tmp;
ganlikun 0:13413ea9a877 1782
ganlikun 0:13413ea9a877 1783 /* Byte 15 */
ganlikun 0:13413ea9a877 1784 tmp = (uint8_t)(hmmc->CID[3U] & 0x000000FFU);
ganlikun 0:13413ea9a877 1785 pCID->CID_CRC = (tmp & 0xFEU) >> 1U;
ganlikun 0:13413ea9a877 1786 pCID->Reserved2 = 1U;
ganlikun 0:13413ea9a877 1787
ganlikun 0:13413ea9a877 1788 return HAL_OK;
ganlikun 0:13413ea9a877 1789 }
ganlikun 0:13413ea9a877 1790
ganlikun 0:13413ea9a877 1791 /**
ganlikun 0:13413ea9a877 1792 * @brief Returns information the information of the card which are stored on
ganlikun 0:13413ea9a877 1793 * the CSD register.
ganlikun 0:13413ea9a877 1794 * @param hmmc: Pointer to MMC handle
ganlikun 0:13413ea9a877 1795 * @param pCSD: Pointer to a HAL_MMC_CardInfoTypeDef structure that
ganlikun 0:13413ea9a877 1796 * contains all CSD register parameters
ganlikun 0:13413ea9a877 1797 * @retval HAL status
ganlikun 0:13413ea9a877 1798 */
ganlikun 0:13413ea9a877 1799 HAL_StatusTypeDef HAL_MMC_GetCardCSD(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCSDTypeDef *pCSD)
ganlikun 0:13413ea9a877 1800 {
ganlikun 0:13413ea9a877 1801 uint32_t tmp = 0U;
ganlikun 0:13413ea9a877 1802
ganlikun 0:13413ea9a877 1803 /* Byte 0 */
ganlikun 0:13413ea9a877 1804 tmp = (hmmc->CSD[0U] & 0xFF000000U) >> 24U;
ganlikun 0:13413ea9a877 1805 pCSD->CSDStruct = (uint8_t)((tmp & 0xC0U) >> 6U);
ganlikun 0:13413ea9a877 1806 pCSD->SysSpecVersion = (uint8_t)((tmp & 0x3CU) >> 2U);
ganlikun 0:13413ea9a877 1807 pCSD->Reserved1 = tmp & 0x03U;
ganlikun 0:13413ea9a877 1808
ganlikun 0:13413ea9a877 1809 /* Byte 1 */
ganlikun 0:13413ea9a877 1810 tmp = (hmmc->CSD[0U] & 0x00FF0000U) >> 16U;
ganlikun 0:13413ea9a877 1811 pCSD->TAAC = (uint8_t)tmp;
ganlikun 0:13413ea9a877 1812
ganlikun 0:13413ea9a877 1813 /* Byte 2 */
ganlikun 0:13413ea9a877 1814 tmp = (hmmc->CSD[0U] & 0x0000FF00U) >> 8U;
ganlikun 0:13413ea9a877 1815 pCSD->NSAC = (uint8_t)tmp;
ganlikun 0:13413ea9a877 1816
ganlikun 0:13413ea9a877 1817 /* Byte 3 */
ganlikun 0:13413ea9a877 1818 tmp = hmmc->CSD[0U] & 0x000000FFU;
ganlikun 0:13413ea9a877 1819 pCSD->MaxBusClkFrec = (uint8_t)tmp;
ganlikun 0:13413ea9a877 1820
ganlikun 0:13413ea9a877 1821 /* Byte 4 */
ganlikun 0:13413ea9a877 1822 tmp = (hmmc->CSD[1U] & 0xFF000000U) >> 24U;
ganlikun 0:13413ea9a877 1823 pCSD->CardComdClasses = (uint16_t)(tmp << 4U);
ganlikun 0:13413ea9a877 1824
ganlikun 0:13413ea9a877 1825 /* Byte 5 */
ganlikun 0:13413ea9a877 1826 tmp = (hmmc->CSD[1U] & 0x00FF0000U) >> 16U;
ganlikun 0:13413ea9a877 1827 pCSD->CardComdClasses |= (uint16_t)((tmp & 0xF0U) >> 4U);
ganlikun 0:13413ea9a877 1828 pCSD->RdBlockLen = (uint8_t)(tmp & 0x0FU);
ganlikun 0:13413ea9a877 1829
ganlikun 0:13413ea9a877 1830 /* Byte 6 */
ganlikun 0:13413ea9a877 1831 tmp = (hmmc->CSD[1U] & 0x0000FF00U) >> 8U;
ganlikun 0:13413ea9a877 1832 pCSD->PartBlockRead = (uint8_t)((tmp & 0x80U) >> 7U);
ganlikun 0:13413ea9a877 1833 pCSD->WrBlockMisalign = (uint8_t)((tmp & 0x40U) >> 6U);
ganlikun 0:13413ea9a877 1834 pCSD->RdBlockMisalign = (uint8_t)((tmp & 0x20U) >> 5U);
ganlikun 0:13413ea9a877 1835 pCSD->DSRImpl = (uint8_t)((tmp & 0x10U) >> 4U);
ganlikun 0:13413ea9a877 1836 pCSD->Reserved2 = 0; /*!< Reserved */
ganlikun 0:13413ea9a877 1837
ganlikun 0:13413ea9a877 1838 pCSD->DeviceSize = (tmp & 0x03U) << 10U;
ganlikun 0:13413ea9a877 1839
ganlikun 0:13413ea9a877 1840 /* Byte 7 */
ganlikun 0:13413ea9a877 1841 tmp = (uint8_t)(hmmc->CSD[1U] & 0x000000FFU);
ganlikun 0:13413ea9a877 1842 pCSD->DeviceSize |= (tmp) << 2U;
ganlikun 0:13413ea9a877 1843
ganlikun 0:13413ea9a877 1844 /* Byte 8 */
ganlikun 0:13413ea9a877 1845 tmp = (uint8_t)((hmmc->CSD[2U] & 0xFF000000U) >> 24U);
ganlikun 0:13413ea9a877 1846 pCSD->DeviceSize |= (tmp & 0xC0U) >> 6U;
ganlikun 0:13413ea9a877 1847
ganlikun 0:13413ea9a877 1848 pCSD->MaxRdCurrentVDDMin = (tmp & 0x38U) >> 3U;
ganlikun 0:13413ea9a877 1849 pCSD->MaxRdCurrentVDDMax = (tmp & 0x07U);
ganlikun 0:13413ea9a877 1850
ganlikun 0:13413ea9a877 1851 /* Byte 9 */
ganlikun 0:13413ea9a877 1852 tmp = (uint8_t)((hmmc->CSD[2U] & 0x00FF0000U) >> 16U);
ganlikun 0:13413ea9a877 1853 pCSD->MaxWrCurrentVDDMin = (tmp & 0xE0U) >> 5U;
ganlikun 0:13413ea9a877 1854 pCSD->MaxWrCurrentVDDMax = (tmp & 0x1CU) >> 2U;
ganlikun 0:13413ea9a877 1855 pCSD->DeviceSizeMul = (tmp & 0x03U) << 1U;
ganlikun 0:13413ea9a877 1856 /* Byte 10 */
ganlikun 0:13413ea9a877 1857 tmp = (uint8_t)((hmmc->CSD[2] & 0x0000FF00U) >> 8U);
ganlikun 0:13413ea9a877 1858 pCSD->DeviceSizeMul |= (tmp & 0x80U) >> 7U;
ganlikun 0:13413ea9a877 1859
ganlikun 0:13413ea9a877 1860 hmmc->MmcCard.BlockNbr = (pCSD->DeviceSize + 1U) ;
ganlikun 0:13413ea9a877 1861 hmmc->MmcCard.BlockNbr *= (1U << (pCSD->DeviceSizeMul + 2U));
ganlikun 0:13413ea9a877 1862 hmmc->MmcCard.BlockSize = 1U << (pCSD->RdBlockLen);
ganlikun 0:13413ea9a877 1863
ganlikun 0:13413ea9a877 1864 hmmc->MmcCard.LogBlockNbr = (hmmc->MmcCard.BlockNbr) * ((hmmc->MmcCard.BlockSize) / 512U);
ganlikun 0:13413ea9a877 1865 hmmc->MmcCard.LogBlockSize = 512U;
ganlikun 0:13413ea9a877 1866
ganlikun 0:13413ea9a877 1867 pCSD->EraseGrSize = (tmp & 0x40U) >> 6U;
ganlikun 0:13413ea9a877 1868 pCSD->EraseGrMul = (tmp & 0x3FU) << 1U;
ganlikun 0:13413ea9a877 1869
ganlikun 0:13413ea9a877 1870 /* Byte 11 */
ganlikun 0:13413ea9a877 1871 tmp = (uint8_t)(hmmc->CSD[2U] & 0x000000FFU);
ganlikun 0:13413ea9a877 1872 pCSD->EraseGrMul |= (tmp & 0x80U) >> 7U;
ganlikun 0:13413ea9a877 1873 pCSD->WrProtectGrSize = (tmp & 0x7FU);
ganlikun 0:13413ea9a877 1874
ganlikun 0:13413ea9a877 1875 /* Byte 12 */
ganlikun 0:13413ea9a877 1876 tmp = (uint8_t)((hmmc->CSD[3U] & 0xFF000000U) >> 24U);
ganlikun 0:13413ea9a877 1877 pCSD->WrProtectGrEnable = (tmp & 0x80U) >> 7U;
ganlikun 0:13413ea9a877 1878 pCSD->ManDeflECC = (tmp & 0x60U) >> 5U;
ganlikun 0:13413ea9a877 1879 pCSD->WrSpeedFact = (tmp & 0x1CU) >> 2U;
ganlikun 0:13413ea9a877 1880 pCSD->MaxWrBlockLen = (tmp & 0x03U) << 2U;
ganlikun 0:13413ea9a877 1881
ganlikun 0:13413ea9a877 1882 /* Byte 13 */
ganlikun 0:13413ea9a877 1883 tmp = (uint8_t)((hmmc->CSD[3U] & 0x00FF0000U) >> 16U);
ganlikun 0:13413ea9a877 1884 pCSD->MaxWrBlockLen |= (tmp & 0xC0U) >> 6U;
ganlikun 0:13413ea9a877 1885 pCSD->WriteBlockPaPartial = (tmp & 0x20U) >> 5U;
ganlikun 0:13413ea9a877 1886 pCSD->Reserved3 = 0U;
ganlikun 0:13413ea9a877 1887 pCSD->ContentProtectAppli = (tmp & 0x01U);
ganlikun 0:13413ea9a877 1888
ganlikun 0:13413ea9a877 1889 /* Byte 14 */
ganlikun 0:13413ea9a877 1890 tmp = (uint8_t)((hmmc->CSD[3U] & 0x0000FF00U) >> 8U);
ganlikun 0:13413ea9a877 1891 pCSD->FileFormatGrouop = (tmp & 0x80U) >> 7U;
ganlikun 0:13413ea9a877 1892 pCSD->CopyFlag = (tmp & 0x40U) >> 6U;
ganlikun 0:13413ea9a877 1893 pCSD->PermWrProtect = (tmp & 0x20U) >> 5U;
ganlikun 0:13413ea9a877 1894 pCSD->TempWrProtect = (tmp & 0x10U) >> 4U;
ganlikun 0:13413ea9a877 1895 pCSD->FileFormat = (tmp & 0x0CU) >> 2U;
ganlikun 0:13413ea9a877 1896 pCSD->ECC = (tmp & 0x03U);
ganlikun 0:13413ea9a877 1897
ganlikun 0:13413ea9a877 1898 /* Byte 15 */
ganlikun 0:13413ea9a877 1899 tmp = (uint8_t)(hmmc->CSD[3U] & 0x000000FFU);
ganlikun 0:13413ea9a877 1900 pCSD->CSD_CRC = (tmp & 0xFEU) >> 1U;
ganlikun 0:13413ea9a877 1901 pCSD->Reserved4 = 1U;
ganlikun 0:13413ea9a877 1902
ganlikun 0:13413ea9a877 1903 return HAL_OK;
ganlikun 0:13413ea9a877 1904 }
ganlikun 0:13413ea9a877 1905
ganlikun 0:13413ea9a877 1906 /**
ganlikun 0:13413ea9a877 1907 * @brief Gets the MMC card info.
ganlikun 0:13413ea9a877 1908 * @param hmmc: Pointer to MMC handle
ganlikun 0:13413ea9a877 1909 * @param pCardInfo: Pointer to the HAL_MMC_CardInfoTypeDef structure that
ganlikun 0:13413ea9a877 1910 * will contain the MMC card status information
ganlikun 0:13413ea9a877 1911 * @retval HAL status
ganlikun 0:13413ea9a877 1912 */
ganlikun 0:13413ea9a877 1913 HAL_StatusTypeDef HAL_MMC_GetCardInfo(MMC_HandleTypeDef *hmmc, HAL_MMC_CardInfoTypeDef *pCardInfo)
ganlikun 0:13413ea9a877 1914 {
ganlikun 0:13413ea9a877 1915 pCardInfo->CardType = (uint32_t)(hmmc->MmcCard.CardType);
ganlikun 0:13413ea9a877 1916 pCardInfo->Class = (uint32_t)(hmmc->MmcCard.Class);
ganlikun 0:13413ea9a877 1917 pCardInfo->RelCardAdd = (uint32_t)(hmmc->MmcCard.RelCardAdd);
ganlikun 0:13413ea9a877 1918 pCardInfo->BlockNbr = (uint32_t)(hmmc->MmcCard.BlockNbr);
ganlikun 0:13413ea9a877 1919 pCardInfo->BlockSize = (uint32_t)(hmmc->MmcCard.BlockSize);
ganlikun 0:13413ea9a877 1920 pCardInfo->LogBlockNbr = (uint32_t)(hmmc->MmcCard.LogBlockNbr);
ganlikun 0:13413ea9a877 1921 pCardInfo->LogBlockSize = (uint32_t)(hmmc->MmcCard.LogBlockSize);
ganlikun 0:13413ea9a877 1922
ganlikun 0:13413ea9a877 1923 return HAL_OK;
ganlikun 0:13413ea9a877 1924 }
ganlikun 0:13413ea9a877 1925
ganlikun 0:13413ea9a877 1926 /**
ganlikun 0:13413ea9a877 1927 * @brief Enables wide bus operation for the requested card if supported by
ganlikun 0:13413ea9a877 1928 * card.
ganlikun 0:13413ea9a877 1929 * @param hmmc: Pointer to MMC handle
ganlikun 0:13413ea9a877 1930 * @param WideMode: Specifies the MMC card wide bus mode
ganlikun 0:13413ea9a877 1931 * This parameter can be one of the following values:
ganlikun 0:13413ea9a877 1932 * @arg SDIO_BUS_WIDE_8B: 8-bit data transfer
ganlikun 0:13413ea9a877 1933 * @arg SDIO_BUS_WIDE_4B: 4-bit data transfer
ganlikun 0:13413ea9a877 1934 * @arg SDIO_BUS_WIDE_1B: 1-bit data transfer
ganlikun 0:13413ea9a877 1935 * @retval HAL status
ganlikun 0:13413ea9a877 1936 */
ganlikun 0:13413ea9a877 1937 HAL_StatusTypeDef HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef *hmmc, uint32_t WideMode)
ganlikun 0:13413ea9a877 1938 {
ganlikun 0:13413ea9a877 1939 __IO uint32_t count = 0U;
ganlikun 0:13413ea9a877 1940 SDIO_InitTypeDef Init;
ganlikun 0:13413ea9a877 1941 uint32_t errorstate = HAL_MMC_ERROR_NONE;
ganlikun 0:13413ea9a877 1942 uint32_t response = 0U, busy = 0U;
ganlikun 0:13413ea9a877 1943
ganlikun 0:13413ea9a877 1944 /* Check the parameters */
ganlikun 0:13413ea9a877 1945 assert_param(IS_SDIO_BUS_WIDE(WideMode));
ganlikun 0:13413ea9a877 1946
ganlikun 0:13413ea9a877 1947 /* Chnage Satte */
ganlikun 0:13413ea9a877 1948 hmmc->State = HAL_MMC_STATE_BUSY;
ganlikun 0:13413ea9a877 1949
ganlikun 0:13413ea9a877 1950 /* Update Clock for Bus mode update */
ganlikun 0:13413ea9a877 1951 Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
ganlikun 0:13413ea9a877 1952 Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
ganlikun 0:13413ea9a877 1953 Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
ganlikun 0:13413ea9a877 1954 Init.BusWide = WideMode;
ganlikun 0:13413ea9a877 1955 Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
ganlikun 0:13413ea9a877 1956 Init.ClockDiv = SDIO_INIT_CLK_DIV;
ganlikun 0:13413ea9a877 1957 /* Initialize SDIO*/
ganlikun 0:13413ea9a877 1958 SDIO_Init(hmmc->Instance, Init);
ganlikun 0:13413ea9a877 1959
ganlikun 0:13413ea9a877 1960 if(WideMode == SDIO_BUS_WIDE_8B)
ganlikun 0:13413ea9a877 1961 {
ganlikun 0:13413ea9a877 1962 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U);
ganlikun 0:13413ea9a877 1963 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 1964 {
ganlikun 0:13413ea9a877 1965 hmmc->ErrorCode |= errorstate;
ganlikun 0:13413ea9a877 1966 }
ganlikun 0:13413ea9a877 1967 }
ganlikun 0:13413ea9a877 1968 else if(WideMode == SDIO_BUS_WIDE_4B)
ganlikun 0:13413ea9a877 1969 {
ganlikun 0:13413ea9a877 1970 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U);
ganlikun 0:13413ea9a877 1971 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 1972 {
ganlikun 0:13413ea9a877 1973 hmmc->ErrorCode |= errorstate;
ganlikun 0:13413ea9a877 1974 }
ganlikun 0:13413ea9a877 1975 }
ganlikun 0:13413ea9a877 1976 else if(WideMode == SDIO_BUS_WIDE_1B)
ganlikun 0:13413ea9a877 1977 {
ganlikun 0:13413ea9a877 1978 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70000U);
ganlikun 0:13413ea9a877 1979 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 1980 {
ganlikun 0:13413ea9a877 1981 hmmc->ErrorCode |= errorstate;
ganlikun 0:13413ea9a877 1982 }
ganlikun 0:13413ea9a877 1983 }
ganlikun 0:13413ea9a877 1984 else
ganlikun 0:13413ea9a877 1985 {
ganlikun 0:13413ea9a877 1986 /* WideMode is not a valid argument*/
ganlikun 0:13413ea9a877 1987 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
ganlikun 0:13413ea9a877 1988 }
ganlikun 0:13413ea9a877 1989
ganlikun 0:13413ea9a877 1990 /* Check for switch error and violation of the trial number of sending CMD 13 */
ganlikun 0:13413ea9a877 1991 while(busy == 0U)
ganlikun 0:13413ea9a877 1992 {
ganlikun 0:13413ea9a877 1993 if(count++ == SDMMC_MAX_TRIAL)
ganlikun 0:13413ea9a877 1994 {
ganlikun 0:13413ea9a877 1995 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 1996 hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
ganlikun 0:13413ea9a877 1997 return HAL_ERROR;
ganlikun 0:13413ea9a877 1998 }
ganlikun 0:13413ea9a877 1999
ganlikun 0:13413ea9a877 2000 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
ganlikun 0:13413ea9a877 2001 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
ganlikun 0:13413ea9a877 2002 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 2003 {
ganlikun 0:13413ea9a877 2004 hmmc->ErrorCode |= errorstate;
ganlikun 0:13413ea9a877 2005 }
ganlikun 0:13413ea9a877 2006
ganlikun 0:13413ea9a877 2007 /* Get command response */
ganlikun 0:13413ea9a877 2008 response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
ganlikun 0:13413ea9a877 2009
ganlikun 0:13413ea9a877 2010 /* Get operating voltage*/
ganlikun 0:13413ea9a877 2011 busy = (((response >> 7U) == 1U) ? 0U : 1U);
ganlikun 0:13413ea9a877 2012 }
ganlikun 0:13413ea9a877 2013
ganlikun 0:13413ea9a877 2014 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
ganlikun 0:13413ea9a877 2015 count = SDMMC_DATATIMEOUT;
ganlikun 0:13413ea9a877 2016 while((response & 0x00000100U) == 0U)
ganlikun 0:13413ea9a877 2017 {
ganlikun 0:13413ea9a877 2018 if(count-- == 0U)
ganlikun 0:13413ea9a877 2019 {
ganlikun 0:13413ea9a877 2020 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 2021 hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
ganlikun 0:13413ea9a877 2022 return HAL_ERROR;
ganlikun 0:13413ea9a877 2023 }
ganlikun 0:13413ea9a877 2024
ganlikun 0:13413ea9a877 2025 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
ganlikun 0:13413ea9a877 2026 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
ganlikun 0:13413ea9a877 2027 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 2028 {
ganlikun 0:13413ea9a877 2029 hmmc->ErrorCode |= errorstate;
ganlikun 0:13413ea9a877 2030 }
ganlikun 0:13413ea9a877 2031
ganlikun 0:13413ea9a877 2032 /* Get command response */
ganlikun 0:13413ea9a877 2033 response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
ganlikun 0:13413ea9a877 2034 }
ganlikun 0:13413ea9a877 2035
ganlikun 0:13413ea9a877 2036 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 2037 {
ganlikun 0:13413ea9a877 2038 /* Clear all the static flags */
ganlikun 0:13413ea9a877 2039 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
ganlikun 0:13413ea9a877 2040 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 2041 return HAL_ERROR;
ganlikun 0:13413ea9a877 2042 }
ganlikun 0:13413ea9a877 2043 else
ganlikun 0:13413ea9a877 2044 {
ganlikun 0:13413ea9a877 2045 /* Configure the SDIO peripheral */
ganlikun 0:13413ea9a877 2046 Init.ClockEdge = hmmc->Init.ClockEdge;
ganlikun 0:13413ea9a877 2047 Init.ClockBypass = hmmc->Init.ClockBypass;
ganlikun 0:13413ea9a877 2048 Init.ClockPowerSave = hmmc->Init.ClockPowerSave;
ganlikun 0:13413ea9a877 2049 Init.BusWide = WideMode;
ganlikun 0:13413ea9a877 2050 Init.HardwareFlowControl = hmmc->Init.HardwareFlowControl;
ganlikun 0:13413ea9a877 2051 Init.ClockDiv = hmmc->Init.ClockDiv;
ganlikun 0:13413ea9a877 2052 SDIO_Init(hmmc->Instance, Init);
ganlikun 0:13413ea9a877 2053 }
ganlikun 0:13413ea9a877 2054
ganlikun 0:13413ea9a877 2055 /* Change State */
ganlikun 0:13413ea9a877 2056 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 2057
ganlikun 0:13413ea9a877 2058 return HAL_OK;
ganlikun 0:13413ea9a877 2059 }
ganlikun 0:13413ea9a877 2060
ganlikun 0:13413ea9a877 2061
ganlikun 0:13413ea9a877 2062 /**
ganlikun 0:13413ea9a877 2063 * @brief Gets the current mmc card data state.
ganlikun 0:13413ea9a877 2064 * @param hmmc: pointer to MMC handle
ganlikun 0:13413ea9a877 2065 * @retval Card state
ganlikun 0:13413ea9a877 2066 */
ganlikun 0:13413ea9a877 2067 HAL_MMC_CardStateTypeDef HAL_MMC_GetCardState(MMC_HandleTypeDef *hmmc)
ganlikun 0:13413ea9a877 2068 {
ganlikun 0:13413ea9a877 2069 HAL_MMC_CardStateTypeDef cardstate = HAL_MMC_CARD_TRANSFER;
ganlikun 0:13413ea9a877 2070 uint32_t errorstate = HAL_MMC_ERROR_NONE;
ganlikun 0:13413ea9a877 2071 uint32_t resp1 = 0U;
ganlikun 0:13413ea9a877 2072
ganlikun 0:13413ea9a877 2073 errorstate = MMC_SendStatus(hmmc, &resp1);
ganlikun 0:13413ea9a877 2074 if(errorstate != HAL_OK)
ganlikun 0:13413ea9a877 2075 {
ganlikun 0:13413ea9a877 2076 hmmc->ErrorCode |= errorstate;
ganlikun 0:13413ea9a877 2077 }
ganlikun 0:13413ea9a877 2078
ganlikun 0:13413ea9a877 2079 cardstate = (HAL_MMC_CardStateTypeDef)((resp1 >> 9U) & 0x0FU);
ganlikun 0:13413ea9a877 2080
ganlikun 0:13413ea9a877 2081 return cardstate;
ganlikun 0:13413ea9a877 2082 }
ganlikun 0:13413ea9a877 2083
ganlikun 0:13413ea9a877 2084 /**
ganlikun 0:13413ea9a877 2085 * @brief Abort the current transfer and disable the MMC.
ganlikun 0:13413ea9a877 2086 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 2087 * the configuration information for MMC module.
ganlikun 0:13413ea9a877 2088 * @retval HAL status
ganlikun 0:13413ea9a877 2089 */
ganlikun 0:13413ea9a877 2090 HAL_StatusTypeDef HAL_MMC_Abort(MMC_HandleTypeDef *hmmc)
ganlikun 0:13413ea9a877 2091 {
ganlikun 0:13413ea9a877 2092 HAL_MMC_CardStateTypeDef CardState;
ganlikun 0:13413ea9a877 2093
ganlikun 0:13413ea9a877 2094 /* DIsable All interrupts */
ganlikun 0:13413ea9a877 2095 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
ganlikun 0:13413ea9a877 2096 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
ganlikun 0:13413ea9a877 2097
ganlikun 0:13413ea9a877 2098 /* Clear All flags */
ganlikun 0:13413ea9a877 2099 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
ganlikun 0:13413ea9a877 2100
ganlikun 0:13413ea9a877 2101 if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL))
ganlikun 0:13413ea9a877 2102 {
ganlikun 0:13413ea9a877 2103 /* Disable the MMC DMA request */
ganlikun 0:13413ea9a877 2104 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
ganlikun 0:13413ea9a877 2105
ganlikun 0:13413ea9a877 2106 /* Abort the MMC DMA Tx Stream */
ganlikun 0:13413ea9a877 2107 if(hmmc->hdmatx != NULL)
ganlikun 0:13413ea9a877 2108 {
ganlikun 0:13413ea9a877 2109 HAL_DMA_Abort(hmmc->hdmatx);
ganlikun 0:13413ea9a877 2110 }
ganlikun 0:13413ea9a877 2111 /* Abort the MMC DMA Rx Stream */
ganlikun 0:13413ea9a877 2112 if(hmmc->hdmarx != NULL)
ganlikun 0:13413ea9a877 2113 {
ganlikun 0:13413ea9a877 2114 HAL_DMA_Abort(hmmc->hdmarx);
ganlikun 0:13413ea9a877 2115 }
ganlikun 0:13413ea9a877 2116 }
ganlikun 0:13413ea9a877 2117
ganlikun 0:13413ea9a877 2118 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 2119 CardState = HAL_MMC_GetCardState(hmmc);
ganlikun 0:13413ea9a877 2120 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
ganlikun 0:13413ea9a877 2121 {
ganlikun 0:13413ea9a877 2122 hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
ganlikun 0:13413ea9a877 2123 }
ganlikun 0:13413ea9a877 2124 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 2125 {
ganlikun 0:13413ea9a877 2126 return HAL_ERROR;
ganlikun 0:13413ea9a877 2127 }
ganlikun 0:13413ea9a877 2128 return HAL_OK;
ganlikun 0:13413ea9a877 2129 }
ganlikun 0:13413ea9a877 2130
ganlikun 0:13413ea9a877 2131 /**
ganlikun 0:13413ea9a877 2132 * @brief Abort the current transfer and disable the MMC (IT mode).
ganlikun 0:13413ea9a877 2133 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 2134 * the configuration information for MMC module.
ganlikun 0:13413ea9a877 2135 * @retval HAL status
ganlikun 0:13413ea9a877 2136 */
ganlikun 0:13413ea9a877 2137 HAL_StatusTypeDef HAL_MMC_Abort_IT(MMC_HandleTypeDef *hmmc)
ganlikun 0:13413ea9a877 2138 {
ganlikun 0:13413ea9a877 2139 HAL_MMC_CardStateTypeDef CardState;
ganlikun 0:13413ea9a877 2140
ganlikun 0:13413ea9a877 2141 /* DIsable All interrupts */
ganlikun 0:13413ea9a877 2142 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
ganlikun 0:13413ea9a877 2143 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
ganlikun 0:13413ea9a877 2144
ganlikun 0:13413ea9a877 2145 /* Clear All flags */
ganlikun 0:13413ea9a877 2146 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
ganlikun 0:13413ea9a877 2147
ganlikun 0:13413ea9a877 2148 if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL))
ganlikun 0:13413ea9a877 2149 {
ganlikun 0:13413ea9a877 2150 /* Disable the MMC DMA request */
ganlikun 0:13413ea9a877 2151 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
ganlikun 0:13413ea9a877 2152
ganlikun 0:13413ea9a877 2153 /* Abort the MMC DMA Tx Stream */
ganlikun 0:13413ea9a877 2154 if(hmmc->hdmatx != NULL)
ganlikun 0:13413ea9a877 2155 {
ganlikun 0:13413ea9a877 2156 hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort;
ganlikun 0:13413ea9a877 2157 if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
ganlikun 0:13413ea9a877 2158 {
ganlikun 0:13413ea9a877 2159 hmmc->hdmatx = NULL;
ganlikun 0:13413ea9a877 2160 }
ganlikun 0:13413ea9a877 2161 }
ganlikun 0:13413ea9a877 2162 /* Abort the MMC DMA Rx Stream */
ganlikun 0:13413ea9a877 2163 if(hmmc->hdmarx != NULL)
ganlikun 0:13413ea9a877 2164 {
ganlikun 0:13413ea9a877 2165 hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort;
ganlikun 0:13413ea9a877 2166 if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
ganlikun 0:13413ea9a877 2167 {
ganlikun 0:13413ea9a877 2168 hmmc->hdmarx = NULL;
ganlikun 0:13413ea9a877 2169 }
ganlikun 0:13413ea9a877 2170 }
ganlikun 0:13413ea9a877 2171 }
ganlikun 0:13413ea9a877 2172
ganlikun 0:13413ea9a877 2173 /* No transfer ongoing on both DMA channels*/
ganlikun 0:13413ea9a877 2174 if((hmmc->hdmatx == NULL) && (hmmc->hdmarx == NULL))
ganlikun 0:13413ea9a877 2175 {
ganlikun 0:13413ea9a877 2176 CardState = HAL_MMC_GetCardState(hmmc);
ganlikun 0:13413ea9a877 2177 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 2178 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
ganlikun 0:13413ea9a877 2179 {
ganlikun 0:13413ea9a877 2180 hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
ganlikun 0:13413ea9a877 2181 }
ganlikun 0:13413ea9a877 2182 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 2183 {
ganlikun 0:13413ea9a877 2184 return HAL_ERROR;
ganlikun 0:13413ea9a877 2185 }
ganlikun 0:13413ea9a877 2186 else
ganlikun 0:13413ea9a877 2187 {
ganlikun 0:13413ea9a877 2188 HAL_MMC_AbortCallback(hmmc);
ganlikun 0:13413ea9a877 2189 }
ganlikun 0:13413ea9a877 2190 }
ganlikun 0:13413ea9a877 2191
ganlikun 0:13413ea9a877 2192 return HAL_OK;
ganlikun 0:13413ea9a877 2193 }
ganlikun 0:13413ea9a877 2194
ganlikun 0:13413ea9a877 2195 /**
ganlikun 0:13413ea9a877 2196 * @}
ganlikun 0:13413ea9a877 2197 */
ganlikun 0:13413ea9a877 2198
ganlikun 0:13413ea9a877 2199 /**
ganlikun 0:13413ea9a877 2200 * @}
ganlikun 0:13413ea9a877 2201 */
ganlikun 0:13413ea9a877 2202
ganlikun 0:13413ea9a877 2203 /* Private function ----------------------------------------------------------*/
ganlikun 0:13413ea9a877 2204 /** @addtogroup MMC_Private_Functions
ganlikun 0:13413ea9a877 2205 * @{
ganlikun 0:13413ea9a877 2206 */
ganlikun 0:13413ea9a877 2207
ganlikun 0:13413ea9a877 2208 /**
ganlikun 0:13413ea9a877 2209 * @brief DMA MMC transmit process complete callback
ganlikun 0:13413ea9a877 2210 * @param hdma: DMA handle
ganlikun 0:13413ea9a877 2211 * @retval None
ganlikun 0:13413ea9a877 2212 */
ganlikun 0:13413ea9a877 2213 static void MMC_DMATransmitCplt(DMA_HandleTypeDef *hdma)
ganlikun 0:13413ea9a877 2214 {
ganlikun 0:13413ea9a877 2215 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
ganlikun 0:13413ea9a877 2216
ganlikun 0:13413ea9a877 2217 /* Enable DATAEND Interrupt */
ganlikun 0:13413ea9a877 2218 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DATAEND));
ganlikun 0:13413ea9a877 2219 }
ganlikun 0:13413ea9a877 2220
ganlikun 0:13413ea9a877 2221 /**
ganlikun 0:13413ea9a877 2222 * @brief DMA MMC receive process complete callback
ganlikun 0:13413ea9a877 2223 * @param hdma: DMA handle
ganlikun 0:13413ea9a877 2224 * @retval None
ganlikun 0:13413ea9a877 2225 */
ganlikun 0:13413ea9a877 2226 static void MMC_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
ganlikun 0:13413ea9a877 2227 {
ganlikun 0:13413ea9a877 2228 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
ganlikun 0:13413ea9a877 2229 uint32_t errorstate = HAL_MMC_ERROR_NONE;
ganlikun 0:13413ea9a877 2230
ganlikun 0:13413ea9a877 2231 /* Send stop command in multiblock write */
ganlikun 0:13413ea9a877 2232 if(hmmc->Context == (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA))
ganlikun 0:13413ea9a877 2233 {
ganlikun 0:13413ea9a877 2234 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
ganlikun 0:13413ea9a877 2235 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 2236 {
ganlikun 0:13413ea9a877 2237 hmmc->ErrorCode |= errorstate;
ganlikun 0:13413ea9a877 2238 HAL_MMC_ErrorCallback(hmmc);
ganlikun 0:13413ea9a877 2239 }
ganlikun 0:13413ea9a877 2240 }
ganlikun 0:13413ea9a877 2241
ganlikun 0:13413ea9a877 2242 /* Disable the DMA transfer for transmit request by setting the DMAEN bit
ganlikun 0:13413ea9a877 2243 in the MMC DCTRL register */
ganlikun 0:13413ea9a877 2244 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
ganlikun 0:13413ea9a877 2245
ganlikun 0:13413ea9a877 2246 /* Clear all the static flags */
ganlikun 0:13413ea9a877 2247 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
ganlikun 0:13413ea9a877 2248
ganlikun 0:13413ea9a877 2249 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 2250
ganlikun 0:13413ea9a877 2251 HAL_MMC_RxCpltCallback(hmmc);
ganlikun 0:13413ea9a877 2252 }
ganlikun 0:13413ea9a877 2253
ganlikun 0:13413ea9a877 2254 /**
ganlikun 0:13413ea9a877 2255 * @brief DMA MMC communication error callback
ganlikun 0:13413ea9a877 2256 * @param hdma: DMA handle
ganlikun 0:13413ea9a877 2257 * @retval None
ganlikun 0:13413ea9a877 2258 */
ganlikun 0:13413ea9a877 2259 static void MMC_DMAError(DMA_HandleTypeDef *hdma)
ganlikun 0:13413ea9a877 2260 {
ganlikun 0:13413ea9a877 2261 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
ganlikun 0:13413ea9a877 2262 HAL_MMC_CardStateTypeDef CardState;
ganlikun 0:13413ea9a877 2263
ganlikun 0:13413ea9a877 2264 if((hmmc->hdmarx->ErrorCode == HAL_DMA_ERROR_TE) || (hmmc->hdmatx->ErrorCode == HAL_DMA_ERROR_TE))
ganlikun 0:13413ea9a877 2265 {
ganlikun 0:13413ea9a877 2266 /* Clear All flags */
ganlikun 0:13413ea9a877 2267 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
ganlikun 0:13413ea9a877 2268
ganlikun 0:13413ea9a877 2269 /* Disable All interrupts */
ganlikun 0:13413ea9a877 2270 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
ganlikun 0:13413ea9a877 2271 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
ganlikun 0:13413ea9a877 2272
ganlikun 0:13413ea9a877 2273 hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
ganlikun 0:13413ea9a877 2274 CardState = HAL_MMC_GetCardState(hmmc);
ganlikun 0:13413ea9a877 2275 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
ganlikun 0:13413ea9a877 2276 {
ganlikun 0:13413ea9a877 2277 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
ganlikun 0:13413ea9a877 2278 }
ganlikun 0:13413ea9a877 2279
ganlikun 0:13413ea9a877 2280 hmmc->State= HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 2281 }
ganlikun 0:13413ea9a877 2282
ganlikun 0:13413ea9a877 2283 HAL_MMC_ErrorCallback(hmmc);
ganlikun 0:13413ea9a877 2284 }
ganlikun 0:13413ea9a877 2285
ganlikun 0:13413ea9a877 2286 /**
ganlikun 0:13413ea9a877 2287 * @brief DMA MMC Tx Abort callback
ganlikun 0:13413ea9a877 2288 * @param hdma: DMA handle
ganlikun 0:13413ea9a877 2289 * @retval None
ganlikun 0:13413ea9a877 2290 */
ganlikun 0:13413ea9a877 2291 static void MMC_DMATxAbort(DMA_HandleTypeDef *hdma)
ganlikun 0:13413ea9a877 2292 {
ganlikun 0:13413ea9a877 2293 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
ganlikun 0:13413ea9a877 2294 HAL_MMC_CardStateTypeDef CardState;
ganlikun 0:13413ea9a877 2295
ganlikun 0:13413ea9a877 2296 if(hmmc->hdmatx != NULL)
ganlikun 0:13413ea9a877 2297 {
ganlikun 0:13413ea9a877 2298 hmmc->hdmatx = NULL;
ganlikun 0:13413ea9a877 2299 }
ganlikun 0:13413ea9a877 2300
ganlikun 0:13413ea9a877 2301 /* All DMA channels are aborted */
ganlikun 0:13413ea9a877 2302 if(hmmc->hdmarx == NULL)
ganlikun 0:13413ea9a877 2303 {
ganlikun 0:13413ea9a877 2304 CardState = HAL_MMC_GetCardState(hmmc);
ganlikun 0:13413ea9a877 2305 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
ganlikun 0:13413ea9a877 2306 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 2307 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
ganlikun 0:13413ea9a877 2308 {
ganlikun 0:13413ea9a877 2309 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
ganlikun 0:13413ea9a877 2310
ganlikun 0:13413ea9a877 2311 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 2312 {
ganlikun 0:13413ea9a877 2313 HAL_MMC_AbortCallback(hmmc);
ganlikun 0:13413ea9a877 2314 }
ganlikun 0:13413ea9a877 2315 else
ganlikun 0:13413ea9a877 2316 {
ganlikun 0:13413ea9a877 2317 HAL_MMC_ErrorCallback(hmmc);
ganlikun 0:13413ea9a877 2318 }
ganlikun 0:13413ea9a877 2319 }
ganlikun 0:13413ea9a877 2320 }
ganlikun 0:13413ea9a877 2321 }
ganlikun 0:13413ea9a877 2322
ganlikun 0:13413ea9a877 2323 /**
ganlikun 0:13413ea9a877 2324 * @brief DMA MMC Rx Abort callback
ganlikun 0:13413ea9a877 2325 * @param hdma: DMA handle
ganlikun 0:13413ea9a877 2326 * @retval None
ganlikun 0:13413ea9a877 2327 */
ganlikun 0:13413ea9a877 2328 static void MMC_DMARxAbort(DMA_HandleTypeDef *hdma)
ganlikun 0:13413ea9a877 2329 {
ganlikun 0:13413ea9a877 2330 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
ganlikun 0:13413ea9a877 2331 HAL_MMC_CardStateTypeDef CardState;
ganlikun 0:13413ea9a877 2332
ganlikun 0:13413ea9a877 2333 if(hmmc->hdmarx != NULL)
ganlikun 0:13413ea9a877 2334 {
ganlikun 0:13413ea9a877 2335 hmmc->hdmarx = NULL;
ganlikun 0:13413ea9a877 2336 }
ganlikun 0:13413ea9a877 2337
ganlikun 0:13413ea9a877 2338 /* All DMA channels are aborted */
ganlikun 0:13413ea9a877 2339 if(hmmc->hdmatx == NULL)
ganlikun 0:13413ea9a877 2340 {
ganlikun 0:13413ea9a877 2341 CardState = HAL_MMC_GetCardState(hmmc);
ganlikun 0:13413ea9a877 2342 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
ganlikun 0:13413ea9a877 2343 hmmc->State = HAL_MMC_STATE_READY;
ganlikun 0:13413ea9a877 2344 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
ganlikun 0:13413ea9a877 2345 {
ganlikun 0:13413ea9a877 2346 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
ganlikun 0:13413ea9a877 2347
ganlikun 0:13413ea9a877 2348 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 2349 {
ganlikun 0:13413ea9a877 2350 HAL_MMC_AbortCallback(hmmc);
ganlikun 0:13413ea9a877 2351 }
ganlikun 0:13413ea9a877 2352 else
ganlikun 0:13413ea9a877 2353 {
ganlikun 0:13413ea9a877 2354 HAL_MMC_ErrorCallback(hmmc);
ganlikun 0:13413ea9a877 2355 }
ganlikun 0:13413ea9a877 2356 }
ganlikun 0:13413ea9a877 2357 }
ganlikun 0:13413ea9a877 2358 }
ganlikun 0:13413ea9a877 2359
ganlikun 0:13413ea9a877 2360
ganlikun 0:13413ea9a877 2361 /**
ganlikun 0:13413ea9a877 2362 * @brief Initializes the mmc card.
ganlikun 0:13413ea9a877 2363 * @param hmmc: Pointer to MMC handle
ganlikun 0:13413ea9a877 2364 * @retval MMC Card error state
ganlikun 0:13413ea9a877 2365 */
ganlikun 0:13413ea9a877 2366 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc)
ganlikun 0:13413ea9a877 2367 {
ganlikun 0:13413ea9a877 2368 HAL_MMC_CardCSDTypeDef CSD;
ganlikun 0:13413ea9a877 2369 uint32_t errorstate = HAL_MMC_ERROR_NONE;
ganlikun 0:13413ea9a877 2370 uint16_t mmc_rca = 1;
ganlikun 0:13413ea9a877 2371
ganlikun 0:13413ea9a877 2372 /* Check the power State */
ganlikun 0:13413ea9a877 2373 if(SDIO_GetPowerState(hmmc->Instance) == 0U)
ganlikun 0:13413ea9a877 2374 {
ganlikun 0:13413ea9a877 2375 /* Power off */
ganlikun 0:13413ea9a877 2376 return HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
ganlikun 0:13413ea9a877 2377 }
ganlikun 0:13413ea9a877 2378
ganlikun 0:13413ea9a877 2379 /* Send CMD2 ALL_SEND_CID */
ganlikun 0:13413ea9a877 2380 errorstate = SDMMC_CmdSendCID(hmmc->Instance);
ganlikun 0:13413ea9a877 2381 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 2382 {
ganlikun 0:13413ea9a877 2383 return errorstate;
ganlikun 0:13413ea9a877 2384 }
ganlikun 0:13413ea9a877 2385 else
ganlikun 0:13413ea9a877 2386 {
ganlikun 0:13413ea9a877 2387 /* Get Card identification number data */
ganlikun 0:13413ea9a877 2388 hmmc->CID[0U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
ganlikun 0:13413ea9a877 2389 hmmc->CID[1U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP2);
ganlikun 0:13413ea9a877 2390 hmmc->CID[2U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP3);
ganlikun 0:13413ea9a877 2391 hmmc->CID[3U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP4);
ganlikun 0:13413ea9a877 2392 }
ganlikun 0:13413ea9a877 2393
ganlikun 0:13413ea9a877 2394 /* Send CMD3 SET_REL_ADDR with argument 0 */
ganlikun 0:13413ea9a877 2395 /* MMC Card publishes its RCA. */
ganlikun 0:13413ea9a877 2396 errorstate = SDMMC_CmdSetRelAdd(hmmc->Instance, &mmc_rca);
ganlikun 0:13413ea9a877 2397 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 2398 {
ganlikun 0:13413ea9a877 2399 return errorstate;
ganlikun 0:13413ea9a877 2400 }
ganlikun 0:13413ea9a877 2401
ganlikun 0:13413ea9a877 2402 /* Get the MMC card RCA */
ganlikun 0:13413ea9a877 2403 hmmc->MmcCard.RelCardAdd = mmc_rca;
ganlikun 0:13413ea9a877 2404
ganlikun 0:13413ea9a877 2405 /* Send CMD9 SEND_CSD with argument as card's RCA */
ganlikun 0:13413ea9a877 2406 errorstate = SDMMC_CmdSendCSD(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
ganlikun 0:13413ea9a877 2407 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 2408 {
ganlikun 0:13413ea9a877 2409 return errorstate;
ganlikun 0:13413ea9a877 2410 }
ganlikun 0:13413ea9a877 2411 else
ganlikun 0:13413ea9a877 2412 {
ganlikun 0:13413ea9a877 2413 /* Get Card Specific Data */
ganlikun 0:13413ea9a877 2414 hmmc->CSD[0U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
ganlikun 0:13413ea9a877 2415 hmmc->CSD[1U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP2);
ganlikun 0:13413ea9a877 2416 hmmc->CSD[2U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP3);
ganlikun 0:13413ea9a877 2417 hmmc->CSD[3U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP4);
ganlikun 0:13413ea9a877 2418 }
ganlikun 0:13413ea9a877 2419
ganlikun 0:13413ea9a877 2420 /* Get the Card Class */
ganlikun 0:13413ea9a877 2421 hmmc->MmcCard.Class = (SDIO_GetResponse(hmmc->Instance, SDIO_RESP2) >> 20U);
ganlikun 0:13413ea9a877 2422
ganlikun 0:13413ea9a877 2423 /* Get CSD parameters */
ganlikun 0:13413ea9a877 2424 HAL_MMC_GetCardCSD(hmmc, &CSD);
ganlikun 0:13413ea9a877 2425
ganlikun 0:13413ea9a877 2426 /* Select the Card */
ganlikun 0:13413ea9a877 2427 errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
ganlikun 0:13413ea9a877 2428 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 2429 {
ganlikun 0:13413ea9a877 2430 return errorstate;
ganlikun 0:13413ea9a877 2431 }
ganlikun 0:13413ea9a877 2432
ganlikun 0:13413ea9a877 2433 /* Configure SDIO peripheral interface */
ganlikun 0:13413ea9a877 2434 SDIO_Init(hmmc->Instance, hmmc->Init);
ganlikun 0:13413ea9a877 2435
ganlikun 0:13413ea9a877 2436 /* All cards are initialized */
ganlikun 0:13413ea9a877 2437 return HAL_MMC_ERROR_NONE;
ganlikun 0:13413ea9a877 2438 }
ganlikun 0:13413ea9a877 2439
ganlikun 0:13413ea9a877 2440 /**
ganlikun 0:13413ea9a877 2441 * @brief Enquires cards about their operating voltage and configures clock
ganlikun 0:13413ea9a877 2442 * controls and stores MMC information that will be needed in future
ganlikun 0:13413ea9a877 2443 * in the MMC handle.
ganlikun 0:13413ea9a877 2444 * @param hmmc: Pointer to MMC handle
ganlikun 0:13413ea9a877 2445 * @retval error state
ganlikun 0:13413ea9a877 2446 */
ganlikun 0:13413ea9a877 2447 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc)
ganlikun 0:13413ea9a877 2448 {
ganlikun 0:13413ea9a877 2449 __IO uint32_t count = 0U;
ganlikun 0:13413ea9a877 2450 uint32_t response = 0U, validvoltage = 0U;
ganlikun 0:13413ea9a877 2451 uint32_t errorstate = HAL_MMC_ERROR_NONE;
ganlikun 0:13413ea9a877 2452
ganlikun 0:13413ea9a877 2453 /* CMD0: GO_IDLE_STATE */
ganlikun 0:13413ea9a877 2454 errorstate = SDMMC_CmdGoIdleState(hmmc->Instance);
ganlikun 0:13413ea9a877 2455 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 2456 {
ganlikun 0:13413ea9a877 2457 return errorstate;
ganlikun 0:13413ea9a877 2458 }
ganlikun 0:13413ea9a877 2459
ganlikun 0:13413ea9a877 2460 while(validvoltage == 0U)
ganlikun 0:13413ea9a877 2461 {
ganlikun 0:13413ea9a877 2462 if(count++ == SDMMC_MAX_VOLT_TRIAL)
ganlikun 0:13413ea9a877 2463 {
ganlikun 0:13413ea9a877 2464 return HAL_MMC_ERROR_INVALID_VOLTRANGE;
ganlikun 0:13413ea9a877 2465 }
ganlikun 0:13413ea9a877 2466
ganlikun 0:13413ea9a877 2467 /* SEND CMD1 APP_CMD with MMC_HIGH_VOLTAGE_RANGE(0xC0FF8000) as argument */
ganlikun 0:13413ea9a877 2468 errorstate = SDMMC_CmdOpCondition(hmmc->Instance, eMMC_HIGH_VOLTAGE_RANGE);
ganlikun 0:13413ea9a877 2469 if(errorstate != HAL_MMC_ERROR_NONE)
ganlikun 0:13413ea9a877 2470 {
ganlikun 0:13413ea9a877 2471 return HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
ganlikun 0:13413ea9a877 2472 }
ganlikun 0:13413ea9a877 2473
ganlikun 0:13413ea9a877 2474 /* Get command response */
ganlikun 0:13413ea9a877 2475 response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
ganlikun 0:13413ea9a877 2476
ganlikun 0:13413ea9a877 2477 /* Get operating voltage*/
ganlikun 0:13413ea9a877 2478 validvoltage = (((response >> 31U) == 1U) ? 1U : 0U);
ganlikun 0:13413ea9a877 2479 }
ganlikun 0:13413ea9a877 2480
ganlikun 0:13413ea9a877 2481 /* When power routine is finished and command returns valid voltage */
ganlikun 0:13413ea9a877 2482 if ((response & eMMC_HIGH_VOLTAGE_RANGE) == MMC_HIGH_VOLTAGE_RANGE)
ganlikun 0:13413ea9a877 2483 {
ganlikun 0:13413ea9a877 2484 /* When voltage range of the card is within 2.7V and 3.6V */
ganlikun 0:13413ea9a877 2485 hmmc->MmcCard.CardType = MMC_HIGH_VOLTAGE_CARD;
ganlikun 0:13413ea9a877 2486 }
ganlikun 0:13413ea9a877 2487 else
ganlikun 0:13413ea9a877 2488 {
ganlikun 0:13413ea9a877 2489 /* When voltage range of the card is within 1.65V and 1.95V or 2.7V and 3.6V */
ganlikun 0:13413ea9a877 2490 hmmc->MmcCard.CardType = MMC_DUAL_VOLTAGE_CARD;
ganlikun 0:13413ea9a877 2491 }
ganlikun 0:13413ea9a877 2492
ganlikun 0:13413ea9a877 2493 return HAL_MMC_ERROR_NONE;
ganlikun 0:13413ea9a877 2494 }
ganlikun 0:13413ea9a877 2495
ganlikun 0:13413ea9a877 2496 /**
ganlikun 0:13413ea9a877 2497 * @brief Turns the SDIO output signals off.
ganlikun 0:13413ea9a877 2498 * @param hmmc: Pointer to MMC handle
ganlikun 0:13413ea9a877 2499 * @retval HAL status
ganlikun 0:13413ea9a877 2500 */
ganlikun 0:13413ea9a877 2501 static HAL_StatusTypeDef MMC_PowerOFF(MMC_HandleTypeDef *hmmc)
ganlikun 0:13413ea9a877 2502 {
ganlikun 0:13413ea9a877 2503 /* Set Power State to OFF */
ganlikun 0:13413ea9a877 2504 SDIO_PowerState_OFF(hmmc->Instance);
ganlikun 0:13413ea9a877 2505
ganlikun 0:13413ea9a877 2506 return HAL_OK;
ganlikun 0:13413ea9a877 2507 }
ganlikun 0:13413ea9a877 2508
ganlikun 0:13413ea9a877 2509 /**
ganlikun 0:13413ea9a877 2510 * @brief Returns the current card's status.
ganlikun 0:13413ea9a877 2511 * @param hmmc: Pointer to MMC handle
ganlikun 0:13413ea9a877 2512 * @param pCardStatus: pointer to the buffer that will contain the MMC card
ganlikun 0:13413ea9a877 2513 * status (Card Status register)
ganlikun 0:13413ea9a877 2514 * @retval error state
ganlikun 0:13413ea9a877 2515 */
ganlikun 0:13413ea9a877 2516 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus)
ganlikun 0:13413ea9a877 2517 {
ganlikun 0:13413ea9a877 2518 uint32_t errorstate = HAL_MMC_ERROR_NONE;
ganlikun 0:13413ea9a877 2519
ganlikun 0:13413ea9a877 2520 if(pCardStatus == NULL)
ganlikun 0:13413ea9a877 2521 {
ganlikun 0:13413ea9a877 2522 return HAL_MMC_ERROR_PARAM;
ganlikun 0:13413ea9a877 2523 }
ganlikun 0:13413ea9a877 2524
ganlikun 0:13413ea9a877 2525 /* Send Status command */
ganlikun 0:13413ea9a877 2526 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
ganlikun 0:13413ea9a877 2527 if(errorstate != HAL_OK)
ganlikun 0:13413ea9a877 2528 {
ganlikun 0:13413ea9a877 2529 return errorstate;
ganlikun 0:13413ea9a877 2530 }
ganlikun 0:13413ea9a877 2531
ganlikun 0:13413ea9a877 2532 /* Get MMC card status */
ganlikun 0:13413ea9a877 2533 *pCardStatus = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
ganlikun 0:13413ea9a877 2534
ganlikun 0:13413ea9a877 2535 return HAL_MMC_ERROR_NONE;
ganlikun 0:13413ea9a877 2536 }
ganlikun 0:13413ea9a877 2537
ganlikun 0:13413ea9a877 2538 /**
ganlikun 0:13413ea9a877 2539 * @brief Wrap up reading in non-blocking mode.
ganlikun 0:13413ea9a877 2540 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 2541 * the configuration information.
ganlikun 0:13413ea9a877 2542 * @retval HAL status
ganlikun 0:13413ea9a877 2543 */
ganlikun 0:13413ea9a877 2544 static HAL_StatusTypeDef MMC_Read_IT(MMC_HandleTypeDef *hmmc)
ganlikun 0:13413ea9a877 2545 {
ganlikun 0:13413ea9a877 2546 uint32_t count = 0U;
ganlikun 0:13413ea9a877 2547 uint32_t* tmp;
ganlikun 0:13413ea9a877 2548
ganlikun 0:13413ea9a877 2549 tmp = (uint32_t*)hmmc->pRxBuffPtr;
ganlikun 0:13413ea9a877 2550
ganlikun 0:13413ea9a877 2551 /* Read data from SDMMC Rx FIFO */
ganlikun 0:13413ea9a877 2552 for(count = 0U; count < 8U; count++)
ganlikun 0:13413ea9a877 2553 {
ganlikun 0:13413ea9a877 2554 *(tmp + count) = SDIO_ReadFIFO(hmmc->Instance);
ganlikun 0:13413ea9a877 2555 }
ganlikun 0:13413ea9a877 2556
ganlikun 0:13413ea9a877 2557 hmmc->pRxBuffPtr += 8U;
ganlikun 0:13413ea9a877 2558
ganlikun 0:13413ea9a877 2559 return HAL_OK;
ganlikun 0:13413ea9a877 2560 }
ganlikun 0:13413ea9a877 2561
ganlikun 0:13413ea9a877 2562 /**
ganlikun 0:13413ea9a877 2563 * @brief Wrap up writing in non-blocking mode.
ganlikun 0:13413ea9a877 2564 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
ganlikun 0:13413ea9a877 2565 * the configuration information.
ganlikun 0:13413ea9a877 2566 * @retval HAL status
ganlikun 0:13413ea9a877 2567 */
ganlikun 0:13413ea9a877 2568 static HAL_StatusTypeDef MMC_Write_IT(MMC_HandleTypeDef *hmmc)
ganlikun 0:13413ea9a877 2569 {
ganlikun 0:13413ea9a877 2570 uint32_t count = 0U;
ganlikun 0:13413ea9a877 2571 uint32_t* tmp;
ganlikun 0:13413ea9a877 2572
ganlikun 0:13413ea9a877 2573 tmp = (uint32_t*)hmmc->pTxBuffPtr;
ganlikun 0:13413ea9a877 2574
ganlikun 0:13413ea9a877 2575 /* Write data to SDMMC Tx FIFO */
ganlikun 0:13413ea9a877 2576 for(count = 0U; count < 8U; count++)
ganlikun 0:13413ea9a877 2577 {
ganlikun 0:13413ea9a877 2578 SDIO_WriteFIFO(hmmc->Instance, (tmp + count));
ganlikun 0:13413ea9a877 2579 }
ganlikun 0:13413ea9a877 2580
ganlikun 0:13413ea9a877 2581 hmmc->pTxBuffPtr += 8U;
ganlikun 0:13413ea9a877 2582
ganlikun 0:13413ea9a877 2583 return HAL_OK;
ganlikun 0:13413ea9a877 2584 }
ganlikun 0:13413ea9a877 2585
ganlikun 0:13413ea9a877 2586 /**
ganlikun 0:13413ea9a877 2587 * @}
ganlikun 0:13413ea9a877 2588 */
ganlikun 0:13413ea9a877 2589
ganlikun 0:13413ea9a877 2590 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx ||
ganlikun 0:13413ea9a877 2591 STM32F401xC || STM32F401xE || STM32F411xE || STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx ||
ganlikun 0:13413ea9a877 2592 STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */
ganlikun 0:13413ea9a877 2593
ganlikun 0:13413ea9a877 2594 #endif /* HAL_MMC_MODULE_ENABLED */
ganlikun 0:13413ea9a877 2595
ganlikun 0:13413ea9a877 2596 /**
ganlikun 0:13413ea9a877 2597 * @}
ganlikun 0:13413ea9a877 2598 */
ganlikun 0:13413ea9a877 2599
ganlikun 0:13413ea9a877 2600 /**
ganlikun 0:13413ea9a877 2601 * @}
ganlikun 0:13413ea9a877 2602 */
ganlikun 0:13413ea9a877 2603
ganlikun 0:13413ea9a877 2604 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
ganlikun 0:13413ea9a877 2605