STM32L443xx HAL User Manual
stm32l4xx_hal_mmc.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32l4xx_hal_mmc.c
00004   * @author  MCD Application Team
00005   * @brief   MMC card HAL module driver.
00006   *          This file provides firmware functions to manage the following
00007   *          functionalities of the Secure Digital (MMC) peripheral:
00008   *           + Initialization and de-initialization functions
00009   *           + IO operation functions
00010   *           + Peripheral Control functions
00011   *           + MMC card Control functions
00012   *
00013   ******************************************************************************
00014   * @attention
00015   *
00016   * Copyright (c) 2017 STMicroelectronics.
00017   * All rights reserved.
00018   *
00019   * This software is licensed under terms that can be found in the LICENSE file
00020   * in the root directory of this software component.
00021   * If no LICENSE file comes with this software, it is provided AS-IS.
00022   *
00023   ******************************************************************************
00024   @verbatim
00025   ==============================================================================
00026                         ##### How to use this driver #####
00027   ==============================================================================
00028   [..]
00029     This driver implements a high level communication layer for read and write from/to
00030     this memory. The needed STM32 hardware resources (SDMMC and GPIO) are performed by
00031     the user in HAL_MMC_MspInit() function (MSP layer).
00032     Basically, the MSP layer configuration should be the same as we provide in the
00033     examples.
00034     You can easily tailor this configuration according to hardware resources.
00035 
00036   [..]
00037     This driver is a generic layered driver for SDMMC memories which uses the HAL
00038     SDMMC driver functions to interface with MMC and eMMC cards devices.
00039     It is used as follows:
00040 
00041     (#)Initialize the SDMMC low level resources by implement the HAL_MMC_MspInit() API:
00042         (##) Enable the SDMMC interface clock using __HAL_RCC_SDMMC_CLK_ENABLE();
00043         (##) SDMMC pins configuration for MMC card
00044             (+++) Enable the clock for the SDMMC GPIOs using the functions __HAL_RCC_GPIOx_CLK_ENABLE();
00045             (+++) Configure these SDMMC pins as alternate function pull-up using HAL_GPIO_Init()
00046                   and according to your pin assignment;
00047         (##) On STM32L4Rx/STM32L4Sxx devices, no DMA configuration is need, an internal DMA for SDMMC Peripheral is used.
00048         (##) On other devices, perform DMA Configuration if you need to use DMA process (HAL_MMC_ReadBlocks_DMA()
00049              and HAL_MMC_WriteBlocks_DMA() APIs).
00050             (+++) Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE();
00051             (+++) Configure the DMA using the function HAL_DMA_Init() with predeclared and filled.
00052         (##) NVIC configuration if you need to use interrupt process when using DMA transfer.
00053             (+++) Configure the SDMMC and DMA interrupt priorities using function HAL_NVIC_SetPriority();
00054                   DMA priority is superior to SDMMC's priority
00055             (+++) Enable the NVIC DMA and SDMMC IRQs using function HAL_NVIC_EnableIRQ()
00056             (+++) SDMMC interrupts are managed using the macros __HAL_MMC_ENABLE_IT()
00057                   and __HAL_MMC_DISABLE_IT() inside the communication process.
00058             (+++) SDMMC interrupts pending bits are managed using the macros __HAL_MMC_GET_IT()
00059                   and __HAL_MMC_CLEAR_IT()
00060         (##) NVIC configuration if you need to use interrupt process (HAL_MMC_ReadBlocks_IT()
00061              and HAL_MMC_WriteBlocks_IT() APIs).
00062             (+++) Configure the SDMMC interrupt priorities using function HAL_NVIC_SetPriority();
00063             (+++) Enable the NVIC SDMMC IRQs using function HAL_NVIC_EnableIRQ()
00064             (+++) SDMMC interrupts are managed using the macros __HAL_MMC_ENABLE_IT()
00065                   and __HAL_MMC_DISABLE_IT() inside the communication process.
00066             (+++) SDMMC interrupts pending bits are managed using the macros __HAL_MMC_GET_IT()
00067                   and __HAL_MMC_CLEAR_IT()
00068     (#) At this stage, you can perform MMC read/write/erase operations after MMC card initialization
00069 
00070 
00071   *** MMC Card Initialization and configuration ***
00072   ================================================
00073   [..]
00074     To initialize the MMC Card, use the HAL_MMC_Init() function. It Initializes
00075     SDMMC Peripheral (STM32 side) and the MMC Card, and put it into StandBy State (Ready for data transfer).
00076     This function provide the following operations:
00077 
00078     (#) Initialize the SDMMC peripheral interface with defaullt configuration.
00079         The initialization process is done at 400KHz. You can change or adapt
00080         this frequency by adjusting the "ClockDiv" field.
00081         The MMC Card frequency (SDMMC_CK) is computed as follows:
00082 
00083            SDMMC_CK = SDMMCCLK / (2 * ClockDiv) on STM32L4Rx/STM32L4Sxx devices
00084            SDMMC_CK = SDMMCCLK / (ClockDiv + 2) on other devices
00085 
00086         In initialization mode and according to the MMC Card standard,
00087         make sure that the SDMMC_CK frequency doesn't exceed 400KHz.
00088 
00089         This phase of initialization is done through SDMMC_Init() and
00090         SDMMC_PowerState_ON() SDMMC low level APIs.
00091 
00092     (#) Initialize the MMC card. The API used is HAL_MMC_InitCard().
00093         This phase allows the card initialization and identification
00094         and check the MMC Card type (Standard Capacity or High Capacity)
00095         The initialization flow is compatible with MMC standard.
00096 
00097         This API (HAL_MMC_InitCard()) could be used also to reinitialize the card in case
00098         of plug-off plug-in.
00099 
00100     (#) Configure the MMC Card Data transfer frequency. By Default, the card transfer
00101         frequency by adjusting the "ClockDiv" field.
00102         In transfer mode and according to the MMC Card standard, make sure that the
00103         SDMMC_CK frequency doesn't exceed 25MHz and 100MHz in High-speed mode switch.
00104 
00105     (#) Select the corresponding MMC Card according to the address read with the step 2.
00106 
00107     (#) Configure the MMC Card in wide bus mode: 4-bits data.
00108 
00109   *** MMC Card Read operation ***
00110   ==============================
00111   [..]
00112     (+) You can read from MMC card in polling mode by using function HAL_MMC_ReadBlocks().
00113         This function support only 512-bytes block length (the block size should be
00114         chosen as 512 bytes).
00115         You can choose either one block read operation or multiple block read operation
00116         by adjusting the "NumberOfBlocks" parameter.
00117         After this, you have to ensure that the transfer is done correctly. The check is done
00118         through HAL_MMC_GetCardState() function for MMC card state.
00119 
00120     (+) You can read from MMC card in DMA mode by using function HAL_MMC_ReadBlocks_DMA().
00121         This function support only 512-bytes block length (the block size should be
00122         chosen as 512 bytes).
00123         You can choose either one block read operation or multiple block read operation
00124         by adjusting the "NumberOfBlocks" parameter.
00125         After this, you have to ensure that the transfer is done correctly. The check is done
00126         through HAL_MMC_GetCardState() function for MMC card state.
00127         You could also check the DMA transfer process through the MMC Rx interrupt event.
00128 
00129     (+) You can read from MMC card in Interrupt mode by using function HAL_MMC_ReadBlocks_IT().
00130         This function allows the read of 512 bytes blocks.
00131         You can choose either one block read operation or multiple block read operation
00132         by adjusting the "NumberOfBlocks" parameter.
00133         After this, you have to ensure that the transfer is done correctly. The check is done
00134         through HAL_MMC_GetCardState() function for MMC card state.
00135         You could also check the IT transfer process through the MMC Rx interrupt event.
00136 
00137   *** MMC Card Write operation ***
00138   ===============================
00139   [..]
00140     (+) You can write to MMC card in polling mode by using function HAL_MMC_WriteBlocks().
00141         This function support only 512-bytes block length (the block size should be
00142         chosen as 512 bytes).
00143         You can choose either one block read operation or multiple block read operation
00144         by adjusting the "NumberOfBlocks" parameter.
00145         After this, you have to ensure that the transfer is done correctly. The check is done
00146         through HAL_MMC_GetCardState() function for MMC card state.
00147 
00148     (+) You can write to MMC card in DMA mode by using function HAL_MMC_WriteBlocks_DMA().
00149         This function support only 512-bytes block length (the block size should be
00150         chosen as 512 byte).
00151         You can choose either one block read operation or multiple block read operation
00152         by adjusting the "NumberOfBlocks" parameter.
00153         After this, you have to ensure that the transfer is done correctly. The check is done
00154         through HAL_MMC_GetCardState() function for MMC card state.
00155         You could also check the DMA transfer process through the MMC Tx interrupt event.
00156 
00157     (+) You can write to MMC card in Interrupt mode by using function HAL_MMC_WriteBlocks_IT().
00158         This function allows the read of 512 bytes blocks.
00159         You can choose either one block read operation or multiple block read operation
00160         by adjusting the "NumberOfBlocks" parameter.
00161         After this, you have to ensure that the transfer is done correctly. The check is done
00162         through HAL_MMC_GetCardState() function for MMC card state.
00163         You could also check the IT transfer process through the MMC Tx interrupt event.
00164 
00165   *** MMC card information ***
00166   ===========================
00167   [..]
00168     (+) To get MMC card information, you can use the function HAL_MMC_GetCardInfo().
00169         It returns useful information about the MMC card such as block size, card type,
00170         block number ...
00171 
00172   *** MMC card CSD register ***
00173   ============================
00174   [..]
00175     (+) The HAL_MMC_GetCardCSD() API allows to get the parameters of the CSD register.
00176         Some of the CSD parameters are useful for card initialization and identification.
00177 
00178   *** MMC card CID register ***
00179   ============================
00180   [..]
00181     (+) The HAL_MMC_GetCardCID() API allows to get the parameters of the CID register.
00182         Some of the CID parameters are useful for card initialization and identification.
00183 
00184   *** MMC HAL driver macros list ***
00185   ==================================
00186   [..]
00187     Below the list of most used macros in MMC HAL driver.
00188 
00189     (+) __HAL_MMC_ENABLE : Enable the MMC device
00190     (+) __HAL_MMC_DISABLE : Disable the MMC device
00191     (+) __HAL_MMC_DMA_ENABLE: Enable the SDMMC DMA transfer
00192     (+) __HAL_MMC_DMA_DISABLE: Disable the SDMMC DMA transfer
00193     (+) __HAL_MMC_ENABLE_IT: Enable the MMC device interrupt
00194     (+) __HAL_MMC_DISABLE_IT: Disable the MMC device interrupt
00195     (+) __HAL_MMC_GET_FLAG:Check whether the specified MMC flag is set or not
00196     (+) __HAL_MMC_CLEAR_FLAG: Clear the MMC's pending flags
00197 
00198   [..]
00199     (@) You can refer to the MMC HAL driver header file for more useful macros
00200 
00201   *** Callback registration ***
00202   =============================================
00203   [..]
00204     The compilation define USE_HAL_MMC_REGISTER_CALLBACKS when set to 1
00205     allows the user to configure dynamically the driver callbacks.
00206 
00207     Use Functions HAL_MMC_RegisterCallback() to register a user callback,
00208     it allows to register following callbacks:
00209       (+) TxCpltCallback : callback when a transmission transfer is completed.
00210       (+) RxCpltCallback : callback when a reception transfer is completed.
00211       (+) ErrorCallback : callback when error occurs.
00212       (+) AbortCpltCallback : callback when abort is completed.
00213       (+) Read_DMADblBuf0CpltCallback : callback when the DMA reception of first buffer is completed.
00214       (+) Read_DMADblBuf1CpltCallback : callback when the DMA reception of second buffer is completed.
00215       (+) Write_DMADblBuf0CpltCallback : callback when the DMA transmission of first buffer is completed.
00216       (+) Write_DMADblBuf1CpltCallback : callback when the DMA transmission of second buffer is completed.
00217       (+) MspInitCallback    : MMC MspInit.
00218       (+) MspDeInitCallback  : MMC MspDeInit.
00219     This function takes as parameters the HAL peripheral handle, the Callback ID
00220     and a pointer to the user callback function.
00221 
00222     Use function HAL_MMC_UnRegisterCallback() to reset a callback to the default
00223     weak (surcharged) function. It allows to reset following callbacks:
00224       (+) TxCpltCallback : callback when a transmission transfer is completed.
00225       (+) RxCpltCallback : callback when a reception transfer is completed.
00226       (+) ErrorCallback : callback when error occurs.
00227       (+) AbortCpltCallback : callback when abort is completed.
00228       (+) Read_DMADblBuf0CpltCallback : callback when the DMA reception of first buffer is completed.
00229       (+) Read_DMADblBuf1CpltCallback : callback when the DMA reception of second buffer is completed.
00230       (+) Write_DMADblBuf0CpltCallback : callback when the DMA transmission of first buffer is completed.
00231       (+) Write_DMADblBuf1CpltCallback : callback when the DMA transmission of second buffer is completed.
00232       (+) MspInitCallback    : MMC MspInit.
00233       (+) MspDeInitCallback  : MMC MspDeInit.
00234     This function) takes as parameters the HAL peripheral handle and the Callback ID.
00235 
00236     By default, after the HAL_MMC_Init and if the state is HAL_MMC_STATE_RESET
00237     all callbacks are reset to the corresponding legacy weak (surcharged) functions.
00238     Exception done for MspInit and MspDeInit callbacks that are respectively
00239     reset to the legacy weak (surcharged) functions in the HAL_MMC_Init
00240     and HAL_MMC_DeInit only when these callbacks are null (not registered beforehand).
00241     If not, MspInit or MspDeInit are not null, the HAL_MMC_Init and HAL_MMC_DeInit
00242     keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
00243 
00244     Callbacks can be registered/unregistered in READY state only.
00245     Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
00246     in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
00247     during the Init/DeInit.
00248     In that case first register the MspInit/MspDeInit user callbacks
00249     using HAL_MMC_RegisterCallback before calling HAL_MMC_DeInit
00250     or HAL_MMC_Init function.
00251 
00252     When The compilation define USE_HAL_MMC_REGISTER_CALLBACKS is set to 0 or
00253     not defined, the callback registering feature is not available
00254     and weak (surcharged) callbacks are used.
00255 
00256   @endverbatim
00257   ******************************************************************************
00258   */
00259 
00260 /* Includes ------------------------------------------------------------------*/
00261 #include "stm32l4xx_hal.h"
00262 
00263 #ifdef HAL_MMC_MODULE_ENABLED
00264 
00265 #if defined(SDMMC1)
00266 
00267 /** @addtogroup STM32L4xx_HAL_Driver
00268   * @{
00269   */
00270 
00271 /** @defgroup MMC MMC
00272   * @{
00273   */
00274 
00275 /* Private typedef -----------------------------------------------------------*/
00276 /* Private define ------------------------------------------------------------*/
00277 /** @addtogroup MMC_Private_Defines
00278   * @{
00279   */
00280 #if defined (VDD_VALUE) && (VDD_VALUE <= 1950U)
00281 #define MMC_VOLTAGE_RANGE               EMMC_LOW_VOLTAGE_RANGE
00282 
00283 #define MMC_EXT_CSD_PWR_CL_26_INDEX     201
00284 #define MMC_EXT_CSD_PWR_CL_52_INDEX     200
00285 #define MMC_EXT_CSD_PWR_CL_DDR_52_INDEX 238
00286 
00287 #define MMC_EXT_CSD_PWR_CL_26_POS       8
00288 #define MMC_EXT_CSD_PWR_CL_52_POS       0
00289 #define MMC_EXT_CSD_PWR_CL_DDR_52_POS   16
00290 #else
00291 #define MMC_VOLTAGE_RANGE               EMMC_HIGH_VOLTAGE_RANGE
00292 
00293 #define MMC_EXT_CSD_PWR_CL_26_INDEX     203
00294 #define MMC_EXT_CSD_PWR_CL_52_INDEX     202
00295 #define MMC_EXT_CSD_PWR_CL_DDR_52_INDEX 239
00296 
00297 #define MMC_EXT_CSD_PWR_CL_26_POS       24
00298 #define MMC_EXT_CSD_PWR_CL_52_POS       16
00299 #define MMC_EXT_CSD_PWR_CL_DDR_52_POS   24
00300 #endif
00301 
00302 #define MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_INDEX 216
00303 #define MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_POS   0
00304 #define MMC_EXT_CSD_S_A_TIMEOUT_INDEX             217
00305 #define MMC_EXT_CSD_S_A_TIMEOUT_POS               8
00306 
00307 /* Frequencies used in the driver for clock divider calculation */
00308 #define MMC_INIT_FREQ                   400000U   /* Initalization phase : 400 kHz max */
00309 #define MMC_HIGH_SPEED_FREQ             52000000U /* High speed phase : 52 MHz max */
00310 /**
00311   * @}
00312   */
00313 
00314 /* Private macro -------------------------------------------------------------*/
00315 /* Private variables ---------------------------------------------------------*/
00316 /* Private function prototypes -----------------------------------------------*/
00317 /* Private functions ---------------------------------------------------------*/
00318 /** @defgroup MMC_Private_Functions MMC Private Functions
00319   * @{
00320   */
00321 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc);
00322 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc);
00323 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus);
00324 static void     MMC_PowerOFF(MMC_HandleTypeDef *hmmc);
00325 static void     MMC_Write_IT(MMC_HandleTypeDef *hmmc);
00326 static void     MMC_Read_IT(MMC_HandleTypeDef *hmmc);
00327 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
00328 static void     MMC_DMATransmitCplt(DMA_HandleTypeDef *hdma);
00329 static void     MMC_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
00330 static void     MMC_DMAError(DMA_HandleTypeDef *hdma);
00331 static void     MMC_DMATxAbort(DMA_HandleTypeDef *hdma);
00332 static void     MMC_DMARxAbort(DMA_HandleTypeDef *hdma);
00333 #else
00334 static uint32_t MMC_HighSpeed(MMC_HandleTypeDef *hmmc, FunctionalState state);
00335 static uint32_t MMC_DDR_Mode(MMC_HandleTypeDef *hmmc, FunctionalState state);
00336 #endif
00337 static HAL_StatusTypeDef MMC_ReadExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pFieldData, uint16_t FieldIndex, uint32_t Timeout);
00338 static uint32_t MMC_PwrClassUpdate(MMC_HandleTypeDef *hmmc, uint32_t Wide, uint32_t Speed);
00339 
00340 /**
00341   * @}
00342   */
00343 /* Exported functions --------------------------------------------------------*/
00344 /** @defgroup MMC_Exported_Functions MMC Exported Functions
00345   * @{
00346   */
00347 
00348 /** @defgroup MMC_Exported_Functions_Group1 MMC_Exported_Functions_Group1
00349  *  @brief   Initialization and de-initialization functions
00350  *
00351 @verbatim
00352   ==============================================================================
00353           ##### Initialization and de-initialization functions #####
00354   ==============================================================================
00355   [..]
00356     This section provides functions allowing to initialize/de-initialize the MMC
00357     card device to be ready for use.
00358 
00359 @endverbatim
00360   * @{
00361   */
00362 
00363 /**
00364   * @brief  Initializes the MMC according to the specified parameters in the
00365             MMC_HandleTypeDef and create the associated handle.
00366   * @param  hmmc Pointer to the MMC handle
00367   * @retval HAL status
00368   */
00369 HAL_StatusTypeDef HAL_MMC_Init(MMC_HandleTypeDef *hmmc)
00370 {
00371   /* Check the MMC handle allocation */
00372   if(hmmc == NULL)
00373   {
00374     return HAL_ERROR;
00375   }
00376 
00377   /* Check the parameters */
00378   assert_param(IS_SDMMC_ALL_INSTANCE(hmmc->Instance));
00379   assert_param(IS_SDMMC_CLOCK_EDGE(hmmc->Init.ClockEdge));
00380 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
00381   assert_param(IS_SDMMC_CLOCK_BYPASS(hmmc->Init.ClockBypass));
00382 #endif
00383   assert_param(IS_SDMMC_CLOCK_POWER_SAVE(hmmc->Init.ClockPowerSave));
00384   assert_param(IS_SDMMC_BUS_WIDE(hmmc->Init.BusWide));
00385   assert_param(IS_SDMMC_HARDWARE_FLOW_CONTROL(hmmc->Init.HardwareFlowControl));
00386   assert_param(IS_SDMMC_CLKDIV(hmmc->Init.ClockDiv));
00387 
00388   if(hmmc->State == HAL_MMC_STATE_RESET)
00389   {
00390     /* Allocate lock resource and initialize it */
00391     hmmc->Lock = HAL_UNLOCKED;
00392 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
00393     /* Reset Callback pointers in HAL_MMC_STATE_RESET only */
00394     hmmc->TxCpltCallback    = HAL_MMC_TxCpltCallback;
00395     hmmc->RxCpltCallback    = HAL_MMC_RxCpltCallback;
00396     hmmc->ErrorCallback     = HAL_MMC_ErrorCallback;
00397     hmmc->AbortCpltCallback = HAL_MMC_AbortCallback;
00398 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
00399     hmmc->Read_DMADblBuf0CpltCallback = HAL_MMCEx_Read_DMADoubleBuffer0CpltCallback;
00400     hmmc->Read_DMADblBuf1CpltCallback = HAL_MMCEx_Read_DMADoubleBuffer1CpltCallback;
00401     hmmc->Write_DMADblBuf0CpltCallback = HAL_MMCEx_Write_DMADoubleBuffer0CpltCallback;
00402     hmmc->Write_DMADblBuf1CpltCallback = HAL_MMCEx_Write_DMADoubleBuffer1CpltCallback;
00403 #endif
00404 
00405     if(hmmc->MspInitCallback == NULL)
00406     {
00407       hmmc->MspInitCallback = HAL_MMC_MspInit;
00408     }
00409 
00410     /* Init the low level hardware */
00411     hmmc->MspInitCallback(hmmc);
00412 #else
00413     /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
00414     HAL_MMC_MspInit(hmmc);
00415 #endif
00416   }
00417 
00418   hmmc->State = HAL_MMC_STATE_BUSY;
00419 
00420   /* Initialize the Card parameters */
00421   if(HAL_MMC_InitCard(hmmc) == HAL_ERROR)
00422   {
00423     return HAL_ERROR;
00424   }
00425 
00426   /* Initialize the error code */
00427   hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
00428 
00429   /* Initialize the MMC operation */
00430   hmmc->Context = MMC_CONTEXT_NONE;
00431 
00432   /* Initialize the MMC state */
00433   hmmc->State = HAL_MMC_STATE_READY;
00434 
00435   /* Configure bus width */
00436   if (hmmc->Init.BusWide != SDMMC_BUS_WIDE_1B)
00437   {
00438     if (HAL_MMC_ConfigWideBusOperation(hmmc, hmmc->Init.BusWide) != HAL_OK)
00439     {
00440       return HAL_ERROR;
00441     }
00442   }
00443 
00444   return HAL_OK;
00445 }
00446 
00447 /**
00448   * @brief  Initializes the MMC Card.
00449   * @param  hmmc Pointer to MMC handle
00450   * @note   This function initializes the MMC card. It could be used when a card
00451             re-initialization is needed.
00452   * @retval HAL status
00453   */
00454 HAL_StatusTypeDef HAL_MMC_InitCard(MMC_HandleTypeDef *hmmc)
00455 {
00456   uint32_t errorstate;
00457   MMC_InitTypeDef Init;
00458   uint32_t sdmmc_clk;
00459 
00460   /* Default SDMMC peripheral configuration for MMC card initialization */
00461   Init.ClockEdge           = SDMMC_CLOCK_EDGE_RISING;
00462 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
00463   Init.ClockBypass         = SDMMC_CLOCK_BYPASS_DISABLE;
00464 #endif
00465   Init.ClockPowerSave      = SDMMC_CLOCK_POWER_SAVE_DISABLE;
00466   Init.BusWide             = SDMMC_BUS_WIDE_1B;
00467   Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
00468 
00469   /* Init Clock should be less or equal to 400Khz*/
00470   sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC1);
00471   if (sdmmc_clk == 0U)
00472   {
00473       hmmc->State = HAL_MMC_STATE_READY;
00474       hmmc->ErrorCode = SDMMC_ERROR_INVALID_PARAMETER;
00475       return HAL_ERROR;
00476   }
00477 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
00478   Init.ClockDiv = ((sdmmc_clk/MMC_INIT_FREQ) - 2U);
00479 #else
00480   Init.ClockDiv = sdmmc_clk/(2U*MMC_INIT_FREQ);
00481   Init.Transceiver = SDMMC_TRANSCEIVER_DISABLE;
00482 #endif
00483 
00484   /* Initialize SDMMC peripheral interface with default configuration */
00485   (void)SDMMC_Init(hmmc->Instance, Init);
00486 
00487 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
00488   /* Disable SDMMC Clock */
00489   __HAL_MMC_DISABLE(hmmc);
00490 #endif
00491 
00492   /* Set Power State to ON */
00493   (void)SDMMC_PowerState_ON(hmmc->Instance);
00494 
00495 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
00496   /* Enable MMC Clock */
00497   __HAL_MMC_ENABLE(hmmc);
00498 #endif
00499 
00500   /* wait 74 Cycles: required power up waiting time before starting
00501      the MMC initialization sequence */
00502 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
00503   sdmmc_clk = sdmmc_clk/(Init.ClockDiv + 2U);
00504 #else
00505   sdmmc_clk = sdmmc_clk/(2U*Init.ClockDiv);
00506 #endif
00507   HAL_Delay(1U+ (74U*1000U/(sdmmc_clk)));
00508 
00509   /* Identify card operating voltage */
00510   errorstate = MMC_PowerON(hmmc);
00511   if(errorstate != HAL_MMC_ERROR_NONE)
00512   {
00513     hmmc->State = HAL_MMC_STATE_READY;
00514     hmmc->ErrorCode |= errorstate;
00515     return HAL_ERROR;
00516   }
00517 
00518   /* Card initialization */
00519   errorstate = MMC_InitCard(hmmc);
00520   if(errorstate != HAL_MMC_ERROR_NONE)
00521   {
00522     hmmc->State = HAL_MMC_STATE_READY;
00523     hmmc->ErrorCode |= errorstate;
00524     return HAL_ERROR;
00525   }
00526 
00527   /* Set Block Size for Card */
00528   errorstate = SDMMC_CmdBlockLength(hmmc->Instance, MMC_BLOCKSIZE);
00529   if(errorstate != HAL_MMC_ERROR_NONE)
00530   {
00531     /* Clear all the static flags */
00532     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
00533     hmmc->ErrorCode |= errorstate;
00534     hmmc->State = HAL_MMC_STATE_READY;
00535     return HAL_ERROR;
00536   }
00537 
00538   return HAL_OK;
00539 }
00540 
00541 /**
00542   * @brief  De-Initializes the MMC card.
00543   * @param  hmmc Pointer to MMC handle
00544   * @retval HAL status
00545   */
00546 HAL_StatusTypeDef HAL_MMC_DeInit(MMC_HandleTypeDef *hmmc)
00547 {
00548   /* Check the MMC handle allocation */
00549   if(hmmc == NULL)
00550   {
00551     return HAL_ERROR;
00552   }
00553 
00554   /* Check the parameters */
00555   assert_param(IS_SDMMC_ALL_INSTANCE(hmmc->Instance));
00556 
00557   hmmc->State = HAL_MMC_STATE_BUSY;
00558 
00559   /* Set MMC power state to off */
00560   MMC_PowerOFF(hmmc);
00561 
00562 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
00563   if(hmmc->MspDeInitCallback == NULL)
00564   {
00565     hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
00566   }
00567 
00568   /* DeInit the low level hardware */
00569   hmmc->MspDeInitCallback(hmmc);
00570 #else
00571   /* De-Initialize the MSP layer */
00572   HAL_MMC_MspDeInit(hmmc);
00573 #endif
00574 
00575   hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
00576   hmmc->State = HAL_MMC_STATE_RESET;
00577 
00578   return HAL_OK;
00579 }
00580 
00581 
00582 /**
00583   * @brief  Initializes the MMC MSP.
00584   * @param  hmmc Pointer to MMC handle
00585   * @retval None
00586   */
00587 __weak void HAL_MMC_MspInit(MMC_HandleTypeDef *hmmc)
00588 {
00589   /* Prevent unused argument(s) compilation warning */
00590   UNUSED(hmmc);
00591 
00592   /* NOTE : This function Should not be modified, when the callback is needed,
00593             the HAL_MMC_MspInit could be implemented in the user file
00594    */
00595 }
00596 
00597 /**
00598   * @brief  De-Initialize MMC MSP.
00599   * @param  hmmc Pointer to MMC handle
00600   * @retval None
00601   */
00602 __weak void HAL_MMC_MspDeInit(MMC_HandleTypeDef *hmmc)
00603 {
00604   /* Prevent unused argument(s) compilation warning */
00605   UNUSED(hmmc);
00606 
00607   /* NOTE : This function Should not be modified, when the callback is needed,
00608             the HAL_MMC_MspDeInit could be implemented in the user file
00609    */
00610 }
00611 
00612 /**
00613   * @}
00614   */
00615 
00616 /** @addtogroup MMC_Exported_Functions_Group2
00617  *  @brief   Data transfer functions
00618  *
00619 @verbatim
00620   ==============================================================================
00621                         ##### IO operation functions #####
00622   ==============================================================================
00623   [..]
00624     This subsection provides a set of functions allowing to manage the data
00625     transfer from/to MMC card.
00626 
00627 @endverbatim
00628   * @{
00629   */
00630 
00631 /**
00632   * @brief  Reads block(s) from a specified address in a card. The Data transfer
00633   *         is managed by polling mode.
00634   * @note   This API should be followed by a check on the card state through
00635   *         HAL_MMC_GetCardState().
00636   * @param  hmmc Pointer to MMC handle
00637   * @param  pData pointer to the buffer that will contain the received data
00638   * @param  BlockAdd Block Address from where data is to be read
00639   * @param  NumberOfBlocks Number of MMC blocks to read
00640   * @param  Timeout Specify timeout value
00641   * @retval HAL status
00642   */
00643 HAL_StatusTypeDef HAL_MMC_ReadBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
00644 {
00645   SDMMC_DataInitTypeDef config;
00646   uint32_t errorstate;
00647   uint32_t tickstart = HAL_GetTick();
00648   uint32_t count, data, dataremaining;
00649   uint32_t add = BlockAdd;
00650   uint8_t *tempbuff = pData;
00651 
00652   if(NULL == pData)
00653   {
00654     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
00655     return HAL_ERROR;
00656   }
00657 
00658   if(hmmc->State == HAL_MMC_STATE_READY)
00659   {
00660     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
00661 
00662     if((add + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
00663     {
00664       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
00665       return HAL_ERROR;
00666     }
00667 
00668     hmmc->State = HAL_MMC_STATE_BUSY;
00669 
00670     /* Initialize data control register */
00671     hmmc->Instance->DCTRL = 0U;
00672 
00673     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
00674     {
00675       add *= 512U;
00676     }
00677 
00678     /* Configure the MMC DPSM (Data Path State Machine) */
00679     config.DataTimeOut   = SDMMC_DATATIMEOUT;
00680     config.DataLength    = NumberOfBlocks * MMC_BLOCKSIZE;
00681     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
00682     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
00683     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
00684 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
00685     config.DPSM          = SDMMC_DPSM_ENABLE;
00686 #else
00687     config.DPSM          = SDMMC_DPSM_DISABLE;
00688 #endif
00689     (void)SDMMC_ConfigData(hmmc->Instance, &config);
00690 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
00691     __SDMMC_CMDTRANS_ENABLE( hmmc->Instance);
00692 #endif
00693 
00694     /* Read block(s) in polling mode */
00695     if(NumberOfBlocks > 1U)
00696     {
00697       hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
00698 
00699       /* Read Multi Block command */
00700       errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
00701     }
00702     else
00703     {
00704       hmmc->Context = MMC_CONTEXT_READ_SINGLE_BLOCK;
00705 
00706       /* Read Single Block command */
00707       errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
00708     }
00709     if(errorstate != HAL_MMC_ERROR_NONE)
00710     {
00711       /* Clear all the static flags */
00712       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
00713       hmmc->ErrorCode |= errorstate;
00714       hmmc->State = HAL_MMC_STATE_READY;
00715       hmmc->Context = MMC_CONTEXT_NONE;
00716       return HAL_ERROR;
00717     }
00718 
00719     /* Poll on SDMMC flags */
00720     dataremaining = config.DataLength;
00721     while(!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
00722     {
00723       if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining > 0U))
00724       {
00725         /* Read data from SDMMC Rx FIFO */
00726         for(count = 0U; count < 8U; count++)
00727         {
00728           data = SDMMC_ReadFIFO(hmmc->Instance);
00729           *tempbuff = (uint8_t)(data & 0xFFU);
00730           tempbuff++;
00731           dataremaining--;
00732           *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
00733           tempbuff++;
00734           dataremaining--;
00735           *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
00736           tempbuff++;
00737           dataremaining--;
00738           *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
00739           tempbuff++;
00740           dataremaining--;
00741         }
00742       }
00743 
00744       if(((HAL_GetTick()-tickstart) >=  Timeout) || (Timeout == 0U))
00745       {
00746         /* Clear all the static flags */
00747         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
00748         hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
00749         hmmc->State= HAL_MMC_STATE_READY;
00750         hmmc->Context = MMC_CONTEXT_NONE;
00751         return HAL_TIMEOUT;
00752       }
00753     }
00754 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
00755     __SDMMC_CMDTRANS_DISABLE( hmmc->Instance);
00756 #endif
00757 
00758     /* Send stop transmission command in case of multiblock read */
00759     if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U))
00760     {
00761       /* Send stop transmission command */
00762       errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
00763       if(errorstate != HAL_MMC_ERROR_NONE)
00764       {
00765         /* Clear all the static flags */
00766         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
00767         hmmc->ErrorCode |= errorstate;
00768         hmmc->State = HAL_MMC_STATE_READY;
00769         hmmc->Context = MMC_CONTEXT_NONE;
00770         return HAL_ERROR;
00771       }
00772     }
00773 
00774     /* Get error state */
00775     if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
00776     {
00777       /* Clear all the static flags */
00778       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
00779       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
00780       hmmc->State = HAL_MMC_STATE_READY;
00781       hmmc->Context = MMC_CONTEXT_NONE;
00782       return HAL_ERROR;
00783     }
00784     else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
00785     {
00786       /* Clear all the static flags */
00787       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
00788       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
00789       hmmc->State = HAL_MMC_STATE_READY;
00790       hmmc->Context = MMC_CONTEXT_NONE;
00791       return HAL_ERROR;
00792     }
00793     else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR))
00794     {
00795       /* Clear all the static flags */
00796       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
00797       hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
00798       hmmc->State = HAL_MMC_STATE_READY;
00799       hmmc->Context = MMC_CONTEXT_NONE;
00800       return HAL_ERROR;
00801     }
00802     else
00803     {
00804       /* Nothing to do */
00805     }
00806 
00807 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
00808     /* Empty FIFO if there is still any data */
00809     while ((__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXDAVL)) && (dataremaining > 0U))
00810     {
00811       data = SDMMC_ReadFIFO(hmmc->Instance);
00812       *tempbuff = (uint8_t)(data & 0xFFU);
00813       tempbuff++;
00814       dataremaining--;
00815       *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
00816       tempbuff++;
00817       dataremaining--;
00818       *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
00819       tempbuff++;
00820       dataremaining--;
00821       *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
00822       tempbuff++;
00823       dataremaining--;
00824 
00825       if(((HAL_GetTick()-tickstart) >=  Timeout) || (Timeout == 0U))
00826       {
00827         /* Clear all the static flags */
00828         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
00829         hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
00830         hmmc->State= HAL_MMC_STATE_READY;
00831         hmmc->Context = MMC_CONTEXT_NONE;
00832         return HAL_ERROR;
00833       }
00834     }
00835 #endif
00836 
00837     /* Clear all the static flags */
00838     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
00839 
00840     hmmc->State = HAL_MMC_STATE_READY;
00841 
00842     return HAL_OK;
00843   }
00844   else
00845   {
00846     hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
00847     return HAL_ERROR;
00848   }
00849 }
00850 
00851 /**
00852   * @brief  Allows to write block(s) to a specified address in a card. The Data
00853   *         transfer is managed by polling mode.
00854   * @note   This API should be followed by a check on the card state through
00855   *         HAL_MMC_GetCardState().
00856   * @param  hmmc Pointer to MMC handle
00857   * @param  pData pointer to the buffer that will contain the data to transmit
00858   * @param  BlockAdd Block Address where data will be written
00859   * @param  NumberOfBlocks Number of MMC blocks to write
00860   * @param  Timeout Specify timeout value
00861   * @retval HAL status
00862   */
00863 HAL_StatusTypeDef HAL_MMC_WriteBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
00864 {
00865   SDMMC_DataInitTypeDef config;
00866   uint32_t errorstate;
00867   uint32_t tickstart = HAL_GetTick();
00868   uint32_t count, data, dataremaining;
00869   uint32_t add = BlockAdd;
00870   uint8_t *tempbuff = pData;
00871 
00872   if(NULL == pData)
00873   {
00874     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
00875     return HAL_ERROR;
00876   }
00877 
00878   if(hmmc->State == HAL_MMC_STATE_READY)
00879   {
00880     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
00881 
00882     if((add + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
00883     {
00884       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
00885       return HAL_ERROR;
00886     }
00887 
00888     hmmc->State = HAL_MMC_STATE_BUSY;
00889 
00890     /* Initialize data control register */
00891     hmmc->Instance->DCTRL = 0U;
00892 
00893     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
00894     {
00895       add *= 512U;
00896     }
00897 
00898 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
00899     /* Configure the MMC DPSM (Data Path State Machine) */
00900     config.DataTimeOut   = SDMMC_DATATIMEOUT;
00901     config.DataLength    = NumberOfBlocks * MMC_BLOCKSIZE;
00902     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
00903     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
00904     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
00905     config.DPSM          = SDMMC_DPSM_DISABLE;
00906     (void)SDMMC_ConfigData(hmmc->Instance, &config);
00907     __SDMMC_CMDTRANS_ENABLE( hmmc->Instance);
00908 #endif
00909 
00910     /* Write Blocks in Polling mode */
00911     if(NumberOfBlocks > 1U)
00912     {
00913       hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
00914 
00915       /* Write Multi Block command */
00916       errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
00917     }
00918     else
00919     {
00920       hmmc->Context = MMC_CONTEXT_WRITE_SINGLE_BLOCK;
00921 
00922       /* Write Single Block command */
00923       errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
00924     }
00925     if(errorstate != HAL_MMC_ERROR_NONE)
00926     {
00927       /* Clear all the static flags */
00928       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
00929       hmmc->ErrorCode |= errorstate;
00930       hmmc->State = HAL_MMC_STATE_READY;
00931       hmmc->Context = MMC_CONTEXT_NONE;
00932       return HAL_ERROR;
00933     }
00934 
00935 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
00936     /* Configure the MMC DPSM (Data Path State Machine) */
00937     config.DataTimeOut   = SDMMC_DATATIMEOUT;
00938     config.DataLength    = NumberOfBlocks * MMC_BLOCKSIZE;
00939     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
00940     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
00941     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
00942     config.DPSM          = SDMMC_DPSM_ENABLE;
00943     (void)SDMMC_ConfigData(hmmc->Instance, &config);
00944 #endif
00945 
00946     /* Write block(s) in polling mode */
00947     dataremaining = config.DataLength;
00948     while(!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
00949     {
00950       if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining > 0U))
00951       {
00952         /* Write data to SDMMC Tx FIFO */
00953         for(count = 0U; count < 8U; count++)
00954         {
00955           data = (uint32_t)(*tempbuff);
00956           tempbuff++;
00957           dataremaining--;
00958           data |= ((uint32_t)(*tempbuff) << 8U);
00959           tempbuff++;
00960           dataremaining--;
00961           data |= ((uint32_t)(*tempbuff) << 16U);
00962           tempbuff++;
00963           dataremaining--;
00964           data |= ((uint32_t)(*tempbuff) << 24U);
00965           tempbuff++;
00966           dataremaining--;
00967           (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
00968         }
00969       }
00970 
00971       if(((HAL_GetTick()-tickstart) >=  Timeout) || (Timeout == 0U))
00972       {
00973         /* Clear all the static flags */
00974         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
00975         hmmc->ErrorCode |= errorstate;
00976         hmmc->State = HAL_MMC_STATE_READY;
00977         hmmc->Context = MMC_CONTEXT_NONE;
00978         return HAL_TIMEOUT;
00979       }
00980     }
00981 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
00982     __SDMMC_CMDTRANS_DISABLE( hmmc->Instance);
00983 #endif
00984 
00985     /* Send stop transmission command in case of multiblock write */
00986     if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U))
00987     {
00988       /* Send stop transmission command */
00989       errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
00990       if(errorstate != HAL_MMC_ERROR_NONE)
00991       {
00992         /* Clear all the static flags */
00993         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
00994         hmmc->ErrorCode |= errorstate;
00995         hmmc->State = HAL_MMC_STATE_READY;
00996         hmmc->Context = MMC_CONTEXT_NONE;
00997         return HAL_ERROR;
00998       }
00999     }
01000 
01001     /* Get error state */
01002     if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
01003     {
01004       /* Clear all the static flags */
01005       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
01006       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
01007       hmmc->State = HAL_MMC_STATE_READY;
01008       hmmc->Context = MMC_CONTEXT_NONE;
01009       return HAL_ERROR;
01010     }
01011     else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
01012     {
01013       /* Clear all the static flags */
01014       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
01015       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
01016       hmmc->State = HAL_MMC_STATE_READY;
01017       hmmc->Context = MMC_CONTEXT_NONE;
01018       return HAL_ERROR;
01019     }
01020     else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
01021     {
01022       /* Clear all the static flags */
01023       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
01024       hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
01025       hmmc->State = HAL_MMC_STATE_READY;
01026       hmmc->Context = MMC_CONTEXT_NONE;
01027       return HAL_ERROR;
01028     }
01029     else
01030     {
01031       /* Nothing to do */
01032     }
01033 
01034     /* Clear all the static flags */
01035     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
01036 
01037     hmmc->State = HAL_MMC_STATE_READY;
01038 
01039     return HAL_OK;
01040   }
01041   else
01042   {
01043     hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
01044     return HAL_ERROR;
01045   }
01046 }
01047 
01048 /**
01049   * @brief  Reads block(s) from a specified address in a card. The Data transfer
01050   *         is managed in interrupt mode.
01051   * @note   This API should be followed by a check on the card state through
01052   *         HAL_MMC_GetCardState().
01053   * @note   You could also check the IT transfer process through the MMC Rx
01054   *         interrupt event.
01055   * @param  hmmc Pointer to MMC handle
01056   * @param  pData Pointer to the buffer that will contain the received data
01057   * @param  BlockAdd Block Address from where data is to be read
01058   * @param  NumberOfBlocks Number of blocks to read.
01059   * @retval HAL status
01060   */
01061 HAL_StatusTypeDef HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
01062 {
01063   SDMMC_DataInitTypeDef config;
01064   uint32_t errorstate;
01065   uint32_t add = BlockAdd;
01066 
01067   if(NULL == pData)
01068   {
01069     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
01070     return HAL_ERROR;
01071   }
01072 
01073   if(hmmc->State == HAL_MMC_STATE_READY)
01074   {
01075     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
01076 
01077     if((add + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
01078     {
01079       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
01080       return HAL_ERROR;
01081     }
01082 
01083     hmmc->State = HAL_MMC_STATE_BUSY;
01084 
01085     /* Initialize data control register */
01086     hmmc->Instance->DCTRL = 0U;
01087 
01088     hmmc->pRxBuffPtr = pData;
01089     hmmc->RxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
01090 
01091     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
01092     {
01093       add *= 512U;
01094     }
01095 
01096     /* Configure the MMC DPSM (Data Path State Machine) */
01097     config.DataTimeOut   = SDMMC_DATATIMEOUT;
01098     config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
01099     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
01100     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
01101     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
01102 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
01103     config.DPSM          = SDMMC_DPSM_ENABLE;
01104 #else
01105     config.DPSM          = SDMMC_DPSM_DISABLE;
01106 #endif
01107     (void)SDMMC_ConfigData(hmmc->Instance, &config);
01108 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
01109     __SDMMC_CMDTRANS_ENABLE( hmmc->Instance);
01110 #endif
01111     /* Read Blocks in IT mode */
01112     if(NumberOfBlocks > 1U)
01113     {
01114       hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_IT);
01115 
01116       /* Read Multi Block command */
01117       errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
01118     }
01119     else
01120     {
01121       hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_IT);
01122 
01123       /* Read Single Block command */
01124       errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
01125     }
01126 
01127     if(errorstate != HAL_MMC_ERROR_NONE)
01128     {
01129       /* Clear all the static flags */
01130       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
01131       hmmc->ErrorCode |= errorstate;
01132       hmmc->State = HAL_MMC_STATE_READY;
01133       hmmc->Context = MMC_CONTEXT_NONE;
01134       return HAL_ERROR;
01135     }
01136 
01137     __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND | SDMMC_FLAG_RXFIFOHF));
01138 
01139     return HAL_OK;
01140   }
01141   else
01142   {
01143     return HAL_BUSY;
01144   }
01145 }
01146 
01147 /**
01148   * @brief  Writes block(s) to a specified address in a card. The Data transfer
01149   *         is managed in interrupt mode.
01150   * @note   This API should be followed by a check on the card state through
01151   *         HAL_MMC_GetCardState().
01152   * @note   You could also check the IT transfer process through the MMC Tx
01153   *         interrupt event.
01154   * @param  hmmc Pointer to MMC handle
01155   * @param  pData Pointer to the buffer that will contain the data to transmit
01156   * @param  BlockAdd Block Address where data will be written
01157   * @param  NumberOfBlocks Number of blocks to write
01158   * @retval HAL status
01159   */
01160 HAL_StatusTypeDef HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
01161 {
01162   SDMMC_DataInitTypeDef config;
01163   uint32_t errorstate;
01164   uint32_t add = BlockAdd;
01165 
01166   if(NULL == pData)
01167   {
01168     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
01169     return HAL_ERROR;
01170   }
01171 
01172   if(hmmc->State == HAL_MMC_STATE_READY)
01173   {
01174     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
01175 
01176     if((add + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
01177     {
01178       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
01179       return HAL_ERROR;
01180     }
01181 
01182     hmmc->State = HAL_MMC_STATE_BUSY;
01183 
01184     /* Initialize data control register */
01185     hmmc->Instance->DCTRL = 0U;
01186 
01187     hmmc->pTxBuffPtr = pData;
01188     hmmc->TxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
01189 
01190     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
01191     {
01192       add *= 512U;
01193     }
01194 
01195 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
01196     /* Configure the MMC DPSM (Data Path State Machine) */
01197     config.DataTimeOut   = SDMMC_DATATIMEOUT;
01198     config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
01199     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
01200     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
01201     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
01202     config.DPSM          = SDMMC_DPSM_DISABLE;
01203     (void)SDMMC_ConfigData(hmmc->Instance, &config);
01204 
01205     __SDMMC_CMDTRANS_ENABLE( hmmc->Instance);
01206 #endif
01207 
01208     /* Write Blocks in Polling mode */
01209     if(NumberOfBlocks > 1U)
01210     {
01211       hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK| MMC_CONTEXT_IT);
01212 
01213       /* Write Multi Block command */
01214       errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
01215     }
01216     else
01217     {
01218       hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_IT);
01219 
01220       /* Write Single Block command */
01221       errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
01222     }
01223     if(errorstate != HAL_MMC_ERROR_NONE)
01224     {
01225       /* Clear all the static flags */
01226       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
01227       hmmc->ErrorCode |= errorstate;
01228       hmmc->State = HAL_MMC_STATE_READY;
01229       hmmc->Context = MMC_CONTEXT_NONE;
01230       return HAL_ERROR;
01231     }
01232 
01233 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
01234     /* Configure the MMC DPSM (Data Path State Machine) */
01235     config.DataTimeOut   = SDMMC_DATATIMEOUT;
01236     config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
01237     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
01238     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
01239     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
01240     config.DPSM          = SDMMC_DPSM_ENABLE;
01241     (void)SDMMC_ConfigData(hmmc->Instance, &config);
01242 #endif
01243 
01244     /* Enable transfer interrupts */
01245     __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND | SDMMC_FLAG_TXFIFOHE));
01246 
01247     return HAL_OK;
01248   }
01249   else
01250   {
01251     return HAL_BUSY;
01252   }
01253 }
01254 
01255 /**
01256   * @brief  Reads block(s) from a specified address in a card. The Data transfer
01257   *         is managed by DMA mode.
01258   * @note   This API should be followed by a check on the card state through
01259   *         HAL_MMC_GetCardState().
01260   * @note   You could also check the DMA transfer process through the MMC Rx
01261   *         interrupt event.
01262   * @param  hmmc Pointer MMC handle
01263   * @param  pData Pointer to the buffer that will contain the received data
01264   * @param  BlockAdd Block Address from where data is to be read
01265   * @param  NumberOfBlocks Number of blocks to read.
01266   * @retval HAL status
01267   */
01268 HAL_StatusTypeDef HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
01269 {
01270   SDMMC_DataInitTypeDef config;
01271   uint32_t errorstate;
01272   uint32_t add = BlockAdd;
01273 
01274   if(NULL == pData)
01275   {
01276     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
01277     return HAL_ERROR;
01278   }
01279 
01280   if(hmmc->State == HAL_MMC_STATE_READY)
01281   {
01282     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
01283 
01284     if((add + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
01285     {
01286       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
01287       return HAL_ERROR;
01288     }
01289 
01290     hmmc->State = HAL_MMC_STATE_BUSY;
01291 
01292     /* Initialize data control register */
01293     hmmc->Instance->DCTRL = 0U;
01294 
01295 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
01296     /* Set the DMA transfer complete callback */
01297     hmmc->hdmarx->XferCpltCallback = MMC_DMAReceiveCplt;
01298 
01299     /* Set the DMA error callback */
01300     hmmc->hdmarx->XferErrorCallback = MMC_DMAError;
01301 
01302     /* Set the DMA Abort callback */
01303     hmmc->hdmarx->XferAbortCallback = NULL;
01304 
01305 #else
01306     hmmc->pRxBuffPtr = pData;
01307     hmmc->RxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
01308 #endif
01309 
01310     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
01311     {
01312       add *= 512U;
01313     }
01314 
01315 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
01316     /* Configure the MMC DPSM (Data Path State Machine) */
01317     config.DataTimeOut   = SDMMC_DATATIMEOUT;
01318     config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
01319     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
01320     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
01321     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
01322     config.DPSM          = SDMMC_DPSM_DISABLE;
01323     (void)SDMMC_ConfigData(hmmc->Instance, &config);
01324 
01325     __SDMMC_CMDTRANS_ENABLE( hmmc->Instance);
01326     hmmc->Instance->IDMABASE0 = (uint32_t) pData ;
01327     hmmc->Instance->IDMACTRL  = SDMMC_ENABLE_IDMA_SINGLE_BUFF;
01328 #else
01329     /* Enable the DMA Channel */
01330     if(HAL_DMA_Start_IT(hmmc->hdmarx, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)pData, (uint32_t)(MMC_BLOCKSIZE * NumberOfBlocks)/4) != HAL_OK)
01331     {
01332       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
01333       hmmc->ErrorCode = HAL_MMC_ERROR_DMA;
01334       hmmc->State = HAL_MMC_STATE_READY;
01335       return HAL_ERROR;
01336     }
01337     else
01338     {
01339       /* Enable MMC DMA transfer */
01340       __HAL_MMC_DMA_ENABLE(hmmc);
01341 
01342       /* Configure the MMC DPSM (Data Path State Machine) */
01343       config.DataTimeOut   = SDMMC_DATATIMEOUT;
01344       config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
01345       config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
01346       config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
01347       config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
01348       config.DPSM          = SDMMC_DPSM_ENABLE;
01349       (void)SDMMC_ConfigData(hmmc->Instance, &config);
01350 #endif
01351 
01352       /* Read Blocks in DMA mode */
01353       if(NumberOfBlocks > 1U)
01354       {
01355         hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
01356 
01357         /* Read Multi Block command */
01358         errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
01359       }
01360       else
01361       {
01362         hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_DMA);
01363 
01364         /* Read Single Block command */
01365         errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
01366       }
01367       if(errorstate != HAL_MMC_ERROR_NONE)
01368       {
01369         /* Clear all the static flags */
01370         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
01371         hmmc->ErrorCode = errorstate;
01372         hmmc->State = HAL_MMC_STATE_READY;
01373         hmmc->Context = MMC_CONTEXT_NONE;
01374         return HAL_ERROR;
01375       }
01376 
01377       /* Enable transfer interrupts */
01378       __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND));
01379 
01380       return HAL_OK;
01381 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
01382     }
01383 #endif
01384   }
01385   else
01386   {
01387     return HAL_BUSY;
01388   }
01389 }
01390 
01391 /**
01392   * @brief  Writes block(s) to a specified address in a card. The Data transfer
01393   *         is managed by DMA mode.
01394   * @note   This API should be followed by a check on the card state through
01395   *         HAL_MMC_GetCardState().
01396   * @note   You could also check the DMA transfer process through the MMC Tx
01397   *         interrupt event.
01398   * @param  hmmc Pointer to MMC handle
01399   * @param  pData Pointer to the buffer that will contain the data to transmit
01400   * @param  BlockAdd Block Address where data will be written
01401   * @param  NumberOfBlocks Number of blocks to write
01402   * @retval HAL status
01403   */
01404 HAL_StatusTypeDef HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
01405 {
01406   SDMMC_DataInitTypeDef config;
01407   uint32_t errorstate;
01408   uint32_t add = BlockAdd;
01409 
01410   if(NULL == pData)
01411   {
01412     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
01413     return HAL_ERROR;
01414   }
01415 
01416   if(hmmc->State == HAL_MMC_STATE_READY)
01417   {
01418     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
01419 
01420     if((add + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
01421     {
01422       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
01423       return HAL_ERROR;
01424     }
01425 
01426     hmmc->State = HAL_MMC_STATE_BUSY;
01427 
01428     /* Initialize data control register */
01429     hmmc->Instance->DCTRL = 0U;
01430 
01431 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
01432     /* Set the DMA transfer complete callback */
01433     hmmc->hdmatx->XferCpltCallback = MMC_DMATransmitCplt;
01434 
01435     /* Set the DMA error callback */
01436     hmmc->hdmatx->XferErrorCallback = MMC_DMAError;
01437 
01438     /* Set the DMA Abort callback */
01439     hmmc->hdmatx->XferAbortCallback = NULL;
01440 #else
01441     hmmc->pTxBuffPtr = pData;
01442     hmmc->TxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
01443 #endif
01444 
01445     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
01446     {
01447       add *= 512U;
01448     }
01449 
01450 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
01451     /* Configure the MMC DPSM (Data Path State Machine) */
01452     config.DataTimeOut   = SDMMC_DATATIMEOUT;
01453     config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
01454     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
01455     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
01456     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
01457     config.DPSM          = SDMMC_DPSM_DISABLE;
01458     (void)SDMMC_ConfigData(hmmc->Instance, &config);
01459 
01460     __SDMMC_CMDTRANS_ENABLE( hmmc->Instance);
01461 
01462     hmmc->Instance->IDMABASE0 = (uint32_t) pData ;
01463     hmmc->Instance->IDMACTRL  = SDMMC_ENABLE_IDMA_SINGLE_BUFF;
01464 #endif
01465 
01466     /* Write Blocks in Polling mode */
01467     if(NumberOfBlocks > 1U)
01468     {
01469       hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
01470 
01471       /* Write Multi Block command */
01472       errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
01473     }
01474     else
01475     {
01476       hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_DMA);
01477 
01478       /* Write Single Block command */
01479       errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
01480     }
01481     if(errorstate != HAL_MMC_ERROR_NONE)
01482     {
01483       /* Clear all the static flags */
01484       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
01485       hmmc->ErrorCode |= errorstate;
01486       hmmc->State = HAL_MMC_STATE_READY;
01487       hmmc->Context = MMC_CONTEXT_NONE;
01488       return HAL_ERROR;
01489     }
01490 
01491 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
01492     /* Enable SDMMC DMA transfer */
01493     __HAL_MMC_DMA_ENABLE(hmmc);
01494 
01495     /* Enable the DMA Channel */
01496     if(HAL_DMA_Start_IT(hmmc->hdmatx, (uint32_t)pData, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)(MMC_BLOCKSIZE * NumberOfBlocks)/4) != HAL_OK)
01497     {
01498       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
01499       hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
01500       hmmc->State = HAL_MMC_STATE_READY;
01501       hmmc->Context = MMC_CONTEXT_NONE;
01502       return HAL_ERROR;
01503     }
01504     else
01505     {
01506       /* Configure the MMC DPSM (Data Path State Machine) */
01507       config.DataTimeOut   = SDMMC_DATATIMEOUT;
01508       config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
01509       config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
01510       config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
01511       config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
01512       config.DPSM          = SDMMC_DPSM_ENABLE;
01513       (void)SDMMC_ConfigData(hmmc->Instance, &config);
01514 
01515       /* Enable MMC Error interrupts */
01516       __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR));
01517 
01518       return HAL_OK;
01519     }
01520 #else
01521     /* Enable MMC Error interrupts */
01522     __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND));
01523 
01524     return HAL_OK;
01525 #endif
01526   }
01527   else
01528   {
01529     return HAL_BUSY;
01530   }
01531 }
01532 
01533 /**
01534   * @brief  Erases the specified memory area of the given MMC card.
01535   * @note   This API should be followed by a check on the card state through
01536   *         HAL_MMC_GetCardState().
01537   * @param  hmmc Pointer to MMC handle
01538   * @param  BlockStartAdd Start Block address
01539   * @param  BlockEndAdd End Block address
01540   * @retval HAL status
01541   */
01542 HAL_StatusTypeDef HAL_MMC_Erase(MMC_HandleTypeDef *hmmc, uint32_t BlockStartAdd, uint32_t BlockEndAdd)
01543 {
01544   uint32_t errorstate;
01545   uint32_t start_add = BlockStartAdd;
01546   uint32_t end_add = BlockEndAdd;
01547 
01548   if(hmmc->State == HAL_MMC_STATE_READY)
01549   {
01550     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
01551 
01552     if(end_add < start_add)
01553     {
01554       hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
01555       return HAL_ERROR;
01556     }
01557 
01558     if(end_add > (hmmc->MmcCard.LogBlockNbr))
01559     {
01560       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
01561       return HAL_ERROR;
01562     }
01563 
01564     hmmc->State = HAL_MMC_STATE_BUSY;
01565 
01566     /* Check if the card command class supports erase command */
01567     if(((hmmc->MmcCard.Class) & SDMMC_CCCC_ERASE) == 0U)
01568     {
01569       /* Clear all the static flags */
01570       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
01571       hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
01572       hmmc->State = HAL_MMC_STATE_READY;
01573       return HAL_ERROR;
01574     }
01575 
01576     if((SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
01577     {
01578       /* Clear all the static flags */
01579       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
01580       hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED;
01581       hmmc->State = HAL_MMC_STATE_READY;
01582       return HAL_ERROR;
01583     }
01584 
01585     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
01586     {
01587       start_add *= 512U;
01588       end_add   *= 512U;
01589     }
01590 
01591     /* Send CMD35 MMC_ERASE_GRP_START with argument as addr  */
01592     errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, start_add);
01593     if(errorstate != HAL_MMC_ERROR_NONE)
01594     {
01595       /* Clear all the static flags */
01596       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
01597       hmmc->ErrorCode |= errorstate;
01598       hmmc->State = HAL_MMC_STATE_READY;
01599       return HAL_ERROR;
01600     }
01601 
01602     /* Send CMD36 MMC_ERASE_GRP_END with argument as addr  */
01603     errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, end_add);
01604     if(errorstate != HAL_MMC_ERROR_NONE)
01605     {
01606       /* Clear all the static flags */
01607       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
01608       hmmc->ErrorCode |= errorstate;
01609       hmmc->State = HAL_MMC_STATE_READY;
01610       return HAL_ERROR;
01611     }
01612 
01613     /* Send CMD38 ERASE */
01614     errorstate = SDMMC_CmdErase(hmmc->Instance, 0UL);
01615     if(errorstate != HAL_MMC_ERROR_NONE)
01616     {
01617       /* Clear all the static flags */
01618       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
01619       hmmc->ErrorCode |= errorstate;
01620       hmmc->State = HAL_MMC_STATE_READY;
01621       return HAL_ERROR;
01622     }
01623 
01624     hmmc->State = HAL_MMC_STATE_READY;
01625 
01626     return HAL_OK;
01627   }
01628   else
01629   {
01630     return HAL_BUSY;
01631   }
01632 }
01633 
01634 /**
01635   * @brief  This function handles MMC card interrupt request.
01636   * @param  hmmc Pointer to MMC handle
01637   * @retval None
01638   */
01639 void HAL_MMC_IRQHandler(MMC_HandleTypeDef *hmmc)
01640 {
01641   uint32_t errorstate;
01642   uint32_t context = hmmc->Context;
01643 
01644   /* Check for SDMMC interrupt flags */
01645   if((__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) != RESET) && ((context & MMC_CONTEXT_IT) != 0U))
01646   {
01647     MMC_Read_IT(hmmc);
01648   }
01649 
01650   else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) != RESET)
01651   {
01652     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_DATAEND);
01653 
01654     __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND  | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT |\
01655                                SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR  | SDMMC_IT_TXFIFOHE |\
01656                                SDMMC_IT_RXFIFOHF);
01657 
01658 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
01659     hmmc->Instance->DCTRL &= ~(SDMMC_DCTRL_DTEN);
01660 #else
01661     __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_IDMABTC);
01662     __SDMMC_CMDTRANS_DISABLE( hmmc->Instance);
01663 #endif
01664 
01665     if((context & MMC_CONTEXT_DMA) != 0U)
01666     {
01667 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
01668       hmmc->Instance->DLEN = 0;
01669       hmmc->Instance->DCTRL = 0;
01670       hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA ;
01671 
01672       /* Stop Transfer for Write Multi blocks or Read Multi blocks */
01673       if(((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
01674       {
01675         errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
01676         if(errorstate != HAL_MMC_ERROR_NONE)
01677         {
01678           hmmc->ErrorCode |= errorstate;
01679 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01680           hmmc->ErrorCallback(hmmc);
01681 #else
01682           HAL_MMC_ErrorCallback(hmmc);
01683 #endif
01684         }
01685       }
01686 
01687       /* Clear all the static flags */
01688       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
01689 
01690       hmmc->State = HAL_MMC_STATE_READY;
01691       hmmc->Context = MMC_CONTEXT_NONE;
01692       if(((context & MMC_CONTEXT_WRITE_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
01693       {
01694 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01695         hmmc->TxCpltCallback(hmmc);
01696 #else
01697         HAL_MMC_TxCpltCallback(hmmc);
01698 #endif
01699       }
01700       if(((context & MMC_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
01701       {
01702 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01703         hmmc->RxCpltCallback(hmmc);
01704 #else
01705         HAL_MMC_RxCpltCallback(hmmc);
01706 #endif
01707       }
01708 #else
01709       if((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)
01710       {
01711         errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
01712         if(errorstate != HAL_MMC_ERROR_NONE)
01713         {
01714           hmmc->ErrorCode |= errorstate;
01715 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01716           hmmc->ErrorCallback(hmmc);
01717 #else
01718           HAL_MMC_ErrorCallback(hmmc);
01719 #endif
01720         }
01721       }
01722       if(((context & MMC_CONTEXT_READ_SINGLE_BLOCK) == 0U) && ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) == 0U))
01723       {
01724         /* Disable the DMA transfer for transmit request by setting the DMAEN bit
01725         in the MMC DCTRL register */
01726         hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN);
01727 
01728         hmmc->State = HAL_MMC_STATE_READY;
01729         hmmc->Context = MMC_CONTEXT_NONE;
01730 
01731 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01732         hmmc->TxCpltCallback(hmmc);
01733 #else
01734         HAL_MMC_TxCpltCallback(hmmc);
01735 #endif
01736       }
01737 #endif
01738     }
01739     else if((context & MMC_CONTEXT_IT) != 0U)
01740     {
01741       /* Stop Transfer for Write Multi blocks or Read Multi blocks */
01742       if(((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
01743       {
01744         errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
01745         if(errorstate != HAL_MMC_ERROR_NONE)
01746         {
01747           hmmc->ErrorCode |= errorstate;
01748 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01749           hmmc->ErrorCallback(hmmc);
01750 #else
01751           HAL_MMC_ErrorCallback(hmmc);
01752 #endif
01753         }
01754       }
01755 
01756       /* Clear all the static flags */
01757       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
01758 
01759       hmmc->State = HAL_MMC_STATE_READY;
01760       hmmc->Context = MMC_CONTEXT_NONE;
01761       if(((context & MMC_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
01762       {
01763 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01764         hmmc->RxCpltCallback(hmmc);
01765 #else
01766         HAL_MMC_RxCpltCallback(hmmc);
01767 #endif
01768       }
01769       else
01770       {
01771 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01772         hmmc->TxCpltCallback(hmmc);
01773 #else
01774         HAL_MMC_TxCpltCallback(hmmc);
01775 #endif
01776       }
01777     }
01778     else
01779     {
01780       /* Nothing to do */
01781     }
01782   }
01783 
01784   else if((__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) != RESET) && ((context & MMC_CONTEXT_IT) != 0U))
01785   {
01786     MMC_Write_IT(hmmc);
01787   }
01788 
01789   else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL| SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_RXOVERR | SDMMC_FLAG_TXUNDERR) != RESET)
01790   {
01791     /* Set Error code */
01792     if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_DCRCFAIL) != RESET)
01793     {
01794       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
01795     }
01796     if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_DTIMEOUT) != RESET)
01797     {
01798       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
01799     }
01800     if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_RXOVERR) != RESET)
01801     {
01802       hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
01803     }
01804     if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_TXUNDERR) != RESET)
01805     {
01806       hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
01807     }
01808 
01809     /* Clear All flags */
01810     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
01811 
01812     /* Disable all interrupts */
01813     __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\
01814                                SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR);
01815 
01816 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
01817     __SDMMC_CMDTRANS_DISABLE( hmmc->Instance);
01818     hmmc->Instance->DCTRL |= SDMMC_DCTRL_FIFORST;
01819     hmmc->Instance->CMD |= SDMMC_CMD_CMDSTOP;
01820 #endif
01821     hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
01822 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
01823     hmmc->Instance->CMD &= ~(SDMMC_CMD_CMDSTOP);
01824     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_DABORT);
01825 #endif
01826 
01827     if((context & MMC_CONTEXT_IT) != 0U)
01828     {
01829       /* Set the MMC state to ready to be able to start again the process */
01830       hmmc->State = HAL_MMC_STATE_READY;
01831       hmmc->Context = MMC_CONTEXT_NONE;
01832 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01833       hmmc->ErrorCallback(hmmc);
01834 #else
01835       HAL_MMC_ErrorCallback(hmmc);
01836 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
01837     }
01838     else if((context & MMC_CONTEXT_DMA) != 0U)
01839     {
01840 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
01841       if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
01842       {
01843         /* Disable Internal DMA */
01844         __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_IDMABTC);
01845         hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA;
01846 
01847         /* Set the MMC state to ready to be able to start again the process */
01848         hmmc->State = HAL_MMC_STATE_READY;
01849 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01850         hmmc->ErrorCallback(hmmc);
01851 #else
01852         HAL_MMC_ErrorCallback(hmmc);
01853 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
01854       }
01855 #else
01856       /* Abort the MMC DMA Streams */
01857       if(hmmc->hdmatx != NULL)
01858       {
01859         /* Set the DMA Tx abort callback */
01860         hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort;
01861         /* Abort DMA in IT mode */
01862         if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
01863         {
01864           MMC_DMATxAbort(hmmc->hdmatx);
01865         }
01866       }
01867       else if(hmmc->hdmarx != NULL)
01868       {
01869         /* Set the DMA Rx abort callback */
01870         hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort;
01871         /* Abort DMA in IT mode */
01872         if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
01873         {
01874           MMC_DMARxAbort(hmmc->hdmarx);
01875         }
01876       }
01877       else
01878       {
01879         hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
01880         hmmc->State = HAL_MMC_STATE_READY;
01881         hmmc->Context = MMC_CONTEXT_NONE;
01882 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01883         hmmc->AbortCpltCallback(hmmc);
01884 #else
01885         HAL_MMC_AbortCallback(hmmc);
01886 #endif
01887       }
01888 #endif
01889     }
01890     else
01891     {
01892       /* Nothing to do */
01893     }
01894   }
01895 
01896 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
01897   else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_IDMABTC) != RESET)
01898   {
01899     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_IT_IDMABTC);
01900     if(READ_BIT(hmmc->Instance->IDMACTRL, SDMMC_IDMA_IDMABACT) == 0U)
01901     {
01902       /* Current buffer is buffer0, Transfer complete for buffer1 */
01903       if((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)
01904       {
01905 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01906         hmmc->Write_DMADblBuf1CpltCallback(hmmc);
01907 #else
01908         HAL_MMCEx_Write_DMADoubleBuffer1CpltCallback(hmmc);
01909 #endif
01910       }
01911       else /* MMC_CONTEXT_READ_MULTIPLE_BLOCK */
01912       {
01913 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01914         hmmc->Read_DMADblBuf1CpltCallback(hmmc);
01915 #else
01916         HAL_MMCEx_Read_DMADoubleBuffer1CpltCallback(hmmc);
01917 #endif
01918       }
01919     }
01920     else /* MMC_DMA_BUFFER1 */
01921     {
01922       /* Current buffer is buffer1, Transfer complete for buffer0 */
01923       if((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)
01924       {
01925 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01926         hmmc->Write_DMADblBuf0CpltCallback(hmmc);
01927 #else
01928         HAL_MMCEx_Write_DMADoubleBuffer0CpltCallback(hmmc);
01929 #endif
01930       }
01931       else /* MMC_CONTEXT_READ_MULTIPLE_BLOCK */
01932       {
01933 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01934         hmmc->Read_DMADblBuf0CpltCallback(hmmc);
01935 #else
01936         HAL_MMCEx_Read_DMADoubleBuffer0CpltCallback(hmmc);
01937 #endif
01938       }
01939     }
01940   }
01941 #endif
01942 
01943   else
01944   {
01945     /* Nothing to do */
01946   }
01947 }
01948 
01949 /**
01950   * @brief return the MMC state
01951   * @param hmmc Pointer to mmc handle
01952   * @retval HAL state
01953   */
01954 HAL_MMC_StateTypeDef HAL_MMC_GetState(MMC_HandleTypeDef *hmmc)
01955 {
01956   return hmmc->State;
01957 }
01958 
01959 /**
01960 * @brief  Return the MMC error code
01961 * @param  hmmc : Pointer to a MMC_HandleTypeDef structure that contains
01962   *              the configuration information.
01963 * @retval MMC Error Code
01964 */
01965 uint32_t HAL_MMC_GetError(MMC_HandleTypeDef *hmmc)
01966 {
01967   return hmmc->ErrorCode;
01968 }
01969 
01970 /**
01971   * @brief Tx Transfer completed callbacks
01972   * @param hmmc Pointer to MMC handle
01973   * @retval None
01974   */
01975 __weak void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef *hmmc)
01976 {
01977   /* Prevent unused argument(s) compilation warning */
01978   UNUSED(hmmc);
01979 
01980   /* NOTE : This function should not be modified, when the callback is needed,
01981             the HAL_MMC_TxCpltCallback can be implemented in the user file
01982    */
01983 }
01984 
01985 /**
01986   * @brief Rx Transfer completed callbacks
01987   * @param hmmc Pointer MMC handle
01988   * @retval None
01989   */
01990 __weak void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef *hmmc)
01991 {
01992   /* Prevent unused argument(s) compilation warning */
01993   UNUSED(hmmc);
01994 
01995   /* NOTE : This function should not be modified, when the callback is needed,
01996             the HAL_MMC_RxCpltCallback can be implemented in the user file
01997    */
01998 }
01999 
02000 /**
02001   * @brief MMC error callbacks
02002   * @param hmmc Pointer MMC handle
02003   * @retval None
02004   */
02005 __weak void HAL_MMC_ErrorCallback(MMC_HandleTypeDef *hmmc)
02006 {
02007   /* Prevent unused argument(s) compilation warning */
02008   UNUSED(hmmc);
02009 
02010   /* NOTE : This function should not be modified, when the callback is needed,
02011             the HAL_MMC_ErrorCallback can be implemented in the user file
02012    */
02013 }
02014 
02015 /**
02016   * @brief MMC Abort callbacks
02017   * @param hmmc Pointer MMC handle
02018   * @retval None
02019   */
02020 __weak void HAL_MMC_AbortCallback(MMC_HandleTypeDef *hmmc)
02021 {
02022   /* Prevent unused argument(s) compilation warning */
02023   UNUSED(hmmc);
02024 
02025   /* NOTE : This function should not be modified, when the callback is needed,
02026             the HAL_MMC_AbortCallback can be implemented in the user file
02027    */
02028 }
02029 
02030 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
02031 /**
02032   * @brief  Register a User MMC Callback
02033   *         To be used instead of the weak (surcharged) predefined callback
02034   * @param hmmc : MMC handle
02035   * @param CallbackId : ID of the callback to be registered
02036   *        This parameter can be one of the following values:
02037   *          @arg @ref HAL_MMC_TX_CPLT_CB_ID                 MMC Tx Complete Callback ID
02038   *          @arg @ref HAL_MMC_RX_CPLT_CB_ID                 MMC Rx Complete Callback ID
02039   *          @arg @ref HAL_MMC_ERROR_CB_ID                   MMC Error Callback ID
02040   *          @arg @ref HAL_MMC_ABORT_CB_ID                   MMC Abort Callback ID
02041   *          @arg @ref HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID  MMC DMA Rx Double buffer 0 Callback ID
02042   *          @arg @ref HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID  MMC DMA Rx Double buffer 1 Callback ID
02043   *          @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID MMC DMA Tx Double buffer 0 Callback ID
02044   *          @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID MMC DMA Tx Double buffer 1 Callback ID
02045   *          @arg @ref HAL_MMC_MSP_INIT_CB_ID                MMC MspInit Callback ID
02046   *          @arg @ref HAL_MMC_MSP_DEINIT_CB_ID              MMC MspDeInit Callback ID
02047   * @param pCallback : pointer to the Callback function
02048   * @retval status
02049   */
02050 HAL_StatusTypeDef HAL_MMC_RegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId, pMMC_CallbackTypeDef pCallback)
02051 {
02052   HAL_StatusTypeDef status = HAL_OK;
02053 
02054   if(pCallback == NULL)
02055   {
02056     /* Update the error code */
02057     hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
02058     return HAL_ERROR;
02059   }
02060 
02061   /* Process locked */
02062   __HAL_LOCK(hmmc);
02063 
02064   if(hmmc->State == HAL_MMC_STATE_READY)
02065   {
02066     switch (CallbackId)
02067     {
02068     case HAL_MMC_TX_CPLT_CB_ID :
02069       hmmc->TxCpltCallback = pCallback;
02070       break;
02071     case HAL_MMC_RX_CPLT_CB_ID :
02072       hmmc->RxCpltCallback = pCallback;
02073       break;
02074     case HAL_MMC_ERROR_CB_ID :
02075       hmmc->ErrorCallback = pCallback;
02076       break;
02077     case HAL_MMC_ABORT_CB_ID :
02078       hmmc->AbortCpltCallback = pCallback;
02079       break;
02080 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
02081     case HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID :
02082       hmmc->Read_DMADblBuf0CpltCallback = pCallback;
02083       break;
02084     case HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID :
02085       hmmc->Read_DMADblBuf1CpltCallback = pCallback;
02086       break;
02087     case HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID :
02088       hmmc->Write_DMADblBuf0CpltCallback = pCallback;
02089       break;
02090     case HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID :
02091       hmmc->Write_DMADblBuf1CpltCallback = pCallback;
02092       break;
02093 #endif
02094     case HAL_MMC_MSP_INIT_CB_ID :
02095       hmmc->MspInitCallback = pCallback;
02096       break;
02097     case HAL_MMC_MSP_DEINIT_CB_ID :
02098       hmmc->MspDeInitCallback = pCallback;
02099       break;
02100     default :
02101       /* Update the error code */
02102       hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
02103       /* update return status */
02104       status =  HAL_ERROR;
02105       break;
02106     }
02107   }
02108   else if (hmmc->State == HAL_MMC_STATE_RESET)
02109   {
02110     switch (CallbackId)
02111     {
02112     case HAL_MMC_MSP_INIT_CB_ID :
02113       hmmc->MspInitCallback = pCallback;
02114       break;
02115     case HAL_MMC_MSP_DEINIT_CB_ID :
02116       hmmc->MspDeInitCallback = pCallback;
02117       break;
02118     default :
02119       /* Update the error code */
02120       hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
02121       /* update return status */
02122       status =  HAL_ERROR;
02123       break;
02124     }
02125   }
02126   else
02127   {
02128     /* Update the error code */
02129     hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
02130     /* update return status */
02131     status =  HAL_ERROR;
02132   }
02133 
02134   /* Release Lock */
02135   __HAL_UNLOCK(hmmc);
02136   return status;
02137 }
02138 
02139 /**
02140   * @brief  Unregister a User MMC Callback
02141   *         MMC Callback is redirected to the weak (surcharged) predefined callback
02142   * @param hmmc : MMC handle
02143   * @param CallbackId : ID of the callback to be unregistered
02144   *        This parameter can be one of the following values:
02145   *          @arg @ref HAL_MMC_TX_CPLT_CB_ID                 MMC Tx Complete Callback ID
02146   *          @arg @ref HAL_MMC_RX_CPLT_CB_ID                 MMC Rx Complete Callback ID
02147   *          @arg @ref HAL_MMC_ERROR_CB_ID                   MMC Error Callback ID
02148   *          @arg @ref HAL_MMC_ABORT_CB_ID                   MMC Abort Callback ID
02149   *          @arg @ref HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID  MMC DMA Rx Double buffer 0 Callback ID
02150   *          @arg @ref HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID  MMC DMA Rx Double buffer 1 Callback ID
02151   *          @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID MMC DMA Tx Double buffer 0 Callback ID
02152   *          @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID MMC DMA Tx Double buffer 1 Callback ID
02153   *          @arg @ref HAL_MMC_MSP_INIT_CB_ID                MMC MspInit Callback ID
02154   *          @arg @ref HAL_MMC_MSP_DEINIT_CB_ID              MMC MspDeInit Callback ID
02155   * @retval status
02156   */
02157 HAL_StatusTypeDef HAL_MMC_UnRegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId)
02158 {
02159   HAL_StatusTypeDef status = HAL_OK;
02160 
02161   /* Process locked */
02162   __HAL_LOCK(hmmc);
02163 
02164   if(hmmc->State == HAL_MMC_STATE_READY)
02165   {
02166     switch (CallbackId)
02167     {
02168     case HAL_MMC_TX_CPLT_CB_ID :
02169       hmmc->TxCpltCallback = HAL_MMC_TxCpltCallback;
02170       break;
02171     case HAL_MMC_RX_CPLT_CB_ID :
02172       hmmc->RxCpltCallback = HAL_MMC_RxCpltCallback;
02173       break;
02174     case HAL_MMC_ERROR_CB_ID :
02175       hmmc->ErrorCallback = HAL_MMC_ErrorCallback;
02176       break;
02177     case HAL_MMC_ABORT_CB_ID :
02178       hmmc->AbortCpltCallback = HAL_MMC_AbortCallback;
02179       break;
02180 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
02181     case HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID :
02182       hmmc->Read_DMADblBuf0CpltCallback = HAL_MMCEx_Read_DMADoubleBuffer0CpltCallback;
02183       break;
02184     case HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID :
02185       hmmc->Read_DMADblBuf1CpltCallback = HAL_MMCEx_Read_DMADoubleBuffer1CpltCallback;
02186       break;
02187     case HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID :
02188       hmmc->Write_DMADblBuf0CpltCallback = HAL_MMCEx_Write_DMADoubleBuffer0CpltCallback;
02189       break;
02190     case HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID :
02191       hmmc->Write_DMADblBuf1CpltCallback = HAL_MMCEx_Write_DMADoubleBuffer1CpltCallback;
02192       break;
02193 #endif
02194     case HAL_MMC_MSP_INIT_CB_ID :
02195       hmmc->MspInitCallback = HAL_MMC_MspInit;
02196       break;
02197     case HAL_MMC_MSP_DEINIT_CB_ID :
02198       hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
02199       break;
02200     default :
02201       /* Update the error code */
02202       hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
02203       /* update return status */
02204       status =  HAL_ERROR;
02205       break;
02206     }
02207   }
02208   else if (hmmc->State == HAL_MMC_STATE_RESET)
02209   {
02210     switch (CallbackId)
02211     {
02212     case HAL_MMC_MSP_INIT_CB_ID :
02213       hmmc->MspInitCallback = HAL_MMC_MspInit;
02214       break;
02215     case HAL_MMC_MSP_DEINIT_CB_ID :
02216       hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
02217       break;
02218     default :
02219       /* Update the error code */
02220       hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
02221       /* update return status */
02222       status =  HAL_ERROR;
02223       break;
02224     }
02225   }
02226   else
02227   {
02228     /* Update the error code */
02229     hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
02230     /* update return status */
02231     status =  HAL_ERROR;
02232   }
02233 
02234   /* Release Lock */
02235   __HAL_UNLOCK(hmmc);
02236   return status;
02237 }
02238 #endif
02239 
02240 /**
02241   * @}
02242   */
02243 
02244 /** @addtogroup MMC_Exported_Functions_Group3
02245  *  @brief   management functions
02246  *
02247 @verbatim
02248   ==============================================================================
02249                       ##### Peripheral Control functions #####
02250   ==============================================================================
02251   [..]
02252     This subsection provides a set of functions allowing to control the MMC card
02253     operations and get the related information
02254 
02255 @endverbatim
02256   * @{
02257   */
02258 
02259 /**
02260   * @brief  Returns information the information of the card which are stored on
02261   *         the CID register.
02262   * @param  hmmc Pointer to MMC handle
02263   * @param  pCID Pointer to a HAL_MMC_CIDTypedef structure that
02264   *         contains all CID register parameters
02265   * @retval HAL status
02266   */
02267 HAL_StatusTypeDef HAL_MMC_GetCardCID(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCIDTypeDef *pCID)
02268 {
02269   pCID->ManufacturerID = (uint8_t)((hmmc->CID[0] & 0xFF000000U) >> 24U);
02270 
02271   pCID->OEM_AppliID = (uint16_t)((hmmc->CID[0] & 0x00FFFF00U) >> 8U);
02272 
02273   pCID->ProdName1 = (((hmmc->CID[0] & 0x000000FFU) << 24U) | ((hmmc->CID[1] & 0xFFFFFF00U) >> 8U));
02274 
02275   pCID->ProdName2 = (uint8_t)(hmmc->CID[1] & 0x000000FFU);
02276 
02277   pCID->ProdRev = (uint8_t)((hmmc->CID[2] & 0xFF000000U) >> 24U);
02278 
02279   pCID->ProdSN = (((hmmc->CID[2] & 0x00FFFFFFU) << 8U) | ((hmmc->CID[3] & 0xFF000000U) >> 24U));
02280 
02281   pCID->Reserved1 = (uint8_t)((hmmc->CID[3] & 0x00F00000U) >> 20U);
02282 
02283   pCID->ManufactDate = (uint16_t)((hmmc->CID[3] & 0x000FFF00U) >> 8U);
02284 
02285   pCID->CID_CRC = (uint8_t)((hmmc->CID[3] & 0x000000FEU) >> 1U);
02286 
02287   pCID->Reserved2 = 1U;
02288 
02289   return HAL_OK;
02290 }
02291 
02292 /**
02293   * @brief  Returns information the information of the card which are stored on
02294   *         the CSD register.
02295   * @param  hmmc Pointer to MMC handle
02296   * @param  pCSD Pointer to a HAL_MMC_CardCSDTypeDef structure that
02297   *         contains all CSD register parameters
02298   * @retval HAL status
02299   */
02300 HAL_StatusTypeDef HAL_MMC_GetCardCSD(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCSDTypeDef *pCSD)
02301 {
02302   uint32_t block_nbr = 0;
02303 
02304   pCSD->CSDStruct = (uint8_t)((hmmc->CSD[0] & 0xC0000000U) >> 30U);
02305 
02306   pCSD->SysSpecVersion = (uint8_t)((hmmc->CSD[0] & 0x3C000000U) >> 26U);
02307 
02308   pCSD->Reserved1 = (uint8_t)((hmmc->CSD[0] & 0x03000000U) >> 24U);
02309 
02310   pCSD->TAAC = (uint8_t)((hmmc->CSD[0] & 0x00FF0000U) >> 16U);
02311 
02312   pCSD->NSAC = (uint8_t)((hmmc->CSD[0] & 0x0000FF00U) >> 8U);
02313 
02314   pCSD->MaxBusClkFrec = (uint8_t)(hmmc->CSD[0] & 0x000000FFU);
02315 
02316   pCSD->CardComdClasses = (uint16_t)((hmmc->CSD[1] & 0xFFF00000U) >> 20U);
02317 
02318   pCSD->RdBlockLen = (uint8_t)((hmmc->CSD[1] & 0x000F0000U) >> 16U);
02319 
02320   pCSD->PartBlockRead   = (uint8_t)((hmmc->CSD[1] & 0x00008000U) >> 15U);
02321 
02322   pCSD->WrBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00004000U) >> 14U);
02323 
02324   pCSD->RdBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00002000U) >> 13U);
02325 
02326   pCSD->DSRImpl = (uint8_t)((hmmc->CSD[1] & 0x00001000U) >> 12U);
02327 
02328   pCSD->Reserved2 = 0U; /*!< Reserved */
02329 
02330   if(MMC_ReadExtCSD(hmmc, &block_nbr, 212, 0x0FFFFFFFU) != HAL_OK) /* Field SEC_COUNT [215:212] */
02331   {
02332     return HAL_ERROR;
02333   }
02334 
02335   if(hmmc->MmcCard.CardType == MMC_LOW_CAPACITY_CARD)
02336   {
02337     pCSD->DeviceSize = (((hmmc->CSD[1] & 0x000003FFU) << 2U) | ((hmmc->CSD[2] & 0xC0000000U) >> 30U));
02338 
02339     pCSD->MaxRdCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x38000000U) >> 27U);
02340 
02341     pCSD->MaxRdCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x07000000U) >> 24U);
02342 
02343     pCSD->MaxWrCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x00E00000U) >> 21U);
02344 
02345     pCSD->MaxWrCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x001C0000U) >> 18U);
02346 
02347     pCSD->DeviceSizeMul = (uint8_t)((hmmc->CSD[2] & 0x00038000U) >> 15U);
02348 
02349     hmmc->MmcCard.BlockNbr  = (pCSD->DeviceSize + 1U) ;
02350     hmmc->MmcCard.BlockNbr *= (1UL << ((pCSD->DeviceSizeMul & 0x07U) + 2U));
02351     hmmc->MmcCard.BlockSize = (1UL << (pCSD->RdBlockLen & 0x0FU));
02352 
02353     hmmc->MmcCard.LogBlockNbr =  (hmmc->MmcCard.BlockNbr) * ((hmmc->MmcCard.BlockSize) / 512U);
02354     hmmc->MmcCard.LogBlockSize = 512U;
02355   }
02356   else if(hmmc->MmcCard.CardType == MMC_HIGH_CAPACITY_CARD)
02357   {
02358     hmmc->MmcCard.BlockNbr = block_nbr;
02359     hmmc->MmcCard.LogBlockNbr = hmmc->MmcCard.BlockNbr;
02360     hmmc->MmcCard.BlockSize = 512U;
02361     hmmc->MmcCard.LogBlockSize = hmmc->MmcCard.BlockSize;
02362   }
02363   else
02364   {
02365     /* Clear all the static flags */
02366     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
02367     hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
02368     hmmc->State = HAL_MMC_STATE_READY;
02369     return HAL_ERROR;
02370   }
02371 
02372   pCSD->EraseGrSize = (uint8_t)((hmmc->CSD[2] & 0x00004000U) >> 14U);
02373 
02374   pCSD->EraseGrMul = (uint8_t)((hmmc->CSD[2] & 0x00003F80U) >> 7U);
02375 
02376   pCSD->WrProtectGrSize = (uint8_t)(hmmc->CSD[2] & 0x0000007FU);
02377 
02378   pCSD->WrProtectGrEnable = (uint8_t)((hmmc->CSD[3] & 0x80000000U) >> 31U);
02379 
02380   pCSD->ManDeflECC = (uint8_t)((hmmc->CSD[3] & 0x60000000U) >> 29U);
02381 
02382   pCSD->WrSpeedFact = (uint8_t)((hmmc->CSD[3] & 0x1C000000U) >> 26U);
02383 
02384   pCSD->MaxWrBlockLen= (uint8_t)((hmmc->CSD[3] & 0x03C00000U) >> 22U);
02385 
02386   pCSD->WriteBlockPaPartial = (uint8_t)((hmmc->CSD[3] & 0x00200000U) >> 21U);
02387 
02388   pCSD->Reserved3 = 0;
02389 
02390   pCSD->ContentProtectAppli = (uint8_t)((hmmc->CSD[3] & 0x00010000U) >> 16U);
02391 
02392   pCSD->FileFormatGroup = (uint8_t)((hmmc->CSD[3] & 0x00008000U) >> 15U);
02393 
02394   pCSD->CopyFlag = (uint8_t)((hmmc->CSD[3] & 0x00004000U) >> 14U);
02395 
02396   pCSD->PermWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00002000U) >> 13U);
02397 
02398   pCSD->TempWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00001000U) >> 12U);
02399 
02400   pCSD->FileFormat = (uint8_t)((hmmc->CSD[3] & 0x00000C00U) >> 10U);
02401 
02402   pCSD->ECC= (uint8_t)((hmmc->CSD[3] & 0x00000300U) >> 8U);
02403 
02404   pCSD->CSD_CRC = (uint8_t)((hmmc->CSD[3] & 0x000000FEU) >> 1U);
02405 
02406   pCSD->Reserved4 = 1;
02407 
02408   return HAL_OK;
02409 }
02410 
02411 /**
02412   * @brief  Gets the MMC card info.
02413   * @param  hmmc Pointer to MMC handle
02414   * @param  pCardInfo Pointer to the HAL_MMC_CardInfoTypeDef structure that
02415   *         will contain the MMC card status information
02416   * @retval HAL status
02417   */
02418 HAL_StatusTypeDef HAL_MMC_GetCardInfo(MMC_HandleTypeDef *hmmc, HAL_MMC_CardInfoTypeDef *pCardInfo)
02419 {
02420   pCardInfo->CardType     = (uint32_t)(hmmc->MmcCard.CardType);
02421   pCardInfo->Class        = (uint32_t)(hmmc->MmcCard.Class);
02422   pCardInfo->RelCardAdd   = (uint32_t)(hmmc->MmcCard.RelCardAdd);
02423   pCardInfo->BlockNbr     = (uint32_t)(hmmc->MmcCard.BlockNbr);
02424   pCardInfo->BlockSize    = (uint32_t)(hmmc->MmcCard.BlockSize);
02425   pCardInfo->LogBlockNbr  = (uint32_t)(hmmc->MmcCard.LogBlockNbr);
02426   pCardInfo->LogBlockSize = (uint32_t)(hmmc->MmcCard.LogBlockSize);
02427 
02428   return HAL_OK;
02429 }
02430 
02431 /**
02432   * @brief  Returns information the information of the card which are stored on
02433   *         the Extended CSD register.
02434   * @param  hmmc Pointer to MMC handle
02435   * @param  pExtCSD Pointer to a memory area (512 bytes) that contains all
02436   *         Extended CSD register parameters
02437   * @param  Timeout Specify timeout value
02438   * @retval HAL status
02439   */
02440 HAL_StatusTypeDef HAL_MMC_GetCardExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pExtCSD, uint32_t Timeout)
02441 {
02442   SDMMC_DataInitTypeDef config;
02443   uint32_t errorstate;
02444   uint32_t tickstart = HAL_GetTick();
02445   uint32_t count;
02446   uint32_t *tmp_buf;
02447 
02448   if(NULL == pExtCSD)
02449   {
02450     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
02451     return HAL_ERROR;
02452   }
02453 
02454   if(hmmc->State == HAL_MMC_STATE_READY)
02455   {
02456     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
02457 
02458     hmmc->State = HAL_MMC_STATE_BUSY;
02459 
02460     /* Initialize data control register */
02461     hmmc->Instance->DCTRL = 0;
02462 
02463     /* Initiaize the destination pointer */
02464     tmp_buf = pExtCSD;
02465 
02466     /* Configure the MMC DPSM (Data Path State Machine) */
02467     config.DataTimeOut   = SDMMC_DATATIMEOUT;
02468     config.DataLength    = 512;
02469     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
02470     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
02471     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
02472 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
02473     config.DPSM          = SDMMC_DPSM_ENABLE;
02474 #else
02475     config.DPSM          = SDMMC_DPSM_DISABLE;
02476 #endif
02477     (void)SDMMC_ConfigData(hmmc->Instance, &config);
02478 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
02479     __SDMMC_CMDTRANS_ENABLE( hmmc->Instance);
02480 #endif
02481 
02482     /* Send ExtCSD Read command to Card */
02483     errorstate = SDMMC_CmdSendEXTCSD(hmmc->Instance, 0);
02484     if(errorstate != HAL_MMC_ERROR_NONE)
02485     {
02486       /* Clear all the static flags */
02487       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
02488       hmmc->ErrorCode |= errorstate;
02489       hmmc->State = HAL_MMC_STATE_READY;
02490       return HAL_ERROR;
02491     }
02492 
02493     /* Poll on SDMMC flags */
02494     while(!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
02495     {
02496       if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF))
02497       {
02498         /* Read data from SDMMC Rx FIFO */
02499         for(count = 0U; count < 8U; count++)
02500         {
02501           *tmp_buf = SDMMC_ReadFIFO(hmmc->Instance);
02502           tmp_buf++;
02503         }
02504       }
02505 
02506       if(((HAL_GetTick()-tickstart) >=  Timeout) || (Timeout == 0U))
02507       {
02508         /* Clear all the static flags */
02509         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
02510         hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
02511         hmmc->State= HAL_MMC_STATE_READY;
02512         return HAL_TIMEOUT;
02513       }
02514     }
02515 
02516 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
02517     __SDMMC_CMDTRANS_DISABLE( hmmc->Instance);
02518 #endif
02519 
02520     /* Get error state */
02521     if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
02522     {
02523       /* Clear all the static flags */
02524       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
02525       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
02526       hmmc->State = HAL_MMC_STATE_READY;
02527       return HAL_ERROR;
02528     }
02529     else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
02530     {
02531       /* Clear all the static flags */
02532       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
02533       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
02534       hmmc->State = HAL_MMC_STATE_READY;
02535       return HAL_ERROR;
02536     }
02537     else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR))
02538     {
02539       /* Clear all the static flags */
02540       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
02541       hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
02542       hmmc->State = HAL_MMC_STATE_READY;
02543       return HAL_ERROR;
02544     }
02545     else
02546     {
02547       /* Nothing to do */
02548     }
02549 
02550     /* Clear all the static flags */
02551     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
02552     hmmc->State = HAL_MMC_STATE_READY;
02553   }
02554 
02555   return HAL_OK;
02556 }
02557 
02558 /**
02559   * @brief  Enables wide bus operation for the requested card if supported by
02560   *         card.
02561   * @param  hmmc Pointer to MMC handle
02562   * @param  WideMode Specifies the MMC card wide bus mode
02563   *          This parameter can be one of the following values:
02564   *            @arg SDMMC_BUS_WIDE_8B: 8-bit data transfer
02565   *            @arg SDMMC_BUS_WIDE_4B: 4-bit data transfer
02566   *            @arg SDMMC_BUS_WIDE_1B: 1-bit data transfer
02567   * @retval HAL status
02568   */
02569 HAL_StatusTypeDef HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef *hmmc, uint32_t WideMode)
02570 {
02571   uint32_t count;
02572   SDMMC_InitTypeDef Init;
02573   uint32_t errorstate;
02574   uint32_t response = 0U;
02575 
02576   /* Check the parameters */
02577   assert_param(IS_SDMMC_BUS_WIDE(WideMode));
02578 
02579   /* Change State */
02580   hmmc->State = HAL_MMC_STATE_BUSY;
02581 
02582 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
02583   /* Check and update the power class if needed */
02584   if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) != 0U)
02585   {
02586     if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) != 0U)
02587     {
02588       errorstate = MMC_PwrClassUpdate(hmmc, WideMode, SDMMC_SPEED_MODE_DDR);
02589     }
02590     else
02591     {
02592       errorstate = MMC_PwrClassUpdate(hmmc, WideMode, SDMMC_SPEED_MODE_HIGH);
02593     }
02594   }
02595   else
02596   {
02597     errorstate = MMC_PwrClassUpdate(hmmc, WideMode, SDMMC_SPEED_MODE_DEFAULT);
02598   }
02599 #else
02600   errorstate = MMC_PwrClassUpdate(hmmc, WideMode, 0U);
02601 #endif
02602 
02603   if(errorstate == HAL_MMC_ERROR_NONE)
02604   {
02605     if(WideMode == SDMMC_BUS_WIDE_8B)
02606     {
02607       errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U);
02608     }
02609     else if(WideMode == SDMMC_BUS_WIDE_4B)
02610     {
02611       errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U);
02612     }
02613     else if(WideMode == SDMMC_BUS_WIDE_1B)
02614     {
02615       errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70000U);
02616     }
02617     else
02618     {
02619       /* WideMode is not a valid argument*/
02620       errorstate = HAL_MMC_ERROR_PARAM;
02621     }
02622 
02623     /* Check for switch error and violation of the trial number of sending CMD 13 */
02624     if(errorstate == HAL_MMC_ERROR_NONE)
02625     {
02626       /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
02627       count = SDMMC_MAX_TRIAL;
02628       do
02629       {
02630         errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
02631         if(errorstate != HAL_MMC_ERROR_NONE)
02632         {
02633           break;
02634         }
02635 
02636         /* Get command response */
02637         response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
02638         count--;
02639       }while(((response & 0x100U) == 0U) && (count != 0U));
02640 
02641       /* Check the status after the switch command execution */
02642       if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
02643       {
02644         /* Check the bit SWITCH_ERROR of the device status */
02645         if ((response & 0x80U) != 0U)
02646         {
02647           errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
02648         }
02649         else
02650         {
02651           /* Configure the SDMMC peripheral */
02652           Init = hmmc->Init;
02653           Init.BusWide = WideMode;
02654           (void)SDMMC_Init(hmmc->Instance, Init);
02655         }
02656       }
02657       else if (count == 0U)
02658       {
02659         errorstate = SDMMC_ERROR_TIMEOUT;
02660       }
02661       else
02662       {
02663         /* Nothing to do */
02664       }
02665     }
02666   }
02667 
02668   /* Change State */
02669   hmmc->State = HAL_MMC_STATE_READY;
02670 
02671   if(errorstate != HAL_MMC_ERROR_NONE)
02672   {
02673     /* Clear all the static flags */
02674     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
02675     hmmc->ErrorCode |= errorstate;
02676     return HAL_ERROR;
02677   }
02678 
02679   return HAL_OK;
02680 }
02681 
02682 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
02683 /**
02684   * @brief  Configure the speed bus mode
02685   * @param  hmmc Pointer to the MMC handle
02686   * @param  SpeedMode Specifies the MMC card speed bus mode
02687   *          This parameter can be one of the following values:
02688   *            @arg SDMMC_SPEED_MODE_AUTO: Max speed mode supported by the card
02689   *            @arg SDMMC_SPEED_MODE_DEFAULT: Default Speed (MMC @ 26MHz)
02690   *            @arg SDMMC_SPEED_MODE_HIGH: High Speed (MMC @ 52 MHz)
02691   *            @arg SDMMC_SPEED_MODE_DDR: High Speed DDR (MMC DDR @ 52 MHz)
02692   * @retval HAL status
02693   */
02694 
02695 HAL_StatusTypeDef HAL_MMC_ConfigSpeedBusOperation(MMC_HandleTypeDef *hmmc, uint32_t SpeedMode)
02696 {
02697   uint32_t tickstart;
02698   HAL_StatusTypeDef status = HAL_OK;
02699   uint32_t device_type;
02700   uint32_t errorstate;
02701 
02702   /* Check the parameters */
02703   assert_param(IS_SDMMC_SPEED_MODE(SpeedMode));
02704 
02705   /* Change State */
02706   hmmc->State = HAL_MMC_STATE_BUSY;
02707 
02708   /* Field DEVICE_TYPE [196 = 49*4] of Extended CSD register */
02709   device_type = (hmmc->Ext_CSD[49] & 0x000000FFU);
02710 
02711   switch (SpeedMode)
02712   {
02713     case SDMMC_SPEED_MODE_AUTO:
02714     {
02715       if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS) != 0U) && ((device_type & 0x04U) != 0U))
02716       {
02717         /* High Speed DDR mode allowed */
02718         errorstate = MMC_HighSpeed(hmmc, ENABLE);
02719         if(errorstate != HAL_MMC_ERROR_NONE)
02720         {
02721           hmmc->ErrorCode |= errorstate;
02722         }
02723         else
02724         {
02725           if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_CLKDIV) != 0U)
02726           {
02727             /* DDR mode not supported with CLKDIV = 0 */
02728             errorstate = MMC_DDR_Mode(hmmc, ENABLE);
02729             if(errorstate != HAL_MMC_ERROR_NONE)
02730             {
02731               hmmc->ErrorCode |= errorstate;
02732             }
02733           }
02734         }
02735       }
02736       else if ((device_type & 0x02U) != 0U)
02737       {
02738         /* High Speed mode allowed */
02739         errorstate = MMC_HighSpeed(hmmc, ENABLE);
02740         if(errorstate != HAL_MMC_ERROR_NONE)
02741         {
02742           hmmc->ErrorCode |= errorstate;
02743         }
02744       }
02745       else
02746       {
02747         /* Nothing to do : keep current speed */
02748       }
02749       break;
02750     }
02751     case SDMMC_SPEED_MODE_DDR:
02752     {
02753       if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS) != 0U) && ((device_type & 0x04U) != 0U))
02754       {
02755         /* High Speed DDR mode allowed */
02756         errorstate = MMC_HighSpeed(hmmc, ENABLE);
02757         if(errorstate != HAL_MMC_ERROR_NONE)
02758         {
02759           hmmc->ErrorCode |= errorstate;
02760         }
02761         else
02762         {
02763           if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_CLKDIV) != 0U)
02764           {
02765             /* DDR mode not supported with CLKDIV = 0 */
02766             errorstate = MMC_DDR_Mode(hmmc, ENABLE);
02767             if(errorstate != HAL_MMC_ERROR_NONE)
02768             {
02769               hmmc->ErrorCode |= errorstate;
02770             }
02771           }
02772         }
02773       }
02774       else
02775       {
02776         /* High Speed DDR mode not allowed */
02777         hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
02778         status = HAL_ERROR;
02779       }
02780       break;
02781     }
02782     case SDMMC_SPEED_MODE_HIGH:
02783     {
02784       if ((device_type & 0x02U) != 0U)
02785       {
02786         /* High Speed mode allowed */
02787         errorstate = MMC_HighSpeed(hmmc, ENABLE);
02788         if(errorstate != HAL_MMC_ERROR_NONE)
02789         {
02790           hmmc->ErrorCode |= errorstate;
02791         }
02792       }
02793       else
02794       {
02795         /* High Speed mode not allowed */
02796         hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
02797         status = HAL_ERROR;
02798       }
02799       break;
02800     }
02801     case SDMMC_SPEED_MODE_DEFAULT:
02802     {
02803       if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) != 0U)
02804       {
02805         /* High Speed DDR mode activated */
02806         errorstate = MMC_DDR_Mode(hmmc, DISABLE);
02807         if(errorstate != HAL_MMC_ERROR_NONE)
02808         {
02809           hmmc->ErrorCode |= errorstate;
02810         }
02811       }
02812       if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) != 0U)
02813       {
02814         /* High Speed mode activated */
02815         errorstate = MMC_HighSpeed(hmmc, DISABLE);
02816         if(errorstate != HAL_MMC_ERROR_NONE)
02817         {
02818           hmmc->ErrorCode |= errorstate;
02819         }
02820       }
02821       break;
02822     }
02823     default:
02824       hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
02825       status = HAL_ERROR;
02826       break;
02827   }
02828 
02829   /* Verify that MMC card is ready to use after Speed mode switch*/
02830   tickstart = HAL_GetTick();
02831   while ((HAL_MMC_GetCardState(hmmc) != HAL_MMC_CARD_TRANSFER))
02832   {
02833     if ((HAL_GetTick() - tickstart) >=  SDMMC_DATATIMEOUT)
02834     {
02835       hmmc->ErrorCode = HAL_MMC_ERROR_TIMEOUT;
02836       hmmc->State = HAL_MMC_STATE_READY;
02837       return HAL_TIMEOUT;
02838     }
02839   }
02840 
02841   /* Change State */
02842   hmmc->State = HAL_MMC_STATE_READY;
02843   return status;
02844 }
02845 #endif
02846 
02847 /**
02848   * @brief  Gets the current mmc card data state.
02849   * @param  hmmc pointer to MMC handle
02850   * @retval Card state
02851   */
02852 HAL_MMC_CardStateTypeDef HAL_MMC_GetCardState(MMC_HandleTypeDef *hmmc)
02853 {
02854   uint32_t cardstate;
02855   uint32_t errorstate;
02856   uint32_t resp1 = 0U;
02857 
02858   errorstate = MMC_SendStatus(hmmc, &resp1);
02859   if(errorstate != HAL_MMC_ERROR_NONE)
02860   {
02861     hmmc->ErrorCode |= errorstate;
02862   }
02863 
02864   cardstate = ((resp1 >> 9U) & 0x0FU);
02865 
02866   return (HAL_MMC_CardStateTypeDef)cardstate;
02867 }
02868 
02869 /**
02870   * @brief  Abort the current transfer and disable the MMC.
02871   * @param  hmmc pointer to a MMC_HandleTypeDef structure that contains
02872   *                the configuration information for MMC module.
02873   * @retval HAL status
02874   */
02875 HAL_StatusTypeDef HAL_MMC_Abort(MMC_HandleTypeDef *hmmc)
02876 {
02877   HAL_MMC_CardStateTypeDef CardState;
02878 
02879   /* DIsable All interrupts */
02880   __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\
02881                            SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR);
02882 
02883   /* Clear All flags */
02884   __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
02885 
02886 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
02887   if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL))
02888   {
02889     /* Disable the MMC DMA request */
02890     hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN);
02891 
02892     /* Abort the MMC DMA Tx Stream */
02893     if(hmmc->hdmatx != NULL)
02894     {
02895       if(HAL_DMA_Abort(hmmc->hdmatx) != HAL_OK)
02896       {
02897         hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
02898       }
02899     }
02900     /* Abort the MMC DMA Rx Stream */
02901     if(hmmc->hdmarx != NULL)
02902     {
02903       if(HAL_DMA_Abort(hmmc->hdmarx) != HAL_OK)
02904       {
02905         hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
02906       }
02907     }
02908   }
02909 #else
02910   /* If IDMA Context, disable Internal DMA */
02911   hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA;
02912 #endif
02913 
02914   hmmc->State = HAL_MMC_STATE_READY;
02915 
02916   /* Initialize the MMC operation */
02917   hmmc->Context = MMC_CONTEXT_NONE;
02918 
02919   CardState = HAL_MMC_GetCardState(hmmc);
02920   if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
02921   {
02922     hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
02923   }
02924   if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
02925   {
02926     return HAL_ERROR;
02927   }
02928   return HAL_OK;
02929 }
02930 
02931 /**
02932   * @brief  Abort the current transfer and disable the MMC (IT mode).
02933   * @param  hmmc pointer to a MMC_HandleTypeDef structure that contains
02934   *                the configuration information for MMC module.
02935   * @retval HAL status
02936   */
02937 HAL_StatusTypeDef HAL_MMC_Abort_IT(MMC_HandleTypeDef *hmmc)
02938 {
02939   HAL_MMC_CardStateTypeDef CardState;
02940 
02941   /* DIsable All interrupts */
02942   __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\
02943                            SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR);
02944 
02945 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
02946   /* If IDMA Context, disable Internal DMA */
02947   hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA;
02948 #endif
02949 
02950   /* Clear All flags */
02951   __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
02952 
02953 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
02954   if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL))
02955   {
02956     /* Disable the MMC DMA request */
02957     hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN);
02958 
02959     /* Abort the MMC DMA Tx Stream */
02960     if(hmmc->hdmatx != NULL)
02961     {
02962       hmmc->hdmatx->XferAbortCallback =  MMC_DMATxAbort;
02963       if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
02964       {
02965         hmmc->hdmatx = NULL;
02966       }
02967     }
02968     /* Abort the MMC DMA Rx Stream */
02969     if(hmmc->hdmarx != NULL)
02970     {
02971       hmmc->hdmarx->XferAbortCallback =  MMC_DMARxAbort;
02972       if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
02973       {
02974         hmmc->hdmarx = NULL;
02975       }
02976     }
02977   }
02978 
02979   /* No transfer ongoing on both DMA channels*/
02980   if((hmmc->hdmatx == NULL) && (hmmc->hdmarx == NULL))
02981   {
02982 #endif
02983     CardState = HAL_MMC_GetCardState(hmmc);
02984     hmmc->State = HAL_MMC_STATE_READY;
02985 
02986     if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
02987     {
02988       hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
02989     }
02990     if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
02991     {
02992       return HAL_ERROR;
02993     }
02994     else
02995     {
02996 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
02997       hmmc->AbortCpltCallback(hmmc);
02998 #else
02999       HAL_MMC_AbortCallback(hmmc);
03000 #endif
03001 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
03002     }
03003 #endif
03004   }
03005 
03006   return HAL_OK;
03007 }
03008 
03009 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
03010 /**
03011   * @brief  Perform specific commands sequence for the different type of erase.
03012   * @note   This API should be followed by a check on the card state through
03013   *         HAL_MMC_GetCardState().
03014   * @param  hmmc Pointer to MMC handle
03015   * @param  EraseType Specifies the type of erase to be performed
03016   *          This parameter can be one of the following values:
03017   *            @arg HAL_MMC_ERASE Erase the erase groups identified by CMD35 & 36
03018   *            @arg HAL_MMC_TRIM Erase the write blocks identified by CMD35 & 36
03019   *            @arg HAL_MMC_DISCARD Discard the write blocks identified by CMD35 & 36
03020   *            @arg HAL_MMC_SECURE_ERASE Perform a secure purge according SRT on the erase groups identified by CMD35 & 36
03021   *            @arg HAL_MMC_SECURE_TRIM_STEP1 Mark the write blocks identified by CMD35 & 36 for secure erase
03022   *            @arg HAL_MMC_SECURE_TRIM_STEP2 Perform a secure purge according SRT on the write blocks previously identified
03023   * @param  BlockStartAdd Start Block address
03024   * @param  BlockEndAdd End Block address
03025   * @retval HAL status
03026   */
03027 HAL_StatusTypeDef HAL_MMC_EraseSequence(MMC_HandleTypeDef *hmmc, uint32_t EraseType, uint32_t BlockStartAdd, uint32_t BlockEndAdd)
03028 {
03029   uint32_t errorstate;
03030   uint32_t start_add = BlockStartAdd;
03031   uint32_t end_add = BlockEndAdd;
03032   uint32_t tickstart = HAL_GetTick();
03033 
03034   /* Check the erase type value is correct */
03035   assert_param(IS_MMC_ERASE_TYPE(EraseType));
03036 
03037   /* Check the coherence between start and end address */
03038   if(end_add < start_add)
03039   {
03040     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
03041     return HAL_ERROR;
03042   }
03043 
03044   /* Check that the end address is not out of range of device memory */
03045   if(end_add > (hmmc->MmcCard.LogBlockNbr))
03046   {
03047     hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
03048     return HAL_ERROR;
03049   }
03050 
03051   /* Check if the card command class supports erase command */
03052   if(((hmmc->MmcCard.Class) & SDMMC_CCCC_ERASE) == 0U)
03053   {
03054     hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
03055     return HAL_ERROR;
03056   }
03057 
03058   /* Check the state of the driver */
03059   if(hmmc->State == HAL_MMC_STATE_READY)
03060   {
03061     /* Change State */
03062     hmmc->State = HAL_MMC_STATE_BUSY;
03063 
03064     /* Check that the card is not locked */
03065     if((SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
03066     {
03067       hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED;
03068       hmmc->State = HAL_MMC_STATE_READY;
03069       return HAL_ERROR;
03070     }
03071 
03072     /* In case of low capacity card, the address is not block number but bytes */
03073     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
03074     {
03075       start_add *= 512U;
03076       end_add   *= 512U;
03077     }
03078 
03079     /* Send CMD35 MMC_ERASE_GRP_START with start address as argument */
03080     errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, start_add);
03081     if(errorstate == HAL_MMC_ERROR_NONE)
03082     {
03083       /* Send CMD36 MMC_ERASE_GRP_END with end address as argument */
03084       errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, end_add);
03085       if(errorstate == HAL_MMC_ERROR_NONE)
03086       {
03087         /* Send CMD38 ERASE with erase type as argument */
03088         errorstate = SDMMC_CmdErase(hmmc->Instance, EraseType);
03089         if(errorstate == HAL_MMC_ERROR_NONE)
03090         {
03091           if ((EraseType == HAL_MMC_SECURE_ERASE) || (EraseType == HAL_MMC_SECURE_TRIM_STEP2))
03092           {
03093             /* Wait that the device is ready by checking the D0 line */
03094             while((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
03095             {
03096               if((HAL_GetTick()-tickstart) >= SDMMC_MAXERASETIMEOUT)
03097               {
03098                 errorstate = HAL_MMC_ERROR_TIMEOUT;
03099               }
03100             }
03101 
03102             /* Clear the flag corresponding to end D0 bus line */
03103             __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
03104           }
03105         }
03106       }
03107     }
03108 
03109     /* Change State */
03110     hmmc->State = HAL_MMC_STATE_READY;
03111 
03112     /* Manage errors */
03113     if(errorstate != HAL_MMC_ERROR_NONE)
03114     {
03115       /* Clear all the static flags */
03116       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
03117       hmmc->ErrorCode |= errorstate;
03118 
03119       if(errorstate != HAL_MMC_ERROR_TIMEOUT)
03120       {
03121         return HAL_ERROR;
03122       }
03123       else
03124       {
03125         return HAL_TIMEOUT;
03126       }
03127     }
03128     else
03129     {
03130       return HAL_OK;
03131     }
03132   }
03133   else
03134   {
03135     return HAL_BUSY;
03136   }
03137 }
03138 
03139 /**
03140   * @brief  Perform sanitize operation on the device.
03141   * @note   This API should be followed by a check on the card state through
03142   *         HAL_MMC_GetCardState().
03143   * @param  hmmc Pointer to MMC handle
03144   * @retval HAL status
03145   */
03146 HAL_StatusTypeDef HAL_MMC_Sanitize(MMC_HandleTypeDef *hmmc)
03147 {
03148   uint32_t errorstate, response = 0U, count;
03149   uint32_t tickstart = HAL_GetTick();
03150 
03151   /* Check the state of the driver */
03152   if(hmmc->State == HAL_MMC_STATE_READY)
03153   {
03154     /* Change State */
03155     hmmc->State = HAL_MMC_STATE_BUSY;
03156 
03157     /* Index : 165 - Value : 0x01 */
03158     errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03A50100U);
03159     if(errorstate == HAL_MMC_ERROR_NONE)
03160     {
03161       /* Wait that the device is ready by checking the D0 line */
03162       while((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
03163       {
03164         if((HAL_GetTick()-tickstart) >= SDMMC_MAXERASETIMEOUT)
03165         {
03166           errorstate = HAL_MMC_ERROR_TIMEOUT;
03167         }
03168       }
03169 
03170       /* Clear the flag corresponding to end D0 bus line */
03171       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
03172 
03173       if(errorstate == HAL_MMC_ERROR_NONE)
03174       {
03175         /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
03176         count = SDMMC_MAX_TRIAL;
03177         do
03178         {
03179           errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
03180           if(errorstate != HAL_MMC_ERROR_NONE)
03181           {
03182             break;
03183           }
03184 
03185           /* Get command response */
03186           response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
03187           count--;
03188         }while(((response & 0x100U) == 0U) && (count != 0U));
03189 
03190         /* Check the status after the switch command execution */
03191         if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
03192         {
03193           /* Check the bit SWITCH_ERROR of the device status */
03194           if ((response & 0x80U) != 0U)
03195           {
03196             errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
03197           }
03198         }
03199         else if (count == 0U)
03200         {
03201           errorstate = SDMMC_ERROR_TIMEOUT;
03202         }
03203         else
03204         {
03205           /* Nothing to do */
03206         }
03207       }
03208     }
03209 
03210     /* Change State */
03211     hmmc->State = HAL_MMC_STATE_READY;
03212 
03213     /* Manage errors */
03214     if(errorstate != HAL_MMC_ERROR_NONE)
03215     {
03216       /* Clear all the static flags */
03217       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
03218       hmmc->ErrorCode |= errorstate;
03219 
03220       if(errorstate != HAL_MMC_ERROR_TIMEOUT)
03221       {
03222         return HAL_ERROR;
03223       }
03224       else
03225       {
03226         return HAL_TIMEOUT;
03227       }
03228     }
03229     else
03230     {
03231       return HAL_OK;
03232     }
03233   }
03234   else
03235   {
03236     return HAL_BUSY;
03237   }
03238 }
03239 
03240 /**
03241   * @brief  Configure the Secure Removal Type (SRT) in the Extended CSD register.
03242   * @note   This API should be followed by a check on the card state through
03243   *         HAL_MMC_GetCardState().
03244   * @param  hmmc Pointer to MMC handle
03245   * @param  SRTMode Specifies the type of erase to be performed
03246   *          This parameter can be one of the following values:
03247   *            @arg HAL_MMC_SRT_ERASE Information removed by an erase
03248   *            @arg HAL_MMC_SRT_WRITE_CHAR_ERASE Information removed by an overwriting with a character followed by an erase
03249   *            @arg HAL_MMC_SRT_WRITE_CHAR_COMPL_RANDOM Information removed by an overwriting with a character, its complement then a random character
03250   *            @arg HAL_MMC_SRT_VENDOR_DEFINED Information removed using a vendor defined
03251   * @retval HAL status
03252   */
03253 HAL_StatusTypeDef HAL_MMC_ConfigSecRemovalType(MMC_HandleTypeDef *hmmc, uint32_t SRTMode)
03254 {
03255   uint32_t srt, errorstate, response = 0U, count;
03256 
03257   /* Check the erase type value is correct */
03258   assert_param(IS_MMC_SRT_TYPE(SRTMode));
03259 
03260   /* Check the state of the driver */
03261   if(hmmc->State == HAL_MMC_STATE_READY)
03262   {
03263     /* Get the supported values by the device */
03264     if(HAL_MMC_GetSupportedSecRemovalType(hmmc, &srt) == HAL_OK)
03265     {
03266       /* Change State */
03267       hmmc->State = HAL_MMC_STATE_BUSY;
03268 
03269       /* Check the value passed as parameter is supported by the device */
03270       if((SRTMode & srt) != 0U)
03271       {
03272         /* Index : 16 - Value : SRTMode */
03273         srt |= ((POSITION_VAL(SRTMode)) << 4U);
03274         errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03100000U | (srt << 8U)));
03275         if(errorstate == HAL_MMC_ERROR_NONE)
03276         {
03277           /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
03278           count = SDMMC_MAX_TRIAL;
03279           do
03280           {
03281             errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
03282             if(errorstate != HAL_MMC_ERROR_NONE)
03283             {
03284               break;
03285             }
03286 
03287             /* Get command response */
03288             response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
03289             count--;
03290           }while(((response & 0x100U) == 0U) && (count != 0U));
03291 
03292           /* Check the status after the switch command execution */
03293           if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
03294           {
03295             /* Check the bit SWITCH_ERROR of the device status */
03296             if ((response & 0x80U) != 0U)
03297             {
03298               errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
03299             }
03300           }
03301           else if (count == 0U)
03302           {
03303             errorstate = SDMMC_ERROR_TIMEOUT;
03304           }
03305           else
03306           {
03307             /* Nothing to do */
03308           }
03309         }
03310       }
03311       else
03312       {
03313         errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
03314       }
03315 
03316       /* Change State */
03317       hmmc->State = HAL_MMC_STATE_READY;
03318     }
03319     else
03320     {
03321       errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
03322     }
03323 
03324     /* Manage errors */
03325     if(errorstate != HAL_MMC_ERROR_NONE)
03326     {
03327       /* Clear all the static flags */
03328       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
03329       hmmc->ErrorCode |= errorstate;
03330       return HAL_ERROR;
03331     }
03332     else
03333     {
03334       return HAL_OK;
03335     }
03336   }
03337   else
03338   {
03339     return HAL_BUSY;
03340   }
03341 }
03342 
03343 /**
03344   * @brief  Gets the supported values of the the Secure Removal Type (SRT).
03345   * @param  hmmc pointer to MMC handle
03346   * @param  SupportedSRT pointer for supported SRT value
03347   *          This parameter is a bit field of the following values:
03348   *            @arg HAL_MMC_SRT_ERASE Information removed by an erase
03349   *            @arg HAL_MMC_SRT_WRITE_CHAR_ERASE Information removed by an overwriting with a character followed by an erase
03350   *            @arg HAL_MMC_SRT_WRITE_CHAR_COMPL_RANDOM Information removed by an overwriting with a character, its complement then a random character
03351   *            @arg HAL_MMC_SRT_VENDOR_DEFINED Information removed using a vendor defined
03352   * @retval HAL status
03353   */
03354 HAL_StatusTypeDef HAL_MMC_GetSupportedSecRemovalType(MMC_HandleTypeDef *hmmc, uint32_t *SupportedSRT)
03355 {
03356   /* Check the state of the driver */
03357   if(hmmc->State == HAL_MMC_STATE_READY)
03358   {
03359     /* Change State */
03360     hmmc->State = HAL_MMC_STATE_BUSY;
03361 
03362     /* Read field SECURE_REMOVAL_TYPE [16 = 4*4] of the Extended CSD register */
03363     *SupportedSRT = (hmmc->Ext_CSD[4] & 0x0000000FU); /* Bits [3:0] of field 16 */
03364 
03365     /* Change State */
03366     hmmc->State = HAL_MMC_STATE_READY;
03367 
03368     return HAL_OK;
03369   }
03370   else
03371   {
03372     return HAL_BUSY;
03373   }
03374 }
03375 
03376 /**
03377   * @brief  Switch the device from Standby State to Sleep State.
03378   * @param  hmmc pointer to MMC handle
03379   * @retval HAL status
03380   */
03381 HAL_StatusTypeDef HAL_MMC_SleepDevice(MMC_HandleTypeDef *hmmc)
03382 {
03383   uint32_t errorstate, sleep_timeout, timeout, count, response = 0U;
03384   uint32_t tickstart = HAL_GetTick();
03385 
03386   /* Check the state of the driver */
03387   if(hmmc->State == HAL_MMC_STATE_READY)
03388   {
03389     /* Change State */
03390     hmmc->State = HAL_MMC_STATE_BUSY;
03391 
03392     /* Set the power-off notification to powered-on : Ext_CSD[34] = 1 */
03393     errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03220100U));
03394     if (errorstate == HAL_MMC_ERROR_NONE)
03395     {
03396       /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
03397       count = SDMMC_MAX_TRIAL;
03398       do
03399       {
03400         errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
03401         if(errorstate != HAL_MMC_ERROR_NONE)
03402         {
03403           break;
03404         }
03405 
03406         /* Get command response */
03407         response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
03408         count--;
03409       }while(((response & 0x100U) == 0U) && (count != 0U));
03410 
03411       /* Check the status after the switch command execution */
03412       if (count == 0U)
03413       {
03414         errorstate = SDMMC_ERROR_TIMEOUT;
03415       }
03416       else if (errorstate == HAL_MMC_ERROR_NONE)
03417       {
03418         /* Check the bit SWITCH_ERROR of the device status */
03419         if ((response & 0x80U) != 0U)
03420         {
03421           errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
03422         }
03423         else
03424         {
03425           /* Set the power-off notification to sleep notification : Ext_CSD[34] = 4 */
03426           errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03220400U));
03427           if (errorstate == HAL_MMC_ERROR_NONE)
03428           {
03429             /* Field SLEEP_NOTIFICATION_TIME [216] */
03430             sleep_timeout = ((hmmc->Ext_CSD[(MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_INDEX/4)] >> MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_POS) & 0x000000FFU);
03431 
03432             /* Sleep/Awake Timeout = 10µs * 2^SLEEP_NOTIFICATION_TIME, max value of SLEEP_NOTIFICATION_TIME is 0x17 */
03433             /* In HAL, the tick interrupt occurs each ms */
03434             timeout = (((1UL << (sleep_timeout & 0x1FU)) / 100U) + 1U);
03435 
03436             /* Wait that the device is ready by checking the D0 line */
03437             while((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
03438             {
03439               if((HAL_GetTick() - tickstart) >= timeout)
03440               {
03441                 errorstate = SDMMC_ERROR_TIMEOUT;
03442               }
03443             }
03444 
03445             /* Clear the flag corresponding to end D0 bus line */
03446             __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
03447 
03448             if (errorstate == HAL_MMC_ERROR_NONE)
03449             {
03450               /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
03451               count = SDMMC_MAX_TRIAL;
03452               do
03453               {
03454                 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
03455                 if(errorstate != HAL_MMC_ERROR_NONE)
03456                 {
03457                   break;
03458                 }
03459 
03460                 /* Get command response */
03461                 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
03462                 count--;
03463               }while(((response & 0x100U) == 0U) && (count != 0U));
03464 
03465               /* Check the status after the switch command execution */
03466               if (count == 0U)
03467               {
03468                 errorstate = SDMMC_ERROR_TIMEOUT;
03469               }
03470               else if (errorstate == HAL_MMC_ERROR_NONE)
03471               {
03472                 /* Check the bit SWITCH_ERROR of the device status */
03473                 if ((response & 0x80U) != 0U)
03474                 {
03475                   errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
03476                 }
03477                 else
03478                 {
03479                   /* Switch the device in stand-by mode */
03480                   (void)SDMMC_CmdSelDesel(hmmc->Instance, 0U);
03481 
03482                   /* Field S_A_TIEMOUT [217] */
03483                   sleep_timeout = ((hmmc->Ext_CSD[(MMC_EXT_CSD_S_A_TIMEOUT_INDEX/4)] >> MMC_EXT_CSD_S_A_TIMEOUT_POS) & 0x000000FFU);
03484 
03485                   /* Sleep/Awake Timeout = 100ns * 2^S_A_TIMEOUT, max value of S_A_TIMEOUT is 0x17 */
03486                   /* In HAL, the tick interrupt occurs each ms */
03487                   timeout = (((1UL << (sleep_timeout & 0x1FU)) / 10000U) + 1U);
03488 
03489                   if (HAL_MMC_GetCardState(hmmc) == HAL_MMC_CARD_STANDBY)
03490                   {
03491                     /* Send CMD5 CMD_MMC_SLEEP_AWAKE with RCA and SLEEP as argument */
03492                     errorstate = SDMMC_CmdSleepMmc(hmmc->Instance, ((hmmc->MmcCard.RelCardAdd << 16U) | (0x1U << 15U)));
03493                     if (errorstate == HAL_MMC_ERROR_NONE)
03494                     {
03495                       /* Wait that the device is ready by checking the D0 line */
03496                       while((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
03497                       {
03498                         if((HAL_GetTick() - tickstart) >= timeout)
03499                         {
03500                           errorstate = SDMMC_ERROR_TIMEOUT;
03501                         }
03502                       }
03503 
03504                       /* Clear the flag corresponding to end D0 bus line */
03505                       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
03506                     }
03507                   }
03508                   else
03509                   {
03510                     errorstate = SDMMC_ERROR_REQUEST_NOT_APPLICABLE;
03511                   }
03512                 }
03513               }
03514               else
03515               {
03516                 /* Nothing to do */
03517               }
03518             }
03519           }
03520         }
03521       }
03522       else
03523       {
03524         /* Nothing to do */
03525       }
03526     }
03527 
03528     /* Change State */
03529     hmmc->State = HAL_MMC_STATE_READY;
03530 
03531     /* Manage errors */
03532     if (errorstate != HAL_MMC_ERROR_NONE)
03533     {
03534       /* Clear all the static flags */
03535       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
03536       hmmc->ErrorCode |= errorstate;
03537 
03538       if (errorstate != HAL_MMC_ERROR_TIMEOUT)
03539       {
03540         return HAL_ERROR;
03541       }
03542       else
03543       {
03544         return HAL_TIMEOUT;
03545       }
03546     }
03547     else
03548     {
03549       return HAL_OK;
03550     }
03551   }
03552   else
03553   {
03554     return HAL_BUSY;
03555   }
03556 }
03557 
03558 /**
03559   * @brief  Switch the device from Sleep State to Standby State.
03560   * @param  hmmc pointer to MMC handle
03561   * @retval HAL status
03562   */
03563 HAL_StatusTypeDef HAL_MMC_AwakeDevice(MMC_HandleTypeDef *hmmc)
03564 {
03565   uint32_t errorstate, sleep_timeout, timeout, count, response = 0U;
03566   uint32_t tickstart = HAL_GetTick();
03567 
03568   /* Check the state of the driver */
03569   if (hmmc->State == HAL_MMC_STATE_READY)
03570   {
03571     /* Change State */
03572     hmmc->State = HAL_MMC_STATE_BUSY;
03573 
03574     /* Field S_A_TIEMOUT [217] */
03575     sleep_timeout = ((hmmc->Ext_CSD[(MMC_EXT_CSD_S_A_TIMEOUT_INDEX/4)] >> MMC_EXT_CSD_S_A_TIMEOUT_POS) & 0x000000FFU);
03576 
03577     /* Sleep/Awake Timeout = 100ns * 2^S_A_TIMEOUT, max value of S_A_TIMEOUT is 0x17 */
03578     /* In HAL, the tick interrupt occurs each ms */
03579     timeout = (((1UL << (sleep_timeout & 0x1FU)) / 10000U) + 1U);
03580 
03581     /* Send CMD5 CMD_MMC_SLEEP_AWAKE with RCA and AWAKE as argument */
03582     errorstate = SDMMC_CmdSleepMmc(hmmc->Instance, (hmmc->MmcCard.RelCardAdd << 16U));
03583     if (errorstate == HAL_MMC_ERROR_NONE)
03584     {
03585       /* Wait that the device is ready by checking the D0 line */
03586       while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
03587       {
03588         if((HAL_GetTick() - tickstart) >= timeout)
03589         {
03590           errorstate = SDMMC_ERROR_TIMEOUT;
03591         }
03592       }
03593 
03594       /* Clear the flag corresponding to end D0 bus line */
03595       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
03596 
03597       if (errorstate == HAL_MMC_ERROR_NONE)
03598       {
03599         if (HAL_MMC_GetCardState(hmmc) == HAL_MMC_CARD_STANDBY)
03600         {
03601           /* Switch the device in transfer mode */
03602           errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
03603           if (errorstate == HAL_MMC_ERROR_NONE)
03604           {
03605             if (HAL_MMC_GetCardState(hmmc) == HAL_MMC_CARD_TRANSFER)
03606             {
03607               /* Set the power-off notification to powered-on : Ext_CSD[34] = 1 */
03608               errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03220100U));
03609               if (errorstate == HAL_MMC_ERROR_NONE)
03610               {
03611                 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
03612                 count = SDMMC_MAX_TRIAL;
03613                 do
03614                 {
03615                   errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
03616                   if(errorstate != HAL_MMC_ERROR_NONE)
03617                   {
03618                     break;
03619                   }
03620 
03621                   /* Get command response */
03622                   response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
03623                   count--;
03624                 }while(((response & 0x100U) == 0U) && (count != 0U));
03625 
03626                 /* Check the status after the switch command execution */
03627                 if (count == 0U)
03628                 {
03629                   errorstate = SDMMC_ERROR_TIMEOUT;
03630                 }
03631                 else if (errorstate == HAL_MMC_ERROR_NONE)
03632                 {
03633                   /* Check the bit SWITCH_ERROR of the device status */
03634                   if ((response & 0x80U) != 0U)
03635                   {
03636                     errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
03637                   }
03638                 }
03639                 else
03640                 {
03641                   /* Nothing to do */
03642                 }
03643               }
03644             }
03645             else
03646             {
03647               errorstate = SDMMC_ERROR_REQUEST_NOT_APPLICABLE;
03648             }
03649           }
03650         }
03651         else
03652         {
03653           errorstate = SDMMC_ERROR_REQUEST_NOT_APPLICABLE;
03654         }
03655       }
03656     }
03657 
03658     /* Change State */
03659     hmmc->State = HAL_MMC_STATE_READY;
03660 
03661     /* Manage errors */
03662     if (errorstate != HAL_MMC_ERROR_NONE)
03663     {
03664       /* Clear all the static flags */
03665       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
03666       hmmc->ErrorCode |= errorstate;
03667 
03668       if (errorstate != HAL_MMC_ERROR_TIMEOUT)
03669       {
03670         return HAL_ERROR;
03671       }
03672       else
03673       {
03674         return HAL_TIMEOUT;
03675       }
03676     }
03677     else
03678     {
03679       return HAL_OK;
03680     }
03681   }
03682   else
03683   {
03684     return HAL_BUSY;
03685   }
03686 }
03687 #endif /* defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) */
03688 
03689 /**
03690   * @}
03691   */
03692 
03693 /**
03694   * @}
03695   */
03696 
03697 /* Private function ----------------------------------------------------------*/
03698 /** @addtogroup MMC_Private_Functions
03699   * @{
03700   */
03701 
03702 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
03703 /**
03704   * @brief  DMA MMC transmit process complete callback
03705   * @param  hdma DMA handle
03706   * @retval None
03707   */
03708 static void MMC_DMATransmitCplt(DMA_HandleTypeDef *hdma)
03709 {
03710   MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
03711 
03712   /* Enable DATAEND Interrupt */
03713   __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DATAEND));
03714 }
03715 
03716 /**
03717   * @brief  DMA MMC receive process complete callback
03718   * @param  hdma DMA handle
03719   * @retval None
03720   */
03721 static void MMC_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
03722 {
03723   MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
03724   uint32_t errorstate;
03725 
03726   /* Send stop command in multiblock write */
03727   if(hmmc->Context == (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA))
03728   {
03729     errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
03730     if(errorstate != HAL_MMC_ERROR_NONE)
03731     {
03732       hmmc->ErrorCode |= errorstate;
03733 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
03734       hmmc->ErrorCallback(hmmc);
03735 #else
03736       HAL_MMC_ErrorCallback(hmmc);
03737 #endif
03738     }
03739   }
03740 
03741   /* Disable the DMA transfer for transmit request by setting the DMAEN bit
03742   in the MMC DCTRL register */
03743   hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN);
03744 
03745   /* Clear all the static flags */
03746   __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
03747 
03748   hmmc->State = HAL_MMC_STATE_READY;
03749   hmmc->Context = MMC_CONTEXT_NONE;
03750 
03751 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
03752   hmmc->RxCpltCallback(hmmc);
03753 #else
03754   HAL_MMC_RxCpltCallback(hmmc);
03755 #endif
03756 }
03757 
03758 /**
03759   * @brief  DMA MMC communication error callback
03760   * @param  hdma DMA handle
03761   * @retval None
03762   */
03763 static void MMC_DMAError(DMA_HandleTypeDef *hdma)
03764 {
03765   MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
03766   HAL_MMC_CardStateTypeDef CardState;
03767   uint32_t RxErrorCode, TxErrorCode;
03768 
03769   RxErrorCode = hmmc->hdmarx->ErrorCode;
03770   TxErrorCode = hmmc->hdmatx->ErrorCode;
03771   if((RxErrorCode == HAL_DMA_ERROR_TE) || (TxErrorCode == HAL_DMA_ERROR_TE))
03772   {
03773     /* Clear All flags */
03774     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
03775 
03776     /* Disable All interrupts */
03777     __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\
03778       SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR);
03779 
03780     hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
03781     CardState = HAL_MMC_GetCardState(hmmc);
03782     if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
03783     {
03784       hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
03785     }
03786 
03787     hmmc->State= HAL_MMC_STATE_READY;
03788     hmmc->Context = MMC_CONTEXT_NONE;
03789   }
03790 
03791 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
03792   hmmc->ErrorCallback(hmmc);
03793 #else
03794   HAL_MMC_ErrorCallback(hmmc);
03795 #endif
03796   }
03797 
03798 /**
03799   * @brief  DMA MMC Tx Abort callback
03800   * @param  hdma DMA handle
03801   * @retval None
03802   */
03803 static void MMC_DMATxAbort(DMA_HandleTypeDef *hdma)
03804 {
03805   MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
03806   HAL_MMC_CardStateTypeDef CardState;
03807 
03808   if(hmmc->hdmatx != NULL)
03809   {
03810     hmmc->hdmatx = NULL;
03811   }
03812 
03813   /* All DMA channels are aborted */
03814   if(hmmc->hdmarx == NULL)
03815   {
03816     CardState = HAL_MMC_GetCardState(hmmc);
03817     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
03818     hmmc->State = HAL_MMC_STATE_READY;
03819     hmmc->Context = MMC_CONTEXT_NONE;
03820     if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
03821     {
03822       hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
03823 
03824       if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
03825       {
03826 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
03827         hmmc->AbortCpltCallback(hmmc);
03828 #else
03829         HAL_MMC_AbortCallback(hmmc);
03830 #endif
03831       }
03832       else
03833       {
03834 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
03835         hmmc->ErrorCallback(hmmc);
03836 #else
03837         HAL_MMC_ErrorCallback(hmmc);
03838 #endif
03839       }
03840     }
03841   }
03842 }
03843 
03844 /**
03845   * @brief  DMA MMC Rx Abort callback
03846   * @param  hdma DMA handle
03847   * @retval None
03848   */
03849 static void MMC_DMARxAbort(DMA_HandleTypeDef *hdma)
03850 {
03851   MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
03852   HAL_MMC_CardStateTypeDef CardState;
03853 
03854   if(hmmc->hdmarx != NULL)
03855   {
03856     hmmc->hdmarx = NULL;
03857   }
03858 
03859   /* All DMA channels are aborted */
03860   if(hmmc->hdmatx == NULL)
03861   {
03862     CardState = HAL_MMC_GetCardState(hmmc);
03863     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
03864     hmmc->State = HAL_MMC_STATE_READY;
03865     hmmc->Context = MMC_CONTEXT_NONE;
03866     if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
03867     {
03868       hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
03869 
03870       if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
03871       {
03872 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
03873         hmmc->AbortCpltCallback(hmmc);
03874 #else
03875         HAL_MMC_AbortCallback(hmmc);
03876 #endif
03877       }
03878       else
03879       {
03880 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
03881         hmmc->ErrorCallback(hmmc);
03882 #else
03883         HAL_MMC_ErrorCallback(hmmc);
03884 #endif
03885       }
03886     }
03887   }
03888 }
03889 #endif
03890 
03891 /**
03892   * @brief  Initializes the mmc card.
03893   * @param  hmmc Pointer to MMC handle
03894   * @retval MMC Card error state
03895   */
03896 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc)
03897 {
03898   HAL_MMC_CardCSDTypeDef CSD;
03899   uint32_t errorstate;
03900   uint16_t mmc_rca = 2U;
03901   MMC_InitTypeDef Init;
03902 
03903   /* Check the power State */
03904   if(SDMMC_GetPowerState(hmmc->Instance) == 0U)
03905   {
03906     /* Power off */
03907     return HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
03908   }
03909 
03910   /* Send CMD2 ALL_SEND_CID */
03911   errorstate = SDMMC_CmdSendCID(hmmc->Instance);
03912   if(errorstate != HAL_MMC_ERROR_NONE)
03913   {
03914     return errorstate;
03915   }
03916   else
03917   {
03918     /* Get Card identification number data */
03919     hmmc->CID[0U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
03920     hmmc->CID[1U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2);
03921     hmmc->CID[2U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP3);
03922     hmmc->CID[3U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP4);
03923   }
03924 
03925   /* Send CMD3 SET_REL_ADDR with RCA = 2 (should be greater than 1) */
03926   /* MMC Card publishes its RCA. */
03927   errorstate = SDMMC_CmdSetRelAddMmc(hmmc->Instance, mmc_rca);
03928   if(errorstate != HAL_MMC_ERROR_NONE)
03929   {
03930     return errorstate;
03931   }
03932 
03933   /* Get the MMC card RCA */
03934   hmmc->MmcCard.RelCardAdd = mmc_rca;
03935 
03936   /* Send CMD9 SEND_CSD with argument as card's RCA */
03937   errorstate = SDMMC_CmdSendCSD(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
03938   if(errorstate != HAL_MMC_ERROR_NONE)
03939   {
03940     return errorstate;
03941   }
03942   else
03943   {
03944     /* Get Card Specific Data */
03945     hmmc->CSD[0U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
03946     hmmc->CSD[1U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2);
03947     hmmc->CSD[2U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP3);
03948     hmmc->CSD[3U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP4);
03949   }
03950 
03951   /* Get the Card Class */
03952   hmmc->MmcCard.Class = (SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2) >> 20U);
03953 
03954    /* Select the Card */
03955   errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
03956   if(errorstate != HAL_MMC_ERROR_NONE)
03957   {
03958     return errorstate;
03959   }
03960 
03961   /* Get CSD parameters */
03962   if (HAL_MMC_GetCardCSD(hmmc, &CSD) != HAL_OK)
03963   {
03964     return hmmc->ErrorCode;
03965   }
03966 
03967   /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
03968   errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
03969   if(errorstate != HAL_MMC_ERROR_NONE)
03970   {
03971     hmmc->ErrorCode |= errorstate;
03972   }
03973 
03974   /* Get Extended CSD parameters */
03975   if (HAL_MMC_GetCardExtCSD(hmmc, hmmc->Ext_CSD, SDMMC_DATATIMEOUT) != HAL_OK)
03976   {
03977     return hmmc->ErrorCode;
03978   }
03979 
03980   /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
03981   errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
03982   if(errorstate != HAL_MMC_ERROR_NONE)
03983   {
03984     hmmc->ErrorCode |= errorstate;
03985   }
03986 
03987   /* Configure the SDMMC peripheral */
03988   Init = hmmc->Init;
03989   Init.BusWide = SDMMC_BUS_WIDE_1B;
03990   (void)SDMMC_Init(hmmc->Instance, Init);
03991 
03992   /* All cards are initialized */
03993   return HAL_MMC_ERROR_NONE;
03994 }
03995 
03996 /**
03997   * @brief  Enquires cards about their operating voltage and configures clock
03998   *         controls and stores MMC information that will be needed in future
03999   *         in the MMC handle.
04000   * @param  hmmc Pointer to MMC handle
04001   * @retval error state
04002   */
04003 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc)
04004 {
04005   __IO uint32_t count = 0U;
04006   uint32_t response = 0U, validvoltage = 0U;
04007   uint32_t errorstate;
04008 
04009   /* CMD0: GO_IDLE_STATE */
04010   errorstate = SDMMC_CmdGoIdleState(hmmc->Instance);
04011   if(errorstate != HAL_MMC_ERROR_NONE)
04012   {
04013     return errorstate;
04014   }
04015 
04016   while(validvoltage == 0U)
04017   {
04018     if(count++ == SDMMC_MAX_VOLT_TRIAL)
04019     {
04020       return HAL_MMC_ERROR_INVALID_VOLTRANGE;
04021     }
04022 
04023     /* SEND CMD1 APP_CMD with voltage range as argument */
04024     errorstate = SDMMC_CmdOpCondition(hmmc->Instance, MMC_VOLTAGE_RANGE);
04025     if(errorstate != HAL_MMC_ERROR_NONE)
04026     {
04027       return HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
04028     }
04029 
04030     /* Get command response */
04031     response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
04032 
04033     /* Get operating voltage*/
04034     validvoltage = (((response >> 31U) == 1U) ? 1U : 0U);
04035   }
04036 
04037   /* When power routine is finished and command returns valid voltage */
04038   if (((response & (0xFF000000U)) >> 24) == 0xC0U)
04039   {
04040     hmmc->MmcCard.CardType = MMC_HIGH_CAPACITY_CARD;
04041   }
04042   else
04043   {
04044     hmmc->MmcCard.CardType = MMC_LOW_CAPACITY_CARD;
04045   }
04046 
04047   return HAL_MMC_ERROR_NONE;
04048 }
04049 
04050 /**
04051   * @brief  Turns the SDMMC output signals off.
04052   * @param  hmmc Pointer to MMC handle
04053   * @retval None
04054   */
04055 static void MMC_PowerOFF(MMC_HandleTypeDef *hmmc)
04056 {
04057   /* Set Power State to OFF */
04058   (void)SDMMC_PowerState_OFF(hmmc->Instance);
04059 }
04060 
04061 /**
04062   * @brief  Returns the current card's status.
04063   * @param  hmmc Pointer to MMC handle
04064   * @param  pCardStatus pointer to the buffer that will contain the MMC card
04065   *         status (Card Status register)
04066   * @retval error state
04067   */
04068 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus)
04069 {
04070   uint32_t errorstate;
04071 
04072   if(pCardStatus == NULL)
04073   {
04074     return HAL_MMC_ERROR_PARAM;
04075   }
04076 
04077   /* Send Status command */
04078   errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
04079   if(errorstate != HAL_MMC_ERROR_NONE)
04080   {
04081     return errorstate;
04082   }
04083 
04084   /* Get MMC card status */
04085   *pCardStatus = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
04086 
04087   return HAL_MMC_ERROR_NONE;
04088 }
04089 
04090 /**
04091   * @brief  Reads extended CSD register to get the sectors number of the device
04092   * @param  hmmc Pointer to MMC handle
04093   * @param  pFieldData Pointer to the read buffer
04094   * @param  FieldIndex Index of the field to be read
04095   * @param  Timeout Specify timeout value
04096   * @retval HAL status
04097   */
04098 static HAL_StatusTypeDef MMC_ReadExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pFieldData, uint16_t FieldIndex, uint32_t Timeout)
04099 {
04100   SDMMC_DataInitTypeDef config;
04101   uint32_t errorstate;
04102   uint32_t tickstart = HAL_GetTick();
04103   uint32_t count;
04104   uint32_t i = 0;
04105   uint32_t tmp_data;
04106 
04107   hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
04108 
04109   /* Initialize data control register */
04110   hmmc->Instance->DCTRL = 0;
04111 
04112   /* Configure the MMC DPSM (Data Path State Machine) */
04113   config.DataTimeOut   = SDMMC_DATATIMEOUT;
04114   config.DataLength    = 512;
04115   config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
04116   config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
04117   config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
04118   config.DPSM          = SDMMC_DPSM_ENABLE;
04119   (void)SDMMC_ConfigData(hmmc->Instance, &config);
04120 
04121   /* Set Block Size for Card */
04122   errorstate = SDMMC_CmdSendEXTCSD(hmmc->Instance, 0);
04123   if(errorstate != HAL_MMC_ERROR_NONE)
04124   {
04125     /* Clear all the static flags */
04126     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
04127     hmmc->ErrorCode |= errorstate;
04128     hmmc->State = HAL_MMC_STATE_READY;
04129     return HAL_ERROR;
04130   }
04131 
04132   /* Poll on SDMMC flags */
04133   while(!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
04134   {
04135     if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF))
04136     {
04137       /* Read data from SDMMC Rx FIFO */
04138       for(count = 0U; count < 8U; count++)
04139       {
04140         tmp_data = SDMMC_ReadFIFO(hmmc->Instance);
04141         /* eg : SEC_COUNT   : FieldIndex = 212 => i+count = 53 */
04142         /*      DEVICE_TYPE : FieldIndex = 196 => i+count = 49 */
04143         if ((i + count) == ((uint32_t)FieldIndex/4U))
04144         {
04145           *pFieldData = tmp_data;
04146         }
04147       }
04148       i += 8U;
04149     }
04150 
04151     if(((HAL_GetTick()-tickstart) >=  Timeout) || (Timeout == 0U))
04152     {
04153       /* Clear all the static flags */
04154       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
04155       hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
04156       hmmc->State= HAL_MMC_STATE_READY;
04157       return HAL_TIMEOUT;
04158     }
04159   }
04160 
04161   /* Get error state */
04162   if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
04163   {
04164     /* Clear all the static flags */
04165     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
04166     hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
04167     hmmc->State = HAL_MMC_STATE_READY;
04168     return HAL_ERROR;
04169   }
04170   else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
04171   {
04172     /* Clear all the static flags */
04173     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
04174     hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
04175     hmmc->State = HAL_MMC_STATE_READY;
04176     return HAL_ERROR;
04177   }
04178   else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR))
04179   {
04180     /* Clear all the static flags */
04181     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
04182     hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
04183     hmmc->State = HAL_MMC_STATE_READY;
04184     return HAL_ERROR;
04185   }
04186   else
04187   {
04188     /* Nothing to do */
04189   }
04190 
04191   /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
04192   errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16));
04193   if(errorstate != HAL_MMC_ERROR_NONE)
04194   {
04195     hmmc->ErrorCode |= errorstate;
04196   }
04197 
04198   /* Clear all the static flags */
04199   __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
04200 
04201   hmmc->State = HAL_MMC_STATE_READY;
04202 
04203   return HAL_OK;
04204 }
04205 
04206 /**
04207   * @brief  Wrap up reading in non-blocking mode.
04208   * @param  hmmc pointer to a MMC_HandleTypeDef structure that contains
04209   *              the configuration information.
04210   * @retval None
04211   */
04212 static void MMC_Read_IT(MMC_HandleTypeDef *hmmc)
04213 {
04214   uint32_t count, data, dataremaining;
04215   uint8_t* tmp;
04216 
04217   tmp = hmmc->pRxBuffPtr;
04218   dataremaining = hmmc->RxXferSize;
04219 
04220   if (dataremaining > 0U)
04221   {
04222     /* Read data from SDMMC Rx FIFO */
04223     for(count = 0U; count < 8U; count++)
04224     {
04225       data = SDMMC_ReadFIFO(hmmc->Instance);
04226       *tmp = (uint8_t)(data & 0xFFU);
04227       tmp++;
04228       dataremaining--;
04229       *tmp = (uint8_t)((data >> 8U) & 0xFFU);
04230       tmp++;
04231       dataremaining--;
04232       *tmp = (uint8_t)((data >> 16U) & 0xFFU);
04233       tmp++;
04234       dataremaining--;
04235       *tmp = (uint8_t)((data >> 24U) & 0xFFU);
04236       tmp++;
04237       dataremaining--;
04238     }
04239 
04240     hmmc->pRxBuffPtr = tmp;
04241     hmmc->RxXferSize = dataremaining;
04242   }
04243 }
04244 
04245 /**
04246   * @brief  Wrap up writing in non-blocking mode.
04247   * @param  hmmc pointer to a MMC_HandleTypeDef structure that contains
04248   *              the configuration information.
04249   * @retval None
04250   */
04251 static void MMC_Write_IT(MMC_HandleTypeDef *hmmc)
04252 {
04253   uint32_t count, data, dataremaining;
04254   uint8_t* tmp;
04255 
04256   tmp = hmmc->pTxBuffPtr;
04257   dataremaining = hmmc->TxXferSize;
04258 
04259   if (dataremaining > 0U)
04260   {
04261     /* Write data to SDMMC Tx FIFO */
04262     for(count = 0U; count < 8U; count++)
04263     {
04264       data = (uint32_t)(*tmp);
04265       tmp++;
04266       dataremaining--;
04267       data |= ((uint32_t)(*tmp) << 8U);
04268       tmp++;
04269       dataremaining--;
04270       data |= ((uint32_t)(*tmp) << 16U);
04271       tmp++;
04272       dataremaining--;
04273       data |= ((uint32_t)(*tmp) << 24U);
04274       tmp++;
04275       dataremaining--;
04276       (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
04277     }
04278 
04279     hmmc->pTxBuffPtr = tmp;
04280     hmmc->TxXferSize = dataremaining;
04281   }
04282 }
04283 
04284 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
04285 /**
04286   * @brief  Switches the MMC card to high speed mode.
04287   * @param  hmmc MMC handle
04288   * @param  state State of high speed mode
04289   * @retval MMC Card error state
04290   */
04291 static uint32_t MMC_HighSpeed(MMC_HandleTypeDef *hmmc, FunctionalState state)
04292 {
04293   uint32_t errorstate = HAL_MMC_ERROR_NONE;
04294   uint32_t response = 0U, count;
04295   uint32_t sdmmc_clk;
04296   SDMMC_InitTypeDef Init;
04297 
04298   if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) != 0U) && (state == DISABLE))
04299   {
04300     errorstate = MMC_PwrClassUpdate(hmmc, (hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS), SDMMC_SPEED_MODE_DEFAULT);
04301     if(errorstate == HAL_MMC_ERROR_NONE)
04302     {
04303       /* Index : 185 - Value : 0 */
04304       errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B90000U);
04305     }
04306   }
04307 
04308   if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) == 0U) && (state != DISABLE))
04309   {
04310     errorstate = MMC_PwrClassUpdate(hmmc, (hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS), SDMMC_SPEED_MODE_HIGH);
04311     if(errorstate == HAL_MMC_ERROR_NONE)
04312     {
04313       /* Index : 185 - Value : 1 */
04314       errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B90100U);
04315     }
04316   }
04317 
04318   if(errorstate == HAL_MMC_ERROR_NONE)
04319   {
04320     /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
04321     count = SDMMC_MAX_TRIAL;
04322     do
04323     {
04324       errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
04325       if(errorstate != HAL_MMC_ERROR_NONE)
04326       {
04327         break;
04328       }
04329 
04330       /* Get command response */
04331       response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
04332       count--;
04333     }while(((response & 0x100U) == 0U) && (count != 0U));
04334 
04335     /* Check the status after the switch command execution */
04336     if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
04337     {
04338       /* Check the bit SWITCH_ERROR of the device status */
04339       if ((response & 0x80U) != 0U)
04340       {
04341         errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
04342       }
04343       else
04344       {
04345         /* Configure high speed */
04346         Init.ClockEdge           = hmmc->Init.ClockEdge;
04347         Init.ClockPowerSave      = hmmc->Init.ClockPowerSave;
04348         Init.BusWide             = (hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS);
04349         Init.HardwareFlowControl = hmmc->Init.HardwareFlowControl;
04350 
04351         if (state == DISABLE)
04352         {
04353           Init.ClockDiv = hmmc->Init.ClockDiv;
04354           (void)SDMMC_Init(hmmc->Instance, Init);
04355 
04356           CLEAR_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_BUSSPEED);
04357         }
04358         else
04359         {
04360           /* High Speed Clock should be less or equal to 52MHz*/
04361           sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC1);
04362           if (sdmmc_clk == 0U)
04363           {
04364             errorstate = SDMMC_ERROR_INVALID_PARAMETER;
04365           }
04366           else
04367           {
04368             Init.ClockDiv = sdmmc_clk/(2U*MMC_HIGH_SPEED_FREQ);
04369             (void)SDMMC_Init(hmmc->Instance, Init);
04370 
04371             SET_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_BUSSPEED);
04372           }
04373         }
04374       }
04375     }
04376     else if (count == 0U)
04377     {
04378       errorstate = SDMMC_ERROR_TIMEOUT;
04379     }
04380     else
04381     {
04382       /* Nothing to do */
04383     }
04384   }
04385 
04386   return errorstate;
04387 }
04388 
04389 /**
04390   * @brief  Switches the MMC card to Double Data Rate (DDR) mode.
04391   * @param  hmmc MMC handle
04392   * @param  state State of DDR mode
04393   * @retval MMC Card error state
04394   */
04395 static uint32_t MMC_DDR_Mode(MMC_HandleTypeDef *hmmc, FunctionalState state)
04396 {
04397   uint32_t errorstate = HAL_MMC_ERROR_NONE;
04398   uint32_t response = 0U, count;
04399 
04400   if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) != 0U) && (state == DISABLE))
04401   {
04402     if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS_0) != 0U)
04403     {
04404       errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_4B, SDMMC_SPEED_MODE_HIGH);
04405       if(errorstate == HAL_MMC_ERROR_NONE)
04406       {
04407         /* Index : 183 - Value : 1 */
04408         errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U);
04409       }
04410     }
04411     else
04412     {
04413       errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_8B, SDMMC_SPEED_MODE_HIGH);
04414       if(errorstate == HAL_MMC_ERROR_NONE)
04415       {
04416         /* Index : 183 - Value : 2 */
04417         errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U);
04418       }
04419     }
04420   }
04421 
04422   if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) == 0U) && (state != DISABLE))
04423   {
04424     if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS_0) != 0U)
04425     {
04426       errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_4B, SDMMC_SPEED_MODE_DDR);
04427       if(errorstate == HAL_MMC_ERROR_NONE)
04428       {
04429         /* Index : 183 - Value : 5 */
04430         errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70500U);
04431       }
04432     }
04433     else
04434     {
04435       errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_8B, SDMMC_SPEED_MODE_DDR);
04436       if(errorstate == HAL_MMC_ERROR_NONE)
04437       {
04438         /* Index : 183 - Value : 6 */
04439         errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70600U);
04440       }
04441     }
04442   }
04443 
04444   if(errorstate == HAL_MMC_ERROR_NONE)
04445   {
04446     /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
04447     count = SDMMC_MAX_TRIAL;
04448     do
04449     {
04450       errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
04451       if(errorstate != HAL_MMC_ERROR_NONE)
04452       {
04453         break;
04454       }
04455 
04456       /* Get command response */
04457       response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
04458       count--;
04459     }while(((response & 0x100U) == 0U) && (count != 0U));
04460 
04461     /* Check the status after the switch command execution */
04462     if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
04463     {
04464       /* Check the bit SWITCH_ERROR of the device status */
04465       if ((response & 0x80U) != 0U)
04466       {
04467         errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
04468       }
04469       else
04470       {
04471         /* Configure DDR mode */
04472         if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
04473         {
04474           if (state == DISABLE)
04475           {
04476             CLEAR_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_DDR);
04477           }
04478           else
04479           {
04480             SET_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_DDR);
04481           }
04482         }
04483       }
04484     }
04485     else if (count == 0U)
04486     {
04487       errorstate = SDMMC_ERROR_TIMEOUT;
04488     }
04489     else
04490     {
04491       /* Nothing to do */
04492     }
04493   }
04494 
04495   return errorstate;
04496 }
04497 #endif
04498 
04499 /**
04500   * @brief  Update the power class of the device.
04501   * @param  hmmc MMC handle
04502   * @param  Wide Wide of MMC bus
04503   * @param  Speed Speed of the MMC bus
04504   * @retval MMC Card error state
04505   */
04506 static uint32_t MMC_PwrClassUpdate(MMC_HandleTypeDef *hmmc, uint32_t Wide, uint32_t Speed)
04507 {
04508   uint32_t count;
04509   uint32_t response = 0U;
04510   uint32_t errorstate = HAL_MMC_ERROR_NONE;
04511   uint32_t power_class, supported_pwr_class;
04512 
04513   if((Wide == SDMMC_BUS_WIDE_8B) || (Wide == SDMMC_BUS_WIDE_4B))
04514   {
04515     power_class = 0U; /* Default value after power-on or software reset */
04516 
04517     /* Read the PowerClass field of the Extended CSD register */
04518     if(MMC_ReadExtCSD(hmmc, &power_class, 187, SDMMC_DATATIMEOUT) != HAL_OK) /* Field POWER_CLASS [187] */
04519     {
04520       errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
04521     }
04522     else
04523     {
04524       power_class = ((power_class >> 24U) & 0x000000FFU);
04525     }
04526 
04527     /* Get the supported PowerClass field of the Extended CSD register */
04528 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
04529     if (Speed == SDMMC_SPEED_MODE_DDR)
04530     {
04531       /* Field PWR_CL_DDR_52_xxx [238 or 239] */
04532       supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_DDR_52_INDEX/4)] >> MMC_EXT_CSD_PWR_CL_DDR_52_POS) & 0x000000FFU);
04533     }
04534     else if (Speed == SDMMC_SPEED_MODE_HIGH)
04535     {
04536       /* Field PWR_CL_52_xxx [200 or 202] */
04537       supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_52_INDEX/4)] >> MMC_EXT_CSD_PWR_CL_52_POS) & 0x000000FFU);
04538     }
04539     else
04540 #endif
04541     {
04542       /* Field PWR_CL_26_xxx [201 or 203] */
04543       supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_26_INDEX/4)] >> MMC_EXT_CSD_PWR_CL_26_POS) & 0x000000FFU);
04544     }
04545 
04546     if(errorstate == HAL_MMC_ERROR_NONE)
04547     {
04548       if(Wide == SDMMC_BUS_WIDE_8B)
04549       {
04550         /* Bit [7:4] : power class for 8-bits bus configuration - Bit [3:0] : power class for 4-bits bus configuration */
04551         supported_pwr_class = (supported_pwr_class >> 4U);
04552       }
04553 
04554       if ((power_class & 0x0FU) != (supported_pwr_class & 0x0FU))
04555       {
04556         /* Need to change current power class */
04557         errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03BB0000U | ((supported_pwr_class & 0x0FU) << 8U)));
04558 
04559         if(errorstate == HAL_MMC_ERROR_NONE)
04560         {
04561           /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
04562           count = SDMMC_MAX_TRIAL;
04563           do
04564           {
04565             errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
04566             if(errorstate != HAL_MMC_ERROR_NONE)
04567             {
04568               break;
04569             }
04570 
04571             /* Get command response */
04572             response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
04573             count--;
04574           }while(((response & 0x100U) == 0U) && (count != 0U));
04575 
04576           /* Check the status after the switch command execution */
04577           if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
04578           {
04579             /* Check the bit SWITCH_ERROR of the device status */
04580             if ((response & 0x80U) != 0U)
04581             {
04582               errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
04583             }
04584           }
04585           else if (count == 0U)
04586           {
04587             errorstate = SDMMC_ERROR_TIMEOUT;
04588           }
04589           else
04590           {
04591             /* Nothing to do */
04592           }
04593         }
04594       }
04595     }
04596   }
04597 
04598   return errorstate;
04599 }
04600 /**
04601   * @}
04602   */
04603 
04604 /**
04605   * @}
04606   */
04607 
04608 /**
04609   * @}
04610   */
04611 
04612 #endif /* HAL_MMC_MODULE_ENABLED */
04613 
04614 #endif /* SDMMC1 */