inport from local

Dependents:   Hobbyking_Cheetah_0511

Committer:
NYX
Date:
Mon Mar 16 06:35:48 2020 +0000
Revision:
0:85b3fd62ea1a
reinport to mbed;

Who changed what in which revision?

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