STM32F479xx HAL User Manual
stm32f4xx_hal_mmc.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32f4xx_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 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 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 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 HAL_MMC_Init
00223     and  HAL_MMC_DeInit only when these callbacks are null (not registered beforehand).
00224     If not, MspInit or MspDeInit are not null, the HAL_MMC_Init and 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 HAL_MMC_RegisterCallback before calling HAL_MMC_DeInit
00233     or 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) 2017 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 "stm32f4xx_hal.h"
00256 
00257 /** @addtogroup STM32F4xx_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 #if defined(SDIO_STA_STBITERR)
00635     while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_FLAG_STBITERR))
00636 #else /* SDIO_STA_STBITERR not defined */
00637     while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND))
00638 #endif /* SDIO_STA_STBITERR */
00639     {
00640       if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXFIFOHF) && (dataremaining > 0U))
00641       {
00642         /* Read data from SDIO Rx FIFO */
00643         for(count = 0U; count < 8U; count++)
00644         {
00645           data = SDIO_ReadFIFO(hmmc->Instance);
00646           *tempbuff = (uint8_t)(data & 0xFFU);
00647           tempbuff++;
00648           dataremaining--;
00649           *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
00650           tempbuff++;
00651           dataremaining--;
00652           *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
00653           tempbuff++;
00654           dataremaining--;
00655           *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
00656           tempbuff++;
00657           dataremaining--;
00658         }
00659       }
00660 
00661       if(((HAL_GetTick()-tickstart) >=  Timeout) || (Timeout == 0U))
00662       {
00663         /* Clear all the static flags */
00664         __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
00665         hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
00666         hmmc->State= HAL_MMC_STATE_READY;
00667         return HAL_TIMEOUT;
00668       }
00669     }
00670 
00671     /* Send stop transmission command in case of multiblock read */
00672     if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1U))
00673     {
00674       /* Send stop transmission command */
00675       errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
00676       if(errorstate != HAL_MMC_ERROR_NONE)
00677       {
00678         /* Clear all the static flags */
00679         __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
00680         hmmc->ErrorCode |= errorstate;
00681         hmmc->State = HAL_MMC_STATE_READY;
00682         return HAL_ERROR;
00683       }
00684     }
00685 
00686     /* Get error state */
00687     if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DTIMEOUT))
00688     {
00689       /* Clear all the static flags */
00690       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
00691       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
00692       hmmc->State = HAL_MMC_STATE_READY;
00693       return HAL_ERROR;
00694     }
00695     else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL))
00696     {
00697       /* Clear all the static flags */
00698       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
00699       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
00700       hmmc->State = HAL_MMC_STATE_READY;
00701       return HAL_ERROR;
00702     }
00703     else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR))
00704     {
00705       /* Clear all the static flags */
00706       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
00707       hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
00708       hmmc->State = HAL_MMC_STATE_READY;
00709       return HAL_ERROR;
00710     }
00711     else
00712     {
00713       /* Nothing to do */
00714     }
00715 
00716     /* Empty FIFO if there is still any data */
00717     while ((__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXDAVL)) && (dataremaining > 0U))
00718     {
00719       data = SDIO_ReadFIFO(hmmc->Instance);
00720       *tempbuff = (uint8_t)(data & 0xFFU);
00721       tempbuff++;
00722       dataremaining--;
00723       *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
00724       tempbuff++;
00725       dataremaining--;
00726       *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
00727       tempbuff++;
00728       dataremaining--;
00729       *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
00730       tempbuff++;
00731       dataremaining--;
00732 
00733       if(((HAL_GetTick()-tickstart) >=  Timeout) || (Timeout == 0U))
00734       {
00735         /* Clear all the static flags */
00736         __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);        
00737         hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
00738         hmmc->State= HAL_MMC_STATE_READY;
00739         return HAL_ERROR;
00740       }
00741     }
00742 
00743     /* Clear all the static flags */
00744     __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
00745 
00746     hmmc->State = HAL_MMC_STATE_READY;
00747 
00748     return HAL_OK;
00749   }
00750   else
00751   {
00752     hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
00753     return HAL_ERROR;
00754   }
00755 }
00756 
00757 /**
00758   * @brief  Allows to write block(s) to a specified address in a card. The Data
00759   *         transfer is managed by polling mode.
00760   * @note   This API should be followed by a check on the card state through
00761   *         HAL_MMC_GetCardState().
00762   * @param  hmmc: Pointer to MMC handle
00763   * @param  pData: pointer to the buffer that will contain the data to transmit
00764   * @param  BlockAdd: Block Address where data will be written
00765   * @param  NumberOfBlocks: Number of MMC blocks to write
00766   * @param  Timeout: Specify timeout value
00767   * @retval HAL status
00768   */
00769 HAL_StatusTypeDef HAL_MMC_WriteBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
00770 {
00771   SDIO_DataInitTypeDef config;
00772   uint32_t errorstate;
00773   uint32_t tickstart = HAL_GetTick();
00774   uint32_t count, data, dataremaining;
00775   uint32_t add = BlockAdd;
00776   uint8_t *tempbuff = pData;
00777 
00778   if(NULL == pData)
00779   {
00780     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
00781     return HAL_ERROR;
00782   }
00783 
00784   if(hmmc->State == HAL_MMC_STATE_READY)
00785   {
00786     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
00787 
00788     if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
00789     {
00790       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
00791       return HAL_ERROR;
00792     }
00793 
00794     hmmc->State = HAL_MMC_STATE_BUSY;
00795 
00796     /* Initialize data control register */
00797     hmmc->Instance->DCTRL = 0U;
00798 
00799     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
00800     {
00801       add *= 512U;
00802     }
00803 
00804     /* Write Blocks in Polling mode */
00805     if(NumberOfBlocks > 1U)
00806     {
00807       hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
00808 
00809       /* Write Multi Block command */
00810       errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
00811     }
00812     else
00813     {
00814       hmmc->Context = MMC_CONTEXT_WRITE_SINGLE_BLOCK;
00815 
00816       /* Write Single Block command */
00817       errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
00818     }
00819     if(errorstate != HAL_MMC_ERROR_NONE)
00820     {
00821       /* Clear all the static flags */
00822       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
00823       hmmc->ErrorCode |= errorstate;
00824       hmmc->State = HAL_MMC_STATE_READY;
00825       return HAL_ERROR;
00826     }
00827 
00828     /* Configure the MMC DPSM (Data Path State Machine) */
00829     config.DataTimeOut   = SDMMC_DATATIMEOUT;
00830     config.DataLength    = NumberOfBlocks * MMC_BLOCKSIZE;
00831     config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
00832     config.TransferDir   = SDIO_TRANSFER_DIR_TO_CARD;
00833     config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
00834     config.DPSM          = SDIO_DPSM_ENABLE;
00835     (void)SDIO_ConfigData(hmmc->Instance, &config);
00836 
00837     /* Write block(s) in polling mode */
00838     dataremaining = config.DataLength;
00839 #if defined(SDIO_STA_STBITERR)
00840     while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_FLAG_STBITERR))
00841 #else /* SDIO_STA_STBITERR not defined */
00842     while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND))
00843 #endif /* SDIO_STA_STBITERR */
00844     {
00845       if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXFIFOHE) && (dataremaining > 0U))
00846       {
00847         /* Write data to SDIO Tx FIFO */
00848         for(count = 0U; count < 8U; count++)
00849         {
00850           data = (uint32_t)(*tempbuff);
00851           tempbuff++;
00852           dataremaining--;
00853           data |= ((uint32_t)(*tempbuff) << 8U);
00854           tempbuff++;
00855           dataremaining--;
00856           data |= ((uint32_t)(*tempbuff) << 16U);
00857           tempbuff++;
00858           dataremaining--;
00859           data |= ((uint32_t)(*tempbuff) << 24U);
00860           tempbuff++;
00861           dataremaining--;
00862           (void)SDIO_WriteFIFO(hmmc->Instance, &data);
00863         }
00864       }
00865 
00866       if(((HAL_GetTick()-tickstart) >=  Timeout) || (Timeout == 0U))
00867       {
00868         /* Clear all the static flags */
00869         __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
00870         hmmc->ErrorCode |= errorstate;
00871         hmmc->State = HAL_MMC_STATE_READY;
00872         return HAL_TIMEOUT;
00873       }
00874     }
00875 
00876     /* Send stop transmission command in case of multiblock write */
00877     if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1U))
00878     {
00879       /* Send stop transmission command */
00880       errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
00881       if(errorstate != HAL_MMC_ERROR_NONE)
00882       {
00883         /* Clear all the static flags */
00884         __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
00885         hmmc->ErrorCode |= errorstate;
00886         hmmc->State = HAL_MMC_STATE_READY;
00887         return HAL_ERROR;
00888       }
00889     }
00890 
00891     /* Get error state */
00892     if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DTIMEOUT))
00893     {
00894       /* Clear all the static flags */
00895       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
00896       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
00897       hmmc->State = HAL_MMC_STATE_READY;
00898       return HAL_ERROR;
00899     }
00900     else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL))
00901     {
00902       /* Clear all the static flags */
00903       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
00904       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
00905       hmmc->State = HAL_MMC_STATE_READY;
00906       return HAL_ERROR;
00907     }
00908     else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR))
00909     {
00910       /* Clear all the static flags */
00911       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
00912       hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
00913       hmmc->State = HAL_MMC_STATE_READY;
00914       return HAL_ERROR;
00915     }
00916     else
00917     {
00918       /* Nothing to do */
00919     }
00920 
00921     /* Clear all the static flags */
00922     __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
00923 
00924     hmmc->State = HAL_MMC_STATE_READY;
00925 
00926     return HAL_OK;
00927   }
00928   else
00929   {
00930     hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
00931     return HAL_ERROR;
00932   }
00933 }
00934 
00935 /**
00936   * @brief  Reads block(s) from a specified address in a card. The Data transfer
00937   *         is managed in interrupt mode.
00938   * @note   This API should be followed by a check on the card state through
00939   *         HAL_MMC_GetCardState().
00940   * @note   You could also check the IT transfer process through the MMC Rx
00941   *         interrupt event.
00942   * @param  hmmc: Pointer to MMC handle
00943   * @param  pData: Pointer to the buffer that will contain the received data
00944   * @param  BlockAdd: Block Address from where data is to be read
00945   * @param  NumberOfBlocks: Number of blocks to read.
00946   * @retval HAL status
00947   */
00948 HAL_StatusTypeDef HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
00949 {
00950   SDIO_DataInitTypeDef config;
00951   uint32_t errorstate;
00952   uint32_t add = BlockAdd;
00953 
00954   if(NULL == pData)
00955   {
00956     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
00957     return HAL_ERROR;
00958   }
00959 
00960   if(hmmc->State == HAL_MMC_STATE_READY)
00961   {
00962     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
00963 
00964     if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
00965     {
00966       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
00967       return HAL_ERROR;
00968     }
00969 
00970     hmmc->State = HAL_MMC_STATE_BUSY;
00971 
00972     /* Initialize data control register */
00973     hmmc->Instance->DCTRL = 0U;
00974 
00975     hmmc->pRxBuffPtr = pData;
00976     hmmc->RxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
00977 
00978 #if defined(SDIO_STA_STBITERR)
00979     __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_FLAG_RXFIFOHF | SDIO_IT_STBITERR));
00980 #else /* SDIO_STA_STBITERR not defined */
00981     __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_FLAG_RXFIFOHF));
00982 #endif /* SDIO_STA_STBITERR */
00983 
00984     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
00985     {
00986       add *= 512U;
00987     }
00988 
00989     /* Configure the MMC DPSM (Data Path State Machine) */
00990     config.DataTimeOut   = SDMMC_DATATIMEOUT;
00991     config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
00992     config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
00993     config.TransferDir   = SDIO_TRANSFER_DIR_TO_SDIO;
00994     config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
00995     config.DPSM          = SDIO_DPSM_ENABLE;
00996     (void)SDIO_ConfigData(hmmc->Instance, &config);
00997 
00998     /* Read Blocks in IT mode */
00999     if(NumberOfBlocks > 1U)
01000     {
01001       hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_IT);
01002 
01003       /* Read Multi Block command */
01004       errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
01005     }
01006     else
01007     {
01008       hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_IT);
01009 
01010       /* Read Single Block command */
01011       errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
01012     }
01013 
01014     if(errorstate != HAL_MMC_ERROR_NONE)
01015     {
01016       /* Clear all the static flags */
01017       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
01018       hmmc->ErrorCode |= errorstate;
01019       hmmc->State = HAL_MMC_STATE_READY;
01020       return HAL_ERROR;
01021     }
01022 
01023     return HAL_OK;
01024   }
01025   else
01026   {
01027     return HAL_BUSY;
01028   }
01029 }
01030 
01031 /**
01032   * @brief  Writes block(s) to a specified address in a card. The Data transfer
01033   *         is managed in interrupt mode.
01034   * @note   This API should be followed by a check on the card state through
01035   *         HAL_MMC_GetCardState().
01036   * @note   You could also check the IT transfer process through the MMC Tx
01037   *         interrupt event.
01038   * @param  hmmc: Pointer to MMC handle
01039   * @param  pData: Pointer to the buffer that will contain the data to transmit
01040   * @param  BlockAdd: Block Address where data will be written
01041   * @param  NumberOfBlocks: Number of blocks to write
01042   * @retval HAL status
01043   */
01044 HAL_StatusTypeDef HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
01045 {
01046   SDIO_DataInitTypeDef config;
01047   uint32_t errorstate;
01048   uint32_t add = BlockAdd;
01049 
01050   if(NULL == pData)
01051   {
01052     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
01053     return HAL_ERROR;
01054   }
01055 
01056   if(hmmc->State == HAL_MMC_STATE_READY)
01057   {
01058     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
01059 
01060     if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
01061     {
01062       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
01063       return HAL_ERROR;
01064     }
01065 
01066     hmmc->State = HAL_MMC_STATE_BUSY;
01067 
01068     /* Initialize data control register */
01069     hmmc->Instance->DCTRL = 0U;
01070 
01071     hmmc->pTxBuffPtr = pData;
01072     hmmc->TxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
01073 
01074     /* Enable transfer interrupts */
01075 #if defined(SDIO_STA_STBITERR)
01076     __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_DATAEND | SDIO_FLAG_TXFIFOHE | SDIO_IT_STBITERR));
01077 #else /* SDIO_STA_STBITERR not defined */
01078     __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_DATAEND | SDIO_FLAG_TXFIFOHE));
01079 #endif /* SDIO_STA_STBITERR */
01080 
01081     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
01082     {
01083       add *= 512U;
01084     }
01085 
01086     /* Write Blocks in Polling mode */
01087     if(NumberOfBlocks > 1U)
01088     {
01089       hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK| MMC_CONTEXT_IT);
01090 
01091       /* Write Multi Block command */
01092       errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
01093     }
01094     else
01095     {
01096       hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_IT);
01097 
01098       /* Write Single Block command */
01099       errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
01100     }
01101     if(errorstate != HAL_MMC_ERROR_NONE)
01102     {
01103       /* Clear all the static flags */
01104       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
01105       hmmc->ErrorCode |= errorstate;
01106       hmmc->State = HAL_MMC_STATE_READY;
01107       return HAL_ERROR;
01108     }
01109 
01110     /* Configure the MMC DPSM (Data Path State Machine) */ 
01111     config.DataTimeOut   = SDMMC_DATATIMEOUT;
01112     config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
01113     config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
01114     config.TransferDir   = SDIO_TRANSFER_DIR_TO_CARD;
01115     config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
01116     config.DPSM          = SDIO_DPSM_ENABLE;
01117     (void)SDIO_ConfigData(hmmc->Instance, &config);
01118     
01119     return HAL_OK;
01120   }
01121   else
01122   {
01123     return HAL_BUSY;
01124   }
01125 }
01126 
01127 /**
01128   * @brief  Reads block(s) from a specified address in a card. The Data transfer
01129   *         is managed by DMA mode.
01130   * @note   This API should be followed by a check on the card state through
01131   *         HAL_MMC_GetCardState().
01132   * @note   You could also check the DMA transfer process through the MMC Rx
01133   *         interrupt event.
01134   * @param  hmmc: Pointer MMC handle
01135   * @param  pData: Pointer to the buffer that will contain the received data
01136   * @param  BlockAdd: Block Address from where data is to be read
01137   * @param  NumberOfBlocks: Number of blocks to read.
01138   * @retval HAL status
01139   */
01140 HAL_StatusTypeDef HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
01141 {
01142   SDIO_DataInitTypeDef config;
01143   uint32_t errorstate;
01144   uint32_t add = BlockAdd;
01145 
01146   if(NULL == pData)
01147   {
01148     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
01149     return HAL_ERROR;
01150   }
01151 
01152   if(hmmc->State == HAL_MMC_STATE_READY)
01153   {
01154     hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
01155 
01156     if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
01157     {
01158       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
01159       return HAL_ERROR;
01160     }
01161 
01162     hmmc->State = HAL_MMC_STATE_BUSY;
01163 
01164     /* Initialize data control register */
01165     hmmc->Instance->DCTRL = 0U;
01166 
01167 #if defined(SDIO_STA_STBITERR)
01168     __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_IT_STBITERR));
01169 #else /* SDIO_STA_STBITERR not defined */
01170     __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND));
01171 #endif /* SDIO_STA_STBITERR */
01172 
01173     /* Set the DMA transfer complete callback */
01174     hmmc->hdmarx->XferCpltCallback = MMC_DMAReceiveCplt;
01175 
01176     /* Set the DMA error callback */
01177     hmmc->hdmarx->XferErrorCallback = MMC_DMAError;
01178 
01179     /* Set the DMA Abort callback */
01180     hmmc->hdmarx->XferAbortCallback = NULL;
01181 
01182     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
01183     {
01184       add *= 512U;
01185     }
01186 
01187     /* Force DMA Direction */
01188     hmmc->hdmarx->Init.Direction = DMA_PERIPH_TO_MEMORY;
01189     MODIFY_REG(hmmc->hdmarx->Instance->CR, DMA_SxCR_DIR, hmmc->hdmarx->Init.Direction);
01190 
01191     /* Enable the DMA Channel */
01192     if(HAL_DMA_Start_IT(hmmc->hdmarx, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)pData, (uint32_t)(MMC_BLOCKSIZE * NumberOfBlocks)/4) != HAL_OK)
01193     {
01194       __HAL_MMC_DISABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND));
01195       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
01196       hmmc->ErrorCode = HAL_MMC_ERROR_DMA;
01197       hmmc->State = HAL_MMC_STATE_READY;
01198       return HAL_ERROR;
01199     }
01200     else
01201     {
01202       /* Enable MMC DMA transfer */
01203       __HAL_MMC_DMA_ENABLE(hmmc);
01204 
01205       /* Configure the MMC DPSM (Data Path State Machine) */
01206       config.DataTimeOut   = SDMMC_DATATIMEOUT;
01207       config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
01208       config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
01209       config.TransferDir   = SDIO_TRANSFER_DIR_TO_SDIO;
01210       config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
01211       config.DPSM          = SDIO_DPSM_ENABLE;
01212       (void)SDIO_ConfigData(hmmc->Instance, &config);
01213 
01214       /* Read Blocks in DMA mode */
01215       if(NumberOfBlocks > 1U)
01216       {
01217         hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
01218 
01219         /* Read Multi Block command */
01220         errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
01221       }
01222       else
01223       {
01224         hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_DMA);
01225 
01226         /* Read Single Block command */
01227         errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
01228       }
01229       if(errorstate != HAL_MMC_ERROR_NONE)
01230       {
01231         /* Clear all the static flags */
01232         __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 
01233         __HAL_MMC_DISABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND));
01234         hmmc->ErrorCode = errorstate;
01235         hmmc->State = HAL_MMC_STATE_READY;
01236         return HAL_ERROR;
01237       }
01238 
01239       return HAL_OK;
01240     }
01241   }
01242   else
01243   {
01244     return HAL_BUSY;
01245   }
01246 }
01247 
01248 /**
01249   * @brief  Writes block(s) to a specified address in a card. The Data transfer
01250   *         is managed by DMA mode.
01251   * @note   This API should be followed by a check on the card state through
01252   *         HAL_MMC_GetCardState().
01253   * @note   You could also check the DMA transfer process through the MMC Tx
01254   *         interrupt event.
01255   * @param  hmmc: Pointer to MMC handle
01256   * @param  pData: Pointer to the buffer that will contain the data to transmit
01257   * @param  BlockAdd: Block Address where data will be written
01258   * @param  NumberOfBlocks: Number of blocks to write
01259   * @retval HAL status
01260   */
01261 HAL_StatusTypeDef HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
01262 {
01263   SDIO_DataInitTypeDef config;
01264   uint32_t errorstate;
01265   uint32_t add = BlockAdd;
01266 
01267   if(NULL == pData)
01268   {
01269     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
01270     return HAL_ERROR;
01271   }
01272 
01273   if(hmmc->State == HAL_MMC_STATE_READY)
01274   {
01275     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
01276 
01277     if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
01278     {
01279       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
01280       return HAL_ERROR;
01281     }
01282 
01283     hmmc->State = HAL_MMC_STATE_BUSY;
01284 
01285     /* Initialize data control register */
01286     hmmc->Instance->DCTRL = 0U;
01287 
01288     /* Enable MMC Error interrupts */
01289 #if defined(SDIO_STA_STBITERR)
01290         __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR));
01291 #else /* SDIO_STA_STBITERR not defined */
01292         __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR));
01293 #endif /* SDIO_STA_STBITERR */  
01294 
01295     /* Set the DMA transfer complete callback */
01296     hmmc->hdmatx->XferCpltCallback = MMC_DMATransmitCplt;
01297 
01298     /* Set the DMA error callback */
01299     hmmc->hdmatx->XferErrorCallback = MMC_DMAError;
01300 
01301     /* Set the DMA Abort callback */
01302     hmmc->hdmatx->XferAbortCallback = NULL;
01303 
01304     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
01305     {
01306       add *= 512U;
01307     }
01308 
01309 
01310     /* Write Blocks in Polling mode */
01311     if(NumberOfBlocks > 1U)
01312     {
01313       hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
01314 
01315       /* Write Multi Block command */
01316       errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
01317     }
01318     else
01319     {
01320       hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_DMA);
01321 
01322       /* Write Single Block command */
01323       errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
01324     }
01325     if(errorstate != HAL_MMC_ERROR_NONE)
01326     {
01327       /* Clear all the static flags */
01328       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
01329       __HAL_MMC_DISABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_DATAEND));
01330       hmmc->ErrorCode |= errorstate;
01331       hmmc->State = HAL_MMC_STATE_READY;
01332       return HAL_ERROR;
01333     }
01334 
01335     /* Enable SDIO DMA transfer */
01336     __HAL_MMC_DMA_ENABLE(hmmc);
01337 
01338     /* Force DMA Direction */
01339     hmmc->hdmatx->Init.Direction = DMA_MEMORY_TO_PERIPH;
01340     MODIFY_REG(hmmc->hdmatx->Instance->CR, DMA_SxCR_DIR, hmmc->hdmatx->Init.Direction);
01341 
01342     /* Enable the DMA Channel */
01343     if(HAL_DMA_Start_IT(hmmc->hdmatx, (uint32_t)pData, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)(MMC_BLOCKSIZE * NumberOfBlocks)/4) != HAL_OK)
01344     {
01345       __HAL_MMC_DISABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_DATAEND));
01346       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
01347       hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
01348       hmmc->State = HAL_MMC_STATE_READY;
01349       return HAL_ERROR;
01350     }
01351     else
01352     {    
01353       /* Configure the MMC DPSM (Data Path State Machine) */ 
01354       config.DataTimeOut   = SDMMC_DATATIMEOUT;
01355       config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
01356       config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
01357       config.TransferDir   = SDIO_TRANSFER_DIR_TO_CARD;
01358       config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
01359       config.DPSM          = SDIO_DPSM_ENABLE;
01360       (void)SDIO_ConfigData(hmmc->Instance, &config);
01361 
01362       return HAL_OK;
01363     }
01364   }
01365   else
01366   {
01367     return HAL_BUSY;
01368   }
01369 }
01370 
01371 /**
01372   * @brief  Erases the specified memory area of the given MMC card.
01373   * @note   This API should be followed by a check on the card state through
01374   *         HAL_MMC_GetCardState().
01375   * @param  hmmc: Pointer to MMC handle
01376   * @param  BlockStartAdd: Start Block address
01377   * @param  BlockEndAdd: End Block address
01378   * @retval HAL status
01379   */
01380 HAL_StatusTypeDef HAL_MMC_Erase(MMC_HandleTypeDef *hmmc, uint32_t BlockStartAdd, uint32_t BlockEndAdd)
01381 {
01382   uint32_t errorstate;
01383   uint32_t start_add = BlockStartAdd;
01384   uint32_t end_add = BlockEndAdd;
01385 
01386   if(hmmc->State == HAL_MMC_STATE_READY)
01387   {
01388     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
01389 
01390     if(end_add < start_add)
01391     {
01392       hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
01393       return HAL_ERROR;
01394     }
01395 
01396     if(end_add > (hmmc->MmcCard.LogBlockNbr))
01397     {
01398       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
01399       return HAL_ERROR;
01400     }
01401 
01402     hmmc->State = HAL_MMC_STATE_BUSY;
01403 
01404     /* Check if the card command class supports erase command */
01405     if(((hmmc->MmcCard.Class) & SDIO_CCCC_ERASE) == 0U)
01406     {
01407       /* Clear all the static flags */
01408       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
01409       hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
01410       hmmc->State = HAL_MMC_STATE_READY;
01411       return HAL_ERROR;
01412     }
01413 
01414     if((SDIO_GetResponse(hmmc->Instance, SDIO_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
01415     {
01416       /* Clear all the static flags */
01417       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
01418       hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED;
01419       hmmc->State = HAL_MMC_STATE_READY;
01420       return HAL_ERROR;
01421     }
01422 
01423     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
01424     {
01425       start_add *= 512U;
01426       end_add   *= 512U;
01427     }
01428 
01429     /* Send CMD35 MMC_ERASE_GRP_START with argument as addr  */
01430     errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, start_add);
01431     if(errorstate != HAL_MMC_ERROR_NONE)
01432     {
01433       /* Clear all the static flags */
01434       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
01435       hmmc->ErrorCode |= errorstate;
01436       hmmc->State = HAL_MMC_STATE_READY;
01437       return HAL_ERROR;
01438     }
01439 
01440     /* Send CMD36 MMC_ERASE_GRP_END with argument as addr  */
01441     errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, end_add);
01442     if(errorstate != HAL_MMC_ERROR_NONE)
01443     {
01444       /* Clear all the static flags */
01445       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
01446       hmmc->ErrorCode |= errorstate;
01447       hmmc->State = HAL_MMC_STATE_READY;
01448       return HAL_ERROR;
01449     }
01450 
01451     /* Send CMD38 ERASE */
01452     errorstate = SDMMC_CmdErase(hmmc->Instance);
01453     if(errorstate != HAL_MMC_ERROR_NONE)
01454     {
01455       /* Clear all the static flags */
01456       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
01457       hmmc->ErrorCode |= errorstate;
01458       hmmc->State = HAL_MMC_STATE_READY;
01459       return HAL_ERROR;
01460     }
01461 
01462     hmmc->State = HAL_MMC_STATE_READY;
01463 
01464     return HAL_OK;
01465   }
01466   else
01467   {
01468     return HAL_BUSY;
01469   }
01470 }
01471 
01472 /**
01473   * @brief  This function handles MMC card interrupt request.
01474   * @param  hmmc: Pointer to MMC handle
01475   * @retval None
01476   */
01477 void HAL_MMC_IRQHandler(MMC_HandleTypeDef *hmmc)
01478 {
01479   uint32_t errorstate;
01480   uint32_t context = hmmc->Context;
01481 
01482   /* Check for SDIO interrupt flags */
01483   if((__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXFIFOHF) != RESET) && ((context & MMC_CONTEXT_IT) != 0U))
01484   {
01485     MMC_Read_IT(hmmc);
01486   }
01487 
01488   else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DATAEND) != RESET)
01489   {
01490     __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_FLAG_DATAEND);
01491 
01492 #if defined(SDIO_STA_STBITERR)
01493     __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
01494                              SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR | SDIO_IT_STBITERR);
01495 #else /* SDIO_STA_STBITERR not defined */
01496     __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND  | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT |\
01497                                SDIO_IT_TXUNDERR | SDIO_IT_RXOVERR  | SDIO_IT_TXFIFOHE |\
01498                                SDIO_IT_RXFIFOHF);
01499 #endif /* SDIO_STA_STBITERR */
01500     
01501     hmmc->Instance->DCTRL &= ~(SDIO_DCTRL_DTEN);
01502 
01503     if((context & MMC_CONTEXT_DMA) != 0U)
01504     {
01505       if((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)
01506       {
01507         errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
01508         if(errorstate != HAL_MMC_ERROR_NONE)
01509         {
01510           hmmc->ErrorCode |= errorstate;
01511 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01512           hmmc->ErrorCallback(hmmc);
01513 #else
01514           HAL_MMC_ErrorCallback(hmmc);
01515 #endif
01516         }
01517       }
01518       if(((context & MMC_CONTEXT_READ_SINGLE_BLOCK) == 0U) && ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) == 0U))
01519       {
01520         /* Disable the DMA transfer for transmit request by setting the DMAEN bit
01521         in the MMC DCTRL register */
01522         hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
01523         
01524         hmmc->State = HAL_MMC_STATE_READY;
01525         
01526 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01527         hmmc->TxCpltCallback(hmmc);
01528 #else
01529         HAL_MMC_TxCpltCallback(hmmc);
01530 #endif
01531       }
01532     }
01533     else if((context & MMC_CONTEXT_IT) != 0U)
01534     {
01535       /* Stop Transfer for Write Multi blocks or Read Multi blocks */
01536       if(((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
01537       {
01538         errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
01539         if(errorstate != HAL_MMC_ERROR_NONE)
01540         {
01541           hmmc->ErrorCode |= errorstate;
01542 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01543           hmmc->ErrorCallback(hmmc);
01544 #else
01545           HAL_MMC_ErrorCallback(hmmc);
01546 #endif
01547         }
01548       }
01549 
01550       /* Clear all the static flags */
01551       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
01552 
01553       hmmc->State = HAL_MMC_STATE_READY;
01554       if(((context & MMC_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
01555       {
01556 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01557         hmmc->RxCpltCallback(hmmc);
01558 #else
01559         HAL_MMC_RxCpltCallback(hmmc);
01560 #endif
01561       }
01562       else
01563       {
01564 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01565         hmmc->TxCpltCallback(hmmc);
01566 #else
01567         HAL_MMC_TxCpltCallback(hmmc);
01568 #endif
01569       }
01570     }
01571     else
01572     {
01573       /* Nothing to do */
01574     }
01575   }
01576 
01577   else if((__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXFIFOHE) != RESET) && ((context & MMC_CONTEXT_IT) != 0U))
01578   {
01579     MMC_Write_IT(hmmc);
01580   }
01581 
01582 #if defined(SDIO_STA_STBITERR)
01583   else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_RXOVERR | SDIO_FLAG_TXUNDERR | SDIO_FLAG_STBITERR) != RESET)
01584 #else /* SDIO_STA_STBITERR not defined */
01585   else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_RXOVERR | SDIO_FLAG_TXUNDERR) != RESET)
01586 #endif /* SDIO_STA_STBITERR */
01587   {
01588     /* Set Error code */
01589     if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL) != RESET)
01590     {
01591       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
01592     }
01593     if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DTIMEOUT) != RESET)
01594     {
01595       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
01596     }
01597     if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR) != RESET)
01598     {
01599       hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
01600     }
01601     if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR) != RESET)
01602     {
01603       hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
01604     }
01605 #if defined(SDIO_STA_STBITERR)
01606     if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_STBITERR) != RESET)
01607     {
01608       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
01609     }
01610 #endif /* SDIO_STA_STBITERR */
01611 
01612 #if defined(SDIO_STA_STBITERR)
01613     /* Clear All flags */
01614     __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS | SDIO_FLAG_STBITERR);
01615 
01616     /* Disable all interrupts */
01617     __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
01618                                SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR | SDIO_IT_STBITERR);
01619 #else /* SDIO_STA_STBITERR */
01620     /* Clear All flags */
01621     __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
01622     
01623     /* Disable all interrupts */
01624     __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
01625                              SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
01626 #endif /* SDIO_STA_STBITERR */
01627 
01628     hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
01629 
01630     if((context & MMC_CONTEXT_IT) != 0U)
01631     {
01632       /* Set the MMC state to ready to be able to start again the process */
01633       hmmc->State = HAL_MMC_STATE_READY;
01634 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01635       hmmc->ErrorCallback(hmmc);
01636 #else
01637       HAL_MMC_ErrorCallback(hmmc);
01638 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
01639     }
01640     else if((context & MMC_CONTEXT_DMA) != 0U)
01641     {
01642       /* Abort the MMC DMA Streams */
01643       if(hmmc->hdmatx != NULL)
01644       {
01645         /* Set the DMA Tx abort callback */
01646         hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort;
01647         /* Abort DMA in IT mode */
01648         if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
01649         {
01650           MMC_DMATxAbort(hmmc->hdmatx);
01651         }
01652       }
01653       else if(hmmc->hdmarx != NULL)
01654       {
01655         /* Set the DMA Rx abort callback */
01656         hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort;
01657         /* Abort DMA in IT mode */
01658         if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
01659         {
01660           MMC_DMARxAbort(hmmc->hdmarx);
01661         }
01662       }
01663       else
01664       {
01665         hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
01666         hmmc->State = HAL_MMC_STATE_READY;
01667 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01668         hmmc->AbortCpltCallback(hmmc);
01669 #else
01670         HAL_MMC_AbortCallback(hmmc);
01671 #endif
01672       }
01673     }
01674     else
01675     {
01676       /* Nothing to do */
01677     }
01678   }
01679 
01680   else
01681   {
01682     /* Nothing to do */
01683   }
01684 }
01685 
01686 /**
01687   * @brief return the MMC state
01688   * @param hmmc: Pointer to mmc handle
01689   * @retval HAL state
01690   */
01691 HAL_MMC_StateTypeDef HAL_MMC_GetState(MMC_HandleTypeDef *hmmc)
01692 {
01693   return hmmc->State;
01694 }
01695 
01696 /**
01697 * @brief  Return the MMC error code
01698 * @param  hmmc : Pointer to a MMC_HandleTypeDef structure that contains
01699   *              the configuration information.
01700 * @retval MMC Error Code
01701 */
01702 uint32_t HAL_MMC_GetError(MMC_HandleTypeDef *hmmc)
01703 {
01704   return hmmc->ErrorCode;
01705 }
01706 
01707 /**
01708   * @brief Tx Transfer completed callbacks
01709   * @param hmmc: Pointer to MMC handle
01710   * @retval None
01711   */
01712 __weak void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef *hmmc)
01713 {
01714   /* Prevent unused argument(s) compilation warning */
01715   UNUSED(hmmc);
01716 
01717   /* NOTE : This function should not be modified, when the callback is needed,
01718             the HAL_MMC_TxCpltCallback can be implemented in the user file
01719    */
01720 }
01721 
01722 /**
01723   * @brief Rx Transfer completed callbacks
01724   * @param hmmc: Pointer MMC handle
01725   * @retval None
01726   */
01727 __weak void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef *hmmc)
01728 {
01729   /* Prevent unused argument(s) compilation warning */
01730   UNUSED(hmmc);
01731 
01732   /* NOTE : This function should not be modified, when the callback is needed,
01733             the HAL_MMC_RxCpltCallback can be implemented in the user file
01734    */
01735 }
01736 
01737 /**
01738   * @brief MMC error callbacks
01739   * @param hmmc: Pointer MMC handle
01740   * @retval None
01741   */
01742 __weak void HAL_MMC_ErrorCallback(MMC_HandleTypeDef *hmmc)
01743 {
01744   /* Prevent unused argument(s) compilation warning */
01745   UNUSED(hmmc);
01746 
01747   /* NOTE : This function should not be modified, when the callback is needed,
01748             the HAL_MMC_ErrorCallback can be implemented in the user file
01749    */
01750 }
01751 
01752 /**
01753   * @brief MMC Abort callbacks
01754   * @param hmmc: Pointer MMC handle
01755   * @retval None
01756   */
01757 __weak void HAL_MMC_AbortCallback(MMC_HandleTypeDef *hmmc)
01758 {
01759   /* Prevent unused argument(s) compilation warning */
01760   UNUSED(hmmc);
01761 
01762   /* NOTE : This function should not be modified, when the callback is needed,
01763             the HAL_MMC_AbortCallback can be implemented in the user file
01764    */
01765 }
01766 
01767 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
01768 /**
01769   * @brief  Register a User MMC Callback
01770   *         To be used instead of the weak (surcharged) predefined callback
01771   * @param hmmc : MMC handle
01772   * @param CallbackId : ID of the callback to be registered
01773   *        This parameter can be one of the following values:
01774   *          @arg @ref HAL_MMC_TX_CPLT_CB_ID    MMC Tx Complete Callback ID
01775   *          @arg @ref HAL_MMC_RX_CPLT_CB_ID    MMC Rx Complete Callback ID
01776   *          @arg @ref HAL_MMC_ERROR_CB_ID      MMC Error Callback ID
01777   *          @arg @ref HAL_MMC_ABORT_CB_ID      MMC Abort Callback ID
01778   *          @arg @ref HAL_MMC_MSP_INIT_CB_ID   MMC MspInit Callback ID
01779   *          @arg @ref HAL_MMC_MSP_DEINIT_CB_ID MMC MspDeInit Callback ID
01780   * @param pCallback : pointer to the Callback function
01781   * @retval status
01782   */
01783 HAL_StatusTypeDef HAL_MMC_RegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId, pMMC_CallbackTypeDef pCallback)
01784 {
01785   HAL_StatusTypeDef status = HAL_OK;
01786 
01787   if(pCallback == NULL)
01788   {
01789     /* Update the error code */
01790     hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
01791     return HAL_ERROR;
01792   }
01793 
01794   /* Process locked */
01795   __HAL_LOCK(hmmc);
01796 
01797   if(hmmc->State == HAL_MMC_STATE_READY)
01798   {
01799     switch (CallbackId)
01800     {
01801     case HAL_MMC_TX_CPLT_CB_ID :
01802       hmmc->TxCpltCallback = pCallback;
01803       break;
01804     case HAL_MMC_RX_CPLT_CB_ID :
01805       hmmc->RxCpltCallback = pCallback;
01806       break;
01807     case HAL_MMC_ERROR_CB_ID :
01808       hmmc->ErrorCallback = pCallback;
01809       break;
01810     case HAL_MMC_ABORT_CB_ID :
01811       hmmc->AbortCpltCallback = pCallback;
01812       break;
01813     case HAL_MMC_MSP_INIT_CB_ID :
01814       hmmc->MspInitCallback = pCallback;
01815       break;
01816     case HAL_MMC_MSP_DEINIT_CB_ID :
01817       hmmc->MspDeInitCallback = pCallback;
01818       break;
01819     default :
01820       /* Update the error code */
01821       hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
01822       /* update return status */
01823       status =  HAL_ERROR;
01824       break;
01825     }
01826   }
01827   else if (hmmc->State == HAL_MMC_STATE_RESET)
01828   {
01829     switch (CallbackId)
01830     {
01831     case HAL_MMC_MSP_INIT_CB_ID :
01832       hmmc->MspInitCallback = pCallback;
01833       break;
01834     case HAL_MMC_MSP_DEINIT_CB_ID :
01835       hmmc->MspDeInitCallback = pCallback;
01836       break;
01837     default :
01838       /* Update the error code */
01839       hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
01840       /* update return status */
01841       status =  HAL_ERROR;
01842       break;
01843     }
01844   }
01845   else
01846   {
01847     /* Update the error code */
01848     hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
01849     /* update return status */
01850     status =  HAL_ERROR;
01851   }
01852 
01853   /* Release Lock */
01854   __HAL_UNLOCK(hmmc);
01855   return status;
01856 }
01857 
01858 /**
01859   * @brief  Unregister a User MMC Callback
01860   *         MMC Callback is redirected to the weak (surcharged) predefined callback
01861   * @param hmmc : MMC handle
01862   * @param CallbackId : ID of the callback to be unregistered
01863   *        This parameter can be one of the following values:
01864   *          @arg @ref HAL_MMC_TX_CPLT_CB_ID    MMC Tx Complete Callback ID
01865   *          @arg @ref HAL_MMC_RX_CPLT_CB_ID    MMC Rx Complete Callback ID
01866   *          @arg @ref HAL_MMC_ERROR_CB_ID      MMC Error Callback ID
01867   *          @arg @ref HAL_MMC_ABORT_CB_ID      MMC Abort Callback ID
01868   *          @arg @ref HAL_MMC_MSP_INIT_CB_ID   MMC MspInit Callback ID
01869   *          @arg @ref HAL_MMC_MSP_DEINIT_CB_ID MMC MspDeInit Callback ID
01870   * @retval status
01871   */
01872 HAL_StatusTypeDef HAL_MMC_UnRegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId)
01873 {
01874   HAL_StatusTypeDef status = HAL_OK;
01875 
01876   /* Process locked */
01877   __HAL_LOCK(hmmc);
01878 
01879   if(hmmc->State == HAL_MMC_STATE_READY)
01880   {
01881     switch (CallbackId)
01882     {
01883     case HAL_MMC_TX_CPLT_CB_ID :
01884       hmmc->TxCpltCallback = HAL_MMC_TxCpltCallback;
01885       break;
01886     case HAL_MMC_RX_CPLT_CB_ID :
01887       hmmc->RxCpltCallback = HAL_MMC_RxCpltCallback;
01888       break;
01889     case HAL_MMC_ERROR_CB_ID :
01890       hmmc->ErrorCallback = HAL_MMC_ErrorCallback;
01891       break;
01892     case HAL_MMC_ABORT_CB_ID :
01893       hmmc->AbortCpltCallback = HAL_MMC_AbortCallback;
01894       break;
01895     case HAL_MMC_MSP_INIT_CB_ID :
01896       hmmc->MspInitCallback = HAL_MMC_MspInit;
01897       break;
01898     case HAL_MMC_MSP_DEINIT_CB_ID :
01899       hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
01900       break;
01901     default :
01902       /* Update the error code */
01903       hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
01904       /* update return status */
01905       status =  HAL_ERROR;
01906       break;
01907     }
01908   }
01909   else if (hmmc->State == HAL_MMC_STATE_RESET)
01910   {
01911     switch (CallbackId)
01912     {
01913     case HAL_MMC_MSP_INIT_CB_ID :
01914       hmmc->MspInitCallback = HAL_MMC_MspInit;
01915       break;
01916     case HAL_MMC_MSP_DEINIT_CB_ID :
01917       hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
01918       break;
01919     default :
01920       /* Update the error code */
01921       hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
01922       /* update return status */
01923       status =  HAL_ERROR;
01924       break;
01925     }
01926   }
01927   else
01928   {
01929     /* Update the error code */
01930     hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
01931     /* update return status */
01932     status =  HAL_ERROR;
01933   }
01934 
01935   /* Release Lock */
01936   __HAL_UNLOCK(hmmc);
01937   return status;
01938 }
01939 #endif
01940 
01941 /**
01942   * @}
01943   */
01944 
01945 /** @addtogroup MMC_Exported_Functions_Group3
01946  *  @brief   management functions
01947  *
01948 @verbatim
01949   ==============================================================================
01950                       ##### Peripheral Control functions #####
01951   ==============================================================================
01952   [..]
01953     This subsection provides a set of functions allowing to control the MMC card
01954     operations and get the related information
01955 
01956 @endverbatim
01957   * @{
01958   */
01959 
01960 /**
01961   * @brief  Returns information the information of the card which are stored on
01962   *         the CID register.
01963   * @param  hmmc: Pointer to MMC handle
01964   * @param  pCID: Pointer to a HAL_MMC_CIDTypedef structure that
01965   *         contains all CID register parameters
01966   * @retval HAL status
01967   */
01968 HAL_StatusTypeDef HAL_MMC_GetCardCID(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCIDTypeDef *pCID)
01969 {
01970   pCID->ManufacturerID = (uint8_t)((hmmc->CID[0] & 0xFF000000U) >> 24U);
01971 
01972   pCID->OEM_AppliID = (uint16_t)((hmmc->CID[0] & 0x00FFFF00U) >> 8U);
01973 
01974   pCID->ProdName1 = (((hmmc->CID[0] & 0x000000FFU) << 24U) | ((hmmc->CID[1] & 0xFFFFFF00U) >> 8U));
01975 
01976   pCID->ProdName2 = (uint8_t)(hmmc->CID[1] & 0x000000FFU);
01977 
01978   pCID->ProdRev = (uint8_t)((hmmc->CID[2] & 0xFF000000U) >> 24U);
01979 
01980   pCID->ProdSN = (((hmmc->CID[2] & 0x00FFFFFFU) << 8U) | ((hmmc->CID[3] & 0xFF000000U) >> 24U));
01981 
01982   pCID->Reserved1 = (uint8_t)((hmmc->CID[3] & 0x00F00000U) >> 20U);
01983 
01984   pCID->ManufactDate = (uint16_t)((hmmc->CID[3] & 0x000FFF00U) >> 8U);
01985 
01986   pCID->CID_CRC = (uint8_t)((hmmc->CID[3] & 0x000000FEU) >> 1U);
01987 
01988   pCID->Reserved2 = 1U;
01989 
01990   return HAL_OK;
01991 }
01992 
01993 /**
01994   * @brief  Returns information the information of the card which are stored on
01995   *         the CSD register.
01996   * @param  hmmc: Pointer to MMC handle
01997   * @param  pCSD: Pointer to a HAL_MMC_CardCSDTypeDef structure that
01998   *         contains all CSD register parameters
01999   * @retval HAL status
02000   */
02001 HAL_StatusTypeDef HAL_MMC_GetCardCSD(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCSDTypeDef *pCSD)
02002 {
02003   uint32_t block_nbr = 0;
02004 
02005   pCSD->CSDStruct = (uint8_t)((hmmc->CSD[0] & 0xC0000000U) >> 30U);
02006 
02007   pCSD->SysSpecVersion = (uint8_t)((hmmc->CSD[0] & 0x3C000000U) >> 26U);
02008 
02009   pCSD->Reserved1 = (uint8_t)((hmmc->CSD[0] & 0x03000000U) >> 24U);
02010 
02011   pCSD->TAAC = (uint8_t)((hmmc->CSD[0] & 0x00FF0000U) >> 16U);
02012 
02013   pCSD->NSAC = (uint8_t)((hmmc->CSD[0] & 0x0000FF00U) >> 8U);
02014 
02015   pCSD->MaxBusClkFrec = (uint8_t)(hmmc->CSD[0] & 0x000000FFU);
02016 
02017   pCSD->CardComdClasses = (uint16_t)((hmmc->CSD[1] & 0xFFF00000U) >> 20U);
02018 
02019   pCSD->RdBlockLen = (uint8_t)((hmmc->CSD[1] & 0x000F0000U) >> 16U);
02020 
02021   pCSD->PartBlockRead   = (uint8_t)((hmmc->CSD[1] & 0x00008000U) >> 15U);
02022 
02023   pCSD->WrBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00004000U) >> 14U);
02024 
02025   pCSD->RdBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00002000U) >> 13U);
02026 
02027   pCSD->DSRImpl = (uint8_t)((hmmc->CSD[1] & 0x00001000U) >> 12U);
02028 
02029   pCSD->Reserved2 = 0U; /*!< Reserved */
02030 
02031   pCSD->DeviceSize = (((hmmc->CSD[1] & 0x000003FFU) << 2U) | ((hmmc->CSD[2] & 0xC0000000U) >> 30U));
02032 
02033   pCSD->MaxRdCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x38000000U) >> 27U);
02034 
02035   pCSD->MaxRdCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x07000000U) >> 24U);
02036 
02037   pCSD->MaxWrCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x00E00000U) >> 21U);
02038 
02039   pCSD->MaxWrCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x001C0000U) >> 18U);
02040 
02041   pCSD->DeviceSizeMul = (uint8_t)((hmmc->CSD[2] & 0x00038000U) >> 15U);
02042 
02043   if(MMC_ReadExtCSD(hmmc, &block_nbr, 212, 0x0FFFFFFFU) != HAL_OK) /* Field SEC_COUNT [215:212] */
02044   {
02045     return HAL_ERROR;
02046   }
02047 
02048   if(hmmc->MmcCard.CardType == MMC_LOW_CAPACITY_CARD)
02049   {
02050     hmmc->MmcCard.BlockNbr  = (pCSD->DeviceSize + 1U) ;
02051     hmmc->MmcCard.BlockNbr *= (1UL << ((pCSD->DeviceSizeMul & 0x07U) + 2U));
02052     hmmc->MmcCard.BlockSize = (1UL << (pCSD->RdBlockLen & 0x0FU));
02053     hmmc->MmcCard.LogBlockNbr =  (hmmc->MmcCard.BlockNbr) * ((hmmc->MmcCard.BlockSize) / 512U);
02054     hmmc->MmcCard.LogBlockSize = 512U;
02055   }
02056   else if(hmmc->MmcCard.CardType == MMC_HIGH_CAPACITY_CARD)
02057   {
02058     hmmc->MmcCard.BlockNbr = block_nbr;
02059     hmmc->MmcCard.LogBlockNbr = hmmc->MmcCard.BlockNbr;
02060     hmmc->MmcCard.BlockSize = 512U;
02061     hmmc->MmcCard.LogBlockSize = hmmc->MmcCard.BlockSize;
02062   }
02063   else
02064   {
02065     /* Clear all the static flags */
02066     __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
02067     hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
02068     hmmc->State = HAL_MMC_STATE_READY;
02069     return HAL_ERROR;
02070   }
02071 
02072   pCSD->EraseGrSize = (uint8_t)((hmmc->CSD[2] & 0x00004000U) >> 14U);
02073 
02074   pCSD->EraseGrMul = (uint8_t)((hmmc->CSD[2] & 0x00003F80U) >> 7U);
02075 
02076   pCSD->WrProtectGrSize = (uint8_t)(hmmc->CSD[2] & 0x0000007FU);
02077 
02078   pCSD->WrProtectGrEnable = (uint8_t)((hmmc->CSD[3] & 0x80000000U) >> 31U);
02079 
02080   pCSD->ManDeflECC = (uint8_t)((hmmc->CSD[3] & 0x60000000U) >> 29U);
02081 
02082   pCSD->WrSpeedFact = (uint8_t)((hmmc->CSD[3] & 0x1C000000U) >> 26U);
02083 
02084   pCSD->MaxWrBlockLen= (uint8_t)((hmmc->CSD[3] & 0x03C00000U) >> 22U);
02085 
02086   pCSD->WriteBlockPaPartial = (uint8_t)((hmmc->CSD[3] & 0x00200000U) >> 21U);
02087 
02088   pCSD->Reserved3 = 0;
02089 
02090   pCSD->ContentProtectAppli = (uint8_t)((hmmc->CSD[3] & 0x00010000U) >> 16U);
02091 
02092   pCSD->FileFormatGroup = (uint8_t)((hmmc->CSD[3] & 0x00008000U) >> 15U);
02093 
02094   pCSD->CopyFlag = (uint8_t)((hmmc->CSD[3] & 0x00004000U) >> 14U);
02095 
02096   pCSD->PermWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00002000U) >> 13U);
02097 
02098   pCSD->TempWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00001000U) >> 12U);
02099 
02100   pCSD->FileFormat = (uint8_t)((hmmc->CSD[3] & 0x00000C00U) >> 10U);
02101 
02102   pCSD->ECC= (uint8_t)((hmmc->CSD[3] & 0x00000300U) >> 8U);
02103 
02104   pCSD->CSD_CRC = (uint8_t)((hmmc->CSD[3] & 0x000000FEU) >> 1U);
02105 
02106   pCSD->Reserved4 = 1;
02107 
02108   return HAL_OK;
02109 }
02110 
02111 /**
02112   * @brief  Gets the MMC card info.
02113   * @param  hmmc: Pointer to MMC handle
02114   * @param  pCardInfo: Pointer to the HAL_MMC_CardInfoTypeDef structure that
02115   *         will contain the MMC card status information
02116   * @retval HAL status
02117   */
02118 HAL_StatusTypeDef HAL_MMC_GetCardInfo(MMC_HandleTypeDef *hmmc, HAL_MMC_CardInfoTypeDef *pCardInfo)
02119 {
02120   pCardInfo->CardType     = (uint32_t)(hmmc->MmcCard.CardType);
02121   pCardInfo->Class        = (uint32_t)(hmmc->MmcCard.Class);
02122   pCardInfo->RelCardAdd   = (uint32_t)(hmmc->MmcCard.RelCardAdd);
02123   pCardInfo->BlockNbr     = (uint32_t)(hmmc->MmcCard.BlockNbr);
02124   pCardInfo->BlockSize    = (uint32_t)(hmmc->MmcCard.BlockSize);
02125   pCardInfo->LogBlockNbr  = (uint32_t)(hmmc->MmcCard.LogBlockNbr);
02126   pCardInfo->LogBlockSize = (uint32_t)(hmmc->MmcCard.LogBlockSize);
02127 
02128   return HAL_OK;
02129 }
02130 
02131 /**
02132   * @brief  Enables wide bus operation for the requested card if supported by
02133   *         card.
02134   * @param  hmmc: Pointer to MMC handle
02135   * @param  WideMode: Specifies the MMC card wide bus mode
02136   *          This parameter can be one of the following values:
02137   *            @arg SDIO_BUS_WIDE_8B: 8-bit data transfer
02138   *            @arg SDIO_BUS_WIDE_4B: 4-bit data transfer
02139   *            @arg SDIO_BUS_WIDE_1B: 1-bit data transfer
02140   * @retval HAL status
02141   */
02142 HAL_StatusTypeDef HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef *hmmc, uint32_t WideMode)
02143 {
02144   __IO uint32_t count = 0U;
02145   SDIO_InitTypeDef Init;
02146   uint32_t errorstate;
02147   uint32_t response = 0U, busy = 0U;
02148 
02149   /* Check the parameters */
02150   assert_param(IS_SDIO_BUS_WIDE(WideMode));
02151 
02152   /* Change State */
02153   hmmc->State = HAL_MMC_STATE_BUSY;
02154 
02155   /* Update Clock for Bus mode update */
02156   Init.ClockEdge           = SDIO_CLOCK_EDGE_RISING;
02157   Init.ClockBypass         = SDIO_CLOCK_BYPASS_DISABLE;
02158   Init.ClockPowerSave      = SDIO_CLOCK_POWER_SAVE_DISABLE;
02159   Init.BusWide             = WideMode;
02160   Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
02161   Init.ClockDiv            = SDIO_INIT_CLK_DIV;
02162   /* Initialize SDIO*/
02163   (void)SDIO_Init(hmmc->Instance, Init); 
02164 
02165   if(WideMode == SDIO_BUS_WIDE_8B)
02166   {
02167     errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U);
02168     if(errorstate != HAL_MMC_ERROR_NONE)
02169     {
02170       hmmc->ErrorCode |= errorstate;
02171     }
02172   }
02173   else if(WideMode == SDIO_BUS_WIDE_4B)
02174   {
02175     errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U);
02176     if(errorstate != HAL_MMC_ERROR_NONE)
02177     {
02178       hmmc->ErrorCode |= errorstate;
02179     }
02180   }
02181   else if(WideMode == SDIO_BUS_WIDE_1B)
02182   {
02183     errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70000U);
02184     if(errorstate != HAL_MMC_ERROR_NONE)
02185     {
02186       hmmc->ErrorCode |= errorstate;
02187     }
02188   }
02189   else
02190   {
02191     /* WideMode is not a valid argument*/
02192     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
02193   }
02194 
02195   /* Check for switch error and violation of the trial number of sending CMD 13 */
02196   while(busy == 0U)
02197   {
02198     if(count == SDMMC_MAX_TRIAL)
02199     {
02200       hmmc->State = HAL_MMC_STATE_READY;
02201       hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
02202       return HAL_ERROR;
02203     }
02204     count++;
02205 
02206     /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
02207     errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
02208     if(errorstate != HAL_MMC_ERROR_NONE)
02209     {
02210       hmmc->ErrorCode |= errorstate;
02211     }
02212 
02213     /* Get command response */
02214     response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
02215 
02216     /* Get operating voltage*/
02217     busy = (((response >> 7U) == 1U) ? 0U : 1U);
02218   }
02219 
02220   /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
02221   count = SDMMC_DATATIMEOUT;
02222   while((response & 0x00000100U) == 0U)
02223   {
02224     if(count == 0U)
02225     {
02226       hmmc->State = HAL_MMC_STATE_READY;
02227       hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
02228       return HAL_ERROR;
02229     }
02230     count--;
02231 
02232     /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
02233     errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
02234     if(errorstate != HAL_MMC_ERROR_NONE)
02235     {
02236       hmmc->ErrorCode |= errorstate;
02237     }
02238 
02239     /* Get command response */
02240     response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
02241   }
02242 
02243   if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
02244   {
02245     /* Clear all the static flags */
02246     __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
02247     hmmc->State = HAL_MMC_STATE_READY;
02248     return HAL_ERROR;
02249   }
02250   else
02251   {
02252     /* Configure the SDIO peripheral */
02253     Init.ClockEdge           = hmmc->Init.ClockEdge;
02254     Init.ClockBypass         = hmmc->Init.ClockBypass;
02255     Init.ClockPowerSave      = hmmc->Init.ClockPowerSave;
02256     Init.BusWide             = WideMode;
02257     Init.HardwareFlowControl = hmmc->Init.HardwareFlowControl;
02258     Init.ClockDiv            = hmmc->Init.ClockDiv;
02259     (void)SDIO_Init(hmmc->Instance, Init);
02260   }
02261 
02262   /* Change State */
02263   hmmc->State = HAL_MMC_STATE_READY;
02264 
02265   return HAL_OK;
02266 }
02267 
02268 /**
02269   * @brief  Gets the current mmc card data state.
02270   * @param  hmmc: pointer to MMC handle
02271   * @retval Card state
02272   */
02273 HAL_MMC_CardStateTypeDef HAL_MMC_GetCardState(MMC_HandleTypeDef *hmmc)
02274 {
02275   uint32_t cardstate;
02276   uint32_t errorstate;
02277   uint32_t resp1 = 0U;
02278 
02279   errorstate = MMC_SendStatus(hmmc, &resp1);
02280   if(errorstate != HAL_MMC_ERROR_NONE)
02281   {
02282     hmmc->ErrorCode |= errorstate;
02283   }
02284 
02285   cardstate = ((resp1 >> 9U) & 0x0FU);
02286 
02287   return (HAL_MMC_CardStateTypeDef)cardstate;
02288 }
02289 
02290 /**
02291   * @brief  Abort the current transfer and disable the MMC.
02292   * @param  hmmc: pointer to a MMC_HandleTypeDef structure that contains
02293   *                the configuration information for MMC module.
02294   * @retval HAL status
02295   */
02296 HAL_StatusTypeDef HAL_MMC_Abort(MMC_HandleTypeDef *hmmc)
02297 {
02298   HAL_MMC_CardStateTypeDef CardState;
02299 
02300   /* DIsable All interrupts */
02301   __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
02302                              SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
02303 
02304   /* Clear All flags */
02305   __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
02306 
02307   if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL))
02308   {
02309     /* Disable the MMC DMA request */
02310     hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
02311     
02312     /* Abort the MMC DMA Tx Stream */
02313     if(hmmc->hdmatx != NULL)
02314     {
02315       if(HAL_DMA_Abort(hmmc->hdmatx) != HAL_OK)
02316       {
02317         hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
02318       }
02319     }
02320     /* Abort the MMC DMA Rx Stream */
02321     if(hmmc->hdmarx != NULL)
02322     {
02323       if(HAL_DMA_Abort(hmmc->hdmarx) != HAL_OK)
02324       {
02325         hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
02326       }
02327     }
02328   }
02329 
02330   hmmc->State = HAL_MMC_STATE_READY;
02331 
02332   /* Initialize the MMC operation */
02333   hmmc->Context = MMC_CONTEXT_NONE;
02334 
02335   CardState = HAL_MMC_GetCardState(hmmc);
02336   if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
02337   {
02338     hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
02339   }
02340   if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
02341   {
02342     return HAL_ERROR;
02343   }
02344   return HAL_OK;
02345 }
02346 
02347 /**
02348   * @brief  Abort the current transfer and disable the MMC (IT mode).
02349   * @param  hmmc: pointer to a MMC_HandleTypeDef structure that contains
02350   *                the configuration information for MMC module.
02351   * @retval HAL status
02352   */
02353 HAL_StatusTypeDef HAL_MMC_Abort_IT(MMC_HandleTypeDef *hmmc)
02354 {
02355   HAL_MMC_CardStateTypeDef CardState;
02356 
02357   /* DIsable All interrupts */
02358   __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
02359                            SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
02360 
02361   /* Clear All flags */
02362   __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
02363 
02364   if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL))
02365   {
02366     /* Disable the MMC DMA request */
02367     hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
02368     
02369     /* Abort the MMC DMA Tx Stream */
02370     if(hmmc->hdmatx != NULL)
02371     {
02372       hmmc->hdmatx->XferAbortCallback =  MMC_DMATxAbort;
02373       if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
02374       {
02375         hmmc->hdmatx = NULL;
02376       }
02377     }
02378     /* Abort the MMC DMA Rx Stream */
02379     if(hmmc->hdmarx != NULL)
02380     {
02381       hmmc->hdmarx->XferAbortCallback =  MMC_DMARxAbort;
02382       if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
02383       {
02384         hmmc->hdmarx = NULL;
02385       }
02386     }
02387   }
02388   
02389   /* No transfer ongoing on both DMA channels*/
02390   if((hmmc->hdmatx == NULL) && (hmmc->hdmarx == NULL))
02391   {
02392     CardState = HAL_MMC_GetCardState(hmmc);
02393     hmmc->State = HAL_MMC_STATE_READY;
02394 
02395     if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
02396     {
02397       hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
02398     }
02399     if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
02400     {
02401       return HAL_ERROR;
02402     }
02403     else
02404     {
02405 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
02406       hmmc->AbortCpltCallback(hmmc);
02407 #else
02408       HAL_MMC_AbortCallback(hmmc);
02409 #endif
02410     }
02411   }
02412 
02413   return HAL_OK;
02414 }
02415 
02416 /**
02417   * @}
02418   */
02419 
02420 /**
02421   * @}
02422   */
02423 
02424 /* Private function ----------------------------------------------------------*/
02425 /** @addtogroup MMC_Private_Functions
02426   * @{
02427   */
02428 
02429 /**
02430   * @brief  DMA MMC transmit process complete callback 
02431   * @param  hdma: DMA handle
02432   * @retval None
02433   */
02434 static void MMC_DMATransmitCplt(DMA_HandleTypeDef *hdma)     
02435 {
02436   MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
02437   
02438   /* Enable DATAEND Interrupt */
02439   __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DATAEND));
02440 }
02441 
02442 /**
02443   * @brief  DMA MMC receive process complete callback 
02444   * @param  hdma: DMA handle
02445   * @retval None
02446   */
02447 static void MMC_DMAReceiveCplt(DMA_HandleTypeDef *hdma)  
02448 {
02449   MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
02450   uint32_t errorstate;
02451   
02452   /* Send stop command in multiblock write */
02453   if(hmmc->Context == (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA))
02454   {
02455     errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
02456     if(errorstate != HAL_MMC_ERROR_NONE)
02457     {
02458       hmmc->ErrorCode |= errorstate;
02459 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
02460       hmmc->ErrorCallback(hmmc);
02461 #else
02462       HAL_MMC_ErrorCallback(hmmc);
02463 #endif
02464     }
02465   }
02466   
02467   /* Disable the DMA transfer for transmit request by setting the DMAEN bit
02468   in the MMC DCTRL register */
02469   hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
02470   
02471   /* Clear all the static flags */
02472   __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
02473   
02474   hmmc->State = HAL_MMC_STATE_READY;
02475 
02476 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
02477   hmmc->RxCpltCallback(hmmc);
02478 #else
02479   HAL_MMC_RxCpltCallback(hmmc);
02480 #endif
02481 }
02482 
02483 /**
02484   * @brief  DMA MMC communication error callback 
02485   * @param  hdma: DMA handle
02486   * @retval None
02487   */
02488 static void MMC_DMAError(DMA_HandleTypeDef *hdma)   
02489 {
02490   MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
02491   HAL_MMC_CardStateTypeDef CardState;
02492   uint32_t RxErrorCode, TxErrorCode;
02493   
02494   /* if DMA error is FIFO error ignore it */
02495   if(HAL_DMA_GetError(hdma) != HAL_DMA_ERROR_FE)
02496   {
02497     RxErrorCode = hmmc->hdmarx->ErrorCode;
02498     TxErrorCode = hmmc->hdmatx->ErrorCode;  
02499     if((RxErrorCode == HAL_DMA_ERROR_TE) || (TxErrorCode == HAL_DMA_ERROR_TE))
02500     {
02501       /* Clear All flags */
02502       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
02503       
02504       /* Disable All interrupts */
02505       __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
02506         SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
02507       
02508       hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
02509       CardState = HAL_MMC_GetCardState(hmmc);
02510       if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
02511       {
02512         hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
02513       }
02514       
02515       hmmc->State= HAL_MMC_STATE_READY;
02516     }
02517     
02518 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
02519     hmmc->ErrorCallback(hmmc);
02520 #else
02521     HAL_MMC_ErrorCallback(hmmc);
02522 #endif
02523   }
02524 }
02525 
02526 /**
02527   * @brief  DMA MMC Tx Abort callback 
02528   * @param  hdma: DMA handle
02529   * @retval None
02530   */
02531 static void MMC_DMATxAbort(DMA_HandleTypeDef *hdma)   
02532 {
02533   MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
02534   HAL_MMC_CardStateTypeDef CardState;
02535   
02536   if(hmmc->hdmatx != NULL)
02537   {
02538     hmmc->hdmatx = NULL;
02539   }
02540   
02541   /* All DMA channels are aborted */
02542   if(hmmc->hdmarx == NULL)
02543   {
02544     CardState = HAL_MMC_GetCardState(hmmc);
02545     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
02546     hmmc->State = HAL_MMC_STATE_READY;
02547     if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
02548     {
02549       hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
02550       
02551       if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
02552       {
02553 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
02554         hmmc->AbortCpltCallback(hmmc);
02555 #else
02556         HAL_MMC_AbortCallback(hmmc);
02557 #endif
02558       }
02559       else
02560       {
02561 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
02562         hmmc->ErrorCallback(hmmc);
02563 #else
02564         HAL_MMC_ErrorCallback(hmmc);
02565 #endif
02566       }
02567     }
02568   }
02569 }
02570 
02571 /**
02572   * @brief  DMA MMC Rx Abort callback 
02573   * @param  hdma: DMA handle
02574   * @retval None
02575   */
02576 static void MMC_DMARxAbort(DMA_HandleTypeDef *hdma)   
02577 {
02578   MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
02579   HAL_MMC_CardStateTypeDef CardState;
02580   
02581   if(hmmc->hdmarx != NULL)
02582   {
02583     hmmc->hdmarx = NULL;
02584   }
02585   
02586   /* All DMA channels are aborted */
02587   if(hmmc->hdmatx == NULL)
02588   {
02589     CardState = HAL_MMC_GetCardState(hmmc);
02590     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
02591     hmmc->State = HAL_MMC_STATE_READY;
02592     if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
02593     {
02594       hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
02595       
02596       if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
02597       {
02598 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
02599         hmmc->AbortCpltCallback(hmmc);
02600 #else
02601         HAL_MMC_AbortCallback(hmmc);
02602 #endif
02603       }
02604       else
02605       {
02606 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
02607         hmmc->ErrorCallback(hmmc);
02608 #else
02609         HAL_MMC_ErrorCallback(hmmc);
02610 #endif
02611       }
02612     }
02613   }
02614 }
02615 
02616 /**
02617   * @brief  Initializes the mmc card.
02618   * @param  hmmc: Pointer to MMC handle
02619   * @retval MMC Card error state
02620   */
02621 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc)
02622 {
02623   HAL_MMC_CardCSDTypeDef CSD;
02624   uint32_t errorstate;
02625   uint16_t mmc_rca = 1U;
02626 
02627   /* Check the power State */
02628   if(SDIO_GetPowerState(hmmc->Instance) == 0U)
02629   {
02630     /* Power off */
02631     return HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
02632   }
02633 
02634   /* Send CMD2 ALL_SEND_CID */
02635   errorstate = SDMMC_CmdSendCID(hmmc->Instance);
02636   if(errorstate != HAL_MMC_ERROR_NONE)
02637   {
02638     return errorstate;
02639   }
02640   else
02641   {
02642     /* Get Card identification number data */
02643     hmmc->CID[0U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
02644     hmmc->CID[1U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP2);
02645     hmmc->CID[2U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP3);
02646     hmmc->CID[3U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP4);
02647   }
02648 
02649   /* Send CMD3 SET_REL_ADDR with argument 0 */
02650   /* MMC Card publishes its RCA. */
02651   errorstate = SDMMC_CmdSetRelAdd(hmmc->Instance, &mmc_rca);
02652   if(errorstate != HAL_MMC_ERROR_NONE)
02653   {
02654     return errorstate;
02655   }
02656 
02657   /* Get the MMC card RCA */
02658   hmmc->MmcCard.RelCardAdd = mmc_rca;
02659 
02660   /* Send CMD9 SEND_CSD with argument as card's RCA */
02661   errorstate = SDMMC_CmdSendCSD(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
02662   if(errorstate != HAL_MMC_ERROR_NONE)
02663   {
02664     return errorstate;
02665   }
02666   else
02667   {
02668     /* Get Card Specific Data */
02669     hmmc->CSD[0U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
02670     hmmc->CSD[1U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP2);
02671     hmmc->CSD[2U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP3);
02672     hmmc->CSD[3U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP4);
02673   }
02674 
02675   /* Get the Card Class */
02676   hmmc->MmcCard.Class = (SDIO_GetResponse(hmmc->Instance, SDIO_RESP2) >> 20U);
02677 
02678   /* Get CSD parameters */
02679   if (HAL_MMC_GetCardCSD(hmmc, &CSD) != HAL_OK)
02680   {
02681     return hmmc->ErrorCode;
02682   }
02683 
02684   /* Select the Card */
02685   errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
02686   if(errorstate != HAL_MMC_ERROR_NONE)
02687   {
02688     return errorstate;
02689   }
02690 
02691   /* Configure SDIO peripheral interface */
02692   (void)SDIO_Init(hmmc->Instance, hmmc->Init);
02693 
02694   /* All cards are initialized */
02695   return HAL_MMC_ERROR_NONE;
02696 }
02697 
02698 /**
02699   * @brief  Enquires cards about their operating voltage and configures clock
02700   *         controls and stores MMC information that will be needed in future
02701   *         in the MMC handle.
02702   * @param  hmmc: Pointer to MMC handle
02703   * @retval error state
02704   */
02705 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc)
02706 {
02707   __IO uint32_t count = 0U;
02708   uint32_t response = 0U, validvoltage = 0U;
02709   uint32_t errorstate;
02710 
02711   /* CMD0: GO_IDLE_STATE */
02712   errorstate = SDMMC_CmdGoIdleState(hmmc->Instance);
02713   if(errorstate != HAL_MMC_ERROR_NONE)
02714   {
02715     return errorstate;
02716   }
02717 
02718   while(validvoltage == 0U)
02719   {
02720     if(count++ == SDMMC_MAX_VOLT_TRIAL)
02721     {
02722       return HAL_MMC_ERROR_INVALID_VOLTRANGE;
02723     }
02724 
02725     /* SEND CMD1 APP_CMD with MMC_HIGH_VOLTAGE_RANGE(0xC0FF8000) as argument */
02726     errorstate = SDMMC_CmdOpCondition(hmmc->Instance, eMMC_HIGH_VOLTAGE_RANGE);
02727     if(errorstate != HAL_MMC_ERROR_NONE)
02728     {
02729       return HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
02730     }
02731 
02732     /* Get command response */
02733     response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
02734 
02735     /* Get operating voltage*/
02736     validvoltage = (((response >> 31U) == 1U) ? 1U : 0U);
02737   }
02738 
02739   /* When power routine is finished and command returns valid voltage */
02740   if (((response & (0xFF000000U)) >> 24U) == 0xC0U)
02741   {
02742     hmmc->MmcCard.CardType = MMC_HIGH_CAPACITY_CARD;
02743   }
02744   else
02745   {
02746     hmmc->MmcCard.CardType = MMC_LOW_CAPACITY_CARD;
02747   }
02748 
02749   return HAL_MMC_ERROR_NONE;
02750 }
02751 
02752 /**
02753   * @brief  Turns the SDIO output signals off.
02754   * @param  hmmc: Pointer to MMC handle
02755   * @retval None
02756   */
02757 static void MMC_PowerOFF(MMC_HandleTypeDef *hmmc)
02758 {
02759   /* Set Power State to OFF */
02760   (void)SDIO_PowerState_OFF(hmmc->Instance);
02761 }
02762 
02763 /**
02764   * @brief  Returns the current card's status.
02765   * @param  hmmc: Pointer to MMC handle
02766   * @param  pCardStatus: pointer to the buffer that will contain the MMC card
02767   *         status (Card Status register)
02768   * @retval error state
02769   */
02770 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus)
02771 {
02772   uint32_t errorstate;
02773 
02774   if(pCardStatus == NULL)
02775   {
02776     return HAL_MMC_ERROR_PARAM;
02777   }
02778 
02779   /* Send Status command */
02780   errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
02781   if(errorstate != HAL_MMC_ERROR_NONE)
02782   {
02783     return errorstate;
02784   }
02785 
02786   /* Get MMC card status */
02787   *pCardStatus = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
02788 
02789   return HAL_MMC_ERROR_NONE;
02790 }
02791 
02792 /**
02793   * @brief  Reads extended CSD register to get the sectors number of the device
02794   * @param  hmmc: Pointer to MMC handle
02795   * @param  pFieldData: Pointer to the read buffer
02796   * @param  FieldIndex: Index of the field to be read
02797   * @param  Timeout: Specify timeout value
02798   * @retval HAL status
02799   */
02800 static uint32_t MMC_ReadExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pFieldData, uint16_t FieldIndex, uint32_t Timeout)
02801 {
02802   SDIO_DataInitTypeDef config;
02803   uint32_t errorstate;
02804   uint32_t tickstart = HAL_GetTick();
02805   uint32_t count;
02806   uint32_t i = 0;
02807   uint32_t tmp_data;
02808 
02809   hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
02810 
02811   /* Initialize data control register */
02812   hmmc->Instance->DCTRL = 0;
02813 
02814   /* Configure the MMC DPSM (Data Path State Machine) */
02815   config.DataTimeOut   = SDMMC_DATATIMEOUT;
02816   config.DataLength    = 512;
02817   config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
02818   config.TransferDir   = SDIO_TRANSFER_DIR_TO_SDIO;
02819   config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
02820   config.DPSM          = SDIO_DPSM_ENABLE;
02821   (void)SDIO_ConfigData(hmmc->Instance, &config);
02822 
02823   /* Set Block Size for Card */
02824   errorstate = SDMMC_CmdSendEXTCSD(hmmc->Instance, 0);
02825   if(errorstate != HAL_MMC_ERROR_NONE)
02826   {
02827     /* Clear all the static flags */
02828     __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
02829     hmmc->ErrorCode |= errorstate;
02830     hmmc->State = HAL_MMC_STATE_READY;
02831     return HAL_ERROR;
02832   }
02833 
02834   /* Poll on SDMMC flags */
02835   while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND))
02836   {
02837     if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXFIFOHF))
02838     {
02839       /* Read data from SDMMC Rx FIFO */
02840       for(count = 0U; count < 8U; count++)
02841       {
02842         tmp_data = SDIO_ReadFIFO(hmmc->Instance);
02843         /* eg : SEC_COUNT   : FieldIndex = 212 => i+count = 53 */
02844         /*      DEVICE_TYPE : FieldIndex = 196 => i+count = 49 */
02845         if ((i + count) == ((uint32_t)FieldIndex/4U))
02846         {
02847           *pFieldData = tmp_data;
02848         }
02849       }
02850       i += 8U;
02851     }
02852 
02853     if(((HAL_GetTick()-tickstart) >=  Timeout) || (Timeout == 0U))
02854     {
02855       /* Clear all the static flags */
02856       __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
02857       hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
02858       hmmc->State= HAL_MMC_STATE_READY;
02859       return HAL_TIMEOUT;
02860     }
02861   }
02862 
02863   /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
02864   errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16));
02865   if(errorstate != HAL_MMC_ERROR_NONE)
02866   {
02867     hmmc->ErrorCode |= errorstate;
02868   }
02869 
02870   /* Clear all the static flags */
02871   __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
02872 
02873   hmmc->State = HAL_MMC_STATE_READY;
02874 
02875   return HAL_OK;
02876 }
02877 
02878 
02879 /**
02880   * @brief  Wrap up reading in non-blocking mode.
02881   * @param  hmmc: pointer to a MMC_HandleTypeDef structure that contains
02882   *              the configuration information.
02883   * @retval None
02884   */
02885 static void MMC_Read_IT(MMC_HandleTypeDef *hmmc)
02886 {
02887   uint32_t count, data, dataremaining;
02888   uint8_t* tmp;
02889 
02890   tmp = hmmc->pRxBuffPtr;
02891   dataremaining = hmmc->RxXferSize;
02892 
02893   if (dataremaining > 0U)
02894   {
02895     /* Read data from SDIO Rx FIFO */
02896     for(count = 0U; count < 8U; count++)
02897     {
02898       data = SDIO_ReadFIFO(hmmc->Instance);
02899       *tmp = (uint8_t)(data & 0xFFU);
02900       tmp++;
02901       dataremaining--;
02902       *tmp = (uint8_t)((data >> 8U) & 0xFFU);
02903       tmp++;
02904       dataremaining--;
02905       *tmp = (uint8_t)((data >> 16U) & 0xFFU);
02906       tmp++;
02907       dataremaining--;
02908       *tmp = (uint8_t)((data >> 24U) & 0xFFU);
02909       tmp++;
02910       dataremaining--;
02911     }
02912 
02913     hmmc->pRxBuffPtr = tmp;
02914     hmmc->RxXferSize = dataremaining;
02915   }
02916 }
02917 
02918 /**
02919   * @brief  Wrap up writing in non-blocking mode.
02920   * @param  hmmc: pointer to a MMC_HandleTypeDef structure that contains
02921   *              the configuration information.
02922   * @retval None
02923   */
02924 static void MMC_Write_IT(MMC_HandleTypeDef *hmmc)
02925 {
02926   uint32_t count, data, dataremaining;
02927   uint8_t* tmp;
02928 
02929   tmp = hmmc->pTxBuffPtr;
02930   dataremaining = hmmc->TxXferSize;
02931 
02932   if (dataremaining > 0U)
02933   {
02934     /* Write data to SDIO Tx FIFO */
02935     for(count = 0U; count < 8U; count++)
02936     {
02937       data = (uint32_t)(*tmp);
02938       tmp++;
02939       dataremaining--;
02940       data |= ((uint32_t)(*tmp) << 8U);
02941       tmp++;
02942       dataremaining--;
02943       data |= ((uint32_t)(*tmp) << 16U);
02944       tmp++;
02945       dataremaining--;
02946       data |= ((uint32_t)(*tmp) << 24U);
02947       tmp++;
02948       dataremaining--;
02949       (void)SDIO_WriteFIFO(hmmc->Instance, &data);
02950     }
02951 
02952     hmmc->pTxBuffPtr = tmp;
02953     hmmc->TxXferSize = dataremaining;
02954   }
02955 }
02956 
02957 /**
02958   * @}
02959   */
02960 
02961 #endif /* SDIO */
02962 
02963 #endif /* HAL_MMC_MODULE_ENABLED */
02964 
02965 /**
02966   * @}
02967   */
02968 
02969 /**
02970   * @}
02971   */
02972 
02973 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/