Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:08

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_hal_mmc.c
0004   * @author  MCD Application Team
0005   * @brief   MMC card HAL module driver.
0006   *          This file provides firmware functions to manage the following
0007   *          functionalities of the Secure Digital (MMC) peripheral:
0008   *           + Initialization and de-initialization functions
0009   *           + IO operation functions
0010   *           + Peripheral Control functions
0011   *           + MMC card Control functions
0012   *
0013   ******************************************************************************
0014   * @attention
0015   *
0016   * Copyright (c) 2017 STMicroelectronics.
0017   * All rights reserved.
0018   *
0019   * This software is licensed under terms that can be found in the LICENSE file
0020   * in the root directory of this software component.
0021   * If no LICENSE file comes with this software, it is provided AS-IS.
0022   *
0023   ******************************************************************************
0024   @verbatim
0025   ==============================================================================
0026                         ##### How to use this driver #####
0027   ==============================================================================
0028   [..]
0029     This driver implements a high level communication layer for read and write from/to
0030     this memory. The needed STM32 hardware resources (SDMMC and GPIO) are performed by
0031     the user in HAL_MMC_MspInit() function (MSP layer).
0032     Basically, the MSP layer configuration should be the same as we provide in the
0033     examples.
0034     You can easily tailor this configuration according to hardware resources.
0035 
0036   [..]
0037     This driver is a generic layered driver for SDMMC memories which uses the HAL
0038     SDMMC driver functions to interface with MMC and eMMC cards devices.
0039     It is used as follows:
0040 
0041     (#)Initialize the SDMMC low level resources by implement the HAL_MMC_MspInit() API:
0042         (##) Enable the SDMMC interface clock using __HAL_RCC_SDMMC_CLK_ENABLE();
0043         (##) SDMMC pins configuration for MMC card
0044             (+++) Enable the clock for the SDMMC GPIOs using the functions __HAL_RCC_GPIOx_CLK_ENABLE();
0045             (+++) Configure these SDMMC pins as alternate function pull-up using HAL_GPIO_Init()
0046                   and according to your pin assignment;
0047         (##) NVIC configuration if you need to use interrupt process (HAL_MMC_ReadBlocks_IT()
0048              and HAL_MMC_WriteBlocks_IT() APIs).
0049             (+++) Configure the SDMMC interrupt priorities using function HAL_NVIC_SetPriority();
0050             (+++) Enable the NVIC SDMMC IRQs using function HAL_NVIC_EnableIRQ()
0051             (+++) SDMMC interrupts are managed using the macros __HAL_MMC_ENABLE_IT()
0052                   and __HAL_MMC_DISABLE_IT() inside the communication process.
0053             (+++) SDMMC interrupts pending bits are managed using the macros __HAL_MMC_GET_IT()
0054                   and __HAL_MMC_CLEAR_IT()
0055         (##) No general propose DMA Configuration is needed, an Internal DMA for SDMMC Peripheral are used.
0056 
0057     (#) At this stage, you can perform MMC read/write/erase operations after MMC card initialization
0058 
0059 
0060   *** MMC Card Initialization and configuration ***
0061   ================================================
0062   [..]
0063     To initialize the MMC Card, use the HAL_MMC_Init() function. It Initializes
0064     SDMMC Peripheral (STM32 side) and the MMC Card, and put it into StandBy State (Ready for data transfer).
0065     This function provide the following operations:
0066 
0067     (#) Initialize the SDMMC peripheral interface with default configuration.
0068         The initialization process is done at 400KHz. You can change or adapt
0069         this frequency by adjusting the "ClockDiv" field.
0070         The MMC Card frequency (SDMMC_CK) is computed as follows:
0071 
0072            SDMMC_CK = SDMMCCLK / (2 * ClockDiv)
0073 
0074         In initialization mode and according to the MMC Card standard,
0075         make sure that the SDMMC_CK frequency doesn't exceed 400KHz.
0076 
0077         This phase of initialization is done through SDMMC_Init() and
0078         SDMMC_PowerState_ON() SDMMC low level APIs.
0079 
0080     (#) Initialize the MMC card. The API used is HAL_MMC_InitCard().
0081         This phase allows the card initialization and identification
0082         and check the MMC Card type (Standard Capacity or High Capacity)
0083         The initialization flow is compatible with MMC standard.
0084 
0085         This API (HAL_MMC_InitCard()) could be used also to reinitialize the card in case
0086         of plug-off plug-in.
0087 
0088     (#) Configure the MMC Card Data transfer frequency. By Default, the card transfer
0089         frequency by adjusting the "ClockDiv" field.
0090         In transfer mode and according to the MMC Card standard, make sure that the
0091         SDMMC_CK frequency doesn't exceed 25MHz and 100MHz in High-speed mode switch.
0092 
0093     (#) Select the corresponding MMC Card according to the address read with the step 2.
0094 
0095     (#) Configure the MMC Card in wide bus mode: 4-bits data.
0096 
0097   *** MMC Card Read operation ***
0098   ==============================
0099   [..]
0100     (+) You can read from MMC card in polling mode by using function HAL_MMC_ReadBlocks().
0101         This function support only 512-bytes block length (the block size should be
0102         chosen as 512 bytes).
0103         You can choose either one block read operation or multiple block read operation
0104         by adjusting the "NumberOfBlocks" parameter.
0105         After this, you have to ensure that the transfer is done correctly. The check is done
0106         through HAL_MMC_GetCardState() function for MMC card state.
0107 
0108     (+) You can read from MMC card in DMA mode by using function HAL_MMC_ReadBlocks_DMA().
0109         This function support only 512-bytes block length (the block size should be
0110         chosen as 512 bytes).
0111         You can choose either one block read operation or multiple block read operation
0112         by adjusting the "NumberOfBlocks" parameter.
0113         After this, you have to ensure that the transfer is done correctly. The check is done
0114         through HAL_MMC_GetCardState() function for MMC card state.
0115         You could also check the DMA transfer process through the MMC Rx interrupt event.
0116 
0117     (+) You can read from MMC card in Interrupt mode by using function HAL_MMC_ReadBlocks_IT().
0118         This function allows the read of 512 bytes blocks.
0119         You can choose either one block read operation or multiple block read operation
0120         by adjusting the "NumberOfBlocks" parameter.
0121         After this, you have to ensure that the transfer is done correctly. The check is done
0122         through HAL_MMC_GetCardState() function for MMC card state.
0123         You could also check the IT transfer process through the MMC Rx interrupt event.
0124 
0125   *** MMC Card Write operation ***
0126   ===============================
0127   [..]
0128     (+) You can write to MMC card in polling mode by using function HAL_MMC_WriteBlocks().
0129         This function support only 512-bytes block length (the block size should be
0130         chosen as 512 bytes).
0131         You can choose either one block read operation or multiple block read operation
0132         by adjusting the "NumberOfBlocks" parameter.
0133         After this, you have to ensure that the transfer is done correctly. The check is done
0134         through HAL_MMC_GetCardState() function for MMC card state.
0135 
0136     (+) You can write to MMC card in DMA mode by using function HAL_MMC_WriteBlocks_DMA().
0137         This function support only 512-bytes block length (the block size should be
0138         chosen as 512 byte).
0139         You can choose either one block read operation or multiple block read operation
0140         by adjusting the "NumberOfBlocks" parameter.
0141         After this, you have to ensure that the transfer is done correctly. The check is done
0142         through HAL_MMC_GetCardState() function for MMC card state.
0143         You could also check the DMA transfer process through the MMC Tx interrupt event.
0144 
0145     (+) You can write to MMC card in Interrupt mode by using function HAL_MMC_WriteBlocks_IT().
0146         This function allows the read of 512 bytes blocks.
0147         You can choose either one block read operation or multiple block read operation
0148         by adjusting the "NumberOfBlocks" parameter.
0149         After this, you have to ensure that the transfer is done correctly. The check is done
0150         through HAL_MMC_GetCardState() function for MMC card state.
0151         You could also check the IT transfer process through the MMC Tx interrupt event.
0152 
0153   *** MMC card information ***
0154   ===========================
0155   [..]
0156     (+) To get MMC card information, you can use the function HAL_MMC_GetCardInfo().
0157         It returns useful information about the MMC card such as block size, card type,
0158         block number ...
0159 
0160   *** MMC card CSD register ***
0161   ============================
0162   [..]
0163     (+) The HAL_MMC_GetCardCSD() API allows to get the parameters of the CSD register.
0164         Some of the CSD parameters are useful for card initialization and identification.
0165 
0166   *** MMC card CID register ***
0167   ============================
0168   [..]
0169     (+) The HAL_MMC_GetCardCID() API allows to get the parameters of the CID register.
0170         Some of the CID parameters are useful for card initialization and identification.
0171 
0172   *** MMC HAL driver macros list ***
0173   ==================================
0174   [..]
0175     Below the list of most used macros in MMC HAL driver.
0176 
0177     (+) __HAL_MMC_ENABLE_IT: Enable the MMC device interrupt
0178     (+) __HAL_MMC_DISABLE_IT: Disable the MMC device interrupt
0179     (+) __HAL_MMC_GET_FLAG:Check whether the specified MMC flag is set or not
0180     (+) __HAL_MMC_CLEAR_FLAG: Clear the MMC's pending flags
0181 
0182   [..]
0183     (@) You can refer to the MMC HAL driver header file for more useful macros
0184 
0185   *** Callback registration ***
0186   =============================================
0187   [..]
0188     The compilation define USE_HAL_MMC_REGISTER_CALLBACKS when set to 1
0189     allows the user to configure dynamically the driver callbacks.
0190 
0191     Use Functions HAL_MMC_RegisterCallback() to register a user callback,
0192     it allows to register following callbacks:
0193       (+) TxCpltCallback : callback when a transmission transfer is completed.
0194       (+) RxCpltCallback : callback when a reception transfer is completed.
0195       (+) ErrorCallback : callback when error occurs.
0196       (+) AbortCpltCallback : callback when abort is completed.
0197       (+) Read_DMADblBuf0CpltCallback : callback when the DMA reception of first buffer is completed.
0198       (+) Read_DMADblBuf1CpltCallback : callback when the DMA reception of second buffer is completed.
0199       (+) Write_DMADblBuf0CpltCallback : callback when the DMA transmission of first buffer is completed.
0200       (+) Write_DMADblBuf1CpltCallback : callback when the DMA transmission of second buffer is completed.
0201       (+) MspInitCallback    : MMC MspInit.
0202       (+) MspDeInitCallback  : MMC MspDeInit.
0203     This function takes as parameters the HAL peripheral handle, the Callback ID
0204     and a pointer to the user callback function.
0205 
0206     Use function HAL_MMC_UnRegisterCallback() to reset a callback to the default
0207     weak (surcharged) function. It allows to reset following callbacks:
0208       (+) TxCpltCallback : callback when a transmission transfer is completed.
0209       (+) RxCpltCallback : callback when a reception transfer is completed.
0210       (+) ErrorCallback : callback when error occurs.
0211       (+) AbortCpltCallback : callback when abort is completed.
0212       (+) Read_DMADblBuf0CpltCallback : callback when the DMA reception of first buffer is completed.
0213       (+) Read_DMADblBuf1CpltCallback : callback when the DMA reception of second buffer is completed.
0214       (+) Write_DMADblBuf0CpltCallback : callback when the DMA transmission of first buffer is completed.
0215       (+) Write_DMADblBuf1CpltCallback : callback when the DMA transmission of second buffer is completed.
0216       (+) MspInitCallback    : MMC MspInit.
0217       (+) MspDeInitCallback  : MMC MspDeInit.
0218     This function) takes as parameters the HAL peripheral handle and the Callback ID.
0219 
0220     By default, after the HAL_MMC_Init and if the state is HAL_MMC_STATE_RESET
0221     all callbacks are reset to the corresponding legacy weak (surcharged) functions.
0222     Exception done for MspInit and MspDeInit callbacks that are respectively
0223     reset to the legacy weak (surcharged) functions in the HAL_MMC_Init
0224     and HAL_MMC_DeInit only when these callbacks are null (not registered beforehand).
0225     If not, MspInit or MspDeInit are not null, the HAL_MMC_Init and HAL_MMC_DeInit
0226     keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
0227 
0228     Callbacks can be registered/unregistered in READY state only.
0229     Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
0230     in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
0231     during the Init/DeInit.
0232     In that case first register the MspInit/MspDeInit user callbacks
0233     using HAL_MMC_RegisterCallback before calling HAL_MMC_DeInit
0234     or HAL_MMC_Init function.
0235 
0236     When The compilation define USE_HAL_MMC_REGISTER_CALLBACKS is set to 0 or
0237     not defined, the callback registering feature is not available
0238     and weak (surcharged) callbacks are used.
0239 
0240   @endverbatim
0241   ******************************************************************************
0242   */
0243 
0244 /* Includes ------------------------------------------------------------------*/
0245 #include "stm32h7xx_hal.h"
0246 
0247 /** @addtogroup STM32H7xx_HAL_Driver
0248   * @{
0249   */
0250 
0251 /** @defgroup MMC MMC
0252   * @ingroup RTEMSBSPsARMSTM32H7
0253   * @brief MMC HAL module driver
0254   * @{
0255   */
0256 
0257 #ifdef HAL_MMC_MODULE_ENABLED
0258 
0259 /* Private typedef -----------------------------------------------------------*/
0260 /* Private define ------------------------------------------------------------*/
0261 /** @addtogroup MMC_Private_Defines
0262   * @{
0263   */
0264 #if defined (VDD_VALUE) && (VDD_VALUE <= 1950U)
0265 #define MMC_VOLTAGE_RANGE               EMMC_LOW_VOLTAGE_RANGE
0266 
0267 #define MMC_EXT_CSD_PWR_CL_26_INDEX     201
0268 #define MMC_EXT_CSD_PWR_CL_52_INDEX     200
0269 #define MMC_EXT_CSD_PWR_CL_DDR_52_INDEX 238
0270 
0271 #define MMC_EXT_CSD_PWR_CL_26_POS       8
0272 #define MMC_EXT_CSD_PWR_CL_52_POS       0
0273 #define MMC_EXT_CSD_PWR_CL_DDR_52_POS   16
0274 #else
0275 #define MMC_VOLTAGE_RANGE               EMMC_HIGH_VOLTAGE_RANGE
0276 
0277 #define MMC_EXT_CSD_PWR_CL_26_INDEX     203
0278 #define MMC_EXT_CSD_PWR_CL_52_INDEX     202
0279 #define MMC_EXT_CSD_PWR_CL_DDR_52_INDEX 239
0280 
0281 #define MMC_EXT_CSD_PWR_CL_26_POS       24
0282 #define MMC_EXT_CSD_PWR_CL_52_POS       16
0283 #define MMC_EXT_CSD_PWR_CL_DDR_52_POS   24
0284 #endif /* (VDD_VALUE) && (VDD_VALUE <= 1950U)*/
0285 
0286 #define MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_INDEX 216
0287 #define MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_POS   0
0288 #define MMC_EXT_CSD_S_A_TIMEOUT_INDEX             217
0289 #define MMC_EXT_CSD_S_A_TIMEOUT_POS               8
0290 
0291 /* Frequencies used in the driver for clock divider calculation */
0292 #define MMC_INIT_FREQ                   400000U   /* Initialization phase : 400 kHz max */
0293 #define MMC_HIGH_SPEED_FREQ             52000000U /* High speed phase : 52 MHz max */
0294 /**
0295   * @}
0296   */
0297 
0298 /* Private macro -------------------------------------------------------------*/
0299 /* Private variables ---------------------------------------------------------*/
0300 /* Private function prototypes -----------------------------------------------*/
0301 /* Private functions ---------------------------------------------------------*/
0302 /** @defgroup MMC_Private_Functions MMC Private Functions
0303   * @ingroup RTEMSBSPsARMSTM32H7
0304   * @{
0305   */
0306 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc);
0307 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc);
0308 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus);
0309 static void     MMC_PowerOFF(MMC_HandleTypeDef *hmmc);
0310 static void     MMC_Write_IT(MMC_HandleTypeDef *hmmc);
0311 static void     MMC_Read_IT(MMC_HandleTypeDef *hmmc);
0312 static uint32_t MMC_HighSpeed(MMC_HandleTypeDef *hmmc, FunctionalState state);
0313 static uint32_t MMC_DDR_Mode(MMC_HandleTypeDef *hmmc, FunctionalState state);
0314 static HAL_StatusTypeDef MMC_ReadExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pFieldData, uint16_t FieldIndex,
0315                                         uint32_t Timeout);
0316 static uint32_t MMC_PwrClassUpdate(MMC_HandleTypeDef *hmmc, uint32_t Wide, uint32_t Speed);
0317 
0318 /**
0319   * @}
0320   */
0321 /* Exported functions --------------------------------------------------------*/
0322 /** @addtogroup MMC_Exported_Functions
0323   * @{
0324   */
0325 
0326 /** @addtogroup MMC_Exported_Functions_Group1
0327   *  @brief   Initialization and de-initialization functions
0328   *
0329 @verbatim
0330   ==============================================================================
0331           ##### Initialization and de-initialization functions #####
0332   ==============================================================================
0333   [..]
0334     This section provides functions allowing to initialize/de-initialize the MMC
0335     card device to be ready for use.
0336 
0337 @endverbatim
0338   * @{
0339   */
0340 
0341 /**
0342   * @brief  Initializes the MMC according to the specified parameters in the
0343             MMC_HandleTypeDef and create the associated handle.
0344   * @param  hmmc: Pointer to the MMC handle
0345   * @retval HAL status
0346   */
0347 HAL_StatusTypeDef HAL_MMC_Init(MMC_HandleTypeDef *hmmc)
0348 {
0349   /* Check the MMC handle allocation */
0350   if (hmmc == NULL)
0351   {
0352     return HAL_ERROR;
0353   }
0354 
0355   /* Check the parameters */
0356   assert_param(IS_SDMMC_ALL_INSTANCE(hmmc->Instance));
0357   assert_param(IS_SDMMC_CLOCK_EDGE(hmmc->Init.ClockEdge));
0358   assert_param(IS_SDMMC_CLOCK_POWER_SAVE(hmmc->Init.ClockPowerSave));
0359   assert_param(IS_SDMMC_BUS_WIDE(hmmc->Init.BusWide));
0360   assert_param(IS_SDMMC_HARDWARE_FLOW_CONTROL(hmmc->Init.HardwareFlowControl));
0361   assert_param(IS_SDMMC_CLKDIV(hmmc->Init.ClockDiv));
0362 
0363   if (hmmc->State == HAL_MMC_STATE_RESET)
0364   {
0365     /* Allocate lock resource and initialize it */
0366     hmmc->Lock = HAL_UNLOCKED;
0367 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
0368     /* Reset Callback pointers in HAL_MMC_STATE_RESET only */
0369     hmmc->TxCpltCallback    = HAL_MMC_TxCpltCallback;
0370     hmmc->RxCpltCallback    = HAL_MMC_RxCpltCallback;
0371     hmmc->ErrorCallback     = HAL_MMC_ErrorCallback;
0372     hmmc->AbortCpltCallback = HAL_MMC_AbortCallback;
0373     hmmc->Read_DMADblBuf0CpltCallback = HAL_MMCEx_Read_DMADoubleBuf0CpltCallback;
0374     hmmc->Read_DMADblBuf1CpltCallback = HAL_MMCEx_Read_DMADoubleBuf1CpltCallback;
0375     hmmc->Write_DMADblBuf0CpltCallback = HAL_MMCEx_Write_DMADoubleBuf0CpltCallback;
0376     hmmc->Write_DMADblBuf1CpltCallback = HAL_MMCEx_Write_DMADoubleBuf1CpltCallback;
0377 
0378     if (hmmc->MspInitCallback == NULL)
0379     {
0380       hmmc->MspInitCallback = HAL_MMC_MspInit;
0381     }
0382 
0383     /* Init the low level hardware */
0384     hmmc->MspInitCallback(hmmc);
0385 #else
0386     /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
0387     HAL_MMC_MspInit(hmmc);
0388 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
0389   }
0390 
0391   hmmc->State = HAL_MMC_STATE_BUSY;
0392 
0393   /* Initialize the Card parameters */
0394   if (HAL_MMC_InitCard(hmmc) == HAL_ERROR)
0395   {
0396     return HAL_ERROR;
0397   }
0398 
0399   /* Initialize the error code */
0400   hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
0401 
0402   /* Initialize the MMC operation */
0403   hmmc->Context = MMC_CONTEXT_NONE;
0404 
0405   /* Initialize the MMC state */
0406   hmmc->State = HAL_MMC_STATE_READY;
0407 
0408   /* Configure bus width */
0409   if (hmmc->Init.BusWide != SDMMC_BUS_WIDE_1B)
0410   {
0411     if (HAL_MMC_ConfigWideBusOperation(hmmc, hmmc->Init.BusWide) != HAL_OK)
0412     {
0413       return HAL_ERROR;
0414     }
0415   }
0416 
0417   return HAL_OK;
0418 }
0419 
0420 /**
0421   * @brief  Initializes the MMC Card.
0422   * @param  hmmc: Pointer to MMC handle
0423   * @note   This function initializes the MMC card. It could be used when a card
0424             re-initialization is needed.
0425   * @retval HAL status
0426   */
0427 HAL_StatusTypeDef HAL_MMC_InitCard(MMC_HandleTypeDef *hmmc)
0428 {
0429   uint32_t errorstate;
0430   MMC_InitTypeDef Init;
0431   uint32_t sdmmc_clk;
0432 
0433   /* Default SDMMC peripheral configuration for MMC card initialization */
0434   Init.ClockEdge           = SDMMC_CLOCK_EDGE_RISING;
0435   Init.ClockPowerSave      = SDMMC_CLOCK_POWER_SAVE_DISABLE;
0436   Init.BusWide             = SDMMC_BUS_WIDE_1B;
0437   Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
0438 
0439   /* Init Clock should be less or equal to 400Khz*/
0440   sdmmc_clk     = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC);
0441   if (sdmmc_clk == 0U)
0442   {
0443     hmmc->State = HAL_MMC_STATE_READY;
0444     hmmc->ErrorCode = SDMMC_ERROR_INVALID_PARAMETER;
0445     return HAL_ERROR;
0446   }
0447   Init.ClockDiv = sdmmc_clk / (2U * MMC_INIT_FREQ);
0448 
0449 #if (USE_SD_TRANSCEIVER != 0U)
0450   Init.TranceiverPresent = SDMMC_TRANSCEIVER_NOT_PRESENT;
0451 #endif /* USE_SD_TRANSCEIVER */
0452 
0453   /* Initialize SDMMC peripheral interface with default configuration */
0454   (void)SDMMC_Init(hmmc->Instance, Init);
0455 
0456   /* Set Power State to ON */
0457   (void)SDMMC_PowerState_ON(hmmc->Instance);
0458 
0459   /* wait 74 Cycles: required power up waiting time before starting
0460      the MMC initialization sequence */
0461   if (Init.ClockDiv != 0U)
0462   {
0463     sdmmc_clk = sdmmc_clk / (2U * Init.ClockDiv);
0464   }
0465 
0466   if (sdmmc_clk != 0U)
0467   {
0468     HAL_Delay(1U + (74U * 1000U / (sdmmc_clk)));
0469   }
0470 
0471   /* Identify card operating voltage */
0472   errorstate = MMC_PowerON(hmmc);
0473   if (errorstate != HAL_MMC_ERROR_NONE)
0474   {
0475     hmmc->State = HAL_MMC_STATE_READY;
0476     hmmc->ErrorCode |= errorstate;
0477     return HAL_ERROR;
0478   }
0479 
0480   /* Card initialization */
0481   errorstate = MMC_InitCard(hmmc);
0482   if (errorstate != HAL_MMC_ERROR_NONE)
0483   {
0484     hmmc->State = HAL_MMC_STATE_READY;
0485     hmmc->ErrorCode |= errorstate;
0486     return HAL_ERROR;
0487   }
0488 
0489   /* Set Block Size for Card */
0490   errorstate = SDMMC_CmdBlockLength(hmmc->Instance, MMC_BLOCKSIZE);
0491   if (errorstate != HAL_MMC_ERROR_NONE)
0492   {
0493     /* Clear all the static flags */
0494     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
0495     hmmc->ErrorCode |= errorstate;
0496     hmmc->State = HAL_MMC_STATE_READY;
0497     return HAL_ERROR;
0498   }
0499 
0500   return HAL_OK;
0501 }
0502 
0503 /**
0504   * @brief  De-Initializes the MMC card.
0505   * @param  hmmc: Pointer to MMC handle
0506   * @retval HAL status
0507   */
0508 HAL_StatusTypeDef HAL_MMC_DeInit(MMC_HandleTypeDef *hmmc)
0509 {
0510   /* Check the MMC handle allocation */
0511   if (hmmc == NULL)
0512   {
0513     return HAL_ERROR;
0514   }
0515 
0516   /* Check the parameters */
0517   assert_param(IS_SDMMC_ALL_INSTANCE(hmmc->Instance));
0518 
0519   hmmc->State = HAL_MMC_STATE_BUSY;
0520 
0521   /* Set MMC power state to off */
0522   MMC_PowerOFF(hmmc);
0523 
0524 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
0525   if (hmmc->MspDeInitCallback == NULL)
0526   {
0527     hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
0528   }
0529 
0530   /* DeInit the low level hardware */
0531   hmmc->MspDeInitCallback(hmmc);
0532 #else
0533   /* De-Initialize the MSP layer */
0534   HAL_MMC_MspDeInit(hmmc);
0535 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
0536 
0537   hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
0538   hmmc->State = HAL_MMC_STATE_RESET;
0539 
0540   return HAL_OK;
0541 }
0542 
0543 
0544 /**
0545   * @brief  Initializes the MMC MSP.
0546   * @param  hmmc: Pointer to MMC handle
0547   * @retval None
0548   */
0549 __weak void HAL_MMC_MspInit(MMC_HandleTypeDef *hmmc)
0550 {
0551   /* Prevent unused argument(s) compilation warning */
0552   UNUSED(hmmc);
0553 
0554   /* NOTE : This function Should not be modified, when the callback is needed,
0555             the HAL_MMC_MspInit could be implemented in the user file
0556    */
0557 }
0558 
0559 /**
0560   * @brief  De-Initialize MMC MSP.
0561   * @param  hmmc: Pointer to MMC handle
0562   * @retval None
0563   */
0564 __weak void HAL_MMC_MspDeInit(MMC_HandleTypeDef *hmmc)
0565 {
0566   /* Prevent unused argument(s) compilation warning */
0567   UNUSED(hmmc);
0568 
0569   /* NOTE : This function Should not be modified, when the callback is needed,
0570             the HAL_MMC_MspDeInit could be implemented in the user file
0571    */
0572 }
0573 
0574 /**
0575   * @}
0576   */
0577 
0578 /** @addtogroup MMC_Exported_Functions_Group2
0579   *  @brief   Data transfer functions
0580   *
0581 @verbatim
0582   ==============================================================================
0583                         ##### IO operation functions #####
0584   ==============================================================================
0585   [..]
0586     This subsection provides a set of functions allowing to manage the data
0587     transfer from/to MMC card.
0588 
0589 @endverbatim
0590   * @{
0591   */
0592 
0593 /**
0594   * @brief  Reads block(s) from a specified address in a card. The Data transfer
0595   *         is managed by polling mode.
0596   * @note   This API should be followed by a check on the card state through
0597   *         HAL_MMC_GetCardState().
0598   * @param  hmmc: Pointer to MMC handle
0599   * @param  pData: pointer to the buffer that will contain the received data
0600   * @param  BlockAdd: Block Address from where data is to be read
0601   * @param  NumberOfBlocks: Number of MMC blocks to read
0602   * @param  Timeout: Specify timeout value
0603   * @retval HAL status
0604   */
0605 HAL_StatusTypeDef HAL_MMC_ReadBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd,
0606                                      uint32_t NumberOfBlocks,
0607                                      uint32_t Timeout)
0608 {
0609   SDMMC_DataInitTypeDef config;
0610   uint32_t errorstate;
0611   uint32_t tickstart = HAL_GetTick();
0612   uint32_t count;
0613   uint32_t data;
0614   uint32_t dataremaining;
0615   uint32_t add = BlockAdd;
0616   uint8_t *tempbuff = pData;
0617 
0618   if (NULL == pData)
0619   {
0620     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
0621     return HAL_ERROR;
0622   }
0623 
0624   if (hmmc->State == HAL_MMC_STATE_READY)
0625   {
0626     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
0627 
0628     if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
0629     {
0630       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
0631       return HAL_ERROR;
0632     }
0633 
0634     /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
0635     if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS)
0636          & 0x000000FFU) != 0x0U)
0637     {
0638       if ((NumberOfBlocks % 8U) != 0U)
0639       {
0640         /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */
0641         hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR;
0642         return HAL_ERROR;
0643       }
0644 
0645       if ((BlockAdd % 8U) != 0U)
0646       {
0647         /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
0648         hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
0649         return HAL_ERROR;
0650       }
0651     }
0652 
0653     hmmc->State = HAL_MMC_STATE_BUSY;
0654 
0655     /* Initialize data control register */
0656     hmmc->Instance->DCTRL = 0U;
0657 
0658     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
0659     {
0660       add *= 512U;
0661     }
0662 
0663     /* Configure the MMC DPSM (Data Path State Machine) */
0664     config.DataTimeOut   = SDMMC_DATATIMEOUT;
0665     config.DataLength    = NumberOfBlocks * MMC_BLOCKSIZE;
0666     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
0667     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
0668     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
0669     config.DPSM          = SDMMC_DPSM_DISABLE;
0670     (void)SDMMC_ConfigData(hmmc->Instance, &config);
0671     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
0672 
0673     /* Read block(s) in polling mode */
0674     if (NumberOfBlocks > 1U)
0675     {
0676       hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
0677 
0678       /* Read Multi Block command */
0679       errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
0680     }
0681     else
0682     {
0683       hmmc->Context = MMC_CONTEXT_READ_SINGLE_BLOCK;
0684 
0685       /* Read Single Block command */
0686       errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
0687     }
0688     if (errorstate != HAL_MMC_ERROR_NONE)
0689     {
0690       /* Clear all the static flags */
0691       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
0692       hmmc->ErrorCode |= errorstate;
0693       hmmc->State = HAL_MMC_STATE_READY;
0694       return HAL_ERROR;
0695     }
0696 
0697     /* Poll on SDMMC flags */
0698     dataremaining = config.DataLength;
0699     while (!__HAL_MMC_GET_FLAG(hmmc,
0700                                SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
0701     {
0702       if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= 32U))
0703       {
0704         /* Read data from SDMMC Rx FIFO */
0705         for (count = 0U; count < 8U; count++)
0706         {
0707           data = SDMMC_ReadFIFO(hmmc->Instance);
0708           *tempbuff = (uint8_t)(data & 0xFFU);
0709           tempbuff++;
0710           *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
0711           tempbuff++;
0712           *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
0713           tempbuff++;
0714           *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
0715           tempbuff++;
0716         }
0717         dataremaining -= 32U;
0718       }
0719 
0720       if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
0721       {
0722         /* Clear all the static flags */
0723         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
0724         hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
0725         hmmc->State = HAL_MMC_STATE_READY;
0726         return HAL_TIMEOUT;
0727       }
0728     }
0729     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
0730 
0731     /* Send stop transmission command in case of multiblock read */
0732     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U))
0733     {
0734       /* Send stop transmission command */
0735       errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
0736       if (errorstate != HAL_MMC_ERROR_NONE)
0737       {
0738         /* Clear all the static flags */
0739         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
0740         hmmc->ErrorCode |= errorstate;
0741         hmmc->State = HAL_MMC_STATE_READY;
0742         return HAL_ERROR;
0743       }
0744     }
0745 
0746     /* Get error state */
0747     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
0748     {
0749       /* Clear all the static flags */
0750       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
0751       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
0752       hmmc->State = HAL_MMC_STATE_READY;
0753       return HAL_ERROR;
0754     }
0755     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
0756     {
0757       /* Clear all the static flags */
0758       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
0759       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
0760       hmmc->State = HAL_MMC_STATE_READY;
0761       return HAL_ERROR;
0762     }
0763     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR))
0764     {
0765       /* Clear all the static flags */
0766       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
0767       hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
0768       hmmc->State = HAL_MMC_STATE_READY;
0769       return HAL_ERROR;
0770     }
0771     else
0772     {
0773       /* Nothing to do */
0774     }
0775 
0776     /* Clear all the static flags */
0777     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
0778 
0779     hmmc->State = HAL_MMC_STATE_READY;
0780 
0781     return HAL_OK;
0782   }
0783   else
0784   {
0785     hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
0786     return HAL_ERROR;
0787   }
0788 }
0789 
0790 /**
0791   * @brief  Allows to write block(s) to a specified address in a card. The Data
0792   *         transfer is managed by polling mode.
0793   * @note   This API should be followed by a check on the card state through
0794   *         HAL_MMC_GetCardState().
0795   * @param  hmmc: Pointer to MMC handle
0796   * @param  pData: pointer to the buffer that will contain the data to transmit
0797   * @param  BlockAdd: Block Address where data will be written
0798   * @param  NumberOfBlocks: Number of MMC blocks to write
0799   * @param  Timeout: Specify timeout value
0800   * @retval HAL status
0801   */
0802 HAL_StatusTypeDef HAL_MMC_WriteBlocks(MMC_HandleTypeDef *hmmc, const uint8_t *pData, uint32_t BlockAdd,
0803                                       uint32_t NumberOfBlocks, uint32_t Timeout)
0804 {
0805   SDMMC_DataInitTypeDef config;
0806   uint32_t errorstate;
0807   uint32_t tickstart = HAL_GetTick();
0808   uint32_t count;
0809   uint32_t data;
0810   uint32_t dataremaining;
0811   uint32_t add = BlockAdd;
0812   const uint8_t *tempbuff = pData;
0813 
0814   if (NULL == pData)
0815   {
0816     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
0817     return HAL_ERROR;
0818   }
0819 
0820   if (hmmc->State == HAL_MMC_STATE_READY)
0821   {
0822     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
0823 
0824     if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
0825     {
0826       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
0827       return HAL_ERROR;
0828     }
0829 
0830     /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
0831     if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U)
0832     {
0833       if ((NumberOfBlocks % 8U) != 0U)
0834       {
0835         /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */
0836         hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR;
0837         return HAL_ERROR;
0838       }
0839 
0840       if ((BlockAdd % 8U) != 0U)
0841       {
0842         /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
0843         hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
0844         return HAL_ERROR;
0845       }
0846     }
0847 
0848     hmmc->State = HAL_MMC_STATE_BUSY;
0849 
0850     /* Initialize data control register */
0851     hmmc->Instance->DCTRL = 0U;
0852 
0853     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
0854     {
0855       add *= 512U;
0856     }
0857 
0858     /* Configure the MMC DPSM (Data Path State Machine) */
0859     config.DataTimeOut   = SDMMC_DATATIMEOUT;
0860     config.DataLength    = NumberOfBlocks * MMC_BLOCKSIZE;
0861     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
0862     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
0863     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
0864     config.DPSM          = SDMMC_DPSM_DISABLE;
0865     (void)SDMMC_ConfigData(hmmc->Instance, &config);
0866     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
0867 
0868     /* Write Blocks in Polling mode */
0869     if (NumberOfBlocks > 1U)
0870     {
0871       hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
0872 
0873       /* Write Multi Block command */
0874       errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
0875     }
0876     else
0877     {
0878       hmmc->Context = MMC_CONTEXT_WRITE_SINGLE_BLOCK;
0879 
0880       /* Write Single Block command */
0881       errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
0882     }
0883     if (errorstate != HAL_MMC_ERROR_NONE)
0884     {
0885       /* Clear all the static flags */
0886       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
0887       hmmc->ErrorCode |= errorstate;
0888       hmmc->State = HAL_MMC_STATE_READY;
0889       return HAL_ERROR;
0890     }
0891 
0892     /* Write block(s) in polling mode */
0893     dataremaining = config.DataLength;
0894     while (!__HAL_MMC_GET_FLAG(hmmc,
0895                                SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
0896     {
0897       if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= 32U))
0898       {
0899         /* Write data to SDMMC Tx FIFO */
0900         for (count = 0U; count < 8U; count++)
0901         {
0902           data = (uint32_t)(*tempbuff);
0903           tempbuff++;
0904           data |= ((uint32_t)(*tempbuff) << 8U);
0905           tempbuff++;
0906           data |= ((uint32_t)(*tempbuff) << 16U);
0907           tempbuff++;
0908           data |= ((uint32_t)(*tempbuff) << 24U);
0909           tempbuff++;
0910           (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
0911         }
0912         dataremaining -= 32U;
0913       }
0914 
0915       if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
0916       {
0917         /* Clear all the static flags */
0918         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
0919         hmmc->ErrorCode |= errorstate;
0920         hmmc->State = HAL_MMC_STATE_READY;
0921         return HAL_TIMEOUT;
0922       }
0923     }
0924     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
0925 
0926     /* Send stop transmission command in case of multiblock write */
0927     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U))
0928     {
0929       /* Send stop transmission command */
0930       errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
0931       if (errorstate != HAL_MMC_ERROR_NONE)
0932       {
0933         /* Clear all the static flags */
0934         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
0935         hmmc->ErrorCode |= errorstate;
0936         hmmc->State = HAL_MMC_STATE_READY;
0937         return HAL_ERROR;
0938       }
0939     }
0940 
0941     /* Get error state */
0942     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
0943     {
0944       /* Clear all the static flags */
0945       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
0946       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
0947       hmmc->State = HAL_MMC_STATE_READY;
0948       return HAL_ERROR;
0949     }
0950     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
0951     {
0952       /* Clear all the static flags */
0953       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
0954       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
0955       hmmc->State = HAL_MMC_STATE_READY;
0956       return HAL_ERROR;
0957     }
0958     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
0959     {
0960       /* Clear all the static flags */
0961       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
0962       hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
0963       hmmc->State = HAL_MMC_STATE_READY;
0964       return HAL_ERROR;
0965     }
0966     else
0967     {
0968       /* Nothing to do */
0969     }
0970 
0971     /* Clear all the static flags */
0972     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
0973 
0974     hmmc->State = HAL_MMC_STATE_READY;
0975 
0976     return HAL_OK;
0977   }
0978   else
0979   {
0980     hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
0981     return HAL_ERROR;
0982   }
0983 }
0984 
0985 /**
0986   * @brief  Reads block(s) from a specified address in a card. The Data transfer
0987   *         is managed in interrupt mode.
0988   * @note   This API should be followed by a check on the card state through
0989   *         HAL_MMC_GetCardState().
0990   * @note   You could also check the IT transfer process through the MMC Rx
0991   *         interrupt event.
0992   * @param  hmmc: Pointer to MMC handle
0993   * @param  pData: Pointer to the buffer that will contain the received data
0994   * @param  BlockAdd: Block Address from where data is to be read
0995   * @param  NumberOfBlocks: Number of blocks to read.
0996   * @retval HAL status
0997   */
0998 HAL_StatusTypeDef HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd,
0999                                         uint32_t NumberOfBlocks)
1000 {
1001   SDMMC_DataInitTypeDef config;
1002   uint32_t errorstate;
1003   uint32_t add = BlockAdd;
1004 
1005   if (NULL == pData)
1006   {
1007     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1008     return HAL_ERROR;
1009   }
1010 
1011   if (hmmc->State == HAL_MMC_STATE_READY)
1012   {
1013     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1014 
1015     if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1016     {
1017       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1018       return HAL_ERROR;
1019     }
1020 
1021     /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
1022     if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U)
1023     {
1024       if ((NumberOfBlocks % 8U) != 0U)
1025       {
1026         /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */
1027         hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR;
1028         return HAL_ERROR;
1029       }
1030 
1031       if ((BlockAdd % 8U) != 0U)
1032       {
1033         /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
1034         hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
1035         return HAL_ERROR;
1036       }
1037     }
1038 
1039     hmmc->State = HAL_MMC_STATE_BUSY;
1040 
1041     /* Initialize data control register */
1042     hmmc->Instance->DCTRL = 0U;
1043 
1044     hmmc->pRxBuffPtr = pData;
1045     hmmc->RxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1046 
1047     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1048     {
1049       add *= 512U;
1050     }
1051 
1052     /* Configure the MMC DPSM (Data Path State Machine) */
1053     config.DataTimeOut   = SDMMC_DATATIMEOUT;
1054     config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
1055     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1056     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
1057     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
1058     config.DPSM          = SDMMC_DPSM_DISABLE;
1059     (void)SDMMC_ConfigData(hmmc->Instance, &config);
1060     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
1061 
1062     /* Read Blocks in IT mode */
1063     if (NumberOfBlocks > 1U)
1064     {
1065       hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_IT);
1066 
1067       /* Read Multi Block command */
1068       errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
1069     }
1070     else
1071     {
1072       hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_IT);
1073 
1074       /* Read Single Block command */
1075       errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
1076     }
1077 
1078     if (errorstate != HAL_MMC_ERROR_NONE)
1079     {
1080       /* Clear all the static flags */
1081       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1082       hmmc->ErrorCode |= errorstate;
1083       hmmc->State = HAL_MMC_STATE_READY;
1084       return HAL_ERROR;
1085     }
1086 
1087     __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND |
1088                                SDMMC_FLAG_RXFIFOHF));
1089 
1090     return HAL_OK;
1091   }
1092   else
1093   {
1094     return HAL_BUSY;
1095   }
1096 }
1097 
1098 /**
1099   * @brief  Writes block(s) to a specified address in a card. The Data transfer
1100   *         is managed in interrupt mode.
1101   * @note   This API should be followed by a check on the card state through
1102   *         HAL_MMC_GetCardState().
1103   * @note   You could also check the IT transfer process through the MMC Tx
1104   *         interrupt event.
1105   * @param  hmmc: Pointer to MMC handle
1106   * @param  pData: Pointer to the buffer that will contain the data to transmit
1107   * @param  BlockAdd: Block Address where data will be written
1108   * @param  NumberOfBlocks: Number of blocks to write
1109   * @retval HAL status
1110   */
1111 HAL_StatusTypeDef HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef *hmmc, const uint8_t *pData,
1112                                          uint32_t BlockAdd, uint32_t NumberOfBlocks)
1113 {
1114   SDMMC_DataInitTypeDef config;
1115   uint32_t errorstate;
1116   uint32_t add = BlockAdd;
1117 
1118   if (NULL == pData)
1119   {
1120     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1121     return HAL_ERROR;
1122   }
1123 
1124   if (hmmc->State == HAL_MMC_STATE_READY)
1125   {
1126     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1127 
1128     if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1129     {
1130       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1131       return HAL_ERROR;
1132     }
1133 
1134     /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
1135     if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U)
1136     {
1137       if ((NumberOfBlocks % 8U) != 0U)
1138       {
1139         /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */
1140         hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR;
1141         return HAL_ERROR;
1142       }
1143 
1144       if ((BlockAdd % 8U) != 0U)
1145       {
1146         /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
1147         hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
1148         return HAL_ERROR;
1149       }
1150     }
1151 
1152     hmmc->State = HAL_MMC_STATE_BUSY;
1153 
1154     /* Initialize data control register */
1155     hmmc->Instance->DCTRL = 0U;
1156 
1157     hmmc->pTxBuffPtr = pData;
1158     hmmc->TxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1159 
1160     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1161     {
1162       add *= 512U;
1163     }
1164 
1165     /* Configure the MMC DPSM (Data Path State Machine) */
1166     config.DataTimeOut   = SDMMC_DATATIMEOUT;
1167     config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
1168     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1169     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
1170     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
1171     config.DPSM          = SDMMC_DPSM_DISABLE;
1172     (void)SDMMC_ConfigData(hmmc->Instance, &config);
1173 
1174     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
1175 
1176     /* Write Blocks in Polling mode */
1177     if (NumberOfBlocks > 1U)
1178     {
1179       hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_IT);
1180 
1181       /* Write Multi Block command */
1182       errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
1183     }
1184     else
1185     {
1186       hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_IT);
1187 
1188       /* Write Single Block command */
1189       errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
1190     }
1191     if (errorstate != HAL_MMC_ERROR_NONE)
1192     {
1193       /* Clear all the static flags */
1194       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1195       hmmc->ErrorCode |= errorstate;
1196       hmmc->State = HAL_MMC_STATE_READY;
1197       return HAL_ERROR;
1198     }
1199 
1200     /* Enable transfer interrupts */
1201     __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND |
1202                                SDMMC_FLAG_TXFIFOHE));
1203 
1204     return HAL_OK;
1205   }
1206   else
1207   {
1208     return HAL_BUSY;
1209   }
1210 }
1211 
1212 /**
1213   * @brief  Reads block(s) from a specified address in a card. The Data transfer
1214   *         is managed by DMA mode.
1215   * @note   This API should be followed by a check on the card state through
1216   *         HAL_MMC_GetCardState().
1217   * @note   You could also check the DMA transfer process through the MMC Rx
1218   *         interrupt event.
1219   * @param  hmmc: Pointer MMC handle
1220   * @param  pData: Pointer to the buffer that will contain the received data
1221   * @param  BlockAdd: Block Address from where data is to be read
1222   * @param  NumberOfBlocks: Number of blocks to read.
1223   * @retval HAL status
1224   */
1225 HAL_StatusTypeDef HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd,
1226                                          uint32_t NumberOfBlocks)
1227 {
1228   SDMMC_DataInitTypeDef config;
1229   uint32_t errorstate;
1230   uint32_t add = BlockAdd;
1231 
1232   if (NULL == pData)
1233   {
1234     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1235     return HAL_ERROR;
1236   }
1237 
1238   if (hmmc->State == HAL_MMC_STATE_READY)
1239   {
1240     hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
1241 
1242     if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1243     {
1244       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1245       return HAL_ERROR;
1246     }
1247 
1248     /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
1249     if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U)
1250     {
1251       if ((NumberOfBlocks % 8U) != 0U)
1252       {
1253         /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */
1254         hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR;
1255         return HAL_ERROR;
1256       }
1257 
1258       if ((BlockAdd % 8U) != 0U)
1259       {
1260         /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
1261         hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
1262         return HAL_ERROR;
1263       }
1264     }
1265 
1266     hmmc->State = HAL_MMC_STATE_BUSY;
1267 
1268     /* Initialize data control register */
1269     hmmc->Instance->DCTRL = 0U;
1270 
1271     hmmc->pRxBuffPtr = pData;
1272     hmmc->RxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1273 
1274     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1275     {
1276       add *= 512U;
1277     }
1278 
1279     /* Configure the MMC DPSM (Data Path State Machine) */
1280     config.DataTimeOut   = SDMMC_DATATIMEOUT;
1281     config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
1282     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1283     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
1284     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
1285     config.DPSM          = SDMMC_DPSM_DISABLE;
1286     (void)SDMMC_ConfigData(hmmc->Instance, &config);
1287 
1288     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
1289     hmmc->Instance->IDMABASE0 = (uint32_t) pData ;
1290     hmmc->Instance->IDMACTRL  = SDMMC_ENABLE_IDMA_SINGLE_BUFF;
1291 
1292     /* Read Blocks in DMA mode */
1293     if (NumberOfBlocks > 1U)
1294     {
1295       hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
1296 
1297       /* Read Multi Block command */
1298       errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
1299     }
1300     else
1301     {
1302       hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_DMA);
1303 
1304       /* Read Single Block command */
1305       errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
1306     }
1307     if (errorstate != HAL_MMC_ERROR_NONE)
1308     {
1309       /* Clear all the static flags */
1310       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1311       hmmc->ErrorCode = errorstate;
1312       hmmc->State = HAL_MMC_STATE_READY;
1313       return HAL_ERROR;
1314     }
1315 
1316     /* Enable transfer interrupts */
1317     __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND));
1318 
1319     return HAL_OK;
1320   }
1321   else
1322   {
1323     return HAL_BUSY;
1324   }
1325 }
1326 
1327 /**
1328   * @brief  Writes block(s) to a specified address in a card. The Data transfer
1329   *         is managed by DMA mode.
1330   * @note   This API should be followed by a check on the card state through
1331   *         HAL_MMC_GetCardState().
1332   * @note   You could also check the DMA transfer process through the MMC Tx
1333   *         interrupt event.
1334   * @param  hmmc: Pointer to MMC handle
1335   * @param  pData: Pointer to the buffer that will contain the data to transmit
1336   * @param  BlockAdd: Block Address where data will be written
1337   * @param  NumberOfBlocks: Number of blocks to write
1338   * @retval HAL status
1339   */
1340 HAL_StatusTypeDef HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef *hmmc, const uint8_t *pData,
1341                                           uint32_t BlockAdd, uint32_t NumberOfBlocks)
1342 {
1343   SDMMC_DataInitTypeDef config;
1344   uint32_t errorstate;
1345   uint32_t add = BlockAdd;
1346 
1347   if (NULL == pData)
1348   {
1349     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1350     return HAL_ERROR;
1351   }
1352 
1353   if (hmmc->State == HAL_MMC_STATE_READY)
1354   {
1355     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1356 
1357     if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1358     {
1359       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1360       return HAL_ERROR;
1361     }
1362 
1363     /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
1364     if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U)
1365     {
1366       if ((NumberOfBlocks % 8U) != 0U)
1367       {
1368         /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */
1369         hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR;
1370         return HAL_ERROR;
1371       }
1372 
1373       if ((BlockAdd % 8U) != 0U)
1374       {
1375         /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
1376         hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
1377         return HAL_ERROR;
1378       }
1379     }
1380 
1381     hmmc->State = HAL_MMC_STATE_BUSY;
1382 
1383     /* Initialize data control register */
1384     hmmc->Instance->DCTRL = 0U;
1385 
1386     hmmc->pTxBuffPtr = pData;
1387     hmmc->TxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1388 
1389     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1390     {
1391       add *= 512U;
1392     }
1393 
1394     /* Configure the MMC DPSM (Data Path State Machine) */
1395     config.DataTimeOut   = SDMMC_DATATIMEOUT;
1396     config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
1397     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1398     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
1399     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
1400     config.DPSM          = SDMMC_DPSM_DISABLE;
1401     (void)SDMMC_ConfigData(hmmc->Instance, &config);
1402 
1403     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
1404 
1405     hmmc->Instance->IDMABASE0 = (uint32_t) pData ;
1406     hmmc->Instance->IDMACTRL  = SDMMC_ENABLE_IDMA_SINGLE_BUFF;
1407 
1408     /* Write Blocks in Polling mode */
1409     if (NumberOfBlocks > 1U)
1410     {
1411       hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
1412 
1413       /* Write Multi Block command */
1414       errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
1415     }
1416     else
1417     {
1418       hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_DMA);
1419 
1420       /* Write Single Block command */
1421       errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
1422     }
1423     if (errorstate != HAL_MMC_ERROR_NONE)
1424     {
1425       /* Clear all the static flags */
1426       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1427       hmmc->ErrorCode |= errorstate;
1428       hmmc->State = HAL_MMC_STATE_READY;
1429       return HAL_ERROR;
1430     }
1431 
1432     /* Enable transfer interrupts */
1433     __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND));
1434 
1435     return HAL_OK;
1436   }
1437   else
1438   {
1439     return HAL_BUSY;
1440   }
1441 }
1442 
1443 /**
1444   * @brief  Erases the specified memory area of the given MMC card.
1445   * @note   This API should be followed by a check on the card state through
1446   *         HAL_MMC_GetCardState().
1447   * @param  hmmc: Pointer to MMC handle
1448   * @param  BlockStartAdd: Start Block address
1449   * @param  BlockEndAdd: End Block address
1450   * @retval HAL status
1451   */
1452 HAL_StatusTypeDef HAL_MMC_Erase(MMC_HandleTypeDef *hmmc, uint32_t BlockStartAdd, uint32_t BlockEndAdd)
1453 {
1454   uint32_t errorstate;
1455   uint32_t start_add = BlockStartAdd;
1456   uint32_t end_add = BlockEndAdd;
1457 
1458   if (hmmc->State == HAL_MMC_STATE_READY)
1459   {
1460     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1461 
1462     if (end_add < start_add)
1463     {
1464       hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1465       return HAL_ERROR;
1466     }
1467 
1468     if (end_add > (hmmc->MmcCard.LogBlockNbr))
1469     {
1470       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1471       return HAL_ERROR;
1472     }
1473 
1474     /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
1475     if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS)
1476          & 0x000000FFU) != 0x0U)
1477     {
1478       if (((start_add % 8U) != 0U) || ((end_add % 8U) != 0U))
1479       {
1480         /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
1481         hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
1482         return HAL_ERROR;
1483       }
1484     }
1485 
1486     hmmc->State = HAL_MMC_STATE_BUSY;
1487 
1488     /* Check if the card command class supports erase command */
1489     if (((hmmc->MmcCard.Class) & SDMMC_CCCC_ERASE) == 0U)
1490     {
1491       /* Clear all the static flags */
1492       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1493       hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
1494       hmmc->State = HAL_MMC_STATE_READY;
1495       return HAL_ERROR;
1496     }
1497 
1498     if ((SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
1499     {
1500       /* Clear all the static flags */
1501       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1502       hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED;
1503       hmmc->State = HAL_MMC_STATE_READY;
1504       return HAL_ERROR;
1505     }
1506 
1507     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1508     {
1509       start_add *= 512U;
1510       end_add   *= 512U;
1511     }
1512 
1513     /* Send CMD35 MMC_ERASE_GRP_START with argument as addr  */
1514     errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, start_add);
1515     if (errorstate != HAL_MMC_ERROR_NONE)
1516     {
1517       /* Clear all the static flags */
1518       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1519       hmmc->ErrorCode |= errorstate;
1520       hmmc->State = HAL_MMC_STATE_READY;
1521       return HAL_ERROR;
1522     }
1523 
1524     /* Send CMD36 MMC_ERASE_GRP_END with argument as addr  */
1525     errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, end_add);
1526     if (errorstate != HAL_MMC_ERROR_NONE)
1527     {
1528       /* Clear all the static flags */
1529       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1530       hmmc->ErrorCode |= errorstate;
1531       hmmc->State = HAL_MMC_STATE_READY;
1532       return HAL_ERROR;
1533     }
1534 
1535     /* Send CMD38 ERASE */
1536     errorstate = SDMMC_CmdErase(hmmc->Instance, 0UL);
1537     if (errorstate != HAL_MMC_ERROR_NONE)
1538     {
1539       /* Clear all the static flags */
1540       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1541       hmmc->ErrorCode |= errorstate;
1542       hmmc->State = HAL_MMC_STATE_READY;
1543       return HAL_ERROR;
1544     }
1545 
1546     hmmc->State = HAL_MMC_STATE_READY;
1547 
1548     return HAL_OK;
1549   }
1550   else
1551   {
1552     return HAL_BUSY;
1553   }
1554 }
1555 
1556 /**
1557   * @brief  This function handles MMC card interrupt request.
1558   * @param  hmmc: Pointer to MMC handle
1559   * @retval None
1560   */
1561 void HAL_MMC_IRQHandler(MMC_HandleTypeDef *hmmc)
1562 {
1563   uint32_t errorstate;
1564   uint32_t context = hmmc->Context;
1565 
1566   /* Check for SDMMC interrupt flags */
1567   if ((__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) != RESET) && ((context & MMC_CONTEXT_IT) != 0U))
1568   {
1569     MMC_Read_IT(hmmc);
1570   }
1571 
1572   else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) != RESET)
1573   {
1574     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_DATAEND);
1575 
1576     __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND  | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | \
1577                          SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR  | SDMMC_IT_TXFIFOHE | \
1578                          SDMMC_IT_RXFIFOHF);
1579 
1580     __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_IDMABTC);
1581     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
1582 
1583     if ((context & MMC_CONTEXT_DMA) != 0U)
1584     {
1585       hmmc->Instance->DLEN = 0;
1586       hmmc->Instance->DCTRL = 0;
1587       hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA ;
1588 
1589       /* Stop Transfer for Write Multi blocks or Read Multi blocks */
1590       if (((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
1591       {
1592         errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
1593         if (errorstate != HAL_MMC_ERROR_NONE)
1594         {
1595           hmmc->ErrorCode |= errorstate;
1596 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1597           hmmc->ErrorCallback(hmmc);
1598 #else
1599           HAL_MMC_ErrorCallback(hmmc);
1600 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1601         }
1602       }
1603 
1604       /* Clear all the static flags */
1605       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
1606 
1607       hmmc->State = HAL_MMC_STATE_READY;
1608       if (((context & MMC_CONTEXT_WRITE_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
1609       {
1610 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1611         hmmc->TxCpltCallback(hmmc);
1612 #else
1613         HAL_MMC_TxCpltCallback(hmmc);
1614 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1615       }
1616       if (((context & MMC_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
1617       {
1618 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1619         hmmc->RxCpltCallback(hmmc);
1620 #else
1621         HAL_MMC_RxCpltCallback(hmmc);
1622 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1623       }
1624     }
1625     else if ((context & MMC_CONTEXT_IT) != 0U)
1626     {
1627       /* Stop Transfer for Write Multi blocks or Read Multi blocks */
1628       if (((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
1629       {
1630         errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
1631         if (errorstate != HAL_MMC_ERROR_NONE)
1632         {
1633           hmmc->ErrorCode |= errorstate;
1634 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1635           hmmc->ErrorCallback(hmmc);
1636 #else
1637           HAL_MMC_ErrorCallback(hmmc);
1638 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1639         }
1640       }
1641 
1642       /* Clear all the static flags */
1643       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
1644 
1645       hmmc->State = HAL_MMC_STATE_READY;
1646       if (((context & MMC_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
1647       {
1648 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1649         hmmc->RxCpltCallback(hmmc);
1650 #else
1651         HAL_MMC_RxCpltCallback(hmmc);
1652 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1653       }
1654       else
1655       {
1656 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1657         hmmc->TxCpltCallback(hmmc);
1658 #else
1659         HAL_MMC_TxCpltCallback(hmmc);
1660 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1661       }
1662     }
1663     else
1664     {
1665       /* Nothing to do */
1666     }
1667   }
1668 
1669   else if ((__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) != RESET) && ((context & MMC_CONTEXT_IT) != 0U))
1670   {
1671     MMC_Write_IT(hmmc);
1672   }
1673 
1674   else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL |
1675                               SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_RXOVERR | SDMMC_FLAG_TXUNDERR) != RESET)
1676   {
1677     /* Set Error code */
1678     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_DCRCFAIL) != RESET)
1679     {
1680       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
1681     }
1682     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_DTIMEOUT) != RESET)
1683     {
1684       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
1685     }
1686     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_RXOVERR) != RESET)
1687     {
1688       hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
1689     }
1690     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_TXUNDERR) != RESET)
1691     {
1692       hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
1693     }
1694 
1695     /* Clear All flags */
1696     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
1697 
1698     /* Disable all interrupts */
1699     __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | \
1700                          SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR);
1701 
1702     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
1703     hmmc->Instance->DCTRL |= SDMMC_DCTRL_FIFORST;
1704     hmmc->Instance->CMD |= SDMMC_CMD_CMDSTOP;
1705     hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
1706     hmmc->Instance->CMD &= ~(SDMMC_CMD_CMDSTOP);
1707     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_DABORT);
1708 
1709     if ((context & MMC_CONTEXT_IT) != 0U)
1710     {
1711       /* Set the MMC state to ready to be able to start again the process */
1712       hmmc->State = HAL_MMC_STATE_READY;
1713 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1714       hmmc->ErrorCallback(hmmc);
1715 #else
1716       HAL_MMC_ErrorCallback(hmmc);
1717 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1718     }
1719     else if ((context & MMC_CONTEXT_DMA) != 0U)
1720     {
1721       if (hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
1722       {
1723         /* Disable Internal DMA */
1724         __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_IDMABTC);
1725         hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA;
1726 
1727         /* Set the MMC state to ready to be able to start again the process */
1728         hmmc->State = HAL_MMC_STATE_READY;
1729 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1730         hmmc->ErrorCallback(hmmc);
1731 #else
1732         HAL_MMC_ErrorCallback(hmmc);
1733 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1734       }
1735     }
1736     else
1737     {
1738       /* Nothing to do */
1739     }
1740   }
1741 
1742   else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_IDMABTC) != RESET)
1743   {
1744     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_IT_IDMABTC);
1745     if (READ_BIT(hmmc->Instance->IDMACTRL, SDMMC_IDMA_IDMABACT) == 0U)
1746     {
1747       /* Current buffer is buffer0, Transfer complete for buffer1 */
1748       if ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)
1749       {
1750 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1751         hmmc->Write_DMADblBuf1CpltCallback(hmmc);
1752 #else
1753         HAL_MMCEx_Write_DMADoubleBuf1CpltCallback(hmmc);
1754 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1755       }
1756       else /* MMC_CONTEXT_READ_MULTIPLE_BLOCK */
1757       {
1758 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1759         hmmc->Read_DMADblBuf1CpltCallback(hmmc);
1760 #else
1761         HAL_MMCEx_Read_DMADoubleBuf1CpltCallback(hmmc);
1762 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1763       }
1764     }
1765     else /* MMC_DMA_BUFFER1 */
1766     {
1767       /* Current buffer is buffer1, Transfer complete for buffer0 */
1768       if ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)
1769       {
1770 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1771         hmmc->Write_DMADblBuf0CpltCallback(hmmc);
1772 #else
1773         HAL_MMCEx_Write_DMADoubleBuf0CpltCallback(hmmc);
1774 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1775       }
1776       else /* MMC_CONTEXT_READ_MULTIPLE_BLOCK */
1777       {
1778 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1779         hmmc->Read_DMADblBuf0CpltCallback(hmmc);
1780 #else
1781         HAL_MMCEx_Read_DMADoubleBuf0CpltCallback(hmmc);
1782 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1783       }
1784     }
1785   }
1786 
1787   else
1788   {
1789     /* Nothing to do */
1790   }
1791 }
1792 
1793 /**
1794   * @brief return the MMC state
1795   * @param hmmc: Pointer to mmc handle
1796   * @retval HAL state
1797   */
1798 HAL_MMC_StateTypeDef HAL_MMC_GetState(MMC_HandleTypeDef *hmmc)
1799 {
1800   return hmmc->State;
1801 }
1802 
1803 /**
1804   * @brief  Return the MMC error code
1805   * @param  hmmc : Pointer to a MMC_HandleTypeDef structure that contains
1806   *              the configuration information.
1807   * @retval MMC Error Code
1808   */
1809 uint32_t HAL_MMC_GetError(MMC_HandleTypeDef *hmmc)
1810 {
1811   return hmmc->ErrorCode;
1812 }
1813 
1814 /**
1815   * @brief Tx Transfer completed callbacks
1816   * @param hmmc: Pointer to MMC handle
1817   * @retval None
1818   */
1819 __weak void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef *hmmc)
1820 {
1821   /* Prevent unused argument(s) compilation warning */
1822   UNUSED(hmmc);
1823 
1824   /* NOTE : This function should not be modified, when the callback is needed,
1825             the HAL_MMC_TxCpltCallback can be implemented in the user file
1826    */
1827 }
1828 
1829 /**
1830   * @brief Rx Transfer completed callbacks
1831   * @param hmmc: Pointer MMC handle
1832   * @retval None
1833   */
1834 __weak void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef *hmmc)
1835 {
1836   /* Prevent unused argument(s) compilation warning */
1837   UNUSED(hmmc);
1838 
1839   /* NOTE : This function should not be modified, when the callback is needed,
1840             the HAL_MMC_RxCpltCallback can be implemented in the user file
1841    */
1842 }
1843 
1844 /**
1845   * @brief MMC error callbacks
1846   * @param hmmc: Pointer MMC handle
1847   * @retval None
1848   */
1849 __weak void HAL_MMC_ErrorCallback(MMC_HandleTypeDef *hmmc)
1850 {
1851   /* Prevent unused argument(s) compilation warning */
1852   UNUSED(hmmc);
1853 
1854   /* NOTE : This function should not be modified, when the callback is needed,
1855             the HAL_MMC_ErrorCallback can be implemented in the user file
1856    */
1857 }
1858 
1859 /**
1860   * @brief MMC Abort callbacks
1861   * @param hmmc: Pointer MMC handle
1862   * @retval None
1863   */
1864 __weak void HAL_MMC_AbortCallback(MMC_HandleTypeDef *hmmc)
1865 {
1866   /* Prevent unused argument(s) compilation warning */
1867   UNUSED(hmmc);
1868 
1869   /* NOTE : This function should not be modified, when the callback is needed,
1870             the HAL_MMC_AbortCallback can be implemented in the user file
1871    */
1872 }
1873 
1874 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1875 /**
1876   * @brief  Register a User MMC Callback
1877   *         To be used instead of the weak (surcharged) predefined callback
1878   * @note   The HAL_MMC_RegisterCallback() may be called before HAL_MMC_Init() in 
1879   *         HAL_MMC_STATE_RESET to register callbacks for HAL_MMC_MSP_INIT_CB_ID 
1880   *         and HAL_MMC_MSP_DEINIT_CB_ID.
1881   * @param hmmc : MMC handle
1882   * @param CallbackId : ID of the callback to be registered
1883   *        This parameter can be one of the following values:
1884   *          @arg @ref HAL_MMC_TX_CPLT_CB_ID                 MMC Tx Complete Callback ID
1885   *          @arg @ref HAL_MMC_RX_CPLT_CB_ID                 MMC Rx Complete Callback ID
1886   *          @arg @ref HAL_MMC_ERROR_CB_ID                   MMC Error Callback ID
1887   *          @arg @ref HAL_MMC_ABORT_CB_ID                   MMC Abort Callback ID
1888   *          @arg @ref HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID  MMC DMA Rx Double buffer 0 Callback ID
1889   *          @arg @ref HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID  MMC DMA Rx Double buffer 1 Callback ID
1890   *          @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID MMC DMA Tx Double buffer 0 Callback ID
1891   *          @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID MMC DMA Tx Double buffer 1 Callback ID
1892   *          @arg @ref HAL_MMC_MSP_INIT_CB_ID                MMC MspInit Callback ID
1893   *          @arg @ref HAL_MMC_MSP_DEINIT_CB_ID              MMC MspDeInit Callback ID
1894   * @param pCallback : pointer to the Callback function
1895   * @retval status
1896   */
1897 HAL_StatusTypeDef HAL_MMC_RegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId,
1898                                            pMMC_CallbackTypeDef pCallback)
1899 {
1900   HAL_StatusTypeDef status = HAL_OK;
1901 
1902   if (pCallback == NULL)
1903   {
1904     /* Update the error code */
1905     hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1906     return HAL_ERROR;
1907   }
1908 
1909   if (hmmc->State == HAL_MMC_STATE_READY)
1910   {
1911     switch (CallbackId)
1912     {
1913       case HAL_MMC_TX_CPLT_CB_ID :
1914         hmmc->TxCpltCallback = pCallback;
1915         break;
1916       case HAL_MMC_RX_CPLT_CB_ID :
1917         hmmc->RxCpltCallback = pCallback;
1918         break;
1919       case HAL_MMC_ERROR_CB_ID :
1920         hmmc->ErrorCallback = pCallback;
1921         break;
1922       case HAL_MMC_ABORT_CB_ID :
1923         hmmc->AbortCpltCallback = pCallback;
1924         break;
1925       case HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID :
1926         hmmc->Read_DMADblBuf0CpltCallback = pCallback;
1927         break;
1928       case HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID :
1929         hmmc->Read_DMADblBuf1CpltCallback = pCallback;
1930         break;
1931       case HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID :
1932         hmmc->Write_DMADblBuf0CpltCallback = pCallback;
1933         break;
1934       case HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID :
1935         hmmc->Write_DMADblBuf1CpltCallback = pCallback;
1936         break;
1937       case HAL_MMC_MSP_INIT_CB_ID :
1938         hmmc->MspInitCallback = pCallback;
1939         break;
1940       case HAL_MMC_MSP_DEINIT_CB_ID :
1941         hmmc->MspDeInitCallback = pCallback;
1942         break;
1943       default :
1944         /* Update the error code */
1945         hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1946         /* update return status */
1947         status =  HAL_ERROR;
1948         break;
1949     }
1950   }
1951   else if (hmmc->State == HAL_MMC_STATE_RESET)
1952   {
1953     switch (CallbackId)
1954     {
1955       case HAL_MMC_MSP_INIT_CB_ID :
1956         hmmc->MspInitCallback = pCallback;
1957         break;
1958       case HAL_MMC_MSP_DEINIT_CB_ID :
1959         hmmc->MspDeInitCallback = pCallback;
1960         break;
1961       default :
1962         /* Update the error code */
1963         hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1964         /* update return status */
1965         status =  HAL_ERROR;
1966         break;
1967     }
1968   }
1969   else
1970   {
1971     /* Update the error code */
1972     hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1973     /* update return status */
1974     status =  HAL_ERROR;
1975   }
1976 
1977   return status;
1978 }
1979 
1980 /**
1981   * @brief  Unregister a User MMC Callback
1982   *         MMC Callback is redirected to the weak (surcharged) predefined callback
1983   * @note   The HAL_MMC_UnRegisterCallback() may be called before HAL_MMC_Init() in 
1984   *         HAL_MMC_STATE_RESET to register callbacks for HAL_MMC_MSP_INIT_CB_ID 
1985   *         and HAL_MMC_MSP_DEINIT_CB_ID.
1986   * @param hmmc : MMC handle
1987   * @param CallbackId : ID of the callback to be unregistered
1988   *        This parameter can be one of the following values:
1989   *          @arg @ref HAL_MMC_TX_CPLT_CB_ID                 MMC Tx Complete Callback ID
1990   *          @arg @ref HAL_MMC_RX_CPLT_CB_ID                 MMC Rx Complete Callback ID
1991   *          @arg @ref HAL_MMC_ERROR_CB_ID                   MMC Error Callback ID
1992   *          @arg @ref HAL_MMC_ABORT_CB_ID                   MMC Abort Callback ID
1993   *          @arg @ref HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID  MMC DMA Rx Double buffer 0 Callback ID
1994   *          @arg @ref HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID  MMC DMA Rx Double buffer 1 Callback ID
1995   *          @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID MMC DMA Tx Double buffer 0 Callback ID
1996   *          @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID MMC DMA Tx Double buffer 1 Callback ID
1997   *          @arg @ref HAL_MMC_MSP_INIT_CB_ID                MMC MspInit Callback ID
1998   *          @arg @ref HAL_MMC_MSP_DEINIT_CB_ID              MMC MspDeInit Callback ID
1999   * @retval status
2000   */
2001 HAL_StatusTypeDef HAL_MMC_UnRegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId)
2002 {
2003   HAL_StatusTypeDef status = HAL_OK;
2004 
2005   if (hmmc->State == HAL_MMC_STATE_READY)
2006   {
2007     switch (CallbackId)
2008     {
2009       case HAL_MMC_TX_CPLT_CB_ID :
2010         hmmc->TxCpltCallback = HAL_MMC_TxCpltCallback;
2011         break;
2012       case HAL_MMC_RX_CPLT_CB_ID :
2013         hmmc->RxCpltCallback = HAL_MMC_RxCpltCallback;
2014         break;
2015       case HAL_MMC_ERROR_CB_ID :
2016         hmmc->ErrorCallback = HAL_MMC_ErrorCallback;
2017         break;
2018       case HAL_MMC_ABORT_CB_ID :
2019         hmmc->AbortCpltCallback = HAL_MMC_AbortCallback;
2020         break;
2021       case HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID :
2022         hmmc->Read_DMADblBuf0CpltCallback = HAL_MMCEx_Read_DMADoubleBuf0CpltCallback;
2023         break;
2024       case HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID :
2025         hmmc->Read_DMADblBuf1CpltCallback = HAL_MMCEx_Read_DMADoubleBuf1CpltCallback;
2026         break;
2027       case HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID :
2028         hmmc->Write_DMADblBuf0CpltCallback = HAL_MMCEx_Write_DMADoubleBuf0CpltCallback;
2029         break;
2030       case HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID :
2031         hmmc->Write_DMADblBuf1CpltCallback = HAL_MMCEx_Write_DMADoubleBuf1CpltCallback;
2032         break;
2033       case HAL_MMC_MSP_INIT_CB_ID :
2034         hmmc->MspInitCallback = HAL_MMC_MspInit;
2035         break;
2036       case HAL_MMC_MSP_DEINIT_CB_ID :
2037         hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
2038         break;
2039       default :
2040         /* Update the error code */
2041         hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
2042         /* update return status */
2043         status =  HAL_ERROR;
2044         break;
2045     }
2046   }
2047   else if (hmmc->State == HAL_MMC_STATE_RESET)
2048   {
2049     switch (CallbackId)
2050     {
2051       case HAL_MMC_MSP_INIT_CB_ID :
2052         hmmc->MspInitCallback = HAL_MMC_MspInit;
2053         break;
2054       case HAL_MMC_MSP_DEINIT_CB_ID :
2055         hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
2056         break;
2057       default :
2058         /* Update the error code */
2059         hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
2060         /* update return status */
2061         status =  HAL_ERROR;
2062         break;
2063     }
2064   }
2065   else
2066   {
2067     /* Update the error code */
2068     hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
2069     /* update return status */
2070     status =  HAL_ERROR;
2071   }
2072 
2073   return status;
2074 }
2075 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
2076 
2077 /**
2078   * @}
2079   */
2080 
2081 /** @addtogroup MMC_Exported_Functions_Group3
2082   *  @brief   management functions
2083   *
2084 @verbatim
2085   ==============================================================================
2086                       ##### Peripheral Control functions #####
2087   ==============================================================================
2088   [..]
2089     This subsection provides a set of functions allowing to control the MMC card
2090     operations and get the related information
2091 
2092 @endverbatim
2093   * @{
2094   */
2095 
2096 /**
2097   * @brief  Returns information the information of the card which are stored on
2098   *         the CID register.
2099   * @param  hmmc: Pointer to MMC handle
2100   * @param  pCID: Pointer to a HAL_MMC_CIDTypedef structure that
2101   *         contains all CID register parameters
2102   * @retval HAL status
2103   */
2104 HAL_StatusTypeDef HAL_MMC_GetCardCID(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCIDTypeDef *pCID)
2105 {
2106   pCID->ManufacturerID = (uint8_t)((hmmc->CID[0] & 0xFF000000U) >> 24U);
2107 
2108   pCID->OEM_AppliID = (uint16_t)((hmmc->CID[0] & 0x00FFFF00U) >> 8U);
2109 
2110   pCID->ProdName1 = (((hmmc->CID[0] & 0x000000FFU) << 24U) | ((hmmc->CID[1] & 0xFFFFFF00U) >> 8U));
2111 
2112   pCID->ProdName2 = (uint8_t)(hmmc->CID[1] & 0x000000FFU);
2113 
2114   pCID->ProdRev = (uint8_t)((hmmc->CID[2] & 0xFF000000U) >> 24U);
2115 
2116   pCID->ProdSN = (((hmmc->CID[2] & 0x00FFFFFFU) << 8U) | ((hmmc->CID[3] & 0xFF000000U) >> 24U));
2117 
2118   pCID->Reserved1 = (uint8_t)((hmmc->CID[3] & 0x00F00000U) >> 20U);
2119 
2120   pCID->ManufactDate = (uint16_t)((hmmc->CID[3] & 0x000FFF00U) >> 8U);
2121 
2122   pCID->CID_CRC = (uint8_t)((hmmc->CID[3] & 0x000000FEU) >> 1U);
2123 
2124   pCID->Reserved2 = 1U;
2125 
2126   return HAL_OK;
2127 }
2128 
2129 /**
2130   * @brief  Returns information the information of the card which are stored on
2131   *         the CSD register.
2132   * @param  hmmc: Pointer to MMC handle
2133   * @param  pCSD: Pointer to a HAL_MMC_CardCSDTypeDef structure that
2134   *         contains all CSD register parameters
2135   * @retval HAL status
2136   */
2137 HAL_StatusTypeDef HAL_MMC_GetCardCSD(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCSDTypeDef *pCSD)
2138 {
2139   uint32_t block_nbr = 0;
2140 
2141   pCSD->CSDStruct = (uint8_t)((hmmc->CSD[0] & 0xC0000000U) >> 30U);
2142 
2143   pCSD->SysSpecVersion = (uint8_t)((hmmc->CSD[0] & 0x3C000000U) >> 26U);
2144 
2145   pCSD->Reserved1 = (uint8_t)((hmmc->CSD[0] & 0x03000000U) >> 24U);
2146 
2147   pCSD->TAAC = (uint8_t)((hmmc->CSD[0] & 0x00FF0000U) >> 16U);
2148 
2149   pCSD->NSAC = (uint8_t)((hmmc->CSD[0] & 0x0000FF00U) >> 8U);
2150 
2151   pCSD->MaxBusClkFrec = (uint8_t)(hmmc->CSD[0] & 0x000000FFU);
2152 
2153   pCSD->CardComdClasses = (uint16_t)((hmmc->CSD[1] & 0xFFF00000U) >> 20U);
2154 
2155   pCSD->RdBlockLen = (uint8_t)((hmmc->CSD[1] & 0x000F0000U) >> 16U);
2156 
2157   pCSD->PartBlockRead   = (uint8_t)((hmmc->CSD[1] & 0x00008000U) >> 15U);
2158 
2159   pCSD->WrBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00004000U) >> 14U);
2160 
2161   pCSD->RdBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00002000U) >> 13U);
2162 
2163   pCSD->DSRImpl = (uint8_t)((hmmc->CSD[1] & 0x00001000U) >> 12U);
2164 
2165   pCSD->Reserved2 = 0U; /*!< Reserved */
2166 
2167   if (MMC_ReadExtCSD(hmmc, &block_nbr, 212, 0x0FFFFFFFU) != HAL_OK) /* Field SEC_COUNT [215:212] */
2168   {
2169     return HAL_ERROR;
2170   }
2171 
2172   if (hmmc->MmcCard.CardType == MMC_LOW_CAPACITY_CARD)
2173   {
2174     pCSD->DeviceSize = (((hmmc->CSD[1] & 0x000003FFU) << 2U) | ((hmmc->CSD[2] & 0xC0000000U) >> 30U));
2175 
2176     pCSD->MaxRdCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x38000000U) >> 27U);
2177 
2178     pCSD->MaxRdCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x07000000U) >> 24U);
2179 
2180     pCSD->MaxWrCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x00E00000U) >> 21U);
2181 
2182     pCSD->MaxWrCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x001C0000U) >> 18U);
2183 
2184     pCSD->DeviceSizeMul = (uint8_t)((hmmc->CSD[2] & 0x00038000U) >> 15U);
2185 
2186     hmmc->MmcCard.BlockNbr  = (pCSD->DeviceSize + 1U) ;
2187     hmmc->MmcCard.BlockNbr *= (1UL << ((pCSD->DeviceSizeMul & 0x07U) + 2U));
2188     hmmc->MmcCard.BlockSize = (1UL << (pCSD->RdBlockLen & 0x0FU));
2189 
2190     hmmc->MmcCard.LogBlockNbr = (hmmc->MmcCard.BlockNbr) * ((hmmc->MmcCard.BlockSize) / 512U);
2191     hmmc->MmcCard.LogBlockSize = 512U;
2192   }
2193   else if (hmmc->MmcCard.CardType == MMC_HIGH_CAPACITY_CARD)
2194   {
2195     hmmc->MmcCard.BlockNbr = block_nbr;
2196     hmmc->MmcCard.LogBlockNbr = hmmc->MmcCard.BlockNbr;
2197     hmmc->MmcCard.BlockSize = 512U;
2198     hmmc->MmcCard.LogBlockSize = hmmc->MmcCard.BlockSize;
2199   }
2200   else
2201   {
2202     /* Clear all the static flags */
2203     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2204     hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2205     hmmc->State = HAL_MMC_STATE_READY;
2206     return HAL_ERROR;
2207   }
2208 
2209   pCSD->EraseGrSize = (uint8_t)((hmmc->CSD[2] & 0x00004000U) >> 14U);
2210 
2211   pCSD->EraseGrMul = (uint8_t)((hmmc->CSD[2] & 0x00003F80U) >> 7U);
2212 
2213   pCSD->WrProtectGrSize = (uint8_t)(hmmc->CSD[2] & 0x0000007FU);
2214 
2215   pCSD->WrProtectGrEnable = (uint8_t)((hmmc->CSD[3] & 0x80000000U) >> 31U);
2216 
2217   pCSD->ManDeflECC = (uint8_t)((hmmc->CSD[3] & 0x60000000U) >> 29U);
2218 
2219   pCSD->WrSpeedFact = (uint8_t)((hmmc->CSD[3] & 0x1C000000U) >> 26U);
2220 
2221   pCSD->MaxWrBlockLen = (uint8_t)((hmmc->CSD[3] & 0x03C00000U) >> 22U);
2222 
2223   pCSD->WriteBlockPaPartial = (uint8_t)((hmmc->CSD[3] & 0x00200000U) >> 21U);
2224 
2225   pCSD->Reserved3 = 0;
2226 
2227   pCSD->ContentProtectAppli = (uint8_t)((hmmc->CSD[3] & 0x00010000U) >> 16U);
2228 
2229   pCSD->FileFormatGroup = (uint8_t)((hmmc->CSD[3] & 0x00008000U) >> 15U);
2230 
2231   pCSD->CopyFlag = (uint8_t)((hmmc->CSD[3] & 0x00004000U) >> 14U);
2232 
2233   pCSD->PermWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00002000U) >> 13U);
2234 
2235   pCSD->TempWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00001000U) >> 12U);
2236 
2237   pCSD->FileFormat = (uint8_t)((hmmc->CSD[3] & 0x00000C00U) >> 10U);
2238 
2239   pCSD->ECC = (uint8_t)((hmmc->CSD[3] & 0x00000300U) >> 8U);
2240 
2241   pCSD->CSD_CRC = (uint8_t)((hmmc->CSD[3] & 0x000000FEU) >> 1U);
2242 
2243   pCSD->Reserved4 = 1;
2244 
2245   return HAL_OK;
2246 }
2247 
2248 /**
2249   * @brief  Gets the MMC card info.
2250   * @param  hmmc: Pointer to MMC handle
2251   * @param  pCardInfo: Pointer to the HAL_MMC_CardInfoTypeDef structure that
2252   *         will contain the MMC card status information
2253   * @retval HAL status
2254   */
2255 HAL_StatusTypeDef HAL_MMC_GetCardInfo(MMC_HandleTypeDef *hmmc, HAL_MMC_CardInfoTypeDef *pCardInfo)
2256 {
2257   pCardInfo->CardType     = (uint32_t)(hmmc->MmcCard.CardType);
2258   pCardInfo->Class        = (uint32_t)(hmmc->MmcCard.Class);
2259   pCardInfo->RelCardAdd   = (uint32_t)(hmmc->MmcCard.RelCardAdd);
2260   pCardInfo->BlockNbr     = (uint32_t)(hmmc->MmcCard.BlockNbr);
2261   pCardInfo->BlockSize    = (uint32_t)(hmmc->MmcCard.BlockSize);
2262   pCardInfo->LogBlockNbr  = (uint32_t)(hmmc->MmcCard.LogBlockNbr);
2263   pCardInfo->LogBlockSize = (uint32_t)(hmmc->MmcCard.LogBlockSize);
2264 
2265   return HAL_OK;
2266 }
2267 
2268 /**
2269   * @brief  Returns information the information of the card which are stored on
2270   *         the Extended CSD register.
2271   * @param  hmmc Pointer to MMC handle
2272   * @param  pExtCSD Pointer to a memory area (512 bytes) that contains all
2273   *         Extended CSD register parameters
2274   * @param  Timeout Specify timeout value
2275   * @retval HAL status
2276   */
2277 HAL_StatusTypeDef HAL_MMC_GetCardExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pExtCSD, uint32_t Timeout)
2278 {
2279   SDMMC_DataInitTypeDef config;
2280   uint32_t errorstate;
2281   uint32_t tickstart = HAL_GetTick();
2282   uint32_t count;
2283   uint32_t *tmp_buf;
2284 
2285   if (NULL == pExtCSD)
2286   {
2287     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
2288     return HAL_ERROR;
2289   }
2290 
2291   if (hmmc->State == HAL_MMC_STATE_READY)
2292   {
2293     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
2294 
2295     hmmc->State = HAL_MMC_STATE_BUSY;
2296 
2297     /* Initialize data control register */
2298     hmmc->Instance->DCTRL = 0;
2299 
2300     /* Initiaize the destination pointer */
2301     tmp_buf = pExtCSD;
2302 
2303     /* Configure the MMC DPSM (Data Path State Machine) */
2304     config.DataTimeOut   = SDMMC_DATATIMEOUT;
2305     config.DataLength    = 512U;
2306     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
2307     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
2308     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
2309     config.DPSM          = SDMMC_DPSM_DISABLE;
2310     (void)SDMMC_ConfigData(hmmc->Instance, &config);
2311     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
2312 
2313     /* Send ExtCSD Read command to Card */
2314     errorstate = SDMMC_CmdSendEXTCSD(hmmc->Instance, 0);
2315     if (errorstate != HAL_MMC_ERROR_NONE)
2316     {
2317       /* Clear all the static flags */
2318       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2319       hmmc->ErrorCode |= errorstate;
2320       hmmc->State = HAL_MMC_STATE_READY;
2321       return HAL_ERROR;
2322     }
2323 
2324     /* Poll on SDMMC flags */
2325     while (!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR |
2326                                SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
2327     {
2328       if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF))
2329       {
2330         /* Read data from SDMMC Rx FIFO */
2331         for (count = 0U; count < 8U; count++)
2332         {
2333           *tmp_buf = SDMMC_ReadFIFO(hmmc->Instance);
2334           tmp_buf++;
2335         }
2336       }
2337 
2338       if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
2339       {
2340         /* Clear all the static flags */
2341         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2342         hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
2343         hmmc->State = HAL_MMC_STATE_READY;
2344         return HAL_TIMEOUT;
2345       }
2346     }
2347 
2348     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
2349 
2350     /* Get error state */
2351     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
2352     {
2353       /* Clear all the static flags */
2354       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2355       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
2356       hmmc->State = HAL_MMC_STATE_READY;
2357       return HAL_ERROR;
2358     }
2359     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
2360     {
2361       /* Clear all the static flags */
2362       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2363       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
2364       hmmc->State = HAL_MMC_STATE_READY;
2365       return HAL_ERROR;
2366     }
2367     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR))
2368     {
2369       /* Clear all the static flags */
2370       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2371       hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
2372       hmmc->State = HAL_MMC_STATE_READY;
2373       return HAL_ERROR;
2374     }
2375     else
2376     {
2377       /* Nothing to do */
2378     }
2379 
2380     /* Clear all the static flags */
2381     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2382     hmmc->State = HAL_MMC_STATE_READY;
2383   }
2384 
2385   return HAL_OK;
2386 }
2387 
2388 /**
2389   * @brief  Enables wide bus operation for the requested card if supported by
2390   *         card.
2391   * @param  hmmc: Pointer to MMC handle
2392   * @param  WideMode: Specifies the MMC card wide bus mode
2393   *          This parameter can be one of the following values:
2394   *            @arg SDMMC_BUS_WIDE_8B: 8-bit data transfer
2395   *            @arg SDMMC_BUS_WIDE_4B: 4-bit data transfer
2396   *            @arg SDMMC_BUS_WIDE_1B: 1-bit data transfer
2397   * @retval HAL status
2398   */
2399 HAL_StatusTypeDef HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef *hmmc, uint32_t WideMode)
2400 {
2401   uint32_t count;
2402   SDMMC_InitTypeDef Init;
2403   uint32_t errorstate;
2404   uint32_t response = 0U;
2405 
2406   /* Check the parameters */
2407   assert_param(IS_SDMMC_BUS_WIDE(WideMode));
2408 
2409   /* Change State */
2410   hmmc->State = HAL_MMC_STATE_BUSY;
2411 
2412   /* Check and update the power class if needed */
2413   if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) != 0U)
2414   {
2415     if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) != 0U)
2416     {
2417       errorstate = MMC_PwrClassUpdate(hmmc, WideMode, SDMMC_SPEED_MODE_DDR);
2418     }
2419     else
2420     {
2421       errorstate = MMC_PwrClassUpdate(hmmc, WideMode, SDMMC_SPEED_MODE_HIGH);
2422     }
2423   }
2424   else
2425   {
2426     errorstate = MMC_PwrClassUpdate(hmmc, WideMode, SDMMC_SPEED_MODE_DEFAULT);
2427   }
2428 
2429   if (errorstate == HAL_MMC_ERROR_NONE)
2430   {
2431     if (WideMode == SDMMC_BUS_WIDE_8B)
2432     {
2433       errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U);
2434     }
2435     else if (WideMode == SDMMC_BUS_WIDE_4B)
2436     {
2437       errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U);
2438     }
2439     else if (WideMode == SDMMC_BUS_WIDE_1B)
2440     {
2441       errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70000U);
2442     }
2443     else
2444     {
2445       /* WideMode is not a valid argument*/
2446       errorstate = HAL_MMC_ERROR_PARAM;
2447     }
2448 
2449     /* Check for switch error and violation of the trial number of sending CMD 13 */
2450     if (errorstate == HAL_MMC_ERROR_NONE)
2451     {
2452       /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2453       count = SDMMC_MAX_TRIAL;
2454       do
2455       {
2456         errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2457         if (errorstate != HAL_MMC_ERROR_NONE)
2458         {
2459           break;
2460         }
2461 
2462         /* Get command response */
2463         response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
2464         count--;
2465       } while (((response & 0x100U) == 0U) && (count != 0U));
2466 
2467       /* Check the status after the switch command execution */
2468       if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
2469       {
2470         /* Check the bit SWITCH_ERROR of the device status */
2471         if ((response & 0x80U) != 0U)
2472         {
2473           errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
2474         }
2475         else
2476         {
2477           /* Configure the SDMMC peripheral */
2478           Init = hmmc->Init;
2479           Init.BusWide = WideMode;
2480           (void)SDMMC_Init(hmmc->Instance, Init);
2481         }
2482       }
2483       else if (count == 0U)
2484       {
2485         errorstate = SDMMC_ERROR_TIMEOUT;
2486       }
2487       else
2488       {
2489         /* Nothing to do */
2490       }
2491     }
2492   }
2493 
2494   /* Change State */
2495   hmmc->State = HAL_MMC_STATE_READY;
2496 
2497   if (errorstate != HAL_MMC_ERROR_NONE)
2498   {
2499     /* Clear all the static flags */
2500     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2501     hmmc->ErrorCode |= errorstate;
2502     return HAL_ERROR;
2503   }
2504 
2505   return HAL_OK;
2506 }
2507 
2508 /**
2509   * @brief  Configure the speed bus mode
2510   * @param  hmmc: Pointer to the MMC handle
2511   * @param  SpeedMode: Specifies the MMC card speed bus mode
2512   *          This parameter can be one of the following values:
2513   *            @arg SDMMC_SPEED_MODE_AUTO: Max speed mode supported by the card
2514   *            @arg SDMMC_SPEED_MODE_DEFAULT: Default Speed (MMC @ 26MHz)
2515   *            @arg SDMMC_SPEED_MODE_HIGH: High Speed (MMC @ 52 MHz)
2516   *            @arg SDMMC_SPEED_MODE_DDR: High Speed DDR (MMC DDR @ 52 MHz)
2517   * @retval HAL status
2518   */
2519 
2520 HAL_StatusTypeDef HAL_MMC_ConfigSpeedBusOperation(MMC_HandleTypeDef *hmmc, uint32_t SpeedMode)
2521 {
2522   uint32_t tickstart;
2523   HAL_StatusTypeDef status = HAL_OK;
2524   uint32_t device_type;
2525   uint32_t errorstate;
2526 
2527   /* Check the parameters */
2528   assert_param(IS_SDMMC_SPEED_MODE(SpeedMode));
2529 
2530   /* Change State */
2531   hmmc->State = HAL_MMC_STATE_BUSY;
2532 
2533   /* Field DEVICE_TYPE [196 = 49*4] of Extended CSD register */
2534   device_type = (hmmc->Ext_CSD[49] & 0x000000FFU);
2535 
2536   switch (SpeedMode)
2537   {
2538     case SDMMC_SPEED_MODE_AUTO:
2539     {
2540       if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS) != 0U) && ((device_type & 0x04U) != 0U))
2541       {
2542         /* High Speed DDR mode allowed */
2543         errorstate = MMC_HighSpeed(hmmc, ENABLE);
2544         if (errorstate != HAL_MMC_ERROR_NONE)
2545         {
2546           hmmc->ErrorCode |= errorstate;
2547         }
2548         else
2549         {
2550           if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_CLKDIV) != 0U)
2551           {
2552             /* DDR mode not supported with CLKDIV = 0 */
2553             errorstate = MMC_DDR_Mode(hmmc, ENABLE);
2554             if (errorstate != HAL_MMC_ERROR_NONE)
2555             {
2556               hmmc->ErrorCode |= errorstate;
2557             }
2558           }
2559         }
2560       }
2561       else if ((device_type & 0x02U) != 0U)
2562       {
2563         /* High Speed mode allowed */
2564         errorstate = MMC_HighSpeed(hmmc, ENABLE);
2565         if (errorstate != HAL_MMC_ERROR_NONE)
2566         {
2567           hmmc->ErrorCode |= errorstate;
2568         }
2569       }
2570       else
2571       {
2572         /* Nothing to do : keep current speed */
2573       }
2574       break;
2575     }
2576     case SDMMC_SPEED_MODE_DDR:
2577     {
2578       if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS) != 0U) && ((device_type & 0x04U) != 0U))
2579       {
2580         /* High Speed DDR mode allowed */
2581         errorstate = MMC_HighSpeed(hmmc, ENABLE);
2582         if (errorstate != HAL_MMC_ERROR_NONE)
2583         {
2584           hmmc->ErrorCode |= errorstate;
2585         }
2586         else
2587         {
2588           if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_CLKDIV) != 0U)
2589           {
2590             /* DDR mode not supported with CLKDIV = 0 */
2591             errorstate = MMC_DDR_Mode(hmmc, ENABLE);
2592             if (errorstate != HAL_MMC_ERROR_NONE)
2593             {
2594               hmmc->ErrorCode |= errorstate;
2595             }
2596           }
2597         }
2598       }
2599       else
2600       {
2601         /* High Speed DDR mode not allowed */
2602         hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2603         status = HAL_ERROR;
2604       }
2605       break;
2606     }
2607     case SDMMC_SPEED_MODE_HIGH:
2608     {
2609       if ((device_type & 0x02U) != 0U)
2610       {
2611         /* High Speed mode allowed */
2612         errorstate = MMC_HighSpeed(hmmc, ENABLE);
2613         if (errorstate != HAL_MMC_ERROR_NONE)
2614         {
2615           hmmc->ErrorCode |= errorstate;
2616         }
2617       }
2618       else
2619       {
2620         /* High Speed mode not allowed */
2621         hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2622         status = HAL_ERROR;
2623       }
2624       break;
2625     }
2626     case SDMMC_SPEED_MODE_DEFAULT:
2627     {
2628       if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) != 0U)
2629       {
2630         /* High Speed DDR mode activated */
2631         errorstate = MMC_DDR_Mode(hmmc, DISABLE);
2632         if (errorstate != HAL_MMC_ERROR_NONE)
2633         {
2634           hmmc->ErrorCode |= errorstate;
2635         }
2636       }
2637       if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) != 0U)
2638       {
2639         /* High Speed mode activated */
2640         errorstate = MMC_HighSpeed(hmmc, DISABLE);
2641         if (errorstate != HAL_MMC_ERROR_NONE)
2642         {
2643           hmmc->ErrorCode |= errorstate;
2644         }
2645       }
2646       break;
2647     }
2648     default:
2649       hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
2650       status = HAL_ERROR;
2651       break;
2652   }
2653 
2654   /* Verify that MMC card is ready to use after Speed mode switch*/
2655   tickstart = HAL_GetTick();
2656   while ((HAL_MMC_GetCardState(hmmc) != HAL_MMC_CARD_TRANSFER))
2657   {
2658     if ((HAL_GetTick() - tickstart) >=  SDMMC_DATATIMEOUT)
2659     {
2660       hmmc->ErrorCode = HAL_MMC_ERROR_TIMEOUT;
2661       hmmc->State = HAL_MMC_STATE_READY;
2662       return HAL_TIMEOUT;
2663     }
2664   }
2665 
2666   /* Change State */
2667   hmmc->State = HAL_MMC_STATE_READY;
2668   return status;
2669 }
2670 
2671 /**
2672   * @brief  Gets the current mmc card data state.
2673   * @param  hmmc: pointer to MMC handle
2674   * @retval Card state
2675   */
2676 HAL_MMC_CardStateTypeDef HAL_MMC_GetCardState(MMC_HandleTypeDef *hmmc)
2677 {
2678   uint32_t cardstate;
2679   uint32_t errorstate;
2680   uint32_t resp1 = 0U;
2681 
2682   errorstate = MMC_SendStatus(hmmc, &resp1);
2683   if (errorstate != HAL_MMC_ERROR_NONE)
2684   {
2685     hmmc->ErrorCode |= errorstate;
2686   }
2687 
2688   cardstate = ((resp1 >> 9U) & 0x0FU);
2689 
2690   return (HAL_MMC_CardStateTypeDef)cardstate;
2691 }
2692 
2693 /**
2694   * @brief  Abort the current transfer and disable the MMC.
2695   * @param  hmmc: pointer to a MMC_HandleTypeDef structure that contains
2696   *                the configuration information for MMC module.
2697   * @retval HAL status
2698   */
2699 HAL_StatusTypeDef HAL_MMC_Abort(MMC_HandleTypeDef *hmmc)
2700 {
2701   uint32_t error_code;
2702   uint32_t tickstart;
2703 
2704   if (hmmc->State == HAL_MMC_STATE_BUSY)
2705   {
2706     /* DIsable All interrupts */
2707     __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | \
2708                          SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR);
2709     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
2710 
2711     /*we will send the CMD12 in all cases in order to stop the data transfers*/
2712     /*In case the data transfer just finished , the external memory will not respond and will return HAL_MMC_ERROR_CMD_RSP_TIMEOUT*/
2713     /*In case the data transfer aborted , the external memory will respond and will return HAL_MMC_ERROR_NONE*/
2714     /*Other scenario will return HAL_ERROR*/
2715 
2716     hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
2717     error_code = hmmc->ErrorCode;
2718     if ((error_code != HAL_MMC_ERROR_NONE) && (error_code != HAL_MMC_ERROR_CMD_RSP_TIMEOUT))
2719     {
2720       return HAL_ERROR;
2721     }
2722 
2723     tickstart = HAL_GetTick();
2724     if ((hmmc->Instance->DCTRL & SDMMC_DCTRL_DTDIR) == SDMMC_TRANSFER_DIR_TO_CARD)
2725     {
2726       if (hmmc->ErrorCode == HAL_MMC_ERROR_NONE)
2727       {
2728          while(!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DABORT | SDMMC_FLAG_BUSYD0END))
2729         {
2730            if ((HAL_GetTick() - tickstart) >=  SDMMC_DATATIMEOUT)
2731            {
2732               hmmc->ErrorCode = HAL_MMC_ERROR_TIMEOUT;
2733               hmmc->State = HAL_MMC_STATE_READY;
2734               return HAL_TIMEOUT;
2735            }
2736         }
2737       }
2738 
2739       if (hmmc->ErrorCode == HAL_MMC_ERROR_CMD_RSP_TIMEOUT)
2740       {
2741         while(!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND))
2742         {
2743            if ((HAL_GetTick() - tickstart) >=  SDMMC_DATATIMEOUT)
2744            {
2745               hmmc->ErrorCode = HAL_MMC_ERROR_TIMEOUT;
2746               hmmc->State = HAL_MMC_STATE_READY;
2747               return HAL_TIMEOUT;
2748            }
2749         }
2750       }
2751     }
2752     else if ((hmmc->Instance->DCTRL & SDMMC_DCTRL_DTDIR) == SDMMC_TRANSFER_DIR_TO_SDMMC)
2753     {
2754       while(!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DABORT | SDMMC_FLAG_DATAEND))
2755       {
2756            if ((HAL_GetTick() - tickstart) >=  SDMMC_DATATIMEOUT)
2757            {
2758               hmmc->ErrorCode = HAL_MMC_ERROR_TIMEOUT;
2759               hmmc->State = HAL_MMC_STATE_READY;
2760               return HAL_TIMEOUT;
2761            }
2762       }
2763     }
2764     else
2765     {
2766       /* Nothing to do*/
2767     }
2768 
2769     /*The reason of all these while conditions previously is that we need to wait the SDMMC and clear the appropriate flags that will be set depending of the abort/non abort of the memory */
2770     /*Not waiting the SDMMC flags will cause the next SDMMC_DISABLE_IDMA to not get cleared and will result in next SDMMC read/write operation to fail */
2771 
2772     /*SDMMC ready for clear data flags*/
2773     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
2774     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2775       /* If IDMA Context, disable Internal DMA */
2776     hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA;
2777 
2778     hmmc->State = HAL_MMC_STATE_READY;
2779 
2780     /* Initialize the MMC operation */
2781     hmmc->Context = MMC_CONTEXT_NONE;
2782   }
2783   return HAL_OK;
2784 }
2785 /**
2786   * @brief  Abort the current transfer and disable the MMC (IT mode).
2787   * @param  hmmc: pointer to a MMC_HandleTypeDef structure that contains
2788   *                the configuration information for MMC module.
2789   * @retval HAL status
2790   */
2791 HAL_StatusTypeDef HAL_MMC_Abort_IT(MMC_HandleTypeDef *hmmc)
2792 {
2793   HAL_MMC_CardStateTypeDef CardState;
2794 
2795   /* DIsable All interrupts */
2796   __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | \
2797                        SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR);
2798 
2799   /* If IDMA Context, disable Internal DMA */
2800   hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA;
2801 
2802   /* Clear All flags */
2803   __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2804 
2805   CardState = HAL_MMC_GetCardState(hmmc);
2806   hmmc->State = HAL_MMC_STATE_READY;
2807 
2808   if ((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2809   {
2810     hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
2811   }
2812   if (hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2813   {
2814     return HAL_ERROR;
2815   }
2816   else
2817   {
2818 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2819     hmmc->AbortCpltCallback(hmmc);
2820 #else
2821     HAL_MMC_AbortCallback(hmmc);
2822 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
2823   }
2824 
2825   return HAL_OK;
2826 }
2827 
2828 /**
2829   * @brief  Perform specific commands sequence for the different type of erase.
2830   * @note   This API should be followed by a check on the card state through
2831   *         HAL_MMC_GetCardState().
2832   * @param  hmmc Pointer to MMC handle
2833   * @param  EraseType Specifies the type of erase to be performed
2834   *          This parameter can be one of the following values:
2835   *             @arg HAL_MMC_TRIM Erase the write blocks identified by CMD35 & 36
2836   *             @arg HAL_MMC_ERASE Erase the erase groups identified by CMD35 & 36
2837   *             @arg HAL_MMC_DISCARD Discard the write blocks identified by CMD35 & 36
2838   *             @arg HAL_MMC_SECURE_ERASE Perform a secure purge according SRT on the erase groups identified
2839   *                  by CMD35 & 36
2840   *             @arg HAL_MMC_SECURE_TRIM_STEP1 Mark the write blocks identified by CMD35 & 36 for secure erase
2841   *             @arg HAL_MMC_SECURE_TRIM_STEP2 Perform a secure purge according SRT on the write blocks
2842   *                  previously identified
2843   * @param  BlockStartAdd Start Block address
2844   * @param  BlockEndAdd End Block address
2845   * @retval HAL status
2846   */
2847 HAL_StatusTypeDef HAL_MMC_EraseSequence(MMC_HandleTypeDef *hmmc, uint32_t EraseType,
2848                                         uint32_t BlockStartAdd, uint32_t BlockEndAdd)
2849 {
2850   uint32_t errorstate;
2851   uint32_t start_add = BlockStartAdd;
2852   uint32_t end_add = BlockEndAdd;
2853   uint32_t tickstart = HAL_GetTick();
2854 
2855   /* Check the erase type value is correct */
2856   assert_param(IS_MMC_ERASE_TYPE(EraseType));
2857 
2858   /* Check the coherence between start and end address */
2859   if (end_add < start_add)
2860   {
2861     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
2862     return HAL_ERROR;
2863   }
2864 
2865   /* Check that the end address is not out of range of device memory */
2866   if (end_add > (hmmc->MmcCard.LogBlockNbr))
2867   {
2868     hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
2869     return HAL_ERROR;
2870   }
2871 
2872   /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
2873   if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U)
2874   {
2875     if (((start_add % 8U) != 0U) || ((end_add % 8U) != 0U))
2876     {
2877       /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
2878       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
2879       return HAL_ERROR;
2880     }
2881   }
2882 
2883   /* Check if the card command class supports erase command */
2884   if (((hmmc->MmcCard.Class) & SDMMC_CCCC_ERASE) == 0U)
2885   {
2886     hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
2887     return HAL_ERROR;
2888   }
2889 
2890   /* Check the state of the driver */
2891   if (hmmc->State == HAL_MMC_STATE_READY)
2892   {
2893     /* Change State */
2894     hmmc->State = HAL_MMC_STATE_BUSY;
2895 
2896     /* Check that the card is not locked */
2897     if ((SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
2898     {
2899       hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED;
2900       hmmc->State = HAL_MMC_STATE_READY;
2901       return HAL_ERROR;
2902     }
2903 
2904     /* In case of low capacity card, the address is not block number but bytes */
2905     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
2906     {
2907       start_add *= 512U;
2908       end_add   *= 512U;
2909     }
2910 
2911     /* Send CMD35 MMC_ERASE_GRP_START with start address as argument */
2912     errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, start_add);
2913     if (errorstate == HAL_MMC_ERROR_NONE)
2914     {
2915       /* Send CMD36 MMC_ERASE_GRP_END with end address as argument */
2916       errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, end_add);
2917       if (errorstate == HAL_MMC_ERROR_NONE)
2918       {
2919         /* Send CMD38 ERASE with erase type as argument */
2920         errorstate = SDMMC_CmdErase(hmmc->Instance, EraseType);
2921         if (errorstate == HAL_MMC_ERROR_NONE)
2922         {
2923           if ((EraseType == HAL_MMC_SECURE_ERASE) || (EraseType == HAL_MMC_SECURE_TRIM_STEP2))
2924           {
2925             /* Wait that the device is ready by checking the D0 line */
2926             while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
2927             {
2928               if ((HAL_GetTick() - tickstart) >= SDMMC_MAXERASETIMEOUT)
2929               {
2930                 errorstate = HAL_MMC_ERROR_TIMEOUT;
2931               }
2932             }
2933 
2934             /* Clear the flag corresponding to end D0 bus line */
2935             __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
2936           }
2937         }
2938       }
2939     }
2940 
2941     /* Change State */
2942     hmmc->State = HAL_MMC_STATE_READY;
2943 
2944     /* Manage errors */
2945     if (errorstate != HAL_MMC_ERROR_NONE)
2946     {
2947       /* Clear all the static flags */
2948       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2949       hmmc->ErrorCode |= errorstate;
2950 
2951       if (errorstate != HAL_MMC_ERROR_TIMEOUT)
2952       {
2953         return HAL_ERROR;
2954       }
2955       else
2956       {
2957         return HAL_TIMEOUT;
2958       }
2959     }
2960     else
2961     {
2962       return HAL_OK;
2963     }
2964   }
2965   else
2966   {
2967     return HAL_BUSY;
2968   }
2969 }
2970 
2971 /**
2972   * @brief  Perform sanitize operation on the device.
2973   * @note   This API should be followed by a check on the card state through
2974   *         HAL_MMC_GetCardState().
2975   * @param  hmmc Pointer to MMC handle
2976   * @retval HAL status
2977   */
2978 HAL_StatusTypeDef HAL_MMC_Sanitize(MMC_HandleTypeDef *hmmc)
2979 {
2980   uint32_t errorstate;
2981   uint32_t response = 0U;
2982   uint32_t count;
2983   uint32_t tickstart = HAL_GetTick();
2984 
2985   /* Check the state of the driver */
2986   if (hmmc->State == HAL_MMC_STATE_READY)
2987   {
2988     /* Change State */
2989     hmmc->State = HAL_MMC_STATE_BUSY;
2990 
2991     /* Index : 165 - Value : 0x01 */
2992     errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03A50100U);
2993     if (errorstate == HAL_MMC_ERROR_NONE)
2994     {
2995       /* Wait that the device is ready by checking the D0 line */
2996       while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
2997       {
2998         if ((HAL_GetTick() - tickstart) >= SDMMC_MAXERASETIMEOUT)
2999         {
3000           errorstate = HAL_MMC_ERROR_TIMEOUT;
3001         }
3002       }
3003 
3004       /* Clear the flag corresponding to end D0 bus line */
3005       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
3006 
3007       if (errorstate == HAL_MMC_ERROR_NONE)
3008       {
3009         /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3010         count = SDMMC_MAX_TRIAL;
3011         do
3012         {
3013           errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3014           if (errorstate != HAL_MMC_ERROR_NONE)
3015           {
3016             break;
3017           }
3018 
3019           /* Get command response */
3020           response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3021           count--;
3022         } while (((response & 0x100U) == 0U) && (count != 0U));
3023 
3024         /* Check the status after the switch command execution */
3025         if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
3026         {
3027           /* Check the bit SWITCH_ERROR of the device status */
3028           if ((response & 0x80U) != 0U)
3029           {
3030             errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
3031           }
3032         }
3033         else if (count == 0U)
3034         {
3035           errorstate = SDMMC_ERROR_TIMEOUT;
3036         }
3037         else
3038         {
3039           /* Nothing to do */
3040         }
3041       }
3042     }
3043 
3044     /* Change State */
3045     hmmc->State = HAL_MMC_STATE_READY;
3046 
3047     /* Manage errors */
3048     if (errorstate != HAL_MMC_ERROR_NONE)
3049     {
3050       /* Clear all the static flags */
3051       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3052       hmmc->ErrorCode |= errorstate;
3053 
3054       if (errorstate != HAL_MMC_ERROR_TIMEOUT)
3055       {
3056         return HAL_ERROR;
3057       }
3058       else
3059       {
3060         return HAL_TIMEOUT;
3061       }
3062     }
3063     else
3064     {
3065       return HAL_OK;
3066     }
3067   }
3068   else
3069   {
3070     return HAL_BUSY;
3071   }
3072 }
3073 
3074 /**
3075   * @brief  Configure the Secure Removal Type (SRT) in the Extended CSD register.
3076   * @note   This API should be followed by a check on the card state through
3077   *         HAL_MMC_GetCardState().
3078   * @param  hmmc Pointer to MMC handle
3079   * @param  SRTMode Specifies the type of erase to be performed
3080   *          This parameter can be one of the following values:
3081   *            @arg HAL_MMC_SRT_ERASE Information removed by an erase
3082   *            @arg HAL_MMC_SRT_WRITE_CHAR_ERASE Information removed by an overwriting with a character
3083   *                 followed by an erase
3084   *            @arg HAL_MMC_SRT_WRITE_CHAR_COMPL_RANDOM Information removed by an overwriting with a character,
3085   *                 its complement then a random character
3086   *            @arg HAL_MMC_SRT_VENDOR_DEFINED Information removed using a vendor defined
3087   * @retval HAL status
3088   */
3089 HAL_StatusTypeDef HAL_MMC_ConfigSecRemovalType(MMC_HandleTypeDef *hmmc, uint32_t SRTMode)
3090 {
3091   uint32_t srt;
3092   uint32_t errorstate;
3093   uint32_t response = 0U;
3094   uint32_t count;
3095 
3096   /* Check the erase type value is correct */
3097   assert_param(IS_MMC_SRT_TYPE(SRTMode));
3098 
3099   /* Check the state of the driver */
3100   if (hmmc->State == HAL_MMC_STATE_READY)
3101   {
3102     /* Get the supported values by the device */
3103     if (HAL_MMC_GetSupportedSecRemovalType(hmmc, &srt) == HAL_OK)
3104     {
3105       /* Change State */
3106       hmmc->State = HAL_MMC_STATE_BUSY;
3107 
3108       /* Check the value passed as parameter is supported by the device */
3109       if ((SRTMode & srt) != 0U)
3110       {
3111         /* Index : 16 - Value : SRTMode */
3112         srt |= ((POSITION_VAL(SRTMode)) << 4U);
3113         errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03100000U | (srt << 8U)));
3114         if (errorstate == HAL_MMC_ERROR_NONE)
3115         {
3116           /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3117           count = SDMMC_MAX_TRIAL;
3118           do
3119           {
3120             errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3121             if (errorstate != HAL_MMC_ERROR_NONE)
3122             {
3123               break;
3124             }
3125 
3126             /* Get command response */
3127             response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3128             count--;
3129           } while (((response & 0x100U) == 0U) && (count != 0U));
3130 
3131           /* Check the status after the switch command execution */
3132           if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
3133           {
3134             /* Check the bit SWITCH_ERROR of the device status */
3135             if ((response & 0x80U) != 0U)
3136             {
3137               errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
3138             }
3139           }
3140           else if (count == 0U)
3141           {
3142             errorstate = SDMMC_ERROR_TIMEOUT;
3143           }
3144           else
3145           {
3146             /* Nothing to do */
3147           }
3148         }
3149       }
3150       else
3151       {
3152         errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3153       }
3154 
3155       /* Change State */
3156       hmmc->State = HAL_MMC_STATE_READY;
3157     }
3158     else
3159     {
3160       errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
3161     }
3162 
3163     /* Manage errors */
3164     if (errorstate != HAL_MMC_ERROR_NONE)
3165     {
3166       /* Clear all the static flags */
3167       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3168       hmmc->ErrorCode |= errorstate;
3169       return HAL_ERROR;
3170     }
3171     else
3172     {
3173       return HAL_OK;
3174     }
3175   }
3176   else
3177   {
3178     return HAL_BUSY;
3179   }
3180 }
3181 
3182 /**
3183   * @brief  Gets the supported values of the the Secure Removal Type (SRT).
3184   * @param  hmmc pointer to MMC handle
3185   * @param  SupportedSRT pointer for supported SRT value
3186   *          This parameter is a bit field of the following values:
3187   *            @arg HAL_MMC_SRT_ERASE Information removed by an erase
3188   *            @arg HAL_MMC_SRT_WRITE_CHAR_ERASE Information removed by an overwriting with a character followed
3189   *                  by an erase
3190   *            @arg HAL_MMC_SRT_WRITE_CHAR_COMPL_RANDOM Information removed by an overwriting with a character,
3191   *                 its complement then a random character
3192   *            @arg HAL_MMC_SRT_VENDOR_DEFINED Information removed using a vendor defined
3193   * @retval HAL status
3194   */
3195 HAL_StatusTypeDef HAL_MMC_GetSupportedSecRemovalType(MMC_HandleTypeDef *hmmc, uint32_t *SupportedSRT)
3196 {
3197   /* Check the state of the driver */
3198   if (hmmc->State == HAL_MMC_STATE_READY)
3199   {
3200     /* Change State */
3201     hmmc->State = HAL_MMC_STATE_BUSY;
3202 
3203     /* Read field SECURE_REMOVAL_TYPE [16 = 4*4] of the Extended CSD register */
3204     *SupportedSRT = (hmmc->Ext_CSD[4] & 0x0000000FU); /* Bits [3:0] of field 16 */
3205 
3206     /* Change State */
3207     hmmc->State = HAL_MMC_STATE_READY;
3208 
3209     return HAL_OK;
3210   }
3211   else
3212   {
3213     return HAL_BUSY;
3214   }
3215 }
3216 
3217 /**
3218   * @brief  Switch the device from Standby State to Sleep State.
3219   * @param  hmmc pointer to MMC handle
3220   * @retval HAL status
3221   */
3222 HAL_StatusTypeDef HAL_MMC_SleepDevice(MMC_HandleTypeDef *hmmc)
3223 {
3224   uint32_t errorstate,
3225            sleep_timeout,
3226            timeout,
3227            count,
3228            response = 0U  ;
3229   uint32_t tickstart = HAL_GetTick();
3230 
3231   /* Check the state of the driver */
3232   if (hmmc->State == HAL_MMC_STATE_READY)
3233   {
3234     /* Change State */
3235     hmmc->State = HAL_MMC_STATE_BUSY;
3236 
3237     /* Set the power-off notification to powered-on : Ext_CSD[34] = 1 */
3238     errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03220100U));
3239     if (errorstate == HAL_MMC_ERROR_NONE)
3240     {
3241       /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3242       count = SDMMC_MAX_TRIAL;
3243       do
3244       {
3245         errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3246         if (errorstate != HAL_MMC_ERROR_NONE)
3247         {
3248           break;
3249         }
3250 
3251         /* Get command response */
3252         response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3253         count--;
3254       } while (((response & 0x100U) == 0U) && (count != 0U));
3255 
3256       /* Check the status after the switch command execution */
3257       if (count == 0U)
3258       {
3259         errorstate = SDMMC_ERROR_TIMEOUT;
3260       }
3261       else if (errorstate == HAL_MMC_ERROR_NONE)
3262       {
3263         /* Check the bit SWITCH_ERROR of the device status */
3264         if ((response & 0x80U) != 0U)
3265         {
3266           errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3267         }
3268         else
3269         {
3270           /* Set the power-off notification to sleep notification : Ext_CSD[34] = 4 */
3271           errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03220400U));
3272           if (errorstate == HAL_MMC_ERROR_NONE)
3273           {
3274             /* Field SLEEP_NOTIFICATION_TIME [216] */
3275             sleep_timeout = ((hmmc->Ext_CSD[(MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_INDEX / 4)] >>
3276                               MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_POS) & 0x000000FFU);
3277 
3278             /* Sleep/Awake Timeout = 10us * 2^SLEEP_NOTIFICATION_TIME */
3279             /* In HAL, the tick interrupt occurs each ms */
3280             if ((sleep_timeout == 0U) || (sleep_timeout > 0x17U))
3281             {
3282               sleep_timeout = 0x17U; /* Max register value defined is 0x17 */
3283             }
3284             timeout = (((1UL << sleep_timeout) / 100U) + 1U);
3285 
3286             /* Wait that the device is ready by checking the D0 line */
3287             while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
3288             {
3289               if ((HAL_GetTick() - tickstart) >= timeout)
3290               {
3291                 errorstate = SDMMC_ERROR_TIMEOUT;
3292               }
3293             }
3294 
3295             /* Clear the flag corresponding to end D0 bus line */
3296             __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
3297 
3298             if (errorstate == HAL_MMC_ERROR_NONE)
3299             {
3300               /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3301               count = SDMMC_MAX_TRIAL;
3302               do
3303               {
3304                 errorstate = SDMMC_CmdSendStatus(hmmc->Instance,
3305                                                  (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3306                 if (errorstate != HAL_MMC_ERROR_NONE)
3307                 {
3308                   break;
3309                 }
3310 
3311                 /* Get command response */
3312                 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3313                 count--;
3314               } while (((response & 0x100U) == 0U) && (count != 0U));
3315 
3316               /* Check the status after the switch command execution */
3317               if (count == 0U)
3318               {
3319                 errorstate = SDMMC_ERROR_TIMEOUT;
3320               }
3321               else if (errorstate == HAL_MMC_ERROR_NONE)
3322               {
3323                 /* Check the bit SWITCH_ERROR of the device status */
3324                 if ((response & 0x80U) != 0U)
3325                 {
3326                   errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3327                 }
3328                 else
3329                 {
3330                   /* Switch the device in stand-by mode */
3331                   (void)SDMMC_CmdSelDesel(hmmc->Instance, 0U);
3332 
3333                   /* Field S_A_TIEMOUT [217] */
3334                   sleep_timeout = ((hmmc->Ext_CSD[(MMC_EXT_CSD_S_A_TIMEOUT_INDEX / 4)] >>
3335                                     MMC_EXT_CSD_S_A_TIMEOUT_POS) & 0x000000FFU);
3336 
3337                   /* Sleep/Awake Timeout = 100ns * 2^S_A_TIMEOUT */
3338                   /* In HAL, the tick interrupt occurs each ms */
3339                   if ((sleep_timeout == 0U) || (sleep_timeout > 0x17U))
3340                   {
3341                     sleep_timeout = 0x17U; /* Max register value defined is 0x17 */
3342                   }
3343                   timeout = (((1UL << sleep_timeout) / 10000U) + 1U);
3344 
3345                   if (HAL_MMC_GetCardState(hmmc) == HAL_MMC_CARD_STANDBY)
3346                   {
3347                     /* Send CMD5 CMD_MMC_SLEEP_AWAKE with RCA and SLEEP as argument */
3348                     errorstate = SDMMC_CmdSleepMmc(hmmc->Instance,
3349                                                    ((hmmc->MmcCard.RelCardAdd << 16U) | (0x1U << 15U)));
3350                     if (errorstate == HAL_MMC_ERROR_NONE)
3351                     {
3352                       /* Wait that the device is ready by checking the D0 line */
3353                       while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
3354                       {
3355                         if ((HAL_GetTick() - tickstart) >= timeout)
3356                         {
3357                           errorstate = SDMMC_ERROR_TIMEOUT;
3358                         }
3359                       }
3360 
3361                       /* Clear the flag corresponding to end D0 bus line */
3362                       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
3363                     }
3364                   }
3365                   else
3366                   {
3367                     errorstate = SDMMC_ERROR_REQUEST_NOT_APPLICABLE;
3368                   }
3369                 }
3370               }
3371               else
3372               {
3373                 /* Nothing to do */
3374               }
3375             }
3376           }
3377         }
3378       }
3379       else
3380       {
3381         /* Nothing to do */
3382       }
3383     }
3384 
3385     /* Change State */
3386     hmmc->State = HAL_MMC_STATE_READY;
3387 
3388     /* Manage errors */
3389     if (errorstate != HAL_MMC_ERROR_NONE)
3390     {
3391       /* Clear all the static flags */
3392       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3393       hmmc->ErrorCode |= errorstate;
3394 
3395       if (errorstate != HAL_MMC_ERROR_TIMEOUT)
3396       {
3397         return HAL_ERROR;
3398       }
3399       else
3400       {
3401         return HAL_TIMEOUT;
3402       }
3403     }
3404     else
3405     {
3406       return HAL_OK;
3407     }
3408   }
3409   else
3410   {
3411     return HAL_BUSY;
3412   }
3413 }
3414 
3415 /**
3416   * @brief  Switch the device from Sleep State to Standby State.
3417   * @param  hmmc pointer to MMC handle
3418   * @retval HAL status
3419   */
3420 HAL_StatusTypeDef HAL_MMC_AwakeDevice(MMC_HandleTypeDef *hmmc)
3421 {
3422   uint32_t errorstate;
3423   uint32_t sleep_timeout;
3424   uint32_t timeout;
3425   uint32_t count;
3426   uint32_t response = 0U;
3427   uint32_t tickstart = HAL_GetTick();
3428 
3429   /* Check the state of the driver */
3430   if (hmmc->State == HAL_MMC_STATE_READY)
3431   {
3432     /* Change State */
3433     hmmc->State = HAL_MMC_STATE_BUSY;
3434 
3435     /* Field S_A_TIEMOUT [217] */
3436     sleep_timeout = ((hmmc->Ext_CSD[(MMC_EXT_CSD_S_A_TIMEOUT_INDEX / 4)] >> MMC_EXT_CSD_S_A_TIMEOUT_POS) &
3437                      0x000000FFU);
3438 
3439     /* Sleep/Awake Timeout = 100ns * 2^S_A_TIMEOUT */
3440     /* In HAL, the tick interrupt occurs each ms */
3441     if ((sleep_timeout == 0U) || (sleep_timeout > 0x17U))
3442     {
3443       sleep_timeout = 0x17U; /* Max register value defined is 0x17 */
3444     }
3445     timeout = (((1UL << sleep_timeout) / 10000U) + 1U);
3446 
3447     /* Send CMD5 CMD_MMC_SLEEP_AWAKE with RCA and AWAKE as argument */
3448     errorstate = SDMMC_CmdSleepMmc(hmmc->Instance, (hmmc->MmcCard.RelCardAdd << 16U));
3449     if (errorstate == HAL_MMC_ERROR_NONE)
3450     {
3451       /* Wait that the device is ready by checking the D0 line */
3452       while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
3453       {
3454         if ((HAL_GetTick() - tickstart) >= timeout)
3455         {
3456           errorstate = SDMMC_ERROR_TIMEOUT;
3457         }
3458       }
3459 
3460       /* Clear the flag corresponding to end D0 bus line */
3461       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
3462 
3463       if (errorstate == HAL_MMC_ERROR_NONE)
3464       {
3465         if (HAL_MMC_GetCardState(hmmc) == HAL_MMC_CARD_STANDBY)
3466         {
3467           /* Switch the device in transfer mode */
3468           errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (hmmc->MmcCard.RelCardAdd << 16U));
3469           if (errorstate == HAL_MMC_ERROR_NONE)
3470           {
3471             if (HAL_MMC_GetCardState(hmmc) == HAL_MMC_CARD_TRANSFER)
3472             {
3473               /* Set the power-off notification to powered-on : Ext_CSD[34] = 1 */
3474               errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03220100U));
3475               if (errorstate == HAL_MMC_ERROR_NONE)
3476               {
3477                 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3478                 count = SDMMC_MAX_TRIAL;
3479                 do
3480                 {
3481                   errorstate = SDMMC_CmdSendStatus(hmmc->Instance,
3482                                                    (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3483                   if (errorstate != HAL_MMC_ERROR_NONE)
3484                   {
3485                     break;
3486                   }
3487 
3488                   /* Get command response */
3489                   response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3490                   count--;
3491                 } while (((response & 0x100U) == 0U) && (count != 0U));
3492 
3493                 /* Check the status after the switch command execution */
3494                 if (count == 0U)
3495                 {
3496                   errorstate = SDMMC_ERROR_TIMEOUT;
3497                 }
3498                 else if (errorstate == HAL_MMC_ERROR_NONE)
3499                 {
3500                   /* Check the bit SWITCH_ERROR of the device status */
3501                   if ((response & 0x80U) != 0U)
3502                   {
3503                     errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3504                   }
3505                 }
3506                 else
3507                 {
3508                   /* NOthing to do */
3509                 }
3510               }
3511             }
3512             else
3513             {
3514               errorstate = SDMMC_ERROR_REQUEST_NOT_APPLICABLE;
3515             }
3516           }
3517         }
3518         else
3519         {
3520           errorstate = SDMMC_ERROR_REQUEST_NOT_APPLICABLE;
3521         }
3522       }
3523     }
3524 
3525     /* Change State */
3526     hmmc->State = HAL_MMC_STATE_READY;
3527 
3528     /* Manage errors */
3529     if (errorstate != HAL_MMC_ERROR_NONE)
3530     {
3531       /* Clear all the static flags */
3532       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3533       hmmc->ErrorCode |= errorstate;
3534 
3535       if (errorstate != HAL_MMC_ERROR_TIMEOUT)
3536       {
3537         return HAL_ERROR;
3538       }
3539       else
3540       {
3541         return HAL_TIMEOUT;
3542       }
3543     }
3544     else
3545     {
3546       return HAL_OK;
3547     }
3548   }
3549   else
3550   {
3551     return HAL_BUSY;
3552   }
3553 }
3554 /**
3555   * @}
3556   */
3557 
3558 /**
3559   * @}
3560   */
3561 
3562 /* Private function ----------------------------------------------------------*/
3563 /** @addtogroup MMC_Private_Functions
3564   * @{
3565   */
3566 
3567 
3568 /**
3569   * @brief  Initializes the mmc card.
3570   * @param  hmmc: Pointer to MMC handle
3571   * @retval MMC Card error state
3572   */
3573 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc)
3574 {
3575   HAL_MMC_CardCSDTypeDef CSD;
3576   uint32_t errorstate;
3577   uint16_t mmc_rca = 2U;
3578   MMC_InitTypeDef Init;
3579 
3580   /* Check the power State */
3581   if (SDMMC_GetPowerState(hmmc->Instance) == 0U)
3582   {
3583     /* Power off */
3584     return HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
3585   }
3586 
3587   /* Send CMD2 ALL_SEND_CID */
3588   errorstate = SDMMC_CmdSendCID(hmmc->Instance);
3589   if (errorstate != HAL_MMC_ERROR_NONE)
3590   {
3591     return errorstate;
3592   }
3593   else
3594   {
3595     /* Get Card identification number data */
3596     hmmc->CID[0U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3597     hmmc->CID[1U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2);
3598     hmmc->CID[2U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP3);
3599     hmmc->CID[3U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP4);
3600   }
3601 
3602   /* Send CMD3 SET_REL_ADDR with RCA = 2 (should be greater than 1) */
3603   /* MMC Card publishes its RCA. */
3604   errorstate = SDMMC_CmdSetRelAddMmc(hmmc->Instance, mmc_rca);
3605   if (errorstate != HAL_MMC_ERROR_NONE)
3606   {
3607     return errorstate;
3608   }
3609 
3610   /* Get the MMC card RCA */
3611   hmmc->MmcCard.RelCardAdd = mmc_rca;
3612 
3613   /* Send CMD9 SEND_CSD with argument as card's RCA */
3614   errorstate = SDMMC_CmdSendCSD(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
3615   if (errorstate != HAL_MMC_ERROR_NONE)
3616   {
3617     return errorstate;
3618   }
3619   else
3620   {
3621     /* Get Card Specific Data */
3622     hmmc->CSD[0U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3623     hmmc->CSD[1U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2);
3624     hmmc->CSD[2U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP3);
3625     hmmc->CSD[3U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP4);
3626   }
3627 
3628   /* Get the Card Class */
3629   hmmc->MmcCard.Class = (SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2) >> 20U);
3630 
3631   /* Select the Card */
3632   errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3633   if (errorstate != HAL_MMC_ERROR_NONE)
3634   {
3635     return errorstate;
3636   }
3637 
3638   /* Get CSD parameters */
3639   if (HAL_MMC_GetCardCSD(hmmc, &CSD) != HAL_OK)
3640   {
3641     return hmmc->ErrorCode;
3642   }
3643 
3644   /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3645   errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3646   if (errorstate != HAL_MMC_ERROR_NONE)
3647   {
3648     hmmc->ErrorCode |= errorstate;
3649   }
3650 
3651 
3652   /* Get Extended CSD parameters */
3653   if (HAL_MMC_GetCardExtCSD(hmmc, hmmc->Ext_CSD, SDMMC_DATATIMEOUT) != HAL_OK)
3654   {
3655     return hmmc->ErrorCode;
3656   }
3657 
3658   /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3659   errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3660   if (errorstate != HAL_MMC_ERROR_NONE)
3661   {
3662     hmmc->ErrorCode |= errorstate;
3663   }
3664 
3665   /* Configure the SDMMC peripheral */
3666   Init = hmmc->Init;
3667   Init.BusWide = SDMMC_BUS_WIDE_1B;
3668   (void)SDMMC_Init(hmmc->Instance, Init);
3669 
3670   /* All cards are initialized */
3671   return HAL_MMC_ERROR_NONE;
3672 }
3673 
3674 /**
3675   * @brief  Enquires cards about their operating voltage and configures clock
3676   *         controls and stores MMC information that will be needed in future
3677   *         in the MMC handle.
3678   * @param  hmmc: Pointer to MMC handle
3679   * @retval error state
3680   */
3681 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc)
3682 {
3683   __IO uint32_t count = 0U;
3684   uint32_t response = 0U;
3685   uint32_t validvoltage = 0U;
3686   uint32_t errorstate;
3687 
3688   /* CMD0: GO_IDLE_STATE */
3689   errorstate = SDMMC_CmdGoIdleState(hmmc->Instance);
3690   if (errorstate != HAL_MMC_ERROR_NONE)
3691   {
3692     return errorstate;
3693   }
3694 
3695   while (validvoltage == 0U)
3696   {
3697     if (count++ == SDMMC_MAX_VOLT_TRIAL)
3698     {
3699       return HAL_MMC_ERROR_INVALID_VOLTRANGE;
3700     }
3701 
3702     /* SEND CMD1 APP_CMD with voltage range as argument */
3703     errorstate = SDMMC_CmdOpCondition(hmmc->Instance, MMC_VOLTAGE_RANGE);
3704     if (errorstate != HAL_MMC_ERROR_NONE)
3705     {
3706       return HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
3707     }
3708 
3709     /* Get command response */
3710     response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3711 
3712     /* Get operating voltage*/
3713     validvoltage = (((response >> 31U) == 1U) ? 1U : 0U);
3714   }
3715 
3716   /* When power routine is finished and command returns valid voltage */
3717   if (((response & (0xFF000000U)) >> 24) == 0xC0U)
3718   {
3719     hmmc->MmcCard.CardType = MMC_HIGH_CAPACITY_CARD;
3720   }
3721   else
3722   {
3723     hmmc->MmcCard.CardType = MMC_LOW_CAPACITY_CARD;
3724   }
3725 
3726   return HAL_MMC_ERROR_NONE;
3727 }
3728 
3729 /**
3730   * @brief  Turns the SDMMC output signals off.
3731   * @param  hmmc: Pointer to MMC handle
3732   * @retval None
3733   */
3734 static void MMC_PowerOFF(MMC_HandleTypeDef *hmmc)
3735 {
3736   /* Set Power State to OFF */
3737   (void)SDMMC_PowerState_OFF(hmmc->Instance);
3738 }
3739 
3740 /**
3741   * @brief  Returns the current card's status.
3742   * @param  hmmc: Pointer to MMC handle
3743   * @param  pCardStatus: pointer to the buffer that will contain the MMC card
3744   *         status (Card Status register)
3745   * @retval error state
3746   */
3747 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus)
3748 {
3749   uint32_t errorstate;
3750 
3751   if (pCardStatus == NULL)
3752   {
3753     return HAL_MMC_ERROR_PARAM;
3754   }
3755 
3756   /* Send Status command */
3757   errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
3758   if (errorstate != HAL_MMC_ERROR_NONE)
3759   {
3760     return errorstate;
3761   }
3762 
3763   /* Get MMC card status */
3764   *pCardStatus = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3765 
3766   return HAL_MMC_ERROR_NONE;
3767 }
3768 
3769 /**
3770   * @brief  Reads extended CSD register to get the sectors number of the device
3771   * @param  hmmc: Pointer to MMC handle
3772   * @param  pFieldData: Pointer to the read buffer
3773   * @param  FieldIndex: Index of the field to be read
3774   * @param  Timeout: Specify timeout value
3775   * @retval HAL status
3776   */
3777 static HAL_StatusTypeDef MMC_ReadExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pFieldData,
3778                                         uint16_t FieldIndex, uint32_t Timeout)
3779 {
3780   SDMMC_DataInitTypeDef config;
3781   uint32_t errorstate;
3782   uint32_t tickstart = HAL_GetTick();
3783   uint32_t count;
3784   uint32_t i = 0;
3785   uint32_t tmp_data;
3786 
3787   hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
3788 
3789   /* Initialize data control register */
3790   hmmc->Instance->DCTRL = 0;
3791 
3792   /* Configure the MMC DPSM (Data Path State Machine) */
3793   config.DataTimeOut   = SDMMC_DATATIMEOUT;
3794   config.DataLength    = 512U;
3795   config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
3796   config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
3797   config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
3798   config.DPSM          = SDMMC_DPSM_ENABLE;
3799   (void)SDMMC_ConfigData(hmmc->Instance, &config);
3800 
3801   /* Set Block Size for Card */
3802   errorstate = SDMMC_CmdSendEXTCSD(hmmc->Instance, 0);
3803   if (errorstate != HAL_MMC_ERROR_NONE)
3804   {
3805     /* Clear all the static flags */
3806     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3807     hmmc->ErrorCode |= errorstate;
3808     hmmc->State = HAL_MMC_STATE_READY;
3809     return HAL_ERROR;
3810   }
3811 
3812   /* Poll on SDMMC flags */
3813   while (!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT |
3814                              SDMMC_FLAG_DATAEND))
3815   {
3816     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF))
3817     {
3818       /* Read data from SDMMC Rx FIFO */
3819       for (count = 0U; count < 8U; count++)
3820       {
3821         tmp_data = SDMMC_ReadFIFO(hmmc->Instance);
3822         /* eg : SEC_COUNT   : FieldIndex = 212 => i+count = 53 */
3823         /*      DEVICE_TYPE : FieldIndex = 196 => i+count = 49 */
3824         if ((i + count) == ((uint32_t)FieldIndex / 4U))
3825         {
3826           *pFieldData = tmp_data;
3827         }
3828       }
3829       i += 8U;
3830     }
3831 
3832     if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
3833     {
3834       /* Clear all the static flags */
3835       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3836       hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
3837       hmmc->State = HAL_MMC_STATE_READY;
3838       return HAL_TIMEOUT;
3839     }
3840   }
3841 
3842   /* Get error state */
3843   if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
3844   {
3845     /* Clear all the static flags */
3846     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3847     hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
3848     hmmc->State = HAL_MMC_STATE_READY;
3849     return HAL_ERROR;
3850   }
3851   else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
3852   {
3853     /* Clear all the static flags */
3854     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3855     hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
3856     hmmc->State = HAL_MMC_STATE_READY;
3857     return HAL_ERROR;
3858   }
3859   else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR))
3860   {
3861     /* Clear all the static flags */
3862     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3863     hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
3864     hmmc->State = HAL_MMC_STATE_READY;
3865     return HAL_ERROR;
3866   }
3867   else
3868   {
3869     /* Nothing to do */
3870   }
3871 
3872   /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3873   errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16));
3874   if (errorstate != HAL_MMC_ERROR_NONE)
3875   {
3876     hmmc->ErrorCode |= errorstate;
3877   }
3878 
3879   /* Clear all the static flags */
3880   __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
3881 
3882   hmmc->State = HAL_MMC_STATE_READY;
3883 
3884   return HAL_OK;
3885 }
3886 
3887 /**
3888   * @brief  Wrap up reading in non-blocking mode.
3889   * @param  hmmc: pointer to a MMC_HandleTypeDef structure that contains
3890   *              the configuration information.
3891   * @retval None
3892   */
3893 static void MMC_Read_IT(MMC_HandleTypeDef *hmmc)
3894 {
3895   uint32_t count;
3896   uint32_t data;
3897   uint8_t *tmp;
3898 
3899   tmp = hmmc->pRxBuffPtr;
3900 
3901   if (hmmc->RxXferSize >= 32U)
3902   {
3903     /* Read data from SDMMC Rx FIFO */
3904     for (count = 0U; count < 8U; count++)
3905     {
3906       data = SDMMC_ReadFIFO(hmmc->Instance);
3907       *tmp = (uint8_t)(data & 0xFFU);
3908       tmp++;
3909       *tmp = (uint8_t)((data >> 8U) & 0xFFU);
3910       tmp++;
3911       *tmp = (uint8_t)((data >> 16U) & 0xFFU);
3912       tmp++;
3913       *tmp = (uint8_t)((data >> 24U) & 0xFFU);
3914       tmp++;
3915     }
3916 
3917     hmmc->pRxBuffPtr = tmp;
3918     hmmc->RxXferSize -= 32U;
3919   }
3920 }
3921 
3922 /**
3923   * @brief  Wrap up writing in non-blocking mode.
3924   * @param  hmmc: pointer to a MMC_HandleTypeDef structure that contains
3925   *              the configuration information.
3926   * @retval None
3927   */
3928 static void MMC_Write_IT(MMC_HandleTypeDef *hmmc)
3929 {
3930   uint32_t count;
3931   uint32_t data;
3932   const uint8_t *tmp;
3933 
3934   tmp = hmmc->pTxBuffPtr;
3935 
3936   if (hmmc->TxXferSize >= 32U)
3937   {
3938     /* Write data to SDMMC Tx FIFO */
3939     for (count = 0U; count < 8U; count++)
3940     {
3941       data = (uint32_t)(*tmp);
3942       tmp++;
3943       data |= ((uint32_t)(*tmp) << 8U);
3944       tmp++;
3945       data |= ((uint32_t)(*tmp) << 16U);
3946       tmp++;
3947       data |= ((uint32_t)(*tmp) << 24U);
3948       tmp++;
3949       (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
3950     }
3951 
3952     hmmc->pTxBuffPtr = tmp;
3953     hmmc->TxXferSize -= 32U;
3954   }
3955 }
3956 
3957 /**
3958   * @brief  Switches the MMC card to high speed mode.
3959   * @param  hmmc: MMC handle
3960   * @param  state: State of high speed mode
3961   * @retval MMC Card error state
3962   */
3963 static uint32_t MMC_HighSpeed(MMC_HandleTypeDef *hmmc, FunctionalState state)
3964 {
3965   uint32_t errorstate = HAL_MMC_ERROR_NONE;
3966   uint32_t response = 0U;
3967   uint32_t count;
3968   uint32_t sdmmc_clk;
3969   SDMMC_InitTypeDef Init;
3970 
3971   if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) != 0U) && (state == DISABLE))
3972   {
3973     errorstate = MMC_PwrClassUpdate(hmmc, (hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS), SDMMC_SPEED_MODE_DEFAULT);
3974     if (errorstate == HAL_MMC_ERROR_NONE)
3975     {
3976       /* Index : 185 - Value : 0 */
3977       errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B90000U);
3978     }
3979   }
3980 
3981   if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) == 0U) && (state != DISABLE))
3982   {
3983     errorstate = MMC_PwrClassUpdate(hmmc, (hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS), SDMMC_SPEED_MODE_HIGH);
3984     if (errorstate == HAL_MMC_ERROR_NONE)
3985     {
3986       /* Index : 185 - Value : 1 */
3987       errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B90100U);
3988     }
3989   }
3990 
3991   if (errorstate == HAL_MMC_ERROR_NONE)
3992   {
3993     /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3994     count = SDMMC_MAX_TRIAL;
3995     do
3996     {
3997       errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3998       if (errorstate != HAL_MMC_ERROR_NONE)
3999       {
4000         break;
4001       }
4002 
4003       /* Get command response */
4004       response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
4005       count--;
4006     } while (((response & 0x100U) == 0U) && (count != 0U));
4007 
4008     /* Check the status after the switch command execution */
4009     if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
4010     {
4011       /* Check the bit SWITCH_ERROR of the device status */
4012       if ((response & 0x80U) != 0U)
4013       {
4014         errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
4015       }
4016       else
4017       {
4018         /* Configure high speed */
4019         Init.ClockEdge           = hmmc->Init.ClockEdge;
4020         Init.ClockPowerSave      = hmmc->Init.ClockPowerSave;
4021         Init.BusWide             = (hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS);
4022         Init.HardwareFlowControl = hmmc->Init.HardwareFlowControl;
4023 
4024         if (state == DISABLE)
4025         {
4026           Init.ClockDiv = hmmc->Init.ClockDiv;
4027           (void)SDMMC_Init(hmmc->Instance, Init);
4028 
4029           CLEAR_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_BUSSPEED);
4030         }
4031         else
4032         {
4033           /* High Speed Clock should be less or equal to 52MHz*/
4034           sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC);
4035 
4036           if (sdmmc_clk == 0U)
4037           {
4038             errorstate = SDMMC_ERROR_INVALID_PARAMETER;
4039           }
4040           else
4041           {
4042             if (sdmmc_clk <= MMC_HIGH_SPEED_FREQ)
4043             {
4044               Init.ClockDiv = 0;
4045             }
4046             else
4047             {
4048               Init.ClockDiv = (sdmmc_clk / (2U * MMC_HIGH_SPEED_FREQ)) + 1U;
4049             }
4050             (void)SDMMC_Init(hmmc->Instance, Init);
4051 
4052             SET_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_BUSSPEED);
4053           }
4054         }
4055       }
4056     }
4057     else if (count == 0U)
4058     {
4059       errorstate = SDMMC_ERROR_TIMEOUT;
4060     }
4061     else
4062     {
4063       /* Nothing to do */
4064     }
4065   }
4066 
4067   return errorstate;
4068 }
4069 
4070 /**
4071   * @brief  Switches the MMC card to Double Data Rate (DDR) mode.
4072   * @param  hmmc: MMC handle
4073   * @param  state: State of DDR mode
4074   * @retval MMC Card error state
4075   */
4076 static uint32_t MMC_DDR_Mode(MMC_HandleTypeDef *hmmc, FunctionalState state)
4077 {
4078   uint32_t errorstate = HAL_MMC_ERROR_NONE;
4079   uint32_t response = 0U;
4080   uint32_t count;
4081 
4082   if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) != 0U) && (state == DISABLE))
4083   {
4084     if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS_0) != 0U)
4085     {
4086       errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_4B, SDMMC_SPEED_MODE_HIGH);
4087       if (errorstate == HAL_MMC_ERROR_NONE)
4088       {
4089         /* Index : 183 - Value : 1 */
4090         errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U);
4091       }
4092     }
4093     else
4094     {
4095       errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_8B, SDMMC_SPEED_MODE_HIGH);
4096       if (errorstate == HAL_MMC_ERROR_NONE)
4097       {
4098         /* Index : 183 - Value : 2 */
4099         errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U);
4100       }
4101     }
4102   }
4103 
4104   if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) == 0U) && (state != DISABLE))
4105   {
4106     if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS_0) != 0U)
4107     {
4108       errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_4B, SDMMC_SPEED_MODE_DDR);
4109       if (errorstate == HAL_MMC_ERROR_NONE)
4110       {
4111         /* Index : 183 - Value : 5 */
4112         errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70500U);
4113       }
4114     }
4115     else
4116     {
4117       errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_8B, SDMMC_SPEED_MODE_DDR);
4118       if (errorstate == HAL_MMC_ERROR_NONE)
4119       {
4120         /* Index : 183 - Value : 6 */
4121         errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70600U);
4122       }
4123     }
4124   }
4125 
4126   if (errorstate == HAL_MMC_ERROR_NONE)
4127   {
4128     /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
4129     count = SDMMC_MAX_TRIAL;
4130     do
4131     {
4132       errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
4133       if (errorstate != HAL_MMC_ERROR_NONE)
4134       {
4135         break;
4136       }
4137 
4138       /* Get command response */
4139       response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
4140       count--;
4141     } while (((response & 0x100U) == 0U) && (count != 0U));
4142 
4143     /* Check the status after the switch command execution */
4144     if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
4145     {
4146       /* Check the bit SWITCH_ERROR of the device status */
4147       if ((response & 0x80U) != 0U)
4148       {
4149         errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
4150       }
4151       else
4152       {
4153         /* Configure DDR mode */
4154         if (state == DISABLE)
4155         {
4156           CLEAR_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_DDR);
4157         }
4158         else
4159         {
4160           SET_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_DDR);
4161         }
4162       }
4163     }
4164     else if (count == 0U)
4165     {
4166       errorstate = SDMMC_ERROR_TIMEOUT;
4167     }
4168     else
4169     {
4170       /* Nothing to do */
4171     }
4172   }
4173 
4174   return errorstate;
4175 }
4176 
4177 /**
4178   * @brief  Update the power class of the device.
4179   * @param  hmmc MMC handle
4180   * @param  Wide Wide of MMC bus
4181   * @param  Speed Speed of the MMC bus
4182   * @retval MMC Card error state
4183   */
4184 static uint32_t MMC_PwrClassUpdate(MMC_HandleTypeDef *hmmc, uint32_t Wide, uint32_t Speed)
4185 {
4186   uint32_t count;
4187   uint32_t response = 0U;
4188   uint32_t errorstate = HAL_MMC_ERROR_NONE;
4189   uint32_t power_class;
4190   uint32_t supported_pwr_class;
4191 
4192   if ((Wide == SDMMC_BUS_WIDE_8B) || (Wide == SDMMC_BUS_WIDE_4B))
4193   {
4194     power_class = 0U; /* Default value after power-on or software reset */
4195 
4196     /* Read the PowerClass field of the Extended CSD register */
4197     if (MMC_ReadExtCSD(hmmc, &power_class, 187, SDMMC_DATATIMEOUT) != HAL_OK) /* Field POWER_CLASS [187] */
4198     {
4199       errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
4200     }
4201     else
4202     {
4203       power_class = ((power_class >> 24U) & 0x000000FFU);
4204     }
4205 
4206     /* Get the supported PowerClass field of the Extended CSD register */
4207     if (Speed == SDMMC_SPEED_MODE_DDR)
4208     {
4209       /* Field PWR_CL_DDR_52_xxx [238 or 239] */
4210       supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_DDR_52_INDEX / 4)] >> MMC_EXT_CSD_PWR_CL_DDR_52_POS) &
4211                              0x000000FFU);
4212     }
4213     else if (Speed == SDMMC_SPEED_MODE_HIGH)
4214     {
4215       /* Field PWR_CL_52_xxx [200 or 202] */
4216       supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_52_INDEX / 4)] >> MMC_EXT_CSD_PWR_CL_52_POS) &
4217                              0x000000FFU);
4218     }
4219     else
4220     {
4221       /* Field PWR_CL_26_xxx [201 or 203] */
4222       supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_26_INDEX / 4)] >> MMC_EXT_CSD_PWR_CL_26_POS) &
4223                              0x000000FFU);
4224     }
4225 
4226     if (errorstate == HAL_MMC_ERROR_NONE)
4227     {
4228       if (Wide == SDMMC_BUS_WIDE_8B)
4229       {
4230         /* Bit [7:4]: power class for 8-bits bus configuration - Bit [3:0]: power class for 4-bits bus configuration */
4231         supported_pwr_class = (supported_pwr_class >> 4U);
4232       }
4233 
4234       if ((power_class & 0x0FU) != (supported_pwr_class & 0x0FU))
4235       {
4236         /* Need to change current power class */
4237         errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03BB0000U | ((supported_pwr_class & 0x0FU) << 8U)));
4238 
4239         if (errorstate == HAL_MMC_ERROR_NONE)
4240         {
4241           /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
4242           count = SDMMC_MAX_TRIAL;
4243           do
4244           {
4245             errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
4246             if (errorstate != HAL_MMC_ERROR_NONE)
4247             {
4248               break;
4249             }
4250 
4251             /* Get command response */
4252             response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
4253             count--;
4254           } while (((response & 0x100U) == 0U) && (count != 0U));
4255 
4256           /* Check the status after the switch command execution */
4257           if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
4258           {
4259             /* Check the bit SWITCH_ERROR of the device status */
4260             if ((response & 0x80U) != 0U)
4261             {
4262               errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
4263             }
4264           }
4265           else if (count == 0U)
4266           {
4267             errorstate = SDMMC_ERROR_TIMEOUT;
4268           }
4269           else
4270           {
4271             /* Nothing to do */
4272           }
4273         }
4274       }
4275     }
4276   }
4277 
4278   return errorstate;
4279 }
4280 
4281 /**
4282   * @brief Read DMA Buffer 0 Transfer completed callbacks
4283   * @param hmmc: MMC handle
4284   * @retval None
4285   */
4286 __weak void HAL_MMCEx_Read_DMADoubleBuf0CpltCallback(MMC_HandleTypeDef *hmmc)
4287 {
4288   /* Prevent unused argument(s) compilation warning */
4289   UNUSED(hmmc);
4290 
4291   /* NOTE : This function should not be modified, when the callback is needed,
4292             the HAL_MMCEx_Read_DMADoubleBuf0CpltCallback can be implemented in the user file
4293    */
4294 }
4295 
4296 /**
4297   * @brief Read DMA Buffer 1 Transfer completed callbacks
4298   * @param hmmc: MMC handle
4299   * @retval None
4300   */
4301 __weak void HAL_MMCEx_Read_DMADoubleBuf1CpltCallback(MMC_HandleTypeDef *hmmc)
4302 {
4303   /* Prevent unused argument(s) compilation warning */
4304   UNUSED(hmmc);
4305 
4306   /* NOTE : This function should not be modified, when the callback is needed,
4307             the HAL_MMCEx_Read_DMADoubleBuf1CpltCallback can be implemented in the user file
4308    */
4309 }
4310 
4311 /**
4312   * @brief Write DMA Buffer 0 Transfer completed callbacks
4313   * @param hmmc: MMC handle
4314   * @retval None
4315   */
4316 __weak void HAL_MMCEx_Write_DMADoubleBuf0CpltCallback(MMC_HandleTypeDef *hmmc)
4317 {
4318   /* Prevent unused argument(s) compilation warning */
4319   UNUSED(hmmc);
4320 
4321   /* NOTE : This function should not be modified, when the callback is needed,
4322             the HAL_MMCEx_Write_DMADoubleBuf0CpltCallback can be implemented in the user file
4323    */
4324 }
4325 
4326 /**
4327   * @brief Write DMA Buffer 1 Transfer completed callbacks
4328   * @param hmmc: MMC handle
4329   * @retval None
4330   */
4331 __weak void HAL_MMCEx_Write_DMADoubleBuf1CpltCallback(MMC_HandleTypeDef *hmmc)
4332 {
4333   /* Prevent unused argument(s) compilation warning */
4334   UNUSED(hmmc);
4335 
4336   /* NOTE : This function should not be modified, when the callback is needed,
4337             the HAL_MMCEx_Write_DMADoubleBuf1CpltCallback can be implemented in the user file
4338    */
4339 }
4340 
4341 /**
4342   * @}
4343   */
4344 
4345 #endif /* HAL_MMC_MODULE_ENABLED */
4346 
4347 /**
4348   * @}
4349   */
4350 
4351 /**
4352   * @}
4353   */