STM32F103xB HAL User Manual
stm32f1xx_hal_mmc.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f1xx_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   @verbatim
00014   ==============================================================================
00015                         ##### How to use this driver #####
00016   ==============================================================================
00017   [..]
00018     This driver implements a high level communication layer for read and write from/to
00019     this memory. The needed STM32 hardware resources (SDMMC and GPIO) are performed by
00020     the user in HAL_MMC_MspInit() function (MSP layer).
00021     Basically, the MSP layer configuration should be the same as we provide in the
00022     examples.
00023     You can easily tailor this configuration according to hardware resources.
00024 
00025   [..]
00026     This driver is a generic layered driver for SDMMC memories which uses the HAL
00027     SDMMC driver functions to interface with MMC and eMMC cards devices.
00028     It is used as follows:
00029 
00030     (#)Initialize the SDMMC low level resources by implement the HAL_MMC_MspInit() API:
00031         (##) Enable the SDMMC interface clock using __HAL_RCC_SDMMC_CLK_ENABLE();
00032         (##) SDMMC pins configuration for MMC card
00033             (+++) Enable the clock for the SDMMC GPIOs using the functions __HAL_RCC_GPIOx_CLK_ENABLE();
00034             (+++) Configure these SDMMC pins as alternate function pull-up using HAL_GPIO_Init()
00035                   and according to your pin assignment;
00036         (##) DMA Configuration if you need to use DMA process (HAL_MMC_ReadBlocks_DMA()
00037              and HAL_MMC_WriteBlocks_DMA() APIs).
00038             (+++) Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE(); 
00039             (+++) Configure the DMA using the function HAL_DMA_Init() with predeclared and filled. 
00040         (##) NVIC configuration if you need to use interrupt process when using DMA transfer.
00041             (+++) Configure the SDMMC and DMA interrupt priorities using function HAL_NVIC_SetPriority();
00042                   DMA priority is superior to SDMMC's priority
00043             (+++) Enable the NVIC DMA and SDMMC IRQs using function HAL_NVIC_EnableIRQ()
00044             (+++) SDMMC interrupts are managed using the macros __HAL_MMC_ENABLE_IT() 
00045                   and __HAL_MMC_DISABLE_IT() inside the communication process.
00046             (+++) SDMMC interrupts pending bits are managed using the macros __HAL_MMC_GET_IT()
00047                   and __HAL_MMC_CLEAR_IT()
00048         (##) NVIC configuration if you need to use interrupt process (HAL_MMC_ReadBlocks_IT()
00049              and HAL_MMC_WriteBlocks_IT() APIs).
00050             (+++) Configure the SDMMC interrupt priorities using function HAL_NVIC_SetPriority();
00051             (+++) Enable the NVIC SDMMC IRQs using function HAL_NVIC_EnableIRQ()
00052             (+++) SDMMC interrupts are managed using the macros __HAL_MMC_ENABLE_IT()
00053                   and __HAL_MMC_DISABLE_IT() inside the communication process.
00054             (+++) SDMMC interrupts pending bits are managed using the macros __HAL_MMC_GET_IT()
00055                   and __HAL_MMC_CLEAR_IT()
00056     (#) At this stage, you can perform MMC read/write/erase operations after MMC card initialization
00057 
00058 
00059   *** MMC Card Initialization and configuration ***
00060   ================================================
00061   [..]
00062     To initialize the MMC Card, use the HAL_MMC_Init() function. It Initializes
00063     SDMMC Peripheral (STM32 side) and the MMC Card, and put it into StandBy State (Ready for data transfer).
00064     This function provide the following operations:
00065 
00066     (#) Initialize the SDMMC peripheral interface with defaullt configuration.
00067         The initialization process is done at 400KHz. You can change or adapt
00068         this frequency by adjusting the "ClockDiv" field.
00069         The MMC Card frequency (SDMMC_CK) is computed as follows:
00070 
00071            SDMMC_CK = SDMMCCLK / (ClockDiv + 2)
00072 
00073         In initialization mode and according to the MMC Card standard,
00074         make sure that the SDMMC_CK frequency doesn't exceed 400KHz.
00075 
00076         This phase of initialization is done through SDMMC_Init() and
00077         SDMMC_PowerState_ON() SDMMC low level APIs.
00078 
00079     (#) Initialize the MMC card. The API used is HAL_MMC_InitCard().
00080         This phase allows the card initialization and identification
00081         and check the MMC Card type (Standard Capacity or High Capacity)
00082         The initialization flow is compatible with MMC standard.
00083 
00084         This API (HAL_MMC_InitCard()) could be used also to reinitialize the card in case
00085         of plug-off plug-in.
00086   
00087     (#) Configure the MMC Card Data transfer frequency. By Default, the card transfer
00088         frequency is set to 24MHz. You can change or adapt this frequency by adjusting 
00089         the "ClockDiv" field.
00090         In transfer mode and according to the MMC Card standard, make sure that the
00091         SDMMC_CK frequency doesn't exceed 25MHz and 50MHz in High-speed mode switch.
00092         To be able to use a frequency higher than 24MHz, you should use the SDMMC
00093         peripheral in bypass mode. Refer to the corresponding reference manual
00094         for more details.
00095 
00096     (#) Select the corresponding MMC Card according to the address read with the step 2.
00097 
00098     (#) Configure the MMC Card in wide bus mode: 4-bits data.
00099 
00100   *** MMC Card Read operation ***
00101   ==============================
00102   [..]
00103     (+) You can read from MMC card in polling mode by using function HAL_MMC_ReadBlocks().
00104         This function support only 512-bytes block length (the block size should be
00105         chosen as 512 bytes).
00106         You can choose either one block read operation or multiple block read operation
00107         by adjusting the "NumberOfBlocks" parameter.
00108         After this, you have to ensure that the transfer is done correctly. The check is done
00109         through HAL_MMC_GetCardState() function for MMC card state.
00110 
00111     (+) You can read from MMC card in DMA mode by using function HAL_MMC_ReadBlocks_DMA().
00112         This function support only 512-bytes block length (the block size should be
00113         chosen as 512 bytes).
00114         You can choose either one block read operation or multiple block read operation
00115         by adjusting the "NumberOfBlocks" parameter.
00116         After this, you have to ensure that the transfer is done correctly. The check is done
00117         through HAL_MMC_GetCardState() function for MMC card state.
00118         You could also check the DMA transfer process through the MMC Rx interrupt event.
00119 
00120     (+) You can read from MMC card in Interrupt mode by using function HAL_MMC_ReadBlocks_IT().
00121         This function allows the read of 512 bytes blocks.
00122         You can choose either one block read operation or multiple block read operation 
00123         by adjusting the "NumberOfBlocks" parameter.
00124         After this, you have to ensure that the transfer is done correctly. The check is done
00125         through HAL_MMC_GetCardState() function for MMC card state.
00126         You could also check the IT transfer process through the MMC Rx interrupt event.
00127 
00128   *** MMC Card Write operation ***
00129   ===============================
00130   [..]
00131     (+) You can write to MMC card in polling mode by using function HAL_MMC_WriteBlocks().
00132         This function support only 512-bytes block length (the block size should be
00133         chosen as 512 bytes).
00134         You can choose either one block read operation or multiple block read operation
00135         by adjusting the "NumberOfBlocks" parameter.
00136         After this, you have to ensure that the transfer is done correctly. The check is done
00137         through HAL_MMC_GetCardState() function for MMC card state.
00138 
00139     (+) You can write to MMC card in DMA mode by using function HAL_MMC_WriteBlocks_DMA().
00140         This function support only 512-bytes block length (the block size should be
00141         chosen as 512 byte).
00142         You can choose either one block read operation or multiple block read operation
00143         by adjusting the "NumberOfBlocks" parameter.
00144         After this, you have to ensure that the transfer is done correctly. The check is done
00145         through HAL_MMC_GetCardState() function for MMC card state.
00146         You could also check the DMA transfer process through the MMC Tx interrupt event.  
00147 
00148     (+) You can write to MMC card in Interrupt mode by using function HAL_MMC_WriteBlocks_IT().
00149         This function allows the read of 512 bytes blocks.
00150         You can choose either one block read operation or multiple block read operation 
00151         by adjusting the "NumberOfBlocks" parameter.
00152         After this, you have to ensure that the transfer is done correctly. The check is done
00153         through HAL_MMC_GetCardState() function for MMC card state.
00154         You could also check the IT transfer process through the MMC Tx interrupt event.
00155 
00156   *** MMC card information ***
00157   =========================== 
00158   [..]
00159     (+) To get MMC card information, you can use the function HAL_MMC_GetCardInfo().
00160         It returns useful information about the MMC card such as block size, card type,
00161         block number ...
00162 
00163   *** MMC card CSD register ***
00164   ============================
00165   [..]
00166     (+) The HAL_MMC_GetCardCSD() API allows to get the parameters of the CSD register.
00167         Some of the CSD parameters are useful for card initialization and identification.
00168 
00169   *** MMC card CID register ***
00170   ============================
00171   [..]
00172     (+) The HAL_MMC_GetCardCID() API allows to get the parameters of the CID register.
00173         Some of the CID parameters are useful for card initialization and identification.
00174 
00175   *** MMC HAL driver macros list ***
00176   ==================================
00177   [..]
00178     Below the list of most used macros in MMC HAL driver.
00179 
00180     (+) __HAL_MMC_ENABLE : Enable the MMC device
00181     (+) __HAL_MMC_DISABLE : Disable the MMC device
00182     (+) __HAL_MMC_DMA_ENABLE: Enable the SDMMC DMA transfer
00183     (+) __HAL_MMC_DMA_DISABLE: Disable the SDMMC DMA transfer
00184     (+) __HAL_MMC_ENABLE_IT: Enable the MMC device interrupt
00185     (+) __HAL_MMC_DISABLE_IT: Disable the MMC device interrupt
00186     (+) __HAL_MMC_GET_FLAG:Check whether the specified MMC flag is set or not
00187     (+) __HAL_MMC_CLEAR_FLAG: Clear the MMC's pending flags
00188 
00189   [..]
00190     (@) You can refer to the MMC HAL driver header file for more useful macros
00191 
00192   *** Callback registration ***
00193   =============================================
00194   [..]
00195     The compilation define USE_HAL_MMC_REGISTER_CALLBACKS when set to 1
00196     allows the user to configure dynamically the driver callbacks.
00197 
00198     Use Functions @ref HAL_MMC_RegisterCallback() to register a user callback,
00199     it allows to register following callbacks:
00200       (+) TxCpltCallback : callback when a transmission transfer is completed.
00201       (+) RxCpltCallback : callback when a reception transfer is completed.
00202       (+) ErrorCallback : callback when error occurs.
00203       (+) AbortCpltCallback : callback when abort is completed.
00204       (+) MspInitCallback    : MMC MspInit.
00205       (+) MspDeInitCallback  : MMC MspDeInit.
00206     This function takes as parameters the HAL peripheral handle, the Callback ID
00207     and a pointer to the user callback function.
00208 
00209     Use function @ref HAL_MMC_UnRegisterCallback() to reset a callback to the default
00210     weak (surcharged) function. It allows to reset following callbacks:
00211       (+) TxCpltCallback : callback when a transmission transfer is completed.
00212       (+) RxCpltCallback : callback when a reception transfer is completed.
00213       (+) ErrorCallback : callback when error occurs.
00214       (+) AbortCpltCallback : callback when abort is completed.
00215       (+) MspInitCallback    : MMC MspInit.
00216       (+) MspDeInitCallback  : MMC MspDeInit.
00217     This function) takes as parameters the HAL peripheral handle and the Callback ID.
00218 
00219     By default, after the @ref HAL_MMC_Init and if the state is HAL_MMC_STATE_RESET
00220     all callbacks are reset to the corresponding legacy weak (surcharged) functions.
00221     Exception done for MspInit and MspDeInit callbacks that are respectively
00222     reset to the legacy weak (surcharged) functions in the @ref HAL_MMC_Init
00223     and @ref  HAL_MMC_DeInit only when these callbacks are null (not registered beforehand).
00224     If not, MspInit or MspDeInit are not null, the @ref HAL_MMC_Init and @ref HAL_MMC_DeInit
00225     keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
00226 
00227     Callbacks can be registered/unregistered in READY state only.
00228     Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
00229     in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
00230     during the Init/DeInit.
00231     In that case first register the MspInit/MspDeInit user callbacks
00232     using @ref HAL_MMC_RegisterCallback before calling @ref HAL_MMC_DeInit
00233     or @ref HAL_MMC_Init function.
00234 
00235     When The compilation define USE_HAL_MMC_REGISTER_CALLBACKS is set to 0 or
00236     not defined, the callback registering feature is not available
00237     and weak (surcharged) callbacks are used.
00238 
00239   @endverbatim
00240   ******************************************************************************
00241   * @attention
00242   *
00243   * <h2><center>&copy; Copyright (c) 2018 STMicroelectronics.
00244   * All rights reserved.</center></h2>
00245   *
00246   * This software component is licensed by ST under BSD 3-Clause license,
00247   * the "License"; You may not use this file except in compliance with the
00248   * License. You may obtain a copy of the License at:
00249   *                       opensource.org/licenses/BSD-3-Clause
00250   *
00251   ******************************************************************************
00252   */
00253 
00254 /* Includes ------------------------------------------------------------------*/
00255 #include "stm32f1xx_hal.h"
00256 
00257 /** @addtogroup STM32F1xx_HAL_Driver
00258   * @{
00259   */
00260 
00261 /** @defgroup MMC MMC
00262   * @brief MMC HAL module driver
00263   * @{
00264   */
00265 
00266 #ifdef HAL_MMC_MODULE_ENABLED
00267 
00268 #if defined(SDIO)
00269 
00270 /* Private typedef -----------------------------------------------------------*/
00271 /* Private define ------------------------------------------------------------*/
00272 /** @addtogroup MMC_Private_Defines
00273   * @{
00274   */
00275 
00276 /**
00277   * @}
00278   */
00279 
00280 /* Private macro -------------------------------------------------------------*/
00281 /* Private variables ---------------------------------------------------------*/
00282 /* Private function prototypes -----------------------------------------------*/
00283 /* Private functions ---------------------------------------------------------*/
00284 /** @defgroup MMC_Private_Functions MMC Private Functions
00285   * @{
00286   */
00287 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc);
00288 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc);
00289 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus);
00290 static uint32_t MMC_ReadExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pFieldData, uint16_t FieldIndex, uint32_t Timeout);
00291 static void     MMC_PowerOFF(MMC_HandleTypeDef *hmmc);
00292 static void     MMC_Write_IT(MMC_HandleTypeDef *hmmc);
00293 static void     MMC_Read_IT(MMC_HandleTypeDef *hmmc);
00294 static void     MMC_DMATransmitCplt(DMA_HandleTypeDef *hdma);
00295 static void     MMC_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
00296 static void     MMC_DMAError(DMA_HandleTypeDef *hdma);
00297 static void     MMC_DMATxAbort(DMA_HandleTypeDef *hdma);
00298 static void     MMC_DMARxAbort(DMA_HandleTypeDef *hdma);
00299 /**
00300   * @}
00301   */
00302 /* Exported functions --------------------------------------------------------*/
00303 /** @addtogroup MMC_Exported_Functions
00304   * @{
00305   */
00306 
00307 /** @addtogroup MMC_Exported_Functions_Group1
00308  *  @brief   Initialization and de-initialization functions
00309  *
00310 @verbatim
00311   ==============================================================================
00312           ##### Initialization and de-initialization functions #####
00313   ==============================================================================
00314   [..]
00315     This section provides functions allowing to initialize/de-initialize the MMC
00316     card device to be ready for use.
00317 
00318 @endverbatim
00319   * @{
00320   */
00321 
00322 /**
00323   * @brief  Initializes the MMC according to the specified parameters in the
00324             MMC_HandleTypeDef and create the associated handle.
00325   * @param  hmmc: Pointer to the MMC handle
00326   * @retval HAL status
00327   */
00328 HAL_StatusTypeDef HAL_MMC_Init(MMC_HandleTypeDef *hmmc)
00329 {
00330   /* Check the MMC handle allocation */
00331   if(hmmc == NULL)
00332   {
00333     return HAL_ERROR;
00334   }
00335 
00336   /* Check the parameters */
00337   assert_param(IS_SDIO_ALL_INSTANCE(hmmc->Instance));
00338   assert_param(IS_SDIO_CLOCK_EDGE(hmmc->Init.ClockEdge));
00339   assert_param(IS_SDIO_CLOCK_BYPASS(hmmc->Init.ClockBypass));
00340   assert_param(IS_SDIO_CLOCK_POWER_SAVE(hmmc->Init.ClockPowerSave));
00341   assert_param(IS_SDIO_BUS_WIDE(hmmc->Init.BusWide));
00342   assert_param(IS_SDIO_HARDWARE_FLOW_CONTROL(hmmc->Init.HardwareFlowControl));
00343   assert_param(IS_SDIO_CLKDIV(hmmc->Init.ClockDiv));
00344 
00345   if(hmmc->State == HAL_MMC_STATE_RESET)
00346   {
00347     /* Allocate lock resource and initialize it */
00348     hmmc->Lock = HAL_UNLOCKED;
00349 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
00350     /* Reset Callback pointers in HAL_MMC_STATE_RESET only */
00351     hmmc->TxCpltCallback    = HAL_MMC_TxCpltCallback;
00352     hmmc->RxCpltCallback    = HAL_MMC_RxCpltCallback;
00353     hmmc->ErrorCallback     = HAL_MMC_ErrorCallback;
00354     hmmc->AbortCpltCallback = HAL_MMC_AbortCallback;
00355 
00356     if(hmmc->MspInitCallback == NULL)
00357     {
00358       hmmc->MspInitCallback = HAL_MMC_MspInit;
00359     }
00360 
00361     /* Init the low level hardware */
00362     hmmc->MspInitCallback(hmmc);
00363 #else
00364     /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
00365     HAL_MMC_MspInit(hmmc);
00366 #endif
00367   }
00368 
00369   hmmc->State = HAL_MMC_STATE_BUSY;
00370 
00371   /* Initialize the Card parameters */
00372   if(HAL_MMC_InitCard(hmmc) == HAL_ERROR)
00373   {
00374     return HAL_ERROR;
00375   }
00376 
00377   /* Initialize the error code */
00378   hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
00379 
00380   /* Initialize the MMC operation */
00381   hmmc->Context = MMC_CONTEXT_NONE;
00382 
00383   /* Initialize the MMC state */
00384   hmmc->State = HAL_MMC_STATE_READY;
00385 
00386   return HAL_OK;
00387 }
00388 
00389 /**
00390   * @brief  Initializes the MMC Card.
00391   * @param  hmmc: Pointer to MMC handle
00392   * @note   This function initializes the MMC card. It could be used when a card
00393             re-initialization is needed.
00394   * @retval HAL status
00395   */
00396 HAL_StatusTypeDef HAL_MMC_InitCard(MMC_HandleTypeDef *hmmc)
00397 {
00398   uint32_t errorstate;
00399   MMC_InitTypeDef Init;
00400   HAL_StatusTypeDef status;
00401   
00402   /* Default SDIO peripheral configuration for MMC card initialization */
00403   Init.ClockEdge           = SDIO_CLOCK_EDGE_RISING;
00404   Init.ClockBypass         = SDIO_CLOCK_BYPASS_DISABLE;
00405   Init.ClockPowerSave      = SDIO_CLOCK_POWER_SAVE_DISABLE;
00406   Init.BusWide             = SDIO_BUS_WIDE_1B;
00407   Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
00408   Init.ClockDiv            = SDIO_INIT_CLK_DIV;
00409 
00410   /* Initialize SDIO peripheral interface with default configuration */
00411   status = SDIO_Init(hmmc->Instance, Init);
00412   if(status == HAL_ERROR)
00413   {
00414     return HAL_ERROR;
00415   }
00416 
00417   /* Disable SDIO Clock */
00418   __HAL_MMC_DISABLE(hmmc); 
00419   
00420   /* Set Power State to ON */
00421   status = SDIO_PowerState_ON(hmmc->Instance);
00422   if(status == HAL_ERROR)
00423   {
00424     return HAL_ERROR;
00425   }
00426 
00427   /* Enable MMC Clock */
00428   __HAL_MMC_ENABLE(hmmc);
00429 
00430   /* Identify card operating voltage */
00431   errorstate = MMC_PowerON(hmmc);
00432   if(errorstate != HAL_MMC_ERROR_NONE)
00433   {
00434     hmmc->State = HAL_MMC_STATE_READY;
00435     hmmc->ErrorCode |= errorstate;
00436     return HAL_ERROR;
00437   }
00438 
00439   /* Card initialization */
00440   errorstate = MMC_InitCard(hmmc);
00441   if(errorstate != HAL_MMC_ERROR_NONE)
00442   {
00443     hmmc->State = HAL_MMC_STATE_READY;
00444     hmmc->ErrorCode |= errorstate;
00445     return HAL_ERROR;
00446   }
00447 
00448   /* Set Block Size for Card */
00449   errorstate = SDMMC_CmdBlockLength(hmmc->Instance, MMC_BLOCKSIZE);
00450   if(errorstate != HAL_MMC_ERROR_NONE)
00451   {
00452     /* Clear all the static flags */
00453     __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
00454     hmmc->ErrorCode |= errorstate;
00455     hmmc->State = HAL_MMC_STATE_READY;
00456     return HAL_ERROR;
00457   }
00458 
00459   return HAL_OK;
00460 }
00461 
00462 /**
00463   * @brief  De-Initializes the MMC card.
00464   * @param  hmmc: Pointer to MMC handle
00465   * @retval HAL status
00466   */
00467 HAL_StatusTypeDef HAL_MMC_DeInit(MMC_HandleTypeDef *hmmc)
00468 {
00469   /* Check the MMC handle allocation */
00470   if(hmmc == NULL)
00471   {
00472     return HAL_ERROR;
00473   }
00474 
00475   /* Check the parameters */
00476   assert_param(IS_SDIO_ALL_INSTANCE(hmmc->Instance));
00477 
00478   hmmc->State = HAL_MMC_STATE_BUSY;
00479 
00480   /* Set MMC power state to off */
00481   MMC_PowerOFF(hmmc);
00482 
00483 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
00484   if(hmmc->MspDeInitCallback == NULL)
00485   {
00486     hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
00487   }
00488 
00489   /* DeInit the low level hardware */
00490   hmmc->MspDeInitCallback(hmmc);
00491 #else
00492   /* De-Initialize the MSP layer */
00493   HAL_MMC_MspDeInit(hmmc);
00494 #endif
00495 
00496   hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
00497   hmmc->State = HAL_MMC_STATE_RESET;
00498 
00499   return HAL_OK;
00500 }
00501 
00502 
00503 /**
00504   * @brief  Initializes the MMC MSP.
00505   * @param  hmmc: Pointer to MMC handle
00506   * @retval None
00507   */
00508 __weak void HAL_MMC_MspInit(MMC_HandleTypeDef *hmmc)
00509 {
00510   /* Prevent unused argument(s) compilation warning */
00511   UNUSED(hmmc);
00512 
00513   /* NOTE : This function Should not be modified, when the callback is needed,
00514             the HAL_MMC_MspInit could be implemented in the user file
00515    */
00516 }
00517 
00518 /**
00519   * @brief  De-Initialize MMC MSP.
00520   * @param  hmmc: Pointer to MMC handle
00521   * @retval None
00522   */
00523 __weak void HAL_MMC_MspDeInit(MMC_HandleTypeDef *hmmc)
00524 {
00525   /* Prevent unused argument(s) compilation warning */
00526   UNUSED(hmmc);
00527 
00528   /* NOTE : This function Should not be modified, when the callback is needed,
00529             the HAL_MMC_MspDeInit could be implemented in the user file
00530    */
00531 }
00532 
00533 /**
00534   * @}
00535   */
00536 
00537 /** @addtogroup MMC_Exported_Functions_Group2
00538  *  @brief   Data transfer functions
00539  *
00540 @verbatim
00541   ==============================================================================
00542                         ##### IO operation functions #####
00543   ==============================================================================
00544   [..]
00545     This subsection provides a set of functions allowing to manage the data
00546     transfer from/to MMC card.
00547 
00548 @endverbatim
00549   * @{
00550   */
00551 
00552 /**
00553   * @brief  Reads block(s) from a specified address in a card. The Data transfer
00554   *         is managed by polling mode.
00555   * @note   This API should be followed by a check on the card state through
00556   *         HAL_MMC_GetCardState().
00557   * @param  hmmc: Pointer to MMC handle
00558   * @param  pData: pointer to the buffer that will contain the received data
00559   * @param  BlockAdd: Block Address from where data is to be read
00560   * @param  NumberOfBlocks: Number of MMC blocks to read
00561   * @param  Timeout: Specify timeout value
00562   * @retval HAL status
00563   */
00564 HAL_StatusTypeDef HAL_MMC_ReadBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
00565 {
00566   SDIO_DataInitTypeDef config;
00567   uint32_t errorstate;
00568   uint32_t tickstart = HAL_GetTick();
00569   uint32_t count, data, dataremaining;
00570   uint32_t add = BlockAdd;
00571   uint8_t *tempbuff = pData;
00572 
00573   if(NULL == pData)
00574   {
00575     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
00576     return HAL_ERROR;
00577   }
00578 
00579   if(hmmc->State == HAL_MMC_STATE_READY)
00580   {
00581     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
00582 
00583     if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
00584     {
00585       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
00586       return HAL_ERROR;
00587     }
00588 
00589     hmmc->State = HAL_MMC_STATE_BUSY;
00590 
00591     /* Initialize data control register */
00592     hmmc->Instance->DCTRL = 0U;
00593 
00594     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
00595     {
00596       add *= 512U;
00597     }
00598 
00599     /* Configure the MMC DPSM (Data Path State Machine) */
00600     config.DataTimeOut   = SDMMC_DATATIMEOUT;
00601     config.DataLength    = NumberOfBlocks * MMC_BLOCKSIZE;
00602     config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
00603     config.TransferDir   = SDIO_TRANSFER_DIR_TO_SDIO;
00604     config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
00605     config.DPSM          = SDIO_DPSM_ENABLE;
00606     (void)SDIO_ConfigData(hmmc->Instance, &config);
00607 
00608     /* Read block(s) in polling mode */
00609     if(NumberOfBlocks > 1U)
00610     {
00611       hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
00612 
00613       /* Read Multi Block command */
00614       errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
00615     }
00616     else
00617     {
00618       hmmc->Context = MMC_CONTEXT_READ_SINGLE_BLOCK;
00619 
00620       /* Read Single Block command */
00621       errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
00622     }
00623     if(errorstate != HAL_MMC_ERROR_NONE)
00624     {
00625       /* Clear all the static flags */
00626       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
00627       hmmc->ErrorCode |= errorstate;
00628       hmmc->State = HAL_MMC_STATE_READY;
00629       return HAL_ERROR;
00630     }
00631 
00632     /* Poll on SDIO flags */
00633     dataremaining = config.DataLength;
00634     while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_FLAG_STBITERR))
00635     {
00636       if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXFIFOHF) && (dataremaining > 0U))
00637       {
00638         /* Read data from SDIO Rx FIFO */
00639         for(count = 0U; count < 8U; count++)
00640         {
00641           data = SDIO_ReadFIFO(hmmc->Instance);
00642           *tempbuff = (uint8_t)(data & 0xFFU);
00643           tempbuff++;
00644           dataremaining--;
00645           *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
00646           tempbuff++;
00647           dataremaining--;
00648           *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
00649           tempbuff++;
00650           dataremaining--;
00651           *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
00652           tempbuff++;
00653           dataremaining--;
00654         }
00655       }
00656 
00657       if(((HAL_GetTick()-tickstart) >=  Timeout) || (Timeout == 0U))
00658       {
00659         /* Clear all the static flags */
00660         __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
00661         hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
00662         hmmc->State= HAL_MMC_STATE_READY;
00663         return HAL_TIMEOUT;
00664       }
00665     }
00666 
00667     /* Send stop transmission command in case of multiblock read */
00668     if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1U))
00669     {
00670       /* Send stop transmission command */
00671       errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
00672       if(errorstate != HAL_MMC_ERROR_NONE)
00673       {
00674         /* Clear all the static flags */
00675         __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
00676         hmmc->ErrorCode |= errorstate;
00677         hmmc->State = HAL_MMC_STATE_READY;
00678         return HAL_ERROR;
00679       }
00680     }
00681 
00682     /* Get error state */
00683     if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DTIMEOUT))
00684     {
00685       /* Clear all the static flags */
00686       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
00687       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
00688       hmmc->State = HAL_MMC_STATE_READY;
00689       return HAL_ERROR;
00690     }
00691     else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL))
00692     {
00693       /* Clear all the static flags */
00694       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
00695       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
00696       hmmc->State = HAL_MMC_STATE_READY;
00697       return HAL_ERROR;
00698     }
00699     else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR))
00700     {
00701       /* Clear all the static flags */
00702       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
00703       hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
00704       hmmc->State = HAL_MMC_STATE_READY;
00705       return HAL_ERROR;
00706     }
00707     else
00708     {
00709       /* Nothing to do */
00710     }
00711 
00712     /* Empty FIFO if there is still any data */
00713     while ((__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXDAVL)) && (dataremaining > 0U))
00714     {
00715       data = SDIO_ReadFIFO(hmmc->Instance);
00716       *tempbuff = (uint8_t)(data & 0xFFU);
00717       tempbuff++;
00718       dataremaining--;
00719       *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
00720       tempbuff++;
00721       dataremaining--;
00722       *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
00723       tempbuff++;
00724       dataremaining--;
00725       *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
00726       tempbuff++;
00727       dataremaining--;
00728 
00729       if(((HAL_GetTick()-tickstart) >=  Timeout) || (Timeout == 0U))
00730       {
00731         /* Clear all the static flags */
00732         __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);        
00733         hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
00734         hmmc->State= HAL_MMC_STATE_READY;
00735         return HAL_ERROR;
00736       }
00737     }
00738 
00739     /* Clear all the static flags */
00740     __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
00741 
00742     hmmc->State = HAL_MMC_STATE_READY;
00743 
00744     return HAL_OK;
00745   }
00746   else
00747   {
00748     hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
00749     return HAL_ERROR;
00750   }
00751 }
00752 
00753 /**
00754   * @brief  Allows to write block(s) to a specified address in a card. The Data
00755   *         transfer is managed by polling mode.
00756   * @note   This API should be followed by a check on the card state through
00757   *         HAL_MMC_GetCardState().
00758   * @param  hmmc: Pointer to MMC handle
00759   * @param  pData: pointer to the buffer that will contain the data to transmit
00760   * @param  BlockAdd: Block Address where data will be written
00761   * @param  NumberOfBlocks: Number of MMC blocks to write
00762   * @param  Timeout: Specify timeout value
00763   * @retval HAL status
00764   */
00765 HAL_StatusTypeDef HAL_MMC_WriteBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
00766 {
00767   SDIO_DataInitTypeDef config;
00768   uint32_t errorstate;
00769   uint32_t tickstart = HAL_GetTick();
00770   uint32_t count, data, dataremaining;
00771   uint32_t add = BlockAdd;
00772   uint8_t *tempbuff = pData;
00773 
00774   if(NULL == pData)
00775   {
00776     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
00777     return HAL_ERROR;
00778   }
00779 
00780   if(hmmc->State == HAL_MMC_STATE_READY)
00781   {
00782     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
00783 
00784     if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
00785     {
00786       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
00787       return HAL_ERROR;
00788     }
00789 
00790     hmmc->State = HAL_MMC_STATE_BUSY;
00791 
00792     /* Initialize data control register */
00793     hmmc->Instance->DCTRL = 0U;
00794 
00795     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
00796     {
00797       add *= 512U;
00798     }
00799 
00800     /* Write Blocks in Polling mode */
00801     if(NumberOfBlocks > 1U)
00802     {
00803       hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
00804 
00805       /* Write Multi Block command */
00806       errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
00807     }
00808     else
00809     {
00810       hmmc->Context = MMC_CONTEXT_WRITE_SINGLE_BLOCK;
00811 
00812       /* Write Single Block command */
00813       errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
00814     }
00815     if(errorstate != HAL_MMC_ERROR_NONE)
00816     {
00817       /* Clear all the static flags */
00818       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
00819       hmmc->ErrorCode |= errorstate;
00820       hmmc->State = HAL_MMC_STATE_READY;
00821       return HAL_ERROR;
00822     }
00823 
00824     /* Configure the MMC DPSM (Data Path State Machine) */
00825     config.DataTimeOut   = SDMMC_DATATIMEOUT;
00826     config.DataLength    = NumberOfBlocks * MMC_BLOCKSIZE;
00827     config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
00828     config.TransferDir   = SDIO_TRANSFER_DIR_TO_CARD;
00829     config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
00830     config.DPSM          = SDIO_DPSM_ENABLE;
00831     (void)SDIO_ConfigData(hmmc->Instance, &config);
00832 
00833     /* Write block(s) in polling mode */
00834     dataremaining = config.DataLength;
00835     while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_FLAG_STBITERR))
00836     {
00837       if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXFIFOHE) && (dataremaining > 0U))
00838       {
00839         /* Write data to SDIO Tx FIFO */
00840         for(count = 0U; count < 8U; count++)
00841         {
00842           data = (uint32_t)(*tempbuff);
00843           tempbuff++;
00844           dataremaining--;
00845           data |= ((uint32_t)(*tempbuff) << 8U);
00846           tempbuff++;
00847           dataremaining--;
00848           data |= ((uint32_t)(*tempbuff) << 16U);
00849           tempbuff++;
00850           dataremaining--;
00851           data |= ((uint32_t)(*tempbuff) << 24U);
00852           tempbuff++;
00853           dataremaining--;
00854           (void)SDIO_WriteFIFO(hmmc->Instance, &data);
00855         }
00856       }
00857 
00858       if(((HAL_GetTick()-tickstart) >=  Timeout) || (Timeout == 0U))
00859       {
00860         /* Clear all the static flags */
00861         __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
00862         hmmc->ErrorCode |= errorstate;
00863         hmmc->State = HAL_MMC_STATE_READY;
00864         return HAL_TIMEOUT;
00865       }
00866     }
00867 
00868     /* Send stop transmission command in case of multiblock write */
00869     if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1U))
00870     {
00871       /* Send stop transmission command */
00872       errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
00873       if(errorstate != HAL_MMC_ERROR_NONE)
00874       {
00875         /* Clear all the static flags */
00876         __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
00877         hmmc->ErrorCode |= errorstate;
00878         hmmc->State = HAL_MMC_STATE_READY;
00879         return HAL_ERROR;
00880       }
00881     }
00882 
00883     /* Get error state */
00884     if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DTIMEOUT))
00885     {
00886       /* Clear all the static flags */
00887       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
00888       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
00889       hmmc->State = HAL_MMC_STATE_READY;
00890       return HAL_ERROR;
00891     }
00892     else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL))
00893     {
00894       /* Clear all the static flags */
00895       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
00896       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
00897       hmmc->State = HAL_MMC_STATE_READY;
00898       return HAL_ERROR;
00899     }
00900     else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR))
00901     {
00902       /* Clear all the static flags */
00903       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
00904       hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
00905       hmmc->State = HAL_MMC_STATE_READY;
00906       return HAL_ERROR;
00907     }
00908     else
00909     {
00910       /* Nothing to do */
00911     }
00912 
00913     /* Clear all the static flags */
00914     __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
00915 
00916     hmmc->State = HAL_MMC_STATE_READY;
00917 
00918     return HAL_OK;
00919   }
00920   else
00921   {
00922     hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
00923     return HAL_ERROR;
00924   }
00925 }
00926 
00927 /**
00928   * @brief  Reads block(s) from a specified address in a card. The Data transfer
00929   *         is managed in interrupt mode.
00930   * @note   This API should be followed by a check on the card state through
00931   *         HAL_MMC_GetCardState().
00932   * @note   You could also check the IT transfer process through the MMC Rx
00933   *         interrupt event.
00934   * @param  hmmc: Pointer to MMC handle
00935   * @param  pData: Pointer to the buffer that will contain the received data
00936   * @param  BlockAdd: Block Address from where data is to be read
00937   * @param  NumberOfBlocks: Number of blocks to read.
00938   * @retval HAL status
00939   */
00940 HAL_StatusTypeDef HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
00941 {
00942   SDIO_DataInitTypeDef config;
00943   uint32_t errorstate;
00944   uint32_t add = BlockAdd;
00945 
00946   if(NULL == pData)
00947   {
00948     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
00949     return HAL_ERROR;
00950   }
00951 
00952   if(hmmc->State == HAL_MMC_STATE_READY)
00953   {
00954     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
00955 
00956     if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
00957     {
00958       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
00959       return HAL_ERROR;
00960     }
00961 
00962     hmmc->State = HAL_MMC_STATE_BUSY;
00963 
00964     /* Initialize data control register */
00965     hmmc->Instance->DCTRL = 0U;
00966 
00967     hmmc->pRxBuffPtr = pData;
00968     hmmc->RxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
00969 
00970     __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_FLAG_RXFIFOHF));
00971 
00972     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
00973     {
00974       add *= 512U;
00975     }
00976 
00977     /* Configure the MMC DPSM (Data Path State Machine) */
00978     config.DataTimeOut   = SDMMC_DATATIMEOUT;
00979     config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
00980     config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
00981     config.TransferDir   = SDIO_TRANSFER_DIR_TO_SDIO;
00982     config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
00983     config.DPSM          = SDIO_DPSM_ENABLE;
00984     (void)SDIO_ConfigData(hmmc->Instance, &config);
00985 
00986     /* Read Blocks in IT mode */
00987     if(NumberOfBlocks > 1U)
00988     {
00989       hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_IT);
00990 
00991       /* Read Multi Block command */
00992       errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
00993     }
00994     else
00995     {
00996       hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_IT);
00997 
00998       /* Read Single Block command */
00999       errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
01000     }
01001 
01002     if(errorstate != HAL_MMC_ERROR_NONE)
01003     {
01004       /* Clear all the static flags */
01005       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
01006       hmmc->ErrorCode |= errorstate;
01007       hmmc->State = HAL_MMC_STATE_READY;
01008       return HAL_ERROR;
01009     }
01010 
01011     return HAL_OK;
01012   }
01013   else
01014   {
01015     return HAL_BUSY;
01016   }
01017 }
01018 
01019 /**
01020   * @brief  Writes block(s) to a specified address in a card. The Data transfer
01021   *         is managed in interrupt mode.
01022   * @note   This API should be followed by a check on the card state through
01023   *         HAL_MMC_GetCardState().
01024   * @note   You could also check the IT transfer process through the MMC Tx
01025   *         interrupt event.
01026   * @param  hmmc: Pointer to MMC handle
01027   * @param  pData: Pointer to the buffer that will contain the data to transmit
01028   * @param  BlockAdd: Block Address where data will be written
01029   * @param  NumberOfBlocks: Number of blocks to write
01030   * @retval HAL status
01031   */
01032 HAL_StatusTypeDef HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
01033 {
01034   SDIO_DataInitTypeDef config;
01035   uint32_t errorstate;
01036   uint32_t add = BlockAdd;
01037 
01038   if(NULL == pData)
01039   {
01040     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
01041     return HAL_ERROR;
01042   }
01043 
01044   if(hmmc->State == HAL_MMC_STATE_READY)
01045   {
01046     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
01047 
01048     if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
01049     {
01050       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
01051       return HAL_ERROR;
01052     }
01053 
01054     hmmc->State = HAL_MMC_STATE_BUSY;
01055 
01056     /* Initialize data control register */
01057     hmmc->Instance->DCTRL = 0U;
01058 
01059     hmmc->pTxBuffPtr = pData;
01060     hmmc->TxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
01061 
01062     /* Enable transfer interrupts */
01063     __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_DATAEND | SDIO_FLAG_TXFIFOHE));
01064 
01065     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
01066     {
01067       add *= 512U;
01068     }
01069 
01070     /* Write Blocks in Polling mode */
01071     if(NumberOfBlocks > 1U)
01072     {
01073       hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK| MMC_CONTEXT_IT);
01074 
01075       /* Write Multi Block command */
01076       errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
01077     }
01078     else
01079     {
01080       hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_IT);
01081 
01082       /* Write Single Block command */
01083       errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
01084     }
01085     if(errorstate != HAL_MMC_ERROR_NONE)
01086     {
01087       /* Clear all the static flags */
01088       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
01089       hmmc->ErrorCode |= errorstate;
01090       hmmc->State = HAL_MMC_STATE_READY;
01091       return HAL_ERROR;
01092     }
01093 
01094     /* Configure the MMC DPSM (Data Path State Machine) */ 
01095     config.DataTimeOut   = SDMMC_DATATIMEOUT;
01096     config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
01097     config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
01098     config.TransferDir   = SDIO_TRANSFER_DIR_TO_CARD;
01099     config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
01100     config.DPSM          = SDIO_DPSM_ENABLE;
01101     (void)SDIO_ConfigData(hmmc->Instance, &config);
01102     
01103     return HAL_OK;
01104   }
01105   else
01106   {
01107     return HAL_BUSY;
01108   }
01109 }
01110 
01111 /**
01112   * @brief  Reads block(s) from a specified address in a card. The Data transfer
01113   *         is managed by DMA mode.
01114   * @note   This API should be followed by a check on the card state through
01115   *         HAL_MMC_GetCardState().
01116   * @note   You could also check the DMA transfer process through the MMC Rx
01117   *         interrupt event.
01118   * @param  hmmc: Pointer MMC handle
01119   * @param  pData: Pointer to the buffer that will contain the received data
01120   * @param  BlockAdd: Block Address from where data is to be read
01121   * @param  NumberOfBlocks: Number of blocks to read.
01122   * @retval HAL status
01123   */
01124 HAL_StatusTypeDef HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
01125 {
01126   SDIO_DataInitTypeDef config;
01127   uint32_t errorstate;
01128   uint32_t add = BlockAdd;
01129 
01130   if(NULL == pData)
01131   {
01132     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
01133     return HAL_ERROR;
01134   }
01135 
01136   if(hmmc->State == HAL_MMC_STATE_READY)
01137   {
01138     hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
01139 
01140     if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
01141     {
01142       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
01143       return HAL_ERROR;
01144     }
01145 
01146     hmmc->State = HAL_MMC_STATE_BUSY;
01147 
01148     /* Initialize data control register */
01149     hmmc->Instance->DCTRL = 0U;
01150 
01151     __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND));
01152 
01153     /* Set the DMA transfer complete callback */
01154     hmmc->hdmarx->XferCpltCallback = MMC_DMAReceiveCplt;
01155 
01156     /* Set the DMA error callback */
01157     hmmc->hdmarx->XferErrorCallback = MMC_DMAError;
01158 
01159     /* Set the DMA Abort callback */
01160     hmmc->hdmarx->XferAbortCallback = NULL;
01161 
01162     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
01163     {
01164       add *= 512U;
01165     }
01166 
01167     /* Force DMA Direction */
01168     hmmc->hdmarx->Init.Direction = DMA_PERIPH_TO_MEMORY;
01169     MODIFY_REG(hmmc->hdmarx->Instance->CCR, DMA_CCR_DIR, hmmc->hdmarx->Init.Direction);
01170 
01171     /* Enable the DMA Channel */
01172     if(HAL_DMA_Start_IT(hmmc->hdmarx, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)pData, (uint32_t)(MMC_BLOCKSIZE * NumberOfBlocks)/4) != HAL_OK)
01173     {
01174       __HAL_MMC_DISABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND));
01175       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
01176       hmmc->ErrorCode = HAL_MMC_ERROR_DMA;
01177       hmmc->State = HAL_MMC_STATE_READY;
01178       return HAL_ERROR;
01179     }
01180     else
01181     {
01182       /* Enable MMC DMA transfer */
01183       __HAL_MMC_DMA_ENABLE(hmmc);
01184 
01185       /* Configure the MMC DPSM (Data Path State Machine) */
01186       config.DataTimeOut   = SDMMC_DATATIMEOUT;
01187       config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
01188       config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
01189       config.TransferDir   = SDIO_TRANSFER_DIR_TO_SDIO;
01190       config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
01191       config.DPSM          = SDIO_DPSM_ENABLE;
01192       (void)SDIO_ConfigData(hmmc->Instance, &config);
01193 
01194       /* Read Blocks in DMA mode */
01195       if(NumberOfBlocks > 1U)
01196       {
01197         hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
01198 
01199         /* Read Multi Block command */
01200         errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
01201       }
01202       else
01203       {
01204         hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_DMA);
01205 
01206         /* Read Single Block command */
01207         errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
01208       }
01209       if(errorstate != HAL_MMC_ERROR_NONE)
01210       {
01211         /* Clear all the static flags */
01212         __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 
01213         __HAL_MMC_DISABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND));
01214         hmmc->ErrorCode = errorstate;
01215         hmmc->State = HAL_MMC_STATE_READY;
01216         return HAL_ERROR;
01217       }
01218 
01219       return HAL_OK;
01220     }
01221   }
01222   else
01223   {
01224     return HAL_BUSY;
01225   }
01226 }
01227 
01228 /**
01229   * @brief  Writes block(s) to a specified address in a card. The Data transfer
01230   *         is managed by DMA mode.
01231   * @note   This API should be followed by a check on the card state through
01232   *         HAL_MMC_GetCardState().
01233   * @note   You could also check the DMA transfer process through the MMC Tx
01234   *         interrupt event.
01235   * @param  hmmc: Pointer to MMC handle
01236   * @param  pData: Pointer to the buffer that will contain the data to transmit
01237   * @param  BlockAdd: Block Address where data will be written
01238   * @param  NumberOfBlocks: Number of blocks to write
01239   * @retval HAL status
01240   */
01241 HAL_StatusTypeDef HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
01242 {
01243   SDIO_DataInitTypeDef config;
01244   uint32_t errorstate;
01245   uint32_t add = BlockAdd;
01246 
01247   if(NULL == pData)
01248   {
01249     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
01250     return HAL_ERROR;
01251   }
01252 
01253   if(hmmc->State == HAL_MMC_STATE_READY)
01254   {
01255     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
01256 
01257     if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
01258     {
01259       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
01260       return HAL_ERROR;
01261     }
01262 
01263     hmmc->State = HAL_MMC_STATE_BUSY;
01264 
01265     /* Initialize data control register */
01266     hmmc->Instance->DCTRL = 0U;
01267 
01268     /* Enable MMC Error interrupts */
01269         __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR));
01270 
01271     /* Set the DMA transfer complete callback */
01272     hmmc->hdmatx->XferCpltCallback = MMC_DMATransmitCplt;
01273 
01274     /* Set the DMA error callback */
01275     hmmc->hdmatx->XferErrorCallback = MMC_DMAError;
01276 
01277     /* Set the DMA Abort callback */
01278     hmmc->hdmatx->XferAbortCallback = NULL;
01279 
01280     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
01281     {
01282       add *= 512U;
01283     }
01284 
01285 
01286     /* Write Blocks in Polling mode */
01287     if(NumberOfBlocks > 1U)
01288     {
01289       hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
01290 
01291       /* Write Multi Block command */
01292       errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
01293     }
01294     else
01295     {
01296       hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_DMA);
01297 
01298       /* Write Single Block command */
01299       errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
01300     }
01301     if(errorstate != HAL_MMC_ERROR_NONE)
01302     {
01303       /* Clear all the static flags */
01304       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
01305       __HAL_MMC_DISABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_DATAEND));
01306       hmmc->ErrorCode |= errorstate;
01307       hmmc->State = HAL_MMC_STATE_READY;
01308       return HAL_ERROR;
01309     }
01310 
01311     /* Enable SDIO DMA transfer */
01312     __HAL_MMC_DMA_ENABLE(hmmc);
01313 
01314     /* Force DMA Direction */
01315     hmmc->hdmatx->Init.Direction = DMA_MEMORY_TO_PERIPH;
01316     MODIFY_REG(hmmc->hdmatx->Instance->CCR, DMA_CCR_DIR, hmmc->hdmatx->Init.Direction);
01317 
01318     /* Enable the DMA Channel */
01319     if(HAL_DMA_Start_IT(hmmc->hdmatx, (uint32_t)pData, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)(MMC_BLOCKSIZE * NumberOfBlocks)/4) != HAL_OK)
01320     {
01321       __HAL_MMC_DISABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_DATAEND));
01322       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
01323       hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
01324       hmmc->State = HAL_MMC_STATE_READY;
01325       return HAL_ERROR;
01326     }
01327     else
01328     {    
01329       /* Configure the MMC DPSM (Data Path State Machine) */ 
01330       config.DataTimeOut   = SDMMC_DATATIMEOUT;
01331       config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
01332       config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
01333       config.TransferDir   = SDIO_TRANSFER_DIR_TO_CARD;
01334       config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
01335       config.DPSM          = SDIO_DPSM_ENABLE;
01336       (void)SDIO_ConfigData(hmmc->Instance, &config);
01337 
01338       return HAL_OK;
01339     }
01340   }
01341   else
01342   {
01343     return HAL_BUSY;
01344   }
01345 }
01346 
01347 /**
01348   * @brief  Erases the specified memory area of the given MMC card.
01349   * @note   This API should be followed by a check on the card state through
01350   *         HAL_MMC_GetCardState().
01351   * @param  hmmc: Pointer to MMC handle
01352   * @param  BlockStartAdd: Start Block address
01353   * @param  BlockEndAdd: End Block address
01354   * @retval HAL status
01355   */
01356 HAL_StatusTypeDef HAL_MMC_Erase(MMC_HandleTypeDef *hmmc, uint32_t BlockStartAdd, uint32_t BlockEndAdd)
01357 {
01358   uint32_t errorstate;
01359   uint32_t start_add = BlockStartAdd;
01360   uint32_t end_add = BlockEndAdd;
01361 
01362   if(hmmc->State == HAL_MMC_STATE_READY)
01363   {
01364     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
01365 
01366     if(end_add < start_add)
01367     {
01368       hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
01369       return HAL_ERROR;
01370     }
01371 
01372     if(end_add > (hmmc->MmcCard.LogBlockNbr))
01373     {
01374       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
01375       return HAL_ERROR;
01376     }
01377 
01378     hmmc->State = HAL_MMC_STATE_BUSY;
01379 
01380     /* Check if the card command class supports erase command */
01381     if(((hmmc->MmcCard.Class) & SDIO_CCCC_ERASE) == 0U)
01382     {
01383       /* Clear all the static flags */
01384       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
01385       hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
01386       hmmc->State = HAL_MMC_STATE_READY;
01387       return HAL_ERROR;
01388     }
01389 
01390     if((SDIO_GetResponse(hmmc->Instance, SDIO_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
01391     {
01392       /* Clear all the static flags */
01393       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
01394       hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED;
01395       hmmc->State = HAL_MMC_STATE_READY;
01396       return HAL_ERROR;
01397     }
01398 
01399     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
01400     {
01401       start_add *= 512U;
01402       end_add   *= 512U;
01403     }
01404 
01405     /* Send CMD35 MMC_ERASE_GRP_START with argument as addr  */
01406     errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, start_add);
01407     if(errorstate != HAL_MMC_ERROR_NONE)
01408     {
01409       /* Clear all the static flags */
01410       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
01411       hmmc->ErrorCode |= errorstate;
01412       hmmc->State = HAL_MMC_STATE_READY;
01413       return HAL_ERROR;
01414     }
01415 
01416     /* Send CMD36 MMC_ERASE_GRP_END with argument as addr  */
01417     errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, end_add);
01418     if(errorstate != HAL_MMC_ERROR_NONE)
01419     {
01420       /* Clear all the static flags */
01421       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
01422       hmmc->ErrorCode |= errorstate;
01423       hmmc->State = HAL_MMC_STATE_READY;
01424       return HAL_ERROR;
01425     }
01426 
01427     /* Send CMD38 ERASE */
01428     errorstate = SDMMC_CmdErase(hmmc->Instance);
01429     if(errorstate != HAL_MMC_ERROR_NONE)
01430     {
01431       /* Clear all the static flags */
01432       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
01433       hmmc->ErrorCode |= errorstate;
01434       hmmc->State = HAL_MMC_STATE_READY;
01435       return HAL_ERROR;
01436     }
01437 
01438     hmmc->State = HAL_MMC_STATE_READY;
01439 
01440     return HAL_OK;
01441   }
01442   else
01443   {
01444     return HAL_BUSY;
01445   }
01446 }
01447 
01448 /**
01449   * @brief  This function handles MMC card interrupt request.
01450   * @param  hmmc: Pointer to MMC handle
01451   * @retval None
01452   */
01453 void HAL_MMC_IRQHandler(MMC_HandleTypeDef *hmmc)
01454 {
01455   uint32_t errorstate;
01456   uint32_t context = hmmc->Context;
01457 
01458   /* Check for SDIO interrupt flags */
01459   if((__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXFIFOHF) != RESET) && ((context & MMC_CONTEXT_IT) != 0U))
01460   {
01461     MMC_Read_IT(hmmc);
01462   }
01463 
01464   else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DATAEND) != RESET)
01465   {
01466     __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_FLAG_DATAEND);
01467 
01468     __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
01469                              SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
01470     
01471     hmmc->Instance->DCTRL &= ~(SDIO_DCTRL_DTEN);
01472 
01473     if((context & MMC_CONTEXT_DMA) != 0U)
01474     {
01475       if((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)
01476       {
01477         errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
01478         if(errorstate != HAL_MMC_ERROR_NONE)
01479         {
01480           hmmc->ErrorCode |= errorstate;
01481 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01482           hmmc->ErrorCallback(hmmc);
01483 #else
01484           HAL_MMC_ErrorCallback(hmmc);
01485 #endif
01486         }
01487       }
01488       if(((context & MMC_CONTEXT_READ_SINGLE_BLOCK) == 0U) && ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) == 0U))
01489       {
01490         /* Disable the DMA transfer for transmit request by setting the DMAEN bit
01491         in the MMC DCTRL register */
01492         hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
01493         
01494         hmmc->State = HAL_MMC_STATE_READY;
01495         
01496 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01497         hmmc->TxCpltCallback(hmmc);
01498 #else
01499         HAL_MMC_TxCpltCallback(hmmc);
01500 #endif
01501       }
01502     }
01503     else if((context & MMC_CONTEXT_IT) != 0U)
01504     {
01505       /* Stop Transfer for Write Multi blocks or Read Multi blocks */
01506       if(((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
01507       {
01508         errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
01509         if(errorstate != HAL_MMC_ERROR_NONE)
01510         {
01511           hmmc->ErrorCode |= errorstate;
01512 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01513           hmmc->ErrorCallback(hmmc);
01514 #else
01515           HAL_MMC_ErrorCallback(hmmc);
01516 #endif
01517         }
01518       }
01519 
01520       /* Clear all the static flags */
01521       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
01522 
01523       hmmc->State = HAL_MMC_STATE_READY;
01524       if(((context & MMC_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
01525       {
01526 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01527         hmmc->RxCpltCallback(hmmc);
01528 #else
01529         HAL_MMC_RxCpltCallback(hmmc);
01530 #endif
01531       }
01532       else
01533       {
01534 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01535         hmmc->TxCpltCallback(hmmc);
01536 #else
01537         HAL_MMC_TxCpltCallback(hmmc);
01538 #endif
01539       }
01540     }
01541     else
01542     {
01543       /* Nothing to do */
01544     }
01545   }
01546 
01547   else if((__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXFIFOHE) != RESET) && ((context & MMC_CONTEXT_IT) != 0U))
01548   {
01549     MMC_Write_IT(hmmc);
01550   }
01551 
01552   else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_RXOVERR | SDIO_FLAG_TXUNDERR) != RESET)
01553   {
01554     /* Set Error code */
01555     if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL) != RESET)
01556     {
01557       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
01558     }
01559     if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DTIMEOUT) != RESET)
01560     {
01561       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
01562     }
01563     if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR) != RESET)
01564     {
01565       hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
01566     }
01567     if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR) != RESET)
01568     {
01569       hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
01570     }
01571 
01572     /* Clear All flags */
01573     __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS | SDIO_FLAG_STBITERR);
01574 
01575     /* Disable all interrupts */
01576     __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
01577                                SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR | SDIO_IT_STBITERR);
01578 
01579     hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
01580 
01581     if((context & MMC_CONTEXT_IT) != 0U)
01582     {
01583       /* Set the MMC state to ready to be able to start again the process */
01584       hmmc->State = HAL_MMC_STATE_READY;
01585 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01586       hmmc->ErrorCallback(hmmc);
01587 #else
01588       HAL_MMC_ErrorCallback(hmmc);
01589 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
01590     }
01591     else if((context & MMC_CONTEXT_DMA) != 0U)
01592     {
01593       /* Abort the MMC DMA Streams */
01594       if(hmmc->hdmatx != NULL)
01595       {
01596         /* Set the DMA Tx abort callback */
01597         hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort;
01598         /* Abort DMA in IT mode */
01599         if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
01600         {
01601           MMC_DMATxAbort(hmmc->hdmatx);
01602         }
01603       }
01604       else if(hmmc->hdmarx != NULL)
01605       {
01606         /* Set the DMA Rx abort callback */
01607         hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort;
01608         /* Abort DMA in IT mode */
01609         if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
01610         {
01611           MMC_DMARxAbort(hmmc->hdmarx);
01612         }
01613       }
01614       else
01615       {
01616         hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
01617         hmmc->State = HAL_MMC_STATE_READY;
01618 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01619         hmmc->AbortCpltCallback(hmmc);
01620 #else
01621         HAL_MMC_AbortCallback(hmmc);
01622 #endif
01623       }
01624     }
01625     else
01626     {
01627       /* Nothing to do */
01628     }
01629   }
01630 
01631   else
01632   {
01633     /* Nothing to do */
01634   }
01635 }
01636 
01637 /**
01638   * @brief return the MMC state
01639   * @param hmmc: Pointer to mmc handle
01640   * @retval HAL state
01641   */
01642 HAL_MMC_StateTypeDef HAL_MMC_GetState(MMC_HandleTypeDef *hmmc)
01643 {
01644   return hmmc->State;
01645 }
01646 
01647 /**
01648 * @brief  Return the MMC error code
01649 * @param  hmmc : Pointer to a MMC_HandleTypeDef structure that contains
01650   *              the configuration information.
01651 * @retval MMC Error Code
01652 */
01653 uint32_t HAL_MMC_GetError(MMC_HandleTypeDef *hmmc)
01654 {
01655   return hmmc->ErrorCode;
01656 }
01657 
01658 /**
01659   * @brief Tx Transfer completed callbacks
01660   * @param hmmc: Pointer to MMC handle
01661   * @retval None
01662   */
01663 __weak void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef *hmmc)
01664 {
01665   /* Prevent unused argument(s) compilation warning */
01666   UNUSED(hmmc);
01667 
01668   /* NOTE : This function should not be modified, when the callback is needed,
01669             the HAL_MMC_TxCpltCallback can be implemented in the user file
01670    */
01671 }
01672 
01673 /**
01674   * @brief Rx Transfer completed callbacks
01675   * @param hmmc: Pointer MMC handle
01676   * @retval None
01677   */
01678 __weak void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef *hmmc)
01679 {
01680   /* Prevent unused argument(s) compilation warning */
01681   UNUSED(hmmc);
01682 
01683   /* NOTE : This function should not be modified, when the callback is needed,
01684             the HAL_MMC_RxCpltCallback can be implemented in the user file
01685    */
01686 }
01687 
01688 /**
01689   * @brief MMC error callbacks
01690   * @param hmmc: Pointer MMC handle
01691   * @retval None
01692   */
01693 __weak void HAL_MMC_ErrorCallback(MMC_HandleTypeDef *hmmc)
01694 {
01695   /* Prevent unused argument(s) compilation warning */
01696   UNUSED(hmmc);
01697 
01698   /* NOTE : This function should not be modified, when the callback is needed,
01699             the HAL_MMC_ErrorCallback can be implemented in the user file
01700    */
01701 }
01702 
01703 /**
01704   * @brief MMC Abort callbacks
01705   * @param hmmc: Pointer MMC handle
01706   * @retval None
01707   */
01708 __weak void HAL_MMC_AbortCallback(MMC_HandleTypeDef *hmmc)
01709 {
01710   /* Prevent unused argument(s) compilation warning */
01711   UNUSED(hmmc);
01712 
01713   /* NOTE : This function should not be modified, when the callback is needed,
01714             the HAL_MMC_AbortCallback can be implemented in the user file
01715    */
01716 }
01717 
01718 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01719 /**
01720   * @brief  Register a User MMC Callback
01721   *         To be used instead of the weak (surcharged) predefined callback
01722   * @param hmmc : MMC handle
01723   * @param CallbackId : ID of the callback to be registered
01724   *        This parameter can be one of the following values:
01725   *          @arg @ref HAL_MMC_TX_CPLT_CB_ID    MMC Tx Complete Callback ID
01726   *          @arg @ref HAL_MMC_RX_CPLT_CB_ID    MMC Rx Complete Callback ID
01727   *          @arg @ref HAL_MMC_ERROR_CB_ID      MMC Error Callback ID
01728   *          @arg @ref HAL_MMC_ABORT_CB_ID      MMC Abort Callback ID
01729   *          @arg @ref HAL_MMC_MSP_INIT_CB_ID   MMC MspInit Callback ID
01730   *          @arg @ref HAL_MMC_MSP_DEINIT_CB_ID MMC MspDeInit Callback ID
01731   * @param pCallback : pointer to the Callback function
01732   * @retval status
01733   */
01734 HAL_StatusTypeDef HAL_MMC_RegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId, pMMC_CallbackTypeDef pCallback)
01735 {
01736   HAL_StatusTypeDef status = HAL_OK;
01737 
01738   if(pCallback == NULL)
01739   {
01740     /* Update the error code */
01741     hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
01742     return HAL_ERROR;
01743   }
01744 
01745   /* Process locked */
01746   __HAL_LOCK(hmmc);
01747 
01748   if(hmmc->State == HAL_MMC_STATE_READY)
01749   {
01750     switch (CallbackId)
01751     {
01752     case HAL_MMC_TX_CPLT_CB_ID :
01753       hmmc->TxCpltCallback = pCallback;
01754       break;
01755     case HAL_MMC_RX_CPLT_CB_ID :
01756       hmmc->RxCpltCallback = pCallback;
01757       break;
01758     case HAL_MMC_ERROR_CB_ID :
01759       hmmc->ErrorCallback = pCallback;
01760       break;
01761     case HAL_MMC_ABORT_CB_ID :
01762       hmmc->AbortCpltCallback = pCallback;
01763       break;
01764     case HAL_MMC_MSP_INIT_CB_ID :
01765       hmmc->MspInitCallback = pCallback;
01766       break;
01767     case HAL_MMC_MSP_DEINIT_CB_ID :
01768       hmmc->MspDeInitCallback = pCallback;
01769       break;
01770     default :
01771       /* Update the error code */
01772       hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
01773       /* update return status */
01774       status =  HAL_ERROR;
01775       break;
01776     }
01777   }
01778   else if (hmmc->State == HAL_MMC_STATE_RESET)
01779   {
01780     switch (CallbackId)
01781     {
01782     case HAL_MMC_MSP_INIT_CB_ID :
01783       hmmc->MspInitCallback = pCallback;
01784       break;
01785     case HAL_MMC_MSP_DEINIT_CB_ID :
01786       hmmc->MspDeInitCallback = pCallback;
01787       break;
01788     default :
01789       /* Update the error code */
01790       hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
01791       /* update return status */
01792       status =  HAL_ERROR;
01793       break;
01794     }
01795   }
01796   else
01797   {
01798     /* Update the error code */
01799     hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
01800     /* update return status */
01801     status =  HAL_ERROR;
01802   }
01803 
01804   /* Release Lock */
01805   __HAL_UNLOCK(hmmc);
01806   return status;
01807 }
01808 
01809 /**
01810   * @brief  Unregister a User MMC Callback
01811   *         MMC Callback is redirected to the weak (surcharged) predefined callback
01812   * @param hmmc : MMC handle
01813   * @param CallbackId : ID of the callback to be unregistered
01814   *        This parameter can be one of the following values:
01815   *          @arg @ref HAL_MMC_TX_CPLT_CB_ID    MMC Tx Complete Callback ID
01816   *          @arg @ref HAL_MMC_RX_CPLT_CB_ID    MMC Rx Complete Callback ID
01817   *          @arg @ref HAL_MMC_ERROR_CB_ID      MMC Error Callback ID
01818   *          @arg @ref HAL_MMC_ABORT_CB_ID      MMC Abort Callback ID
01819   *          @arg @ref HAL_MMC_MSP_INIT_CB_ID   MMC MspInit Callback ID
01820   *          @arg @ref HAL_MMC_MSP_DEINIT_CB_ID MMC MspDeInit Callback ID
01821   * @retval status
01822   */
01823 HAL_StatusTypeDef HAL_MMC_UnRegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId)
01824 {
01825   HAL_StatusTypeDef status = HAL_OK;
01826 
01827   /* Process locked */
01828   __HAL_LOCK(hmmc);
01829 
01830   if(hmmc->State == HAL_MMC_STATE_READY)
01831   {
01832     switch (CallbackId)
01833     {
01834     case HAL_MMC_TX_CPLT_CB_ID :
01835       hmmc->TxCpltCallback = HAL_MMC_TxCpltCallback;
01836       break;
01837     case HAL_MMC_RX_CPLT_CB_ID :
01838       hmmc->RxCpltCallback = HAL_MMC_RxCpltCallback;
01839       break;
01840     case HAL_MMC_ERROR_CB_ID :
01841       hmmc->ErrorCallback = HAL_MMC_ErrorCallback;
01842       break;
01843     case HAL_MMC_ABORT_CB_ID :
01844       hmmc->AbortCpltCallback = HAL_MMC_AbortCallback;
01845       break;
01846     case HAL_MMC_MSP_INIT_CB_ID :
01847       hmmc->MspInitCallback = HAL_MMC_MspInit;
01848       break;
01849     case HAL_MMC_MSP_DEINIT_CB_ID :
01850       hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
01851       break;
01852     default :
01853       /* Update the error code */
01854       hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
01855       /* update return status */
01856       status =  HAL_ERROR;
01857       break;
01858     }
01859   }
01860   else if (hmmc->State == HAL_MMC_STATE_RESET)
01861   {
01862     switch (CallbackId)
01863     {
01864     case HAL_MMC_MSP_INIT_CB_ID :
01865       hmmc->MspInitCallback = HAL_MMC_MspInit;
01866       break;
01867     case HAL_MMC_MSP_DEINIT_CB_ID :
01868       hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
01869       break;
01870     default :
01871       /* Update the error code */
01872       hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
01873       /* update return status */
01874       status =  HAL_ERROR;
01875       break;
01876     }
01877   }
01878   else
01879   {
01880     /* Update the error code */
01881     hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
01882     /* update return status */
01883     status =  HAL_ERROR;
01884   }
01885 
01886   /* Release Lock */
01887   __HAL_UNLOCK(hmmc);
01888   return status;
01889 }
01890 #endif
01891 
01892 /**
01893   * @}
01894   */
01895 
01896 /** @addtogroup MMC_Exported_Functions_Group3
01897  *  @brief   management functions
01898  *
01899 @verbatim
01900   ==============================================================================
01901                       ##### Peripheral Control functions #####
01902   ==============================================================================
01903   [..]
01904     This subsection provides a set of functions allowing to control the MMC card
01905     operations and get the related information
01906 
01907 @endverbatim
01908   * @{
01909   */
01910 
01911 /**
01912   * @brief  Returns information the information of the card which are stored on
01913   *         the CID register.
01914   * @param  hmmc: Pointer to MMC handle
01915   * @param  pCID: Pointer to a HAL_MMC_CIDTypedef structure that
01916   *         contains all CID register parameters
01917   * @retval HAL status
01918   */
01919 HAL_StatusTypeDef HAL_MMC_GetCardCID(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCIDTypeDef *pCID)
01920 {
01921   pCID->ManufacturerID = (uint8_t)((hmmc->CID[0] & 0xFF000000U) >> 24U);
01922 
01923   pCID->OEM_AppliID = (uint16_t)((hmmc->CID[0] & 0x00FFFF00U) >> 8U);
01924 
01925   pCID->ProdName1 = (((hmmc->CID[0] & 0x000000FFU) << 24U) | ((hmmc->CID[1] & 0xFFFFFF00U) >> 8U));
01926 
01927   pCID->ProdName2 = (uint8_t)(hmmc->CID[1] & 0x000000FFU);
01928 
01929   pCID->ProdRev = (uint8_t)((hmmc->CID[2] & 0xFF000000U) >> 24U);
01930 
01931   pCID->ProdSN = (((hmmc->CID[2] & 0x00FFFFFFU) << 8U) | ((hmmc->CID[3] & 0xFF000000U) >> 24U));
01932 
01933   pCID->Reserved1 = (uint8_t)((hmmc->CID[3] & 0x00F00000U) >> 20U);
01934 
01935   pCID->ManufactDate = (uint16_t)((hmmc->CID[3] & 0x000FFF00U) >> 8U);
01936 
01937   pCID->CID_CRC = (uint8_t)((hmmc->CID[3] & 0x000000FEU) >> 1U);
01938 
01939   pCID->Reserved2 = 1U;
01940 
01941   return HAL_OK;
01942 }
01943 
01944 /**
01945   * @brief  Returns information the information of the card which are stored on
01946   *         the CSD register.
01947   * @param  hmmc: Pointer to MMC handle
01948   * @param  pCSD: Pointer to a HAL_MMC_CardCSDTypeDef structure that
01949   *         contains all CSD register parameters
01950   * @retval HAL status
01951   */
01952 HAL_StatusTypeDef HAL_MMC_GetCardCSD(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCSDTypeDef *pCSD)
01953 {
01954   uint32_t block_nbr = 0;
01955 
01956   pCSD->CSDStruct = (uint8_t)((hmmc->CSD[0] & 0xC0000000U) >> 30U);
01957 
01958   pCSD->SysSpecVersion = (uint8_t)((hmmc->CSD[0] & 0x3C000000U) >> 26U);
01959 
01960   pCSD->Reserved1 = (uint8_t)((hmmc->CSD[0] & 0x03000000U) >> 24U);
01961 
01962   pCSD->TAAC = (uint8_t)((hmmc->CSD[0] & 0x00FF0000U) >> 16U);
01963 
01964   pCSD->NSAC = (uint8_t)((hmmc->CSD[0] & 0x0000FF00U) >> 8U);
01965 
01966   pCSD->MaxBusClkFrec = (uint8_t)(hmmc->CSD[0] & 0x000000FFU);
01967 
01968   pCSD->CardComdClasses = (uint16_t)((hmmc->CSD[1] & 0xFFF00000U) >> 20U);
01969 
01970   pCSD->RdBlockLen = (uint8_t)((hmmc->CSD[1] & 0x000F0000U) >> 16U);
01971 
01972   pCSD->PartBlockRead   = (uint8_t)((hmmc->CSD[1] & 0x00008000U) >> 15U);
01973 
01974   pCSD->WrBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00004000U) >> 14U);
01975 
01976   pCSD->RdBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00002000U) >> 13U);
01977 
01978   pCSD->DSRImpl = (uint8_t)((hmmc->CSD[1] & 0x00001000U) >> 12U);
01979 
01980   pCSD->Reserved2 = 0U; /*!< Reserved */
01981 
01982   pCSD->DeviceSize = (((hmmc->CSD[1] & 0x000003FFU) << 2U) | ((hmmc->CSD[2] & 0xC0000000U) >> 30U));
01983 
01984   pCSD->MaxRdCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x38000000U) >> 27U);
01985 
01986   pCSD->MaxRdCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x07000000U) >> 24U);
01987 
01988   pCSD->MaxWrCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x00E00000U) >> 21U);
01989 
01990   pCSD->MaxWrCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x001C0000U) >> 18U);
01991 
01992   pCSD->DeviceSizeMul = (uint8_t)((hmmc->CSD[2] & 0x00038000U) >> 15U);
01993 
01994   if(MMC_ReadExtCSD(hmmc, &block_nbr, 212, 0x0FFFFFFFU) != HAL_OK) /* Field SEC_COUNT [215:212] */
01995   {
01996     return HAL_ERROR;
01997   }
01998 
01999   if(hmmc->MmcCard.CardType == MMC_LOW_CAPACITY_CARD)
02000   {
02001     hmmc->MmcCard.BlockNbr  = (pCSD->DeviceSize + 1U) ;
02002     hmmc->MmcCard.BlockNbr *= (1UL << ((pCSD->DeviceSizeMul & 0x07U) + 2U));
02003     hmmc->MmcCard.BlockSize = (1UL << (pCSD->RdBlockLen & 0x0FU));
02004     hmmc->MmcCard.LogBlockNbr =  (hmmc->MmcCard.BlockNbr) * ((hmmc->MmcCard.BlockSize) / 512U);
02005     hmmc->MmcCard.LogBlockSize = 512U;
02006   }
02007   else if(hmmc->MmcCard.CardType == MMC_HIGH_CAPACITY_CARD)
02008   {
02009     hmmc->MmcCard.BlockNbr = block_nbr;
02010     hmmc->MmcCard.LogBlockNbr = hmmc->MmcCard.BlockNbr;
02011     hmmc->MmcCard.BlockSize = 512U;
02012     hmmc->MmcCard.LogBlockSize = hmmc->MmcCard.BlockSize;
02013   }
02014   else
02015   {
02016     /* Clear all the static flags */
02017     __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
02018     hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
02019     hmmc->State = HAL_MMC_STATE_READY;
02020     return HAL_ERROR;
02021   }
02022 
02023   pCSD->EraseGrSize = (uint8_t)((hmmc->CSD[2] & 0x00004000U) >> 14U);
02024 
02025   pCSD->EraseGrMul = (uint8_t)((hmmc->CSD[2] & 0x00003F80U) >> 7U);
02026 
02027   pCSD->WrProtectGrSize = (uint8_t)(hmmc->CSD[2] & 0x0000007FU);
02028 
02029   pCSD->WrProtectGrEnable = (uint8_t)((hmmc->CSD[3] & 0x80000000U) >> 31U);
02030 
02031   pCSD->ManDeflECC = (uint8_t)((hmmc->CSD[3] & 0x60000000U) >> 29U);
02032 
02033   pCSD->WrSpeedFact = (uint8_t)((hmmc->CSD[3] & 0x1C000000U) >> 26U);
02034 
02035   pCSD->MaxWrBlockLen= (uint8_t)((hmmc->CSD[3] & 0x03C00000U) >> 22U);
02036 
02037   pCSD->WriteBlockPaPartial = (uint8_t)((hmmc->CSD[3] & 0x00200000U) >> 21U);
02038 
02039   pCSD->Reserved3 = 0;
02040 
02041   pCSD->ContentProtectAppli = (uint8_t)((hmmc->CSD[3] & 0x00010000U) >> 16U);
02042 
02043   pCSD->FileFormatGroup = (uint8_t)((hmmc->CSD[3] & 0x00008000U) >> 15U);
02044 
02045   pCSD->CopyFlag = (uint8_t)((hmmc->CSD[3] & 0x00004000U) >> 14U);
02046 
02047   pCSD->PermWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00002000U) >> 13U);
02048 
02049   pCSD->TempWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00001000U) >> 12U);
02050 
02051   pCSD->FileFormat = (uint8_t)((hmmc->CSD[3] & 0x00000C00U) >> 10U);
02052 
02053   pCSD->ECC= (uint8_t)((hmmc->CSD[3] & 0x00000300U) >> 8U);
02054 
02055   pCSD->CSD_CRC = (uint8_t)((hmmc->CSD[3] & 0x000000FEU) >> 1U);
02056 
02057   pCSD->Reserved4 = 1;
02058 
02059   return HAL_OK;
02060 }
02061 
02062 /**
02063   * @brief  Gets the MMC card info.
02064   * @param  hmmc: Pointer to MMC handle
02065   * @param  pCardInfo: Pointer to the HAL_MMC_CardInfoTypeDef structure that
02066   *         will contain the MMC card status information
02067   * @retval HAL status
02068   */
02069 HAL_StatusTypeDef HAL_MMC_GetCardInfo(MMC_HandleTypeDef *hmmc, HAL_MMC_CardInfoTypeDef *pCardInfo)
02070 {
02071   pCardInfo->CardType     = (uint32_t)(hmmc->MmcCard.CardType);
02072   pCardInfo->Class        = (uint32_t)(hmmc->MmcCard.Class);
02073   pCardInfo->RelCardAdd   = (uint32_t)(hmmc->MmcCard.RelCardAdd);
02074   pCardInfo->BlockNbr     = (uint32_t)(hmmc->MmcCard.BlockNbr);
02075   pCardInfo->BlockSize    = (uint32_t)(hmmc->MmcCard.BlockSize);
02076   pCardInfo->LogBlockNbr  = (uint32_t)(hmmc->MmcCard.LogBlockNbr);
02077   pCardInfo->LogBlockSize = (uint32_t)(hmmc->MmcCard.LogBlockSize);
02078 
02079   return HAL_OK;
02080 }
02081 
02082 /**
02083   * @brief  Enables wide bus operation for the requested card if supported by
02084   *         card.
02085   * @param  hmmc: Pointer to MMC handle
02086   * @param  WideMode: Specifies the MMC card wide bus mode
02087   *          This parameter can be one of the following values:
02088   *            @arg SDIO_BUS_WIDE_8B: 8-bit data transfer
02089   *            @arg SDIO_BUS_WIDE_4B: 4-bit data transfer
02090   *            @arg SDIO_BUS_WIDE_1B: 1-bit data transfer
02091   * @retval HAL status
02092   */
02093 HAL_StatusTypeDef HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef *hmmc, uint32_t WideMode)
02094 {
02095   __IO uint32_t count = 0U;
02096   SDIO_InitTypeDef Init;
02097   uint32_t errorstate;
02098   uint32_t response = 0U, busy = 0U;
02099 
02100   /* Check the parameters */
02101   assert_param(IS_SDIO_BUS_WIDE(WideMode));
02102 
02103   /* Change State */
02104   hmmc->State = HAL_MMC_STATE_BUSY;
02105 
02106   /* Update Clock for Bus mode update */
02107   Init.ClockEdge           = SDIO_CLOCK_EDGE_RISING;
02108   Init.ClockBypass         = SDIO_CLOCK_BYPASS_DISABLE;
02109   Init.ClockPowerSave      = SDIO_CLOCK_POWER_SAVE_DISABLE;
02110   Init.BusWide             = WideMode;
02111   Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
02112   Init.ClockDiv            = SDIO_INIT_CLK_DIV;
02113   /* Initialize SDIO*/
02114   (void)SDIO_Init(hmmc->Instance, Init); 
02115 
02116   if(WideMode == SDIO_BUS_WIDE_8B)
02117   {
02118     errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U);
02119     if(errorstate != HAL_MMC_ERROR_NONE)
02120     {
02121       hmmc->ErrorCode |= errorstate;
02122     }
02123   }
02124   else if(WideMode == SDIO_BUS_WIDE_4B)
02125   {
02126     errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U);
02127     if(errorstate != HAL_MMC_ERROR_NONE)
02128     {
02129       hmmc->ErrorCode |= errorstate;
02130     }
02131   }
02132   else if(WideMode == SDIO_BUS_WIDE_1B)
02133   {
02134     errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70000U);
02135     if(errorstate != HAL_MMC_ERROR_NONE)
02136     {
02137       hmmc->ErrorCode |= errorstate;
02138     }
02139   }
02140   else
02141   {
02142     /* WideMode is not a valid argument*/
02143     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
02144   }
02145 
02146   /* Check for switch error and violation of the trial number of sending CMD 13 */
02147   while(busy == 0U)
02148   {
02149     if(count == SDMMC_MAX_TRIAL)
02150     {
02151       hmmc->State = HAL_MMC_STATE_READY;
02152       hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
02153       return HAL_ERROR;
02154     }
02155     count++;
02156 
02157     /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
02158     errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
02159     if(errorstate != HAL_MMC_ERROR_NONE)
02160     {
02161       hmmc->ErrorCode |= errorstate;
02162     }
02163 
02164     /* Get command response */
02165     response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
02166 
02167     /* Get operating voltage*/
02168     busy = (((response >> 7U) == 1U) ? 0U : 1U);
02169   }
02170 
02171   /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
02172   count = SDMMC_DATATIMEOUT;
02173   while((response & 0x00000100U) == 0U)
02174   {
02175     if(count == 0U)
02176     {
02177       hmmc->State = HAL_MMC_STATE_READY;
02178       hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
02179       return HAL_ERROR;
02180     }
02181     count--;
02182 
02183     /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
02184     errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
02185     if(errorstate != HAL_MMC_ERROR_NONE)
02186     {
02187       hmmc->ErrorCode |= errorstate;
02188     }
02189 
02190     /* Get command response */
02191     response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
02192   }
02193 
02194   if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
02195   {
02196     /* Clear all the static flags */
02197     __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
02198     hmmc->State = HAL_MMC_STATE_READY;
02199     return HAL_ERROR;
02200   }
02201   else
02202   {
02203     /* Configure the SDIO peripheral */
02204     Init.ClockEdge           = hmmc->Init.ClockEdge;
02205     Init.ClockBypass         = hmmc->Init.ClockBypass;
02206     Init.ClockPowerSave      = hmmc->Init.ClockPowerSave;
02207     Init.BusWide             = WideMode;
02208     Init.HardwareFlowControl = hmmc->Init.HardwareFlowControl;
02209     Init.ClockDiv            = hmmc->Init.ClockDiv;
02210     (void)SDIO_Init(hmmc->Instance, Init);
02211   }
02212 
02213   /* Change State */
02214   hmmc->State = HAL_MMC_STATE_READY;
02215 
02216   return HAL_OK;
02217 }
02218 
02219 /**
02220   * @brief  Gets the current mmc card data state.
02221   * @param  hmmc: pointer to MMC handle
02222   * @retval Card state
02223   */
02224 HAL_MMC_CardStateTypeDef HAL_MMC_GetCardState(MMC_HandleTypeDef *hmmc)
02225 {
02226   uint32_t cardstate;
02227   uint32_t errorstate;
02228   uint32_t resp1 = 0U;
02229 
02230   errorstate = MMC_SendStatus(hmmc, &resp1);
02231   if(errorstate != HAL_MMC_ERROR_NONE)
02232   {
02233     hmmc->ErrorCode |= errorstate;
02234   }
02235 
02236   cardstate = ((resp1 >> 9U) & 0x0FU);
02237 
02238   return (HAL_MMC_CardStateTypeDef)cardstate;
02239 }
02240 
02241 /**
02242   * @brief  Abort the current transfer and disable the MMC.
02243   * @param  hmmc: pointer to a MMC_HandleTypeDef structure that contains
02244   *                the configuration information for MMC module.
02245   * @retval HAL status
02246   */
02247 HAL_StatusTypeDef HAL_MMC_Abort(MMC_HandleTypeDef *hmmc)
02248 {
02249   HAL_MMC_CardStateTypeDef CardState;
02250 
02251   /* DIsable All interrupts */
02252   __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
02253                              SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
02254 
02255   /* Clear All flags */
02256   __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
02257 
02258   if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL))
02259   {
02260     /* Disable the MMC DMA request */
02261     hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
02262     
02263     /* Abort the MMC DMA Tx Stream */
02264     if(hmmc->hdmatx != NULL)
02265     {
02266       if(HAL_DMA_Abort(hmmc->hdmatx) != HAL_OK)
02267       {
02268         hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
02269       }
02270     }
02271     /* Abort the MMC DMA Rx Stream */
02272     if(hmmc->hdmarx != NULL)
02273     {
02274       if(HAL_DMA_Abort(hmmc->hdmarx) != HAL_OK)
02275       {
02276         hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
02277       }
02278     }
02279   }
02280 
02281   hmmc->State = HAL_MMC_STATE_READY;
02282 
02283   /* Initialize the MMC operation */
02284   hmmc->Context = MMC_CONTEXT_NONE;
02285 
02286   CardState = HAL_MMC_GetCardState(hmmc);
02287   if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
02288   {
02289     hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
02290   }
02291   if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
02292   {
02293     return HAL_ERROR;
02294   }
02295   return HAL_OK;
02296 }
02297 
02298 /**
02299   * @brief  Abort the current transfer and disable the MMC (IT mode).
02300   * @param  hmmc: pointer to a MMC_HandleTypeDef structure that contains
02301   *                the configuration information for MMC module.
02302   * @retval HAL status
02303   */
02304 HAL_StatusTypeDef HAL_MMC_Abort_IT(MMC_HandleTypeDef *hmmc)
02305 {
02306   HAL_MMC_CardStateTypeDef CardState;
02307 
02308   /* DIsable All interrupts */
02309   __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
02310                            SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
02311 
02312   /* Clear All flags */
02313   __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
02314 
02315   if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL))
02316   {
02317     /* Disable the MMC DMA request */
02318     hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
02319     
02320     /* Abort the MMC DMA Tx Stream */
02321     if(hmmc->hdmatx != NULL)
02322     {
02323       hmmc->hdmatx->XferAbortCallback =  MMC_DMATxAbort;
02324       if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
02325       {
02326         hmmc->hdmatx = NULL;
02327       }
02328     }
02329     /* Abort the MMC DMA Rx Stream */
02330     if(hmmc->hdmarx != NULL)
02331     {
02332       hmmc->hdmarx->XferAbortCallback =  MMC_DMARxAbort;
02333       if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
02334       {
02335         hmmc->hdmarx = NULL;
02336       }
02337     }
02338   }
02339   
02340   /* No transfer ongoing on both DMA channels*/
02341   if((hmmc->hdmatx == NULL) && (hmmc->hdmarx == NULL))
02342   {
02343     CardState = HAL_MMC_GetCardState(hmmc);
02344     hmmc->State = HAL_MMC_STATE_READY;
02345 
02346     if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
02347     {
02348       hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
02349     }
02350     if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
02351     {
02352       return HAL_ERROR;
02353     }
02354     else
02355     {
02356 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
02357       hmmc->AbortCpltCallback(hmmc);
02358 #else
02359       HAL_MMC_AbortCallback(hmmc);
02360 #endif
02361     }
02362   }
02363 
02364   return HAL_OK;
02365 }
02366 
02367 /**
02368   * @}
02369   */
02370 
02371 /**
02372   * @}
02373   */
02374 
02375 /* Private function ----------------------------------------------------------*/
02376 /** @addtogroup MMC_Private_Functions
02377   * @{
02378   */
02379 
02380 /**
02381   * @brief  DMA MMC transmit process complete callback 
02382   * @param  hdma: DMA handle
02383   * @retval None
02384   */
02385 static void MMC_DMATransmitCplt(DMA_HandleTypeDef *hdma)     
02386 {
02387   MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
02388   
02389   /* Enable DATAEND Interrupt */
02390   __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DATAEND));
02391 }
02392 
02393 /**
02394   * @brief  DMA MMC receive process complete callback 
02395   * @param  hdma: DMA handle
02396   * @retval None
02397   */
02398 static void MMC_DMAReceiveCplt(DMA_HandleTypeDef *hdma)  
02399 {
02400   MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
02401   uint32_t errorstate;
02402   
02403   /* Send stop command in multiblock write */
02404   if(hmmc->Context == (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA))
02405   {
02406     errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
02407     if(errorstate != HAL_MMC_ERROR_NONE)
02408     {
02409       hmmc->ErrorCode |= errorstate;
02410 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
02411       hmmc->ErrorCallback(hmmc);
02412 #else
02413       HAL_MMC_ErrorCallback(hmmc);
02414 #endif
02415     }
02416   }
02417   
02418   /* Disable the DMA transfer for transmit request by setting the DMAEN bit
02419   in the MMC DCTRL register */
02420   hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
02421   
02422   /* Clear all the static flags */
02423   __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
02424   
02425   hmmc->State = HAL_MMC_STATE_READY;
02426 
02427 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
02428   hmmc->RxCpltCallback(hmmc);
02429 #else
02430   HAL_MMC_RxCpltCallback(hmmc);
02431 #endif
02432 }
02433 
02434 /**
02435   * @brief  DMA MMC communication error callback 
02436   * @param  hdma: DMA handle
02437   * @retval None
02438   */
02439 static void MMC_DMAError(DMA_HandleTypeDef *hdma)   
02440 {
02441   MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
02442   HAL_MMC_CardStateTypeDef CardState;
02443   uint32_t RxErrorCode, TxErrorCode;
02444   
02445     RxErrorCode = hmmc->hdmarx->ErrorCode;
02446     TxErrorCode = hmmc->hdmatx->ErrorCode;  
02447     if((RxErrorCode == HAL_DMA_ERROR_TE) || (TxErrorCode == HAL_DMA_ERROR_TE))
02448     {
02449       /* Clear All flags */
02450       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
02451       
02452       /* Disable All interrupts */
02453       __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
02454         SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
02455       
02456       hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
02457       CardState = HAL_MMC_GetCardState(hmmc);
02458       if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
02459       {
02460         hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
02461       }
02462       
02463       hmmc->State= HAL_MMC_STATE_READY;
02464     }
02465     
02466 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
02467     hmmc->ErrorCallback(hmmc);
02468 #else
02469     HAL_MMC_ErrorCallback(hmmc);
02470 #endif
02471 }
02472 
02473 /**
02474   * @brief  DMA MMC Tx Abort callback 
02475   * @param  hdma: DMA handle
02476   * @retval None
02477   */
02478 static void MMC_DMATxAbort(DMA_HandleTypeDef *hdma)   
02479 {
02480   MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
02481   HAL_MMC_CardStateTypeDef CardState;
02482   
02483   if(hmmc->hdmatx != NULL)
02484   {
02485     hmmc->hdmatx = NULL;
02486   }
02487   
02488   /* All DMA channels are aborted */
02489   if(hmmc->hdmarx == NULL)
02490   {
02491     CardState = HAL_MMC_GetCardState(hmmc);
02492     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
02493     hmmc->State = HAL_MMC_STATE_READY;
02494     if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
02495     {
02496       hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
02497       
02498       if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
02499       {
02500 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
02501         hmmc->AbortCpltCallback(hmmc);
02502 #else
02503         HAL_MMC_AbortCallback(hmmc);
02504 #endif
02505       }
02506       else
02507       {
02508 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
02509         hmmc->ErrorCallback(hmmc);
02510 #else
02511         HAL_MMC_ErrorCallback(hmmc);
02512 #endif
02513       }
02514     }
02515   }
02516 }
02517 
02518 /**
02519   * @brief  DMA MMC Rx Abort callback 
02520   * @param  hdma: DMA handle
02521   * @retval None
02522   */
02523 static void MMC_DMARxAbort(DMA_HandleTypeDef *hdma)   
02524 {
02525   MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
02526   HAL_MMC_CardStateTypeDef CardState;
02527   
02528   if(hmmc->hdmarx != NULL)
02529   {
02530     hmmc->hdmarx = NULL;
02531   }
02532   
02533   /* All DMA channels are aborted */
02534   if(hmmc->hdmatx == NULL)
02535   {
02536     CardState = HAL_MMC_GetCardState(hmmc);
02537     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
02538     hmmc->State = HAL_MMC_STATE_READY;
02539     if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
02540     {
02541       hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
02542       
02543       if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
02544       {
02545 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
02546         hmmc->AbortCpltCallback(hmmc);
02547 #else
02548         HAL_MMC_AbortCallback(hmmc);
02549 #endif
02550       }
02551       else
02552       {
02553 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
02554         hmmc->ErrorCallback(hmmc);
02555 #else
02556         HAL_MMC_ErrorCallback(hmmc);
02557 #endif
02558       }
02559     }
02560   }
02561 }
02562 
02563 /**
02564   * @brief  Initializes the mmc card.
02565   * @param  hmmc: Pointer to MMC handle
02566   * @retval MMC Card error state
02567   */
02568 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc)
02569 {
02570   HAL_MMC_CardCSDTypeDef CSD;
02571   uint32_t errorstate;
02572   uint16_t mmc_rca = 1U;
02573 
02574   /* Check the power State */
02575   if(SDIO_GetPowerState(hmmc->Instance) == 0U)
02576   {
02577     /* Power off */
02578     return HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
02579   }
02580 
02581   /* Send CMD2 ALL_SEND_CID */
02582   errorstate = SDMMC_CmdSendCID(hmmc->Instance);
02583   if(errorstate != HAL_MMC_ERROR_NONE)
02584   {
02585     return errorstate;
02586   }
02587   else
02588   {
02589     /* Get Card identification number data */
02590     hmmc->CID[0U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
02591     hmmc->CID[1U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP2);
02592     hmmc->CID[2U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP3);
02593     hmmc->CID[3U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP4);
02594   }
02595 
02596   /* Send CMD3 SET_REL_ADDR with argument 0 */
02597   /* MMC Card publishes its RCA. */
02598   errorstate = SDMMC_CmdSetRelAdd(hmmc->Instance, &mmc_rca);
02599   if(errorstate != HAL_MMC_ERROR_NONE)
02600   {
02601     return errorstate;
02602   }
02603 
02604   /* Get the MMC card RCA */
02605   hmmc->MmcCard.RelCardAdd = mmc_rca;
02606 
02607   /* Send CMD9 SEND_CSD with argument as card's RCA */
02608   errorstate = SDMMC_CmdSendCSD(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
02609   if(errorstate != HAL_MMC_ERROR_NONE)
02610   {
02611     return errorstate;
02612   }
02613   else
02614   {
02615     /* Get Card Specific Data */
02616     hmmc->CSD[0U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
02617     hmmc->CSD[1U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP2);
02618     hmmc->CSD[2U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP3);
02619     hmmc->CSD[3U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP4);
02620   }
02621 
02622   /* Get the Card Class */
02623   hmmc->MmcCard.Class = (SDIO_GetResponse(hmmc->Instance, SDIO_RESP2) >> 20U);
02624 
02625   /* Get CSD parameters */
02626   if (HAL_MMC_GetCardCSD(hmmc, &CSD) != HAL_OK)
02627   {
02628     return hmmc->ErrorCode;
02629   }
02630 
02631   /* Select the Card */
02632   errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
02633   if(errorstate != HAL_MMC_ERROR_NONE)
02634   {
02635     return errorstate;
02636   }
02637 
02638   /* Configure SDIO peripheral interface */
02639   (void)SDIO_Init(hmmc->Instance, hmmc->Init);
02640 
02641   /* All cards are initialized */
02642   return HAL_MMC_ERROR_NONE;
02643 }
02644 
02645 /**
02646   * @brief  Enquires cards about their operating voltage and configures clock
02647   *         controls and stores MMC information that will be needed in future
02648   *         in the MMC handle.
02649   * @param  hmmc: Pointer to MMC handle
02650   * @retval error state
02651   */
02652 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc)
02653 {
02654   __IO uint32_t count = 0U;
02655   uint32_t response = 0U, validvoltage = 0U;
02656   uint32_t errorstate;
02657 
02658   /* CMD0: GO_IDLE_STATE */
02659   errorstate = SDMMC_CmdGoIdleState(hmmc->Instance);
02660   if(errorstate != HAL_MMC_ERROR_NONE)
02661   {
02662     return errorstate;
02663   }
02664 
02665   while(validvoltage == 0U)
02666   {
02667     if(count++ == SDMMC_MAX_VOLT_TRIAL)
02668     {
02669       return HAL_MMC_ERROR_INVALID_VOLTRANGE;
02670     }
02671 
02672     /* SEND CMD1 APP_CMD with MMC_HIGH_VOLTAGE_RANGE(0xC0FF8000) as argument */
02673     errorstate = SDMMC_CmdOpCondition(hmmc->Instance, eMMC_HIGH_VOLTAGE_RANGE);
02674     if(errorstate != HAL_MMC_ERROR_NONE)
02675     {
02676       return HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
02677     }
02678 
02679     /* Get command response */
02680     response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
02681 
02682     /* Get operating voltage*/
02683     validvoltage = (((response >> 31U) == 1U) ? 1U : 0U);
02684   }
02685 
02686   /* When power routine is finished and command returns valid voltage */
02687   if (((response & (0xFF000000U)) >> 24U) == 0xC0U)
02688   {
02689     hmmc->MmcCard.CardType = MMC_HIGH_CAPACITY_CARD;
02690   }
02691   else
02692   {
02693     hmmc->MmcCard.CardType = MMC_LOW_CAPACITY_CARD;
02694   }
02695 
02696   return HAL_MMC_ERROR_NONE;
02697 }
02698 
02699 /**
02700   * @brief  Turns the SDIO output signals off.
02701   * @param  hmmc: Pointer to MMC handle
02702   * @retval None
02703   */
02704 static void MMC_PowerOFF(MMC_HandleTypeDef *hmmc)
02705 {
02706   /* Set Power State to OFF */
02707   (void)SDIO_PowerState_OFF(hmmc->Instance);
02708 }
02709 
02710 /**
02711   * @brief  Returns the current card's status.
02712   * @param  hmmc: Pointer to MMC handle
02713   * @param  pCardStatus: pointer to the buffer that will contain the MMC card
02714   *         status (Card Status register)
02715   * @retval error state
02716   */
02717 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus)
02718 {
02719   uint32_t errorstate;
02720 
02721   if(pCardStatus == NULL)
02722   {
02723     return HAL_MMC_ERROR_PARAM;
02724   }
02725 
02726   /* Send Status command */
02727   errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
02728   if(errorstate != HAL_MMC_ERROR_NONE)
02729   {
02730     return errorstate;
02731   }
02732 
02733   /* Get MMC card status */
02734   *pCardStatus = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
02735 
02736   return HAL_MMC_ERROR_NONE;
02737 }
02738 
02739 /**
02740   * @brief  Reads extended CSD register to get the sectors number of the device
02741   * @param  hmmc: Pointer to MMC handle
02742   * @param  pFieldData: Pointer to the read buffer
02743   * @param  FieldIndex: Index of the field to be read
02744   * @param  Timeout: Specify timeout value
02745   * @retval HAL status
02746   */
02747 static uint32_t MMC_ReadExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pFieldData, uint16_t FieldIndex, uint32_t Timeout)
02748 {
02749   SDIO_DataInitTypeDef config;
02750   uint32_t errorstate;
02751   uint32_t tickstart = HAL_GetTick();
02752   uint32_t count;
02753   uint32_t i = 0;
02754   uint32_t tmp_data;
02755 
02756   hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
02757 
02758   /* Initialize data control register */
02759   hmmc->Instance->DCTRL = 0;
02760 
02761   /* Configure the MMC DPSM (Data Path State Machine) */
02762   config.DataTimeOut   = SDMMC_DATATIMEOUT;
02763   config.DataLength    = 512;
02764   config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
02765   config.TransferDir   = SDIO_TRANSFER_DIR_TO_SDIO;
02766   config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
02767   config.DPSM          = SDIO_DPSM_ENABLE;
02768   (void)SDIO_ConfigData(hmmc->Instance, &config);
02769 
02770   /* Set Block Size for Card */
02771   errorstate = SDMMC_CmdSendEXTCSD(hmmc->Instance, 0);
02772   if(errorstate != HAL_MMC_ERROR_NONE)
02773   {
02774     /* Clear all the static flags */
02775     __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
02776     hmmc->ErrorCode |= errorstate;
02777     hmmc->State = HAL_MMC_STATE_READY;
02778     return HAL_ERROR;
02779   }
02780 
02781   /* Poll on SDMMC flags */
02782   while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND))
02783   {
02784     if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXFIFOHF))
02785     {
02786       /* Read data from SDMMC Rx FIFO */
02787       for(count = 0U; count < 8U; count++)
02788       {
02789         tmp_data = SDIO_ReadFIFO(hmmc->Instance);
02790         /* eg : SEC_COUNT   : FieldIndex = 212 => i+count = 53 */
02791         /*      DEVICE_TYPE : FieldIndex = 196 => i+count = 49 */
02792         if ((i + count) == ((uint32_t)FieldIndex/4U))
02793         {
02794           *pFieldData = tmp_data;
02795         }
02796       }
02797       i += 8U;
02798     }
02799 
02800     if(((HAL_GetTick()-tickstart) >=  Timeout) || (Timeout == 0U))
02801     {
02802       /* Clear all the static flags */
02803       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
02804       hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
02805       hmmc->State= HAL_MMC_STATE_READY;
02806       return HAL_TIMEOUT;
02807     }
02808   }
02809 
02810   /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
02811   errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16));
02812   if(errorstate != HAL_MMC_ERROR_NONE)
02813   {
02814     hmmc->ErrorCode |= errorstate;
02815   }
02816 
02817   /* Clear all the static flags */
02818   __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
02819 
02820   hmmc->State = HAL_MMC_STATE_READY;
02821 
02822   return HAL_OK;
02823 }
02824 
02825 
02826 /**
02827   * @brief  Wrap up reading in non-blocking mode.
02828   * @param  hmmc: pointer to a MMC_HandleTypeDef structure that contains
02829   *              the configuration information.
02830   * @retval None
02831   */
02832 static void MMC_Read_IT(MMC_HandleTypeDef *hmmc)
02833 {
02834   uint32_t count, data, dataremaining;
02835   uint8_t* tmp;
02836 
02837   tmp = hmmc->pRxBuffPtr;
02838   dataremaining = hmmc->RxXferSize;
02839 
02840   if (dataremaining > 0U)
02841   {
02842     /* Read data from SDIO Rx FIFO */
02843     for(count = 0U; count < 8U; count++)
02844     {
02845       data = SDIO_ReadFIFO(hmmc->Instance);
02846       *tmp = (uint8_t)(data & 0xFFU);
02847       tmp++;
02848       dataremaining--;
02849       *tmp = (uint8_t)((data >> 8U) & 0xFFU);
02850       tmp++;
02851       dataremaining--;
02852       *tmp = (uint8_t)((data >> 16U) & 0xFFU);
02853       tmp++;
02854       dataremaining--;
02855       *tmp = (uint8_t)((data >> 24U) & 0xFFU);
02856       tmp++;
02857       dataremaining--;
02858     }
02859 
02860     hmmc->pRxBuffPtr = tmp;
02861     hmmc->RxXferSize = dataremaining;
02862   }
02863 }
02864 
02865 /**
02866   * @brief  Wrap up writing in non-blocking mode.
02867   * @param  hmmc: pointer to a MMC_HandleTypeDef structure that contains
02868   *              the configuration information.
02869   * @retval None
02870   */
02871 static void MMC_Write_IT(MMC_HandleTypeDef *hmmc)
02872 {
02873   uint32_t count, data, dataremaining;
02874   uint8_t* tmp;
02875 
02876   tmp = hmmc->pTxBuffPtr;
02877   dataremaining = hmmc->TxXferSize;
02878 
02879   if (dataremaining > 0U)
02880   {
02881     /* Write data to SDIO Tx FIFO */
02882     for(count = 0U; count < 8U; count++)
02883     {
02884       data = (uint32_t)(*tmp);
02885       tmp++;
02886       dataremaining--;
02887       data |= ((uint32_t)(*tmp) << 8U);
02888       tmp++;
02889       dataremaining--;
02890       data |= ((uint32_t)(*tmp) << 16U);
02891       tmp++;
02892       dataremaining--;
02893       data |= ((uint32_t)(*tmp) << 24U);
02894       tmp++;
02895       dataremaining--;
02896       (void)SDIO_WriteFIFO(hmmc->Instance, &data);
02897     }
02898 
02899     hmmc->pTxBuffPtr = tmp;
02900     hmmc->TxXferSize = dataremaining;
02901   }
02902 }
02903 
02904 /**
02905   * @}
02906   */
02907 
02908 #endif /* SDIO */
02909 
02910 #endif /* HAL_MMC_MODULE_ENABLED */
02911 
02912 /**
02913   * @}
02914   */
02915 
02916 /**
02917   * @}
02918   */
02919 
02920 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/