1 /**
2   ******************************************************************************
3   * @file    stm32f7xx_hal_mmc.c
4   * @author  MCD Application Team
5   * @brief   MMC card HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the Secure Digital (MMC) peripheral:
8   *           + Initialization and de-initialization functions
9   *           + IO operation functions
10   *           + Peripheral Control functions
11   *           + MMC card Control functions
12   *
13   ******************************************************************************
14   * @attention
15   *
16   * Copyright (c) 2017 STMicroelectronics.
17   * All rights reserved.
18   *
19   * This software is licensed under terms that can be found in the LICENSE file
20   * in the root directory of this software component.
21   * If no LICENSE file comes with this software, it is provided AS-IS.
22   *
23   ******************************************************************************
24   @verbatim
25   ==============================================================================
26                         ##### How to use this driver #####
27   ==============================================================================
28   [..]
29     This driver implements a high level communication layer for read and write from/to
30     this memory. The needed STM32 hardware resources (SDMMC and GPIO) are performed by
31     the user in HAL_MMC_MspInit() function (MSP layer).
32     Basically, the MSP layer configuration should be the same as we provide in the
33     examples.
34     You can easily tailor this configuration according to hardware resources.
35 
36   [..]
37     This driver is a generic layered driver for SDMMC memories which uses the HAL
38     SDMMC driver functions to interface with MMC and eMMC cards devices.
39     It is used as follows:
40 
41     (#)Initialize the SDMMC low level resources by implement the HAL_MMC_MspInit() API:
42         (##) Enable the SDMMC interface clock using __HAL_RCC_SDMMC_CLK_ENABLE();
43         (##) SDMMC pins configuration for MMC card
44             (+++) Enable the clock for the SDMMC GPIOs using the functions __HAL_RCC_GPIOx_CLK_ENABLE();
45             (+++) Configure these SDMMC pins as alternate function pull-up using HAL_GPIO_Init()
46                   and according to your pin assignment;
47         (##) DMA Configuration if you need to use DMA process (HAL_MMC_ReadBlocks_DMA()
48              and HAL_MMC_WriteBlocks_DMA() APIs).
49             (+++) Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE();
50             (+++) Configure the DMA using the function HAL_DMA_Init() with predeclared and filled.
51         (##) NVIC configuration if you need to use interrupt process when using DMA transfer.
52             (+++) Configure the SDMMC and DMA interrupt priorities using function HAL_NVIC_SetPriority();
53                   DMA priority is superior to SDMMC's priority
54             (+++) Enable the NVIC DMA and SDMMC IRQs using function HAL_NVIC_EnableIRQ()
55             (+++) SDMMC interrupts are managed using the macros __HAL_MMC_ENABLE_IT()
56                   and __HAL_MMC_DISABLE_IT() inside the communication process.
57             (+++) SDMMC interrupts pending bits are managed using the macros __HAL_MMC_GET_IT()
58                   and __HAL_MMC_CLEAR_IT()
59         (##) NVIC configuration if you need to use interrupt process (HAL_MMC_ReadBlocks_IT()
60              and HAL_MMC_WriteBlocks_IT() APIs).
61             (+++) Configure the SDMMC interrupt priorities using function HAL_NVIC_SetPriority();
62             (+++) Enable the NVIC SDMMC IRQs using function HAL_NVIC_EnableIRQ()
63             (+++) SDMMC interrupts are managed using the macros __HAL_MMC_ENABLE_IT()
64                   and __HAL_MMC_DISABLE_IT() inside the communication process.
65             (+++) SDMMC interrupts pending bits are managed using the macros __HAL_MMC_GET_IT()
66                   and __HAL_MMC_CLEAR_IT()
67     (#) At this stage, you can perform MMC read/write/erase operations after MMC card initialization
68 
69 
70   *** MMC Card Initialization and configuration ***
71   ================================================
72   [..]
73     To initialize the MMC Card, use the HAL_MMC_Init() function. It Initializes
74     SDMMC Peripheral (STM32 side) and the MMC Card, and put it into StandBy State (Ready for data transfer).
75     This function provide the following operations:
76 
77     (#) Initialize the SDMMC peripheral interface with default configuration.
78         The initialization process is done at 400KHz. You can change or adapt
79         this frequency by adjusting the "ClockDiv" field.
80         The MMC Card frequency (SDMMC_CK) is computed as follows:
81 
82            SDMMC_CK = SDMMCCLK / (ClockDiv + 2)
83 
84         In initialization mode and according to the MMC Card standard,
85         make sure that the SDMMC_CK frequency doesn't exceed 400KHz.
86 
87         This phase of initialization is done through SDMMC_Init() and
88         SDMMC_PowerState_ON() SDMMC low level APIs.
89 
90     (#) Initialize the MMC card. The API used is HAL_MMC_InitCard().
91         This phase allows the card initialization and identification
92         and check the MMC Card type (Standard Capacity or High Capacity)
93         The initialization flow is compatible with MMC standard.
94 
95         This API (HAL_MMC_InitCard()) could be used also to reinitialize the card in case
96         of plug-off plug-in.
97 
98     (#) Configure the MMC Card Data transfer frequency. By Default, the card transfer
99         frequency is set to 24MHz. You can change or adapt this frequency by adjusting
100         the "ClockDiv" field.
101         In transfer mode and according to the MMC Card standard, make sure that the
102         SDMMC_CK frequency doesn't exceed 25MHz and 50MHz in High-speed mode switch.
103         To be able to use a frequency higher than 24MHz, you should use the SDMMC
104         peripheral in bypass mode. Refer to the corresponding reference manual
105         for more details.
106 
107     (#) Select the corresponding MMC Card according to the address read with the step 2.
108 
109     (#) Configure the MMC Card in wide bus mode: 4-bits data.
110 
111   *** MMC Card Read operation ***
112   ==============================
113   [..]
114     (+) You can read from MMC card in polling mode by using function HAL_MMC_ReadBlocks().
115         This function support only 512-bytes block length (the block size should be
116         chosen as 512 bytes).
117         You can choose either one block read operation or multiple block read operation
118         by adjusting the "NumberOfBlocks" parameter.
119         After this, you have to ensure that the transfer is done correctly. The check is done
120         through HAL_MMC_GetCardState() function for MMC card state.
121 
122     (+) You can read from MMC card in DMA mode by using function HAL_MMC_ReadBlocks_DMA().
123         This function support only 512-bytes block length (the block size should be
124         chosen as 512 bytes).
125         You can choose either one block read operation or multiple block read operation
126         by adjusting the "NumberOfBlocks" parameter.
127         After this, you have to ensure that the transfer is done correctly. The check is done
128         through HAL_MMC_GetCardState() function for MMC card state.
129         You could also check the DMA transfer process through the MMC Rx interrupt event.
130 
131     (+) You can read from MMC card in Interrupt mode by using function HAL_MMC_ReadBlocks_IT().
132         This function allows the read of 512 bytes blocks.
133         You can choose either one block read operation or multiple block read operation
134         by adjusting the "NumberOfBlocks" parameter.
135         After this, you have to ensure that the transfer is done correctly. The check is done
136         through HAL_MMC_GetCardState() function for MMC card state.
137         You could also check the IT transfer process through the MMC Rx interrupt event.
138 
139   *** MMC Card Write operation ***
140   ===============================
141   [..]
142     (+) You can write to MMC card in polling mode by using function HAL_MMC_WriteBlocks().
143         This function support only 512-bytes block length (the block size should be
144         chosen as 512 bytes).
145         You can choose either one block read operation or multiple block read operation
146         by adjusting the "NumberOfBlocks" parameter.
147         After this, you have to ensure that the transfer is done correctly. The check is done
148         through HAL_MMC_GetCardState() function for MMC card state.
149 
150     (+) You can write to MMC card in DMA mode by using function HAL_MMC_WriteBlocks_DMA().
151         This function support only 512-bytes block length (the block size should be
152         chosen as 512 byte).
153         You can choose either one block read operation or multiple block read operation
154         by adjusting the "NumberOfBlocks" parameter.
155         After this, you have to ensure that the transfer is done correctly. The check is done
156         through HAL_MMC_GetCardState() function for MMC card state.
157         You could also check the DMA transfer process through the MMC Tx interrupt event.
158 
159     (+) You can write to MMC card in Interrupt mode by using function HAL_MMC_WriteBlocks_IT().
160         This function allows the read of 512 bytes blocks.
161         You can choose either one block read operation or multiple block read operation
162         by adjusting the "NumberOfBlocks" parameter.
163         After this, you have to ensure that the transfer is done correctly. The check is done
164         through HAL_MMC_GetCardState() function for MMC card state.
165         You could also check the IT transfer process through the MMC Tx interrupt event.
166 
167   *** MMC card information ***
168   ===========================
169   [..]
170     (+) To get MMC card information, you can use the function HAL_MMC_GetCardInfo().
171         It returns useful information about the MMC card such as block size, card type,
172         block number ...
173 
174   *** MMC card CSD register ***
175   ============================
176   [..]
177     (+) The HAL_MMC_GetCardCSD() API allows to get the parameters of the CSD register.
178         Some of the CSD parameters are useful for card initialization and identification.
179 
180   *** MMC card CID register ***
181   ============================
182   [..]
183     (+) The HAL_MMC_GetCardCID() API allows to get the parameters of the CID register.
184         Some of the CID parameters are useful for card initialization and identification.
185 
186   *** MMC HAL driver macros list ***
187   ==================================
188   [..]
189     Below the list of most used macros in MMC HAL driver.
190 
191     (+) __HAL_MMC_ENABLE : Enable the MMC device
192     (+) __HAL_MMC_DISABLE : Disable the MMC device
193     (+) __HAL_MMC_DMA_ENABLE: Enable the SDMMC DMA transfer
194     (+) __HAL_MMC_DMA_DISABLE: Disable the SDMMC DMA transfer
195     (+) __HAL_MMC_ENABLE_IT: Enable the MMC device interrupt
196     (+) __HAL_MMC_DISABLE_IT: Disable the MMC device interrupt
197     (+) __HAL_MMC_GET_FLAG:Check whether the specified MMC flag is set or not
198     (+) __HAL_MMC_CLEAR_FLAG: Clear the MMC's pending flags
199 
200   [..]
201     (@) You can refer to the MMC HAL driver header file for more useful macros
202 
203   *** Callback registration ***
204   =============================================
205   [..]
206     The compilation define USE_HAL_MMC_REGISTER_CALLBACKS when set to 1
207     allows the user to configure dynamically the driver callbacks.
208 
209     Use Functions HAL_MMC_RegisterCallback() to register a user callback,
210     it allows to register following callbacks:
211       (+) TxCpltCallback : callback when a transmission transfer is completed.
212       (+) RxCpltCallback : callback when a reception transfer is completed.
213       (+) ErrorCallback : callback when error occurs.
214       (+) AbortCpltCallback : callback when abort is completed.
215       (+) MspInitCallback    : MMC MspInit.
216       (+) MspDeInitCallback  : MMC MspDeInit.
217     This function takes as parameters the HAL peripheral handle, the Callback ID
218     and a pointer to the user callback function.
219 
220     Use function HAL_MMC_UnRegisterCallback() to reset a callback to the default
221     weak (surcharged) function. It allows to reset following callbacks:
222       (+) TxCpltCallback : callback when a transmission transfer is completed.
223       (+) RxCpltCallback : callback when a reception transfer is completed.
224       (+) ErrorCallback : callback when error occurs.
225       (+) AbortCpltCallback : callback when abort is completed.
226       (+) MspInitCallback    : MMC MspInit.
227       (+) MspDeInitCallback  : MMC MspDeInit.
228     This function) takes as parameters the HAL peripheral handle and the Callback ID.
229 
230     By default, after the HAL_MMC_Init and if the state is HAL_MMC_STATE_RESET
231     all callbacks are reset to the corresponding legacy weak (surcharged) functions.
232     Exception done for MspInit and MspDeInit callbacks that are respectively
233     reset to the legacy weak (surcharged) functions in the HAL_MMC_Init
234     and  HAL_MMC_DeInit only when these callbacks are null (not registered beforehand).
235     If not, MspInit or MspDeInit are not null, the HAL_MMC_Init and HAL_MMC_DeInit
236     keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
237 
238     Callbacks can be registered/unregistered in READY state only.
239     Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
240     in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
241     during the Init/DeInit.
242     In that case first register the MspInit/MspDeInit user callbacks
243     using HAL_MMC_RegisterCallback before calling HAL_MMC_DeInit
244     or HAL_MMC_Init function.
245 
246     When The compilation define USE_HAL_MMC_REGISTER_CALLBACKS is set to 0 or
247     not defined, the callback registering feature is not available
248     and weak (surcharged) callbacks are used.
249 
250   @endverbatim
251   ******************************************************************************
252   */
253 
254 /* Includes ------------------------------------------------------------------*/
255 #include "stm32f7xx_hal.h"
256 
257 /** @addtogroup STM32F7xx_HAL_Driver
258   * @{
259   */
260 
261 /** @defgroup MMC MMC
262   * @brief MMC HAL module driver
263   * @{
264   */
265 
266 #ifdef HAL_MMC_MODULE_ENABLED
267 
268 #if defined(SDMMC1)
269 
270 /* Private typedef -----------------------------------------------------------*/
271 /* Private define ------------------------------------------------------------*/
272 /** @addtogroup MMC_Private_Defines
273   * @{
274   */
275 #if defined (VDD_VALUE) && (VDD_VALUE <= 1950U)
276 #define MMC_VOLTAGE_RANGE               EMMC_LOW_VOLTAGE_RANGE
277 
278 #define MMC_EXT_CSD_PWR_CL_26_INDEX     201
279 #define MMC_EXT_CSD_PWR_CL_52_INDEX     200
280 #define MMC_EXT_CSD_PWR_CL_DDR_52_INDEX 238
281 
282 #define MMC_EXT_CSD_PWR_CL_26_POS       8
283 #define MMC_EXT_CSD_PWR_CL_52_POS       0
284 #define MMC_EXT_CSD_PWR_CL_DDR_52_POS   16
285 #else
286 #define MMC_VOLTAGE_RANGE               EMMC_HIGH_VOLTAGE_RANGE
287 
288 #define MMC_EXT_CSD_PWR_CL_26_INDEX     203
289 #define MMC_EXT_CSD_PWR_CL_52_INDEX     202
290 #define MMC_EXT_CSD_PWR_CL_DDR_52_INDEX 239
291 
292 #define MMC_EXT_CSD_PWR_CL_26_POS       24
293 #define MMC_EXT_CSD_PWR_CL_52_POS       16
294 #define MMC_EXT_CSD_PWR_CL_DDR_52_POS   24
295 #endif
296 
297 /* Frequencies used in the driver for clock divider calculation */
298 #define MMC_INIT_FREQ                   400000U   /* Initialization phase : 400 kHz max */
299 /**
300   * @}
301   */
302 
303 /* Private macro -------------------------------------------------------------*/
304 /* Private variables ---------------------------------------------------------*/
305 /* Private function prototypes -----------------------------------------------*/
306 /* Private functions ---------------------------------------------------------*/
307 /** @defgroup MMC_Private_Functions MMC Private Functions
308   * @{
309   */
310 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc);
311 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc);
312 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus);
313 static uint32_t MMC_ReadExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pFieldData, uint16_t FieldIndex, uint32_t Timeout);
314 static void     MMC_PowerOFF(MMC_HandleTypeDef *hmmc);
315 static void     MMC_Write_IT(MMC_HandleTypeDef *hmmc);
316 static void     MMC_Read_IT(MMC_HandleTypeDef *hmmc);
317 static void     MMC_DMATransmitCplt(DMA_HandleTypeDef *hdma);
318 static void     MMC_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
319 static void     MMC_DMAError(DMA_HandleTypeDef *hdma);
320 static void     MMC_DMATxAbort(DMA_HandleTypeDef *hdma);
321 static void     MMC_DMARxAbort(DMA_HandleTypeDef *hdma);
322 static uint32_t MMC_PwrClassUpdate(MMC_HandleTypeDef *hmmc, uint32_t Wide);
323 /**
324   * @}
325   */
326 /* Exported functions --------------------------------------------------------*/
327 /** @addtogroup MMC_Exported_Functions
328   * @{
329   */
330 
331 /** @addtogroup MMC_Exported_Functions_Group1
332  *  @brief   Initialization and de-initialization functions
333  *
334 @verbatim
335   ==============================================================================
336           ##### Initialization and de-initialization functions #####
337   ==============================================================================
338   [..]
339     This section provides functions allowing to initialize/de-initialize the MMC
340     card device to be ready for use.
341 
342 @endverbatim
343   * @{
344   */
345 
346 /**
347   * @brief  Initializes the MMC according to the specified parameters in the
348             MMC_HandleTypeDef and create the associated handle.
349   * @param  hmmc: Pointer to the MMC handle
350   * @retval HAL status
351   */
HAL_MMC_Init(MMC_HandleTypeDef * hmmc)352 HAL_StatusTypeDef HAL_MMC_Init(MMC_HandleTypeDef *hmmc)
353 {
354   /* Check the MMC handle allocation */
355   if(hmmc == NULL)
356   {
357     return HAL_ERROR;
358   }
359 
360   /* Check the parameters */
361   assert_param(IS_SDMMC_ALL_INSTANCE(hmmc->Instance));
362   assert_param(IS_SDMMC_CLOCK_EDGE(hmmc->Init.ClockEdge));
363   assert_param(IS_SDMMC_CLOCK_BYPASS(hmmc->Init.ClockBypass));
364   assert_param(IS_SDMMC_CLOCK_POWER_SAVE(hmmc->Init.ClockPowerSave));
365   assert_param(IS_SDMMC_BUS_WIDE(hmmc->Init.BusWide));
366   assert_param(IS_SDMMC_HARDWARE_FLOW_CONTROL(hmmc->Init.HardwareFlowControl));
367   assert_param(IS_SDMMC_CLKDIV(hmmc->Init.ClockDiv));
368 
369   if(hmmc->State == HAL_MMC_STATE_RESET)
370   {
371     /* Allocate lock resource and initialize it */
372     hmmc->Lock = HAL_UNLOCKED;
373 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
374     /* Reset Callback pointers in HAL_MMC_STATE_RESET only */
375     hmmc->TxCpltCallback    = HAL_MMC_TxCpltCallback;
376     hmmc->RxCpltCallback    = HAL_MMC_RxCpltCallback;
377     hmmc->ErrorCallback     = HAL_MMC_ErrorCallback;
378     hmmc->AbortCpltCallback = HAL_MMC_AbortCallback;
379 
380     if(hmmc->MspInitCallback == NULL)
381     {
382       hmmc->MspInitCallback = HAL_MMC_MspInit;
383     }
384 
385     /* Init the low level hardware */
386     hmmc->MspInitCallback(hmmc);
387 #else
388     /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
389     HAL_MMC_MspInit(hmmc);
390 #endif
391   }
392 
393   hmmc->State = HAL_MMC_STATE_BUSY;
394 
395   /* Initialize the Card parameters */
396   if(HAL_MMC_InitCard(hmmc) == HAL_ERROR)
397   {
398     return HAL_ERROR;
399   }
400 
401   /* Initialize the error code */
402   hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
403 
404   /* Initialize the MMC operation */
405   hmmc->Context = MMC_CONTEXT_NONE;
406 
407   /* Initialize the MMC state */
408   hmmc->State = HAL_MMC_STATE_READY;
409 
410   /* Configure bus width */
411   if (hmmc->Init.BusWide != SDMMC_BUS_WIDE_1B)
412   {
413     if (HAL_MMC_ConfigWideBusOperation(hmmc, hmmc->Init.BusWide) != HAL_OK)
414     {
415       return HAL_ERROR;
416     }
417   }
418 
419   return HAL_OK;
420 }
421 
422 /**
423   * @brief  Initializes the MMC Card.
424   * @param  hmmc: Pointer to MMC handle
425   * @note   This function initializes the MMC card. It could be used when a card
426             re-initialization is needed.
427   * @retval HAL status
428   */
HAL_MMC_InitCard(MMC_HandleTypeDef * hmmc)429 HAL_StatusTypeDef HAL_MMC_InitCard(MMC_HandleTypeDef *hmmc)
430 {
431   uint32_t errorstate;
432   MMC_InitTypeDef Init;
433   HAL_StatusTypeDef status;
434 
435   /* Default SDMMC peripheral configuration for MMC card initialization */
436   Init.ClockEdge           = SDMMC_CLOCK_EDGE_RISING;
437   Init.ClockBypass         = SDMMC_CLOCK_BYPASS_DISABLE;
438   Init.ClockPowerSave      = SDMMC_CLOCK_POWER_SAVE_DISABLE;
439   Init.BusWide             = SDMMC_BUS_WIDE_1B;
440   Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
441   Init.ClockDiv            = SDMMC_INIT_CLK_DIV;
442 
443   /* Initialize SDMMC peripheral interface with default configuration */
444   status = SDMMC_Init(hmmc->Instance, Init);
445   if(status == HAL_ERROR)
446   {
447     return HAL_ERROR;
448   }
449 
450   /* Disable SDMMC Clock */
451   __HAL_MMC_DISABLE(hmmc);
452 
453   /* Set Power State to ON */
454   status = SDMMC_PowerState_ON(hmmc->Instance);
455   if(status == HAL_ERROR)
456   {
457     return HAL_ERROR;
458   }
459 
460   /* Enable MMC Clock */
461   __HAL_MMC_ENABLE(hmmc);
462 
463   /* Required power up waiting time before starting the MMC initialization  sequence */
464   HAL_Delay(2);
465 
466   /* Identify card operating voltage */
467   errorstate = MMC_PowerON(hmmc);
468   if(errorstate != HAL_MMC_ERROR_NONE)
469   {
470     hmmc->State = HAL_MMC_STATE_READY;
471     hmmc->ErrorCode |= errorstate;
472     return HAL_ERROR;
473   }
474 
475   /* Card initialization */
476   errorstate = MMC_InitCard(hmmc);
477   if(errorstate != HAL_MMC_ERROR_NONE)
478   {
479     hmmc->State = HAL_MMC_STATE_READY;
480     hmmc->ErrorCode |= errorstate;
481     return HAL_ERROR;
482   }
483 
484   /* Set Block Size for Card */
485   errorstate = SDMMC_CmdBlockLength(hmmc->Instance, MMC_BLOCKSIZE);
486   if(errorstate != HAL_MMC_ERROR_NONE)
487   {
488     /* Clear all the static flags */
489     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
490     hmmc->ErrorCode |= errorstate;
491     hmmc->State = HAL_MMC_STATE_READY;
492     return HAL_ERROR;
493   }
494 
495   return HAL_OK;
496 }
497 
498 /**
499   * @brief  De-Initializes the MMC card.
500   * @param  hmmc: Pointer to MMC handle
501   * @retval HAL status
502   */
HAL_MMC_DeInit(MMC_HandleTypeDef * hmmc)503 HAL_StatusTypeDef HAL_MMC_DeInit(MMC_HandleTypeDef *hmmc)
504 {
505   /* Check the MMC handle allocation */
506   if(hmmc == NULL)
507   {
508     return HAL_ERROR;
509   }
510 
511   /* Check the parameters */
512   assert_param(IS_SDMMC_ALL_INSTANCE(hmmc->Instance));
513 
514   hmmc->State = HAL_MMC_STATE_BUSY;
515 
516   /* Set MMC power state to off */
517   MMC_PowerOFF(hmmc);
518 
519 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
520   if(hmmc->MspDeInitCallback == NULL)
521   {
522     hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
523   }
524 
525   /* DeInit the low level hardware */
526   hmmc->MspDeInitCallback(hmmc);
527 #else
528   /* De-Initialize the MSP layer */
529   HAL_MMC_MspDeInit(hmmc);
530 #endif
531 
532   hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
533   hmmc->State = HAL_MMC_STATE_RESET;
534 
535   return HAL_OK;
536 }
537 
538 
539 /**
540   * @brief  Initializes the MMC MSP.
541   * @param  hmmc: Pointer to MMC handle
542   * @retval None
543   */
HAL_MMC_MspInit(MMC_HandleTypeDef * hmmc)544 __weak void HAL_MMC_MspInit(MMC_HandleTypeDef *hmmc)
545 {
546   /* Prevent unused argument(s) compilation warning */
547   UNUSED(hmmc);
548 
549   /* NOTE : This function Should not be modified, when the callback is needed,
550             the HAL_MMC_MspInit could be implemented in the user file
551    */
552 }
553 
554 /**
555   * @brief  De-Initialize MMC MSP.
556   * @param  hmmc: Pointer to MMC handle
557   * @retval None
558   */
HAL_MMC_MspDeInit(MMC_HandleTypeDef * hmmc)559 __weak void HAL_MMC_MspDeInit(MMC_HandleTypeDef *hmmc)
560 {
561   /* Prevent unused argument(s) compilation warning */
562   UNUSED(hmmc);
563 
564   /* NOTE : This function Should not be modified, when the callback is needed,
565             the HAL_MMC_MspDeInit could be implemented in the user file
566    */
567 }
568 
569 /**
570   * @}
571   */
572 
573 /** @addtogroup MMC_Exported_Functions_Group2
574  *  @brief   Data transfer functions
575  *
576 @verbatim
577   ==============================================================================
578                         ##### IO operation functions #####
579   ==============================================================================
580   [..]
581     This subsection provides a set of functions allowing to manage the data
582     transfer from/to MMC card.
583 
584 @endverbatim
585   * @{
586   */
587 
588 /**
589   * @brief  Reads block(s) from a specified address in a card. The Data transfer
590   *         is managed by polling mode.
591   * @note   This API should be followed by a check on the card state through
592   *         HAL_MMC_GetCardState().
593   * @param  hmmc: Pointer to MMC handle
594   * @param  pData: pointer to the buffer that will contain the received data
595   * @param  BlockAdd: Block Address from where data is to be read
596   * @param  NumberOfBlocks: Number of MMC blocks to read
597   * @param  Timeout: Specify timeout value
598   * @retval HAL status
599   */
HAL_MMC_ReadBlocks(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks,uint32_t Timeout)600 HAL_StatusTypeDef HAL_MMC_ReadBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
601 {
602   SDMMC_DataInitTypeDef config;
603   uint32_t errorstate;
604   uint32_t tickstart = HAL_GetTick();
605   uint32_t count, data, dataremaining;
606   uint32_t add = BlockAdd;
607   uint8_t *tempbuff = pData;
608 
609   if(NULL == pData)
610   {
611     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
612     return HAL_ERROR;
613   }
614 
615   if(hmmc->State == HAL_MMC_STATE_READY)
616   {
617     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
618 
619     if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
620     {
621       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
622       return HAL_ERROR;
623     }
624 
625     hmmc->State = HAL_MMC_STATE_BUSY;
626 
627     /* Initialize data control register */
628     hmmc->Instance->DCTRL = 0U;
629 
630     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
631     {
632       add *= 512U;
633     }
634 
635     /* Configure the MMC DPSM (Data Path State Machine) */
636     config.DataTimeOut   = SDMMC_DATATIMEOUT;
637     config.DataLength    = NumberOfBlocks * MMC_BLOCKSIZE;
638     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
639     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
640     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
641     config.DPSM          = SDMMC_DPSM_ENABLE;
642     (void)SDMMC_ConfigData(hmmc->Instance, &config);
643 
644     /* Read block(s) in polling mode */
645     if(NumberOfBlocks > 1U)
646     {
647       hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
648 
649       /* Read Multi Block command */
650       errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
651     }
652     else
653     {
654       hmmc->Context = MMC_CONTEXT_READ_SINGLE_BLOCK;
655 
656       /* Read Single Block command */
657       errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
658     }
659     if(errorstate != HAL_MMC_ERROR_NONE)
660     {
661       /* Clear all the static flags */
662       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
663       hmmc->ErrorCode |= errorstate;
664       hmmc->State = HAL_MMC_STATE_READY;
665       return HAL_ERROR;
666     }
667 
668     /* Poll on SDMMC flags */
669     dataremaining = config.DataLength;
670     while(!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
671     {
672       if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining > 0U))
673       {
674         /* Read data from SDMMC Rx FIFO */
675         for(count = 0U; count < 8U; count++)
676         {
677           data = SDMMC_ReadFIFO(hmmc->Instance);
678           *tempbuff = (uint8_t)(data & 0xFFU);
679           tempbuff++;
680           dataremaining--;
681           *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
682           tempbuff++;
683           dataremaining--;
684           *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
685           tempbuff++;
686           dataremaining--;
687           *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
688           tempbuff++;
689           dataremaining--;
690         }
691       }
692 
693       if(((HAL_GetTick()-tickstart) >=  Timeout) || (Timeout == 0U))
694       {
695         /* Clear all the static flags */
696         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
697         hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
698         hmmc->State= HAL_MMC_STATE_READY;
699         return HAL_TIMEOUT;
700       }
701     }
702 
703     /* Send stop transmission command in case of multiblock read */
704     if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U))
705     {
706       /* Send stop transmission command */
707       errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
708       if(errorstate != HAL_MMC_ERROR_NONE)
709       {
710         /* Clear all the static flags */
711         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
712         hmmc->ErrorCode |= errorstate;
713         hmmc->State = HAL_MMC_STATE_READY;
714         return HAL_ERROR;
715       }
716     }
717 
718     /* Get error state */
719     if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
720     {
721       /* Clear all the static flags */
722       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
723       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
724       hmmc->State = HAL_MMC_STATE_READY;
725       return HAL_ERROR;
726     }
727     else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
728     {
729       /* Clear all the static flags */
730       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
731       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
732       hmmc->State = HAL_MMC_STATE_READY;
733       return HAL_ERROR;
734     }
735     else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR))
736     {
737       /* Clear all the static flags */
738       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
739       hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
740       hmmc->State = HAL_MMC_STATE_READY;
741       return HAL_ERROR;
742     }
743     else
744     {
745       /* Nothing to do */
746     }
747 
748     /* Empty FIFO if there is still any data */
749     while ((__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXDAVL)) && (dataremaining > 0U))
750     {
751       data = SDMMC_ReadFIFO(hmmc->Instance);
752       *tempbuff = (uint8_t)(data & 0xFFU);
753       tempbuff++;
754       dataremaining--;
755       *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
756       tempbuff++;
757       dataremaining--;
758       *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
759       tempbuff++;
760       dataremaining--;
761       *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
762       tempbuff++;
763       dataremaining--;
764 
765       if(((HAL_GetTick()-tickstart) >=  Timeout) || (Timeout == 0U))
766       {
767         /* Clear all the static flags */
768         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
769         hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
770         hmmc->State= HAL_MMC_STATE_READY;
771         return HAL_ERROR;
772       }
773     }
774 
775     /* Clear all the static flags */
776     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
777 
778     hmmc->State = HAL_MMC_STATE_READY;
779 
780     return HAL_OK;
781   }
782   else
783   {
784     hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
785     return HAL_ERROR;
786   }
787 }
788 
789 /**
790   * @brief  Allows to write block(s) to a specified address in a card. The Data
791   *         transfer is managed by polling mode.
792   * @note   This API should be followed by a check on the card state through
793   *         HAL_MMC_GetCardState().
794   * @param  hmmc: Pointer to MMC handle
795   * @param  pData: pointer to the buffer that will contain the data to transmit
796   * @param  BlockAdd: Block Address where data will be written
797   * @param  NumberOfBlocks: Number of MMC blocks to write
798   * @param  Timeout: Specify timeout value
799   * @retval HAL status
800   */
HAL_MMC_WriteBlocks(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks,uint32_t Timeout)801 HAL_StatusTypeDef HAL_MMC_WriteBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
802 {
803   SDMMC_DataInitTypeDef config;
804   uint32_t errorstate;
805   uint32_t tickstart = HAL_GetTick();
806   uint32_t count, data, dataremaining;
807   uint32_t add = BlockAdd;
808   uint8_t *tempbuff = pData;
809 
810   if(NULL == pData)
811   {
812     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
813     return HAL_ERROR;
814   }
815 
816   if(hmmc->State == HAL_MMC_STATE_READY)
817   {
818     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
819 
820     if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
821     {
822       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
823       return HAL_ERROR;
824     }
825 
826     hmmc->State = HAL_MMC_STATE_BUSY;
827 
828     /* Initialize data control register */
829     hmmc->Instance->DCTRL = 0U;
830 
831     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
832     {
833       add *= 512U;
834     }
835 
836     /* Write Blocks in Polling mode */
837     if(NumberOfBlocks > 1U)
838     {
839       hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
840 
841       /* Write Multi Block command */
842       errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
843     }
844     else
845     {
846       hmmc->Context = MMC_CONTEXT_WRITE_SINGLE_BLOCK;
847 
848       /* Write Single Block command */
849       errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
850     }
851     if(errorstate != HAL_MMC_ERROR_NONE)
852     {
853       /* Clear all the static flags */
854       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
855       hmmc->ErrorCode |= errorstate;
856       hmmc->State = HAL_MMC_STATE_READY;
857       return HAL_ERROR;
858     }
859 
860     /* Configure the MMC DPSM (Data Path State Machine) */
861     config.DataTimeOut   = SDMMC_DATATIMEOUT;
862     config.DataLength    = NumberOfBlocks * MMC_BLOCKSIZE;
863     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
864     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
865     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
866     config.DPSM          = SDMMC_DPSM_ENABLE;
867     (void)SDMMC_ConfigData(hmmc->Instance, &config);
868 
869     /* Write block(s) in polling mode */
870     dataremaining = config.DataLength;
871     while(!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
872     {
873       if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining > 0U))
874       {
875         /* Write data to SDMMC Tx FIFO */
876         for(count = 0U; count < 8U; count++)
877         {
878           data = (uint32_t)(*tempbuff);
879           tempbuff++;
880           dataremaining--;
881           data |= ((uint32_t)(*tempbuff) << 8U);
882           tempbuff++;
883           dataremaining--;
884           data |= ((uint32_t)(*tempbuff) << 16U);
885           tempbuff++;
886           dataremaining--;
887           data |= ((uint32_t)(*tempbuff) << 24U);
888           tempbuff++;
889           dataremaining--;
890           (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
891         }
892       }
893 
894       if(((HAL_GetTick()-tickstart) >=  Timeout) || (Timeout == 0U))
895       {
896         /* Clear all the static flags */
897         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
898         hmmc->ErrorCode |= errorstate;
899         hmmc->State = HAL_MMC_STATE_READY;
900         return HAL_TIMEOUT;
901       }
902     }
903 
904     /* Send stop transmission command in case of multiblock write */
905     if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U))
906     {
907       /* Send stop transmission command */
908       errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
909       if(errorstate != HAL_MMC_ERROR_NONE)
910       {
911         /* Clear all the static flags */
912         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
913         hmmc->ErrorCode |= errorstate;
914         hmmc->State = HAL_MMC_STATE_READY;
915         return HAL_ERROR;
916       }
917     }
918 
919     /* Get error state */
920     if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
921     {
922       /* Clear all the static flags */
923       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
924       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
925       hmmc->State = HAL_MMC_STATE_READY;
926       return HAL_ERROR;
927     }
928     else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
929     {
930       /* Clear all the static flags */
931       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
932       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
933       hmmc->State = HAL_MMC_STATE_READY;
934       return HAL_ERROR;
935     }
936     else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
937     {
938       /* Clear all the static flags */
939       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
940       hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
941       hmmc->State = HAL_MMC_STATE_READY;
942       return HAL_ERROR;
943     }
944     else
945     {
946       /* Nothing to do */
947     }
948 
949     /* Clear all the static flags */
950     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
951 
952     hmmc->State = HAL_MMC_STATE_READY;
953 
954     return HAL_OK;
955   }
956   else
957   {
958     hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
959     return HAL_ERROR;
960   }
961 }
962 
963 /**
964   * @brief  Reads block(s) from a specified address in a card. The Data transfer
965   *         is managed in interrupt mode.
966   * @note   This API should be followed by a check on the card state through
967   *         HAL_MMC_GetCardState().
968   * @note   You could also check the IT transfer process through the MMC Rx
969   *         interrupt event.
970   * @param  hmmc: Pointer to MMC handle
971   * @param  pData: Pointer to the buffer that will contain the received data
972   * @param  BlockAdd: Block Address from where data is to be read
973   * @param  NumberOfBlocks: Number of blocks to read.
974   * @retval HAL status
975   */
HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)976 HAL_StatusTypeDef HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
977 {
978   SDMMC_DataInitTypeDef config;
979   uint32_t errorstate;
980   uint32_t add = BlockAdd;
981 
982   if(NULL == pData)
983   {
984     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
985     return HAL_ERROR;
986   }
987 
988   if(hmmc->State == HAL_MMC_STATE_READY)
989   {
990     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
991 
992     if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
993     {
994       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
995       return HAL_ERROR;
996     }
997 
998     hmmc->State = HAL_MMC_STATE_BUSY;
999 
1000     /* Initialize data control register */
1001     hmmc->Instance->DCTRL = 0U;
1002 
1003     hmmc->pRxBuffPtr = pData;
1004     hmmc->RxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1005 
1006     __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND | SDMMC_FLAG_RXFIFOHF));
1007 
1008     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1009     {
1010       add *= 512U;
1011     }
1012 
1013     /* Configure the MMC DPSM (Data Path State Machine) */
1014     config.DataTimeOut   = SDMMC_DATATIMEOUT;
1015     config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
1016     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1017     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
1018     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
1019     config.DPSM          = SDMMC_DPSM_ENABLE;
1020     (void)SDMMC_ConfigData(hmmc->Instance, &config);
1021 
1022     /* Read Blocks in IT mode */
1023     if(NumberOfBlocks > 1U)
1024     {
1025       hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_IT);
1026 
1027       /* Read Multi Block command */
1028       errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
1029     }
1030     else
1031     {
1032       hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_IT);
1033 
1034       /* Read Single Block command */
1035       errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
1036     }
1037 
1038     if(errorstate != HAL_MMC_ERROR_NONE)
1039     {
1040       /* Clear all the static flags */
1041       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1042       hmmc->ErrorCode |= errorstate;
1043       hmmc->State = HAL_MMC_STATE_READY;
1044       return HAL_ERROR;
1045     }
1046 
1047     return HAL_OK;
1048   }
1049   else
1050   {
1051     return HAL_BUSY;
1052   }
1053 }
1054 
1055 /**
1056   * @brief  Writes block(s) to a specified address in a card. The Data transfer
1057   *         is managed in interrupt mode.
1058   * @note   This API should be followed by a check on the card state through
1059   *         HAL_MMC_GetCardState().
1060   * @note   You could also check the IT transfer process through the MMC Tx
1061   *         interrupt event.
1062   * @param  hmmc: Pointer to MMC handle
1063   * @param  pData: Pointer to the buffer that will contain the data to transmit
1064   * @param  BlockAdd: Block Address where data will be written
1065   * @param  NumberOfBlocks: Number of blocks to write
1066   * @retval HAL status
1067   */
HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)1068 HAL_StatusTypeDef HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
1069 {
1070   SDMMC_DataInitTypeDef config;
1071   uint32_t errorstate;
1072   uint32_t add = BlockAdd;
1073 
1074   if(NULL == pData)
1075   {
1076     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1077     return HAL_ERROR;
1078   }
1079 
1080   if(hmmc->State == HAL_MMC_STATE_READY)
1081   {
1082     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1083 
1084     if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1085     {
1086       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1087       return HAL_ERROR;
1088     }
1089 
1090     hmmc->State = HAL_MMC_STATE_BUSY;
1091 
1092     /* Initialize data control register */
1093     hmmc->Instance->DCTRL = 0U;
1094 
1095     hmmc->pTxBuffPtr = pData;
1096     hmmc->TxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1097 
1098     /* Enable transfer interrupts */
1099     __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND | SDMMC_FLAG_TXFIFOHE));
1100 
1101     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1102     {
1103       add *= 512U;
1104     }
1105 
1106     /* Write Blocks in Polling mode */
1107     if(NumberOfBlocks > 1U)
1108     {
1109       hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK| MMC_CONTEXT_IT);
1110 
1111       /* Write Multi Block command */
1112       errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
1113     }
1114     else
1115     {
1116       hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_IT);
1117 
1118       /* Write Single Block command */
1119       errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
1120     }
1121     if(errorstate != HAL_MMC_ERROR_NONE)
1122     {
1123       /* Clear all the static flags */
1124       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1125       hmmc->ErrorCode |= errorstate;
1126       hmmc->State = HAL_MMC_STATE_READY;
1127       return HAL_ERROR;
1128     }
1129 
1130     /* Configure the MMC DPSM (Data Path State Machine) */
1131     config.DataTimeOut   = SDMMC_DATATIMEOUT;
1132     config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
1133     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1134     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
1135     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
1136     config.DPSM          = SDMMC_DPSM_ENABLE;
1137     (void)SDMMC_ConfigData(hmmc->Instance, &config);
1138 
1139     return HAL_OK;
1140   }
1141   else
1142   {
1143     return HAL_BUSY;
1144   }
1145 }
1146 
1147 /**
1148   * @brief  Reads block(s) from a specified address in a card. The Data transfer
1149   *         is managed by DMA mode.
1150   * @note   This API should be followed by a check on the card state through
1151   *         HAL_MMC_GetCardState().
1152   * @note   You could also check the DMA transfer process through the MMC Rx
1153   *         interrupt event.
1154   * @param  hmmc: Pointer MMC handle
1155   * @param  pData: Pointer to the buffer that will contain the received data
1156   * @param  BlockAdd: Block Address from where data is to be read
1157   * @param  NumberOfBlocks: Number of blocks to read.
1158   * @retval HAL status
1159   */
HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)1160 HAL_StatusTypeDef HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
1161 {
1162   SDMMC_DataInitTypeDef config;
1163   uint32_t errorstate;
1164   uint32_t add = BlockAdd;
1165 
1166   if(NULL == pData)
1167   {
1168     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1169     return HAL_ERROR;
1170   }
1171 
1172   if(hmmc->State == HAL_MMC_STATE_READY)
1173   {
1174     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1175 
1176     if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1177     {
1178       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1179       return HAL_ERROR;
1180     }
1181 
1182     hmmc->State = HAL_MMC_STATE_BUSY;
1183 
1184     /* Initialize data control register */
1185     hmmc->Instance->DCTRL = 0U;
1186 
1187     __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND));
1188 
1189     /* Set the DMA transfer complete callback */
1190     hmmc->hdmarx->XferCpltCallback = MMC_DMAReceiveCplt;
1191 
1192     /* Set the DMA error callback */
1193     hmmc->hdmarx->XferErrorCallback = MMC_DMAError;
1194 
1195     /* Set the DMA Abort callback */
1196     hmmc->hdmarx->XferAbortCallback = NULL;
1197 
1198     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1199     {
1200       add *= 512U;
1201     }
1202 
1203     /* Force DMA Direction */
1204     hmmc->hdmarx->Init.Direction = DMA_PERIPH_TO_MEMORY;
1205     MODIFY_REG(hmmc->hdmarx->Instance->CR, DMA_SxCR_DIR, hmmc->hdmarx->Init.Direction);
1206 
1207     /* Enable the DMA Channel */
1208     if(HAL_DMA_Start_IT(hmmc->hdmarx, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)pData, (uint32_t)(MMC_BLOCKSIZE * NumberOfBlocks)/4) != HAL_OK)
1209     {
1210       __HAL_MMC_DISABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND));
1211       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1212       hmmc->ErrorCode = HAL_MMC_ERROR_DMA;
1213       hmmc->State = HAL_MMC_STATE_READY;
1214       return HAL_ERROR;
1215     }
1216     else
1217     {
1218       /* Enable MMC DMA transfer */
1219       __HAL_MMC_DMA_ENABLE(hmmc);
1220 
1221       /* Configure the MMC DPSM (Data Path State Machine) */
1222       config.DataTimeOut   = SDMMC_DATATIMEOUT;
1223       config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
1224       config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1225       config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
1226       config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
1227       config.DPSM          = SDMMC_DPSM_ENABLE;
1228       (void)SDMMC_ConfigData(hmmc->Instance, &config);
1229 
1230       /* Read Blocks in DMA mode */
1231       if(NumberOfBlocks > 1U)
1232       {
1233         hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
1234 
1235         /* Read Multi Block command */
1236         errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
1237       }
1238       else
1239       {
1240         hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_DMA);
1241 
1242         /* Read Single Block command */
1243         errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
1244       }
1245       if(errorstate != HAL_MMC_ERROR_NONE)
1246       {
1247         /* Clear all the static flags */
1248         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1249         __HAL_MMC_DISABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND));
1250         hmmc->ErrorCode = errorstate;
1251         hmmc->State = HAL_MMC_STATE_READY;
1252         return HAL_ERROR;
1253       }
1254 
1255       return HAL_OK;
1256     }
1257   }
1258   else
1259   {
1260     return HAL_BUSY;
1261   }
1262 }
1263 
1264 /**
1265   * @brief  Writes block(s) to a specified address in a card. The Data transfer
1266   *         is managed by DMA mode.
1267   * @note   This API should be followed by a check on the card state through
1268   *         HAL_MMC_GetCardState().
1269   * @note   You could also check the DMA transfer process through the MMC Tx
1270   *         interrupt event.
1271   * @param  hmmc: Pointer to MMC handle
1272   * @param  pData: Pointer to the buffer that will contain the data to transmit
1273   * @param  BlockAdd: Block Address where data will be written
1274   * @param  NumberOfBlocks: Number of blocks to write
1275   * @retval HAL status
1276   */
HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)1277 HAL_StatusTypeDef HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
1278 {
1279   SDMMC_DataInitTypeDef config;
1280   uint32_t errorstate;
1281   uint32_t add = BlockAdd;
1282 
1283   if(NULL == pData)
1284   {
1285     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1286     return HAL_ERROR;
1287   }
1288 
1289   if(hmmc->State == HAL_MMC_STATE_READY)
1290   {
1291     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1292 
1293     if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1294     {
1295       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1296       return HAL_ERROR;
1297     }
1298 
1299     hmmc->State = HAL_MMC_STATE_BUSY;
1300 
1301     /* Initialize data control register */
1302     hmmc->Instance->DCTRL = 0U;
1303 
1304     /* Enable MMC Error interrupts */
1305 	__HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR));
1306 
1307     /* Set the DMA transfer complete callback */
1308     hmmc->hdmatx->XferCpltCallback = MMC_DMATransmitCplt;
1309 
1310     /* Set the DMA error callback */
1311     hmmc->hdmatx->XferErrorCallback = MMC_DMAError;
1312 
1313     /* Set the DMA Abort callback */
1314     hmmc->hdmatx->XferAbortCallback = NULL;
1315 
1316     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1317     {
1318       add *= 512U;
1319     }
1320 
1321 
1322     /* Write Blocks in Polling mode */
1323     if(NumberOfBlocks > 1U)
1324     {
1325       hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
1326 
1327       /* Write Multi Block command */
1328       errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
1329     }
1330     else
1331     {
1332       hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_DMA);
1333 
1334       /* Write Single Block command */
1335       errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
1336     }
1337     if(errorstate != HAL_MMC_ERROR_NONE)
1338     {
1339       /* Clear all the static flags */
1340       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1341       __HAL_MMC_DISABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND));
1342       hmmc->ErrorCode |= errorstate;
1343       hmmc->State = HAL_MMC_STATE_READY;
1344       return HAL_ERROR;
1345     }
1346 
1347     /* Enable SDMMC DMA transfer */
1348     __HAL_MMC_DMA_ENABLE(hmmc);
1349 
1350     /* Force DMA Direction */
1351     hmmc->hdmatx->Init.Direction = DMA_MEMORY_TO_PERIPH;
1352     MODIFY_REG(hmmc->hdmatx->Instance->CR, DMA_SxCR_DIR, hmmc->hdmatx->Init.Direction);
1353 
1354     /* Enable the DMA Channel */
1355     if(HAL_DMA_Start_IT(hmmc->hdmatx, (uint32_t)pData, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)(MMC_BLOCKSIZE * NumberOfBlocks)/4) != HAL_OK)
1356     {
1357       __HAL_MMC_DISABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND));
1358       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1359       hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
1360       hmmc->State = HAL_MMC_STATE_READY;
1361       return HAL_ERROR;
1362     }
1363     else
1364     {
1365       /* Configure the MMC DPSM (Data Path State Machine) */
1366       config.DataTimeOut   = SDMMC_DATATIMEOUT;
1367       config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
1368       config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1369       config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
1370       config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
1371       config.DPSM          = SDMMC_DPSM_ENABLE;
1372       (void)SDMMC_ConfigData(hmmc->Instance, &config);
1373 
1374       return HAL_OK;
1375     }
1376   }
1377   else
1378   {
1379     return HAL_BUSY;
1380   }
1381 }
1382 
1383 /**
1384   * @brief  Erases the specified memory area of the given MMC card.
1385   * @note   This API should be followed by a check on the card state through
1386   *         HAL_MMC_GetCardState().
1387   * @param  hmmc: Pointer to MMC handle
1388   * @param  BlockStartAdd: Start Block address
1389   * @param  BlockEndAdd: End Block address
1390   * @retval HAL status
1391   */
HAL_MMC_Erase(MMC_HandleTypeDef * hmmc,uint32_t BlockStartAdd,uint32_t BlockEndAdd)1392 HAL_StatusTypeDef HAL_MMC_Erase(MMC_HandleTypeDef *hmmc, uint32_t BlockStartAdd, uint32_t BlockEndAdd)
1393 {
1394   uint32_t errorstate;
1395   uint32_t start_add = BlockStartAdd;
1396   uint32_t end_add = BlockEndAdd;
1397 
1398   if(hmmc->State == HAL_MMC_STATE_READY)
1399   {
1400     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1401 
1402     if(end_add < start_add)
1403     {
1404       hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1405       return HAL_ERROR;
1406     }
1407 
1408     if(end_add > (hmmc->MmcCard.LogBlockNbr))
1409     {
1410       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1411       return HAL_ERROR;
1412     }
1413 
1414     hmmc->State = HAL_MMC_STATE_BUSY;
1415 
1416     /* Check if the card command class supports erase command */
1417     if(((hmmc->MmcCard.Class) & SDMMC_CCCC_ERASE) == 0U)
1418     {
1419       /* Clear all the static flags */
1420       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1421       hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
1422       hmmc->State = HAL_MMC_STATE_READY;
1423       return HAL_ERROR;
1424     }
1425 
1426     if((SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
1427     {
1428       /* Clear all the static flags */
1429       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1430       hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED;
1431       hmmc->State = HAL_MMC_STATE_READY;
1432       return HAL_ERROR;
1433     }
1434 
1435     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1436     {
1437       start_add *= 512U;
1438       end_add   *= 512U;
1439     }
1440 
1441     /* Send CMD35 MMC_ERASE_GRP_START with argument as addr  */
1442     errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, start_add);
1443     if(errorstate != HAL_MMC_ERROR_NONE)
1444     {
1445       /* Clear all the static flags */
1446       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1447       hmmc->ErrorCode |= errorstate;
1448       hmmc->State = HAL_MMC_STATE_READY;
1449       return HAL_ERROR;
1450     }
1451 
1452     /* Send CMD36 MMC_ERASE_GRP_END with argument as addr  */
1453     errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, end_add);
1454     if(errorstate != HAL_MMC_ERROR_NONE)
1455     {
1456       /* Clear all the static flags */
1457       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1458       hmmc->ErrorCode |= errorstate;
1459       hmmc->State = HAL_MMC_STATE_READY;
1460       return HAL_ERROR;
1461     }
1462 
1463     /* Send CMD38 ERASE */
1464     errorstate = SDMMC_CmdErase(hmmc->Instance);
1465     if(errorstate != HAL_MMC_ERROR_NONE)
1466     {
1467       /* Clear all the static flags */
1468       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1469       hmmc->ErrorCode |= errorstate;
1470       hmmc->State = HAL_MMC_STATE_READY;
1471       return HAL_ERROR;
1472     }
1473 
1474     hmmc->State = HAL_MMC_STATE_READY;
1475 
1476     return HAL_OK;
1477   }
1478   else
1479   {
1480     return HAL_BUSY;
1481   }
1482 }
1483 
1484 /**
1485   * @brief  This function handles MMC card interrupt request.
1486   * @param  hmmc: Pointer to MMC handle
1487   * @retval None
1488   */
HAL_MMC_IRQHandler(MMC_HandleTypeDef * hmmc)1489 void HAL_MMC_IRQHandler(MMC_HandleTypeDef *hmmc)
1490 {
1491   uint32_t errorstate;
1492   uint32_t context = hmmc->Context;
1493 
1494   /* Check for SDMMC interrupt flags */
1495   if((__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) != RESET) && ((context & MMC_CONTEXT_IT) != 0U))
1496   {
1497     MMC_Read_IT(hmmc);
1498   }
1499 
1500   else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) != RESET)
1501   {
1502     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_DATAEND);
1503 
1504     __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND  | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT |\
1505                                SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR  | SDMMC_IT_TXFIFOHE |\
1506                                SDMMC_IT_RXFIFOHF);
1507 
1508     hmmc->Instance->DCTRL &= ~(SDMMC_DCTRL_DTEN);
1509 
1510     if((context & MMC_CONTEXT_DMA) != 0U)
1511     {
1512       if((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)
1513       {
1514         errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
1515         if(errorstate != HAL_MMC_ERROR_NONE)
1516         {
1517           hmmc->ErrorCode |= errorstate;
1518 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1519           hmmc->ErrorCallback(hmmc);
1520 #else
1521           HAL_MMC_ErrorCallback(hmmc);
1522 #endif
1523         }
1524       }
1525       if(((context & MMC_CONTEXT_READ_SINGLE_BLOCK) == 0U) && ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) == 0U))
1526       {
1527         /* Disable the DMA transfer for transmit request by setting the DMAEN bit
1528         in the MMC DCTRL register */
1529         hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN);
1530 
1531         hmmc->State = HAL_MMC_STATE_READY;
1532 
1533 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1534         hmmc->TxCpltCallback(hmmc);
1535 #else
1536         HAL_MMC_TxCpltCallback(hmmc);
1537 #endif
1538       }
1539     }
1540     else if((context & MMC_CONTEXT_IT) != 0U)
1541     {
1542       /* Stop Transfer for Write Multi blocks or Read Multi blocks */
1543       if(((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
1544       {
1545         errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
1546         if(errorstate != HAL_MMC_ERROR_NONE)
1547         {
1548           hmmc->ErrorCode |= errorstate;
1549 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1550           hmmc->ErrorCallback(hmmc);
1551 #else
1552           HAL_MMC_ErrorCallback(hmmc);
1553 #endif
1554         }
1555       }
1556 
1557       /* Clear all the static flags */
1558       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
1559 
1560       hmmc->State = HAL_MMC_STATE_READY;
1561       if(((context & MMC_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
1562       {
1563 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1564         hmmc->RxCpltCallback(hmmc);
1565 #else
1566         HAL_MMC_RxCpltCallback(hmmc);
1567 #endif
1568       }
1569       else
1570       {
1571 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1572         hmmc->TxCpltCallback(hmmc);
1573 #else
1574         HAL_MMC_TxCpltCallback(hmmc);
1575 #endif
1576       }
1577     }
1578     else
1579     {
1580       /* Nothing to do */
1581     }
1582   }
1583 
1584   else if((__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) != RESET) && ((context & MMC_CONTEXT_IT) != 0U))
1585   {
1586     MMC_Write_IT(hmmc);
1587   }
1588 
1589   else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_RXOVERR | SDMMC_FLAG_TXUNDERR) != RESET)
1590   {
1591     /* Set Error code */
1592     if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL) != RESET)
1593     {
1594       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
1595     }
1596     if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT) != RESET)
1597     {
1598       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
1599     }
1600     if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR) != RESET)
1601     {
1602       hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
1603     }
1604     if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR) != RESET)
1605     {
1606       hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
1607     }
1608 
1609     /* Clear All flags */
1610     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
1611 
1612     /* Disable all interrupts */
1613     __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\
1614                              SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR);
1615 
1616     hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
1617 
1618     if((context & MMC_CONTEXT_IT) != 0U)
1619     {
1620       /* Set the MMC state to ready to be able to start again the process */
1621       hmmc->State = HAL_MMC_STATE_READY;
1622 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1623       hmmc->ErrorCallback(hmmc);
1624 #else
1625       HAL_MMC_ErrorCallback(hmmc);
1626 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1627     }
1628     else if((context & MMC_CONTEXT_DMA) != 0U)
1629     {
1630       /* Abort the MMC DMA Streams */
1631       if(hmmc->hdmatx != NULL)
1632       {
1633         /* Set the DMA Tx abort callback */
1634         hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort;
1635         /* Abort DMA in IT mode */
1636         if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
1637         {
1638           MMC_DMATxAbort(hmmc->hdmatx);
1639         }
1640       }
1641       else if(hmmc->hdmarx != NULL)
1642       {
1643         /* Set the DMA Rx abort callback */
1644         hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort;
1645         /* Abort DMA in IT mode */
1646         if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
1647         {
1648           MMC_DMARxAbort(hmmc->hdmarx);
1649         }
1650       }
1651       else
1652       {
1653         hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1654         hmmc->State = HAL_MMC_STATE_READY;
1655 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1656         hmmc->AbortCpltCallback(hmmc);
1657 #else
1658         HAL_MMC_AbortCallback(hmmc);
1659 #endif
1660       }
1661     }
1662     else
1663     {
1664       /* Nothing to do */
1665     }
1666   }
1667 
1668   else
1669   {
1670     /* Nothing to do */
1671   }
1672 }
1673 
1674 /**
1675   * @brief return the MMC state
1676   * @param hmmc: Pointer to mmc handle
1677   * @retval HAL state
1678   */
HAL_MMC_GetState(MMC_HandleTypeDef * hmmc)1679 HAL_MMC_StateTypeDef HAL_MMC_GetState(MMC_HandleTypeDef *hmmc)
1680 {
1681   return hmmc->State;
1682 }
1683 
1684 /**
1685 * @brief  Return the MMC error code
1686 * @param  hmmc : Pointer to a MMC_HandleTypeDef structure that contains
1687   *              the configuration information.
1688 * @retval MMC Error Code
1689 */
HAL_MMC_GetError(MMC_HandleTypeDef * hmmc)1690 uint32_t HAL_MMC_GetError(MMC_HandleTypeDef *hmmc)
1691 {
1692   return hmmc->ErrorCode;
1693 }
1694 
1695 /**
1696   * @brief Tx Transfer completed callbacks
1697   * @param hmmc: Pointer to MMC handle
1698   * @retval None
1699   */
HAL_MMC_TxCpltCallback(MMC_HandleTypeDef * hmmc)1700 __weak void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef *hmmc)
1701 {
1702   /* Prevent unused argument(s) compilation warning */
1703   UNUSED(hmmc);
1704 
1705   /* NOTE : This function should not be modified, when the callback is needed,
1706             the HAL_MMC_TxCpltCallback can be implemented in the user file
1707    */
1708 }
1709 
1710 /**
1711   * @brief Rx Transfer completed callbacks
1712   * @param hmmc: Pointer MMC handle
1713   * @retval None
1714   */
HAL_MMC_RxCpltCallback(MMC_HandleTypeDef * hmmc)1715 __weak void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef *hmmc)
1716 {
1717   /* Prevent unused argument(s) compilation warning */
1718   UNUSED(hmmc);
1719 
1720   /* NOTE : This function should not be modified, when the callback is needed,
1721             the HAL_MMC_RxCpltCallback can be implemented in the user file
1722    */
1723 }
1724 
1725 /**
1726   * @brief MMC error callbacks
1727   * @param hmmc: Pointer MMC handle
1728   * @retval None
1729   */
HAL_MMC_ErrorCallback(MMC_HandleTypeDef * hmmc)1730 __weak void HAL_MMC_ErrorCallback(MMC_HandleTypeDef *hmmc)
1731 {
1732   /* Prevent unused argument(s) compilation warning */
1733   UNUSED(hmmc);
1734 
1735   /* NOTE : This function should not be modified, when the callback is needed,
1736             the HAL_MMC_ErrorCallback can be implemented in the user file
1737    */
1738 }
1739 
1740 /**
1741   * @brief MMC Abort callbacks
1742   * @param hmmc: Pointer MMC handle
1743   * @retval None
1744   */
HAL_MMC_AbortCallback(MMC_HandleTypeDef * hmmc)1745 __weak void HAL_MMC_AbortCallback(MMC_HandleTypeDef *hmmc)
1746 {
1747   /* Prevent unused argument(s) compilation warning */
1748   UNUSED(hmmc);
1749 
1750   /* NOTE : This function should not be modified, when the callback is needed,
1751             the HAL_MMC_AbortCallback can be implemented in the user file
1752    */
1753 }
1754 
1755 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1756 /**
1757   * @brief  Register a User MMC Callback
1758   *         To be used instead of the weak (surcharged) predefined callback
1759   * @param hmmc : MMC handle
1760   * @param CallbackId : ID of the callback to be registered
1761   *        This parameter can be one of the following values:
1762   *          @arg @ref HAL_MMC_TX_CPLT_CB_ID    MMC Tx Complete Callback ID
1763   *          @arg @ref HAL_MMC_RX_CPLT_CB_ID    MMC Rx Complete Callback ID
1764   *          @arg @ref HAL_MMC_ERROR_CB_ID      MMC Error Callback ID
1765   *          @arg @ref HAL_MMC_ABORT_CB_ID      MMC Abort Callback ID
1766   *          @arg @ref HAL_MMC_MSP_INIT_CB_ID   MMC MspInit Callback ID
1767   *          @arg @ref HAL_MMC_MSP_DEINIT_CB_ID MMC MspDeInit Callback ID
1768   * @param pCallback : pointer to the Callback function
1769   * @retval status
1770   */
HAL_MMC_RegisterCallback(MMC_HandleTypeDef * hmmc,HAL_MMC_CallbackIDTypeDef CallbackId,pMMC_CallbackTypeDef pCallback)1771 HAL_StatusTypeDef HAL_MMC_RegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId, pMMC_CallbackTypeDef pCallback)
1772 {
1773   HAL_StatusTypeDef status = HAL_OK;
1774 
1775   if(pCallback == NULL)
1776   {
1777     /* Update the error code */
1778     hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1779     return HAL_ERROR;
1780   }
1781 
1782   /* Process locked */
1783   __HAL_LOCK(hmmc);
1784 
1785   if(hmmc->State == HAL_MMC_STATE_READY)
1786   {
1787     switch (CallbackId)
1788     {
1789     case HAL_MMC_TX_CPLT_CB_ID :
1790       hmmc->TxCpltCallback = pCallback;
1791       break;
1792     case HAL_MMC_RX_CPLT_CB_ID :
1793       hmmc->RxCpltCallback = pCallback;
1794       break;
1795     case HAL_MMC_ERROR_CB_ID :
1796       hmmc->ErrorCallback = pCallback;
1797       break;
1798     case HAL_MMC_ABORT_CB_ID :
1799       hmmc->AbortCpltCallback = pCallback;
1800       break;
1801     case HAL_MMC_MSP_INIT_CB_ID :
1802       hmmc->MspInitCallback = pCallback;
1803       break;
1804     case HAL_MMC_MSP_DEINIT_CB_ID :
1805       hmmc->MspDeInitCallback = pCallback;
1806       break;
1807     default :
1808       /* Update the error code */
1809       hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1810       /* update return status */
1811       status =  HAL_ERROR;
1812       break;
1813     }
1814   }
1815   else if (hmmc->State == HAL_MMC_STATE_RESET)
1816   {
1817     switch (CallbackId)
1818     {
1819     case HAL_MMC_MSP_INIT_CB_ID :
1820       hmmc->MspInitCallback = pCallback;
1821       break;
1822     case HAL_MMC_MSP_DEINIT_CB_ID :
1823       hmmc->MspDeInitCallback = pCallback;
1824       break;
1825     default :
1826       /* Update the error code */
1827       hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1828       /* update return status */
1829       status =  HAL_ERROR;
1830       break;
1831     }
1832   }
1833   else
1834   {
1835     /* Update the error code */
1836     hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1837     /* update return status */
1838     status =  HAL_ERROR;
1839   }
1840 
1841   /* Release Lock */
1842   __HAL_UNLOCK(hmmc);
1843   return status;
1844 }
1845 
1846 /**
1847   * @brief  Unregister a User MMC Callback
1848   *         MMC Callback is redirected to the weak (surcharged) predefined callback
1849   * @param hmmc : MMC handle
1850   * @param CallbackId : ID of the callback to be unregistered
1851   *        This parameter can be one of the following values:
1852   *          @arg @ref HAL_MMC_TX_CPLT_CB_ID    MMC Tx Complete Callback ID
1853   *          @arg @ref HAL_MMC_RX_CPLT_CB_ID    MMC Rx Complete Callback ID
1854   *          @arg @ref HAL_MMC_ERROR_CB_ID      MMC Error Callback ID
1855   *          @arg @ref HAL_MMC_ABORT_CB_ID      MMC Abort Callback ID
1856   *          @arg @ref HAL_MMC_MSP_INIT_CB_ID   MMC MspInit Callback ID
1857   *          @arg @ref HAL_MMC_MSP_DEINIT_CB_ID MMC MspDeInit Callback ID
1858   * @retval status
1859   */
HAL_MMC_UnRegisterCallback(MMC_HandleTypeDef * hmmc,HAL_MMC_CallbackIDTypeDef CallbackId)1860 HAL_StatusTypeDef HAL_MMC_UnRegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId)
1861 {
1862   HAL_StatusTypeDef status = HAL_OK;
1863 
1864   /* Process locked */
1865   __HAL_LOCK(hmmc);
1866 
1867   if(hmmc->State == HAL_MMC_STATE_READY)
1868   {
1869     switch (CallbackId)
1870     {
1871     case HAL_MMC_TX_CPLT_CB_ID :
1872       hmmc->TxCpltCallback = HAL_MMC_TxCpltCallback;
1873       break;
1874     case HAL_MMC_RX_CPLT_CB_ID :
1875       hmmc->RxCpltCallback = HAL_MMC_RxCpltCallback;
1876       break;
1877     case HAL_MMC_ERROR_CB_ID :
1878       hmmc->ErrorCallback = HAL_MMC_ErrorCallback;
1879       break;
1880     case HAL_MMC_ABORT_CB_ID :
1881       hmmc->AbortCpltCallback = HAL_MMC_AbortCallback;
1882       break;
1883     case HAL_MMC_MSP_INIT_CB_ID :
1884       hmmc->MspInitCallback = HAL_MMC_MspInit;
1885       break;
1886     case HAL_MMC_MSP_DEINIT_CB_ID :
1887       hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
1888       break;
1889     default :
1890       /* Update the error code */
1891       hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1892       /* update return status */
1893       status =  HAL_ERROR;
1894       break;
1895     }
1896   }
1897   else if (hmmc->State == HAL_MMC_STATE_RESET)
1898   {
1899     switch (CallbackId)
1900     {
1901     case HAL_MMC_MSP_INIT_CB_ID :
1902       hmmc->MspInitCallback = HAL_MMC_MspInit;
1903       break;
1904     case HAL_MMC_MSP_DEINIT_CB_ID :
1905       hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
1906       break;
1907     default :
1908       /* Update the error code */
1909       hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1910       /* update return status */
1911       status =  HAL_ERROR;
1912       break;
1913     }
1914   }
1915   else
1916   {
1917     /* Update the error code */
1918     hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1919     /* update return status */
1920     status =  HAL_ERROR;
1921   }
1922 
1923   /* Release Lock */
1924   __HAL_UNLOCK(hmmc);
1925   return status;
1926 }
1927 #endif
1928 
1929 /**
1930   * @}
1931   */
1932 
1933 /** @addtogroup MMC_Exported_Functions_Group3
1934  *  @brief   management functions
1935  *
1936 @verbatim
1937   ==============================================================================
1938                       ##### Peripheral Control functions #####
1939   ==============================================================================
1940   [..]
1941     This subsection provides a set of functions allowing to control the MMC card
1942     operations and get the related information
1943 
1944 @endverbatim
1945   * @{
1946   */
1947 
1948 /**
1949   * @brief  Returns information the information of the card which are stored on
1950   *         the CID register.
1951   * @param  hmmc: Pointer to MMC handle
1952   * @param  pCID: Pointer to a HAL_MMC_CIDTypedef structure that
1953   *         contains all CID register parameters
1954   * @retval HAL status
1955   */
HAL_MMC_GetCardCID(MMC_HandleTypeDef * hmmc,HAL_MMC_CardCIDTypeDef * pCID)1956 HAL_StatusTypeDef HAL_MMC_GetCardCID(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCIDTypeDef *pCID)
1957 {
1958   pCID->ManufacturerID = (uint8_t)((hmmc->CID[0] & 0xFF000000U) >> 24U);
1959 
1960   pCID->OEM_AppliID = (uint16_t)((hmmc->CID[0] & 0x00FFFF00U) >> 8U);
1961 
1962   pCID->ProdName1 = (((hmmc->CID[0] & 0x000000FFU) << 24U) | ((hmmc->CID[1] & 0xFFFFFF00U) >> 8U));
1963 
1964   pCID->ProdName2 = (uint8_t)(hmmc->CID[1] & 0x000000FFU);
1965 
1966   pCID->ProdRev = (uint8_t)((hmmc->CID[2] & 0xFF000000U) >> 24U);
1967 
1968   pCID->ProdSN = (((hmmc->CID[2] & 0x00FFFFFFU) << 8U) | ((hmmc->CID[3] & 0xFF000000U) >> 24U));
1969 
1970   pCID->Reserved1 = (uint8_t)((hmmc->CID[3] & 0x00F00000U) >> 20U);
1971 
1972   pCID->ManufactDate = (uint16_t)((hmmc->CID[3] & 0x000FFF00U) >> 8U);
1973 
1974   pCID->CID_CRC = (uint8_t)((hmmc->CID[3] & 0x000000FEU) >> 1U);
1975 
1976   pCID->Reserved2 = 1U;
1977 
1978   return HAL_OK;
1979 }
1980 
1981 /**
1982   * @brief  Returns information the information of the card which are stored on
1983   *         the CSD register.
1984   * @param  hmmc: Pointer to MMC handle
1985   * @param  pCSD: Pointer to a HAL_MMC_CardCSDTypeDef structure that
1986   *         contains all CSD register parameters
1987   * @retval HAL status
1988   */
HAL_MMC_GetCardCSD(MMC_HandleTypeDef * hmmc,HAL_MMC_CardCSDTypeDef * pCSD)1989 HAL_StatusTypeDef HAL_MMC_GetCardCSD(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCSDTypeDef *pCSD)
1990 {
1991   uint32_t block_nbr = 0;
1992 
1993   pCSD->CSDStruct = (uint8_t)((hmmc->CSD[0] & 0xC0000000U) >> 30U);
1994 
1995   pCSD->SysSpecVersion = (uint8_t)((hmmc->CSD[0] & 0x3C000000U) >> 26U);
1996 
1997   pCSD->Reserved1 = (uint8_t)((hmmc->CSD[0] & 0x03000000U) >> 24U);
1998 
1999   pCSD->TAAC = (uint8_t)((hmmc->CSD[0] & 0x00FF0000U) >> 16U);
2000 
2001   pCSD->NSAC = (uint8_t)((hmmc->CSD[0] & 0x0000FF00U) >> 8U);
2002 
2003   pCSD->MaxBusClkFrec = (uint8_t)(hmmc->CSD[0] & 0x000000FFU);
2004 
2005   pCSD->CardComdClasses = (uint16_t)((hmmc->CSD[1] & 0xFFF00000U) >> 20U);
2006 
2007   pCSD->RdBlockLen = (uint8_t)((hmmc->CSD[1] & 0x000F0000U) >> 16U);
2008 
2009   pCSD->PartBlockRead   = (uint8_t)((hmmc->CSD[1] & 0x00008000U) >> 15U);
2010 
2011   pCSD->WrBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00004000U) >> 14U);
2012 
2013   pCSD->RdBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00002000U) >> 13U);
2014 
2015   pCSD->DSRImpl = (uint8_t)((hmmc->CSD[1] & 0x00001000U) >> 12U);
2016 
2017   pCSD->Reserved2 = 0U; /*!< Reserved */
2018 
2019   pCSD->DeviceSize = (((hmmc->CSD[1] & 0x000003FFU) << 2U) | ((hmmc->CSD[2] & 0xC0000000U) >> 30U));
2020 
2021   pCSD->MaxRdCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x38000000U) >> 27U);
2022 
2023   pCSD->MaxRdCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x07000000U) >> 24U);
2024 
2025   pCSD->MaxWrCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x00E00000U) >> 21U);
2026 
2027   pCSD->MaxWrCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x001C0000U) >> 18U);
2028 
2029   pCSD->DeviceSizeMul = (uint8_t)((hmmc->CSD[2] & 0x00038000U) >> 15U);
2030 
2031   if(MMC_ReadExtCSD(hmmc, &block_nbr, 212, 0x0FFFFFFFU) != HAL_OK) /* Field SEC_COUNT [215:212] */
2032   {
2033     return HAL_ERROR;
2034   }
2035 
2036   if(hmmc->MmcCard.CardType == MMC_LOW_CAPACITY_CARD)
2037   {
2038     hmmc->MmcCard.BlockNbr  = (pCSD->DeviceSize + 1U) ;
2039     hmmc->MmcCard.BlockNbr *= (1UL << ((pCSD->DeviceSizeMul & 0x07U) + 2U));
2040     hmmc->MmcCard.BlockSize = (1UL << (pCSD->RdBlockLen & 0x0FU));
2041     hmmc->MmcCard.LogBlockNbr =  (hmmc->MmcCard.BlockNbr) * ((hmmc->MmcCard.BlockSize) / 512U);
2042     hmmc->MmcCard.LogBlockSize = 512U;
2043   }
2044   else if(hmmc->MmcCard.CardType == MMC_HIGH_CAPACITY_CARD)
2045   {
2046     hmmc->MmcCard.BlockNbr = block_nbr;
2047     hmmc->MmcCard.LogBlockNbr = hmmc->MmcCard.BlockNbr;
2048     hmmc->MmcCard.BlockSize = 512U;
2049     hmmc->MmcCard.LogBlockSize = hmmc->MmcCard.BlockSize;
2050   }
2051   else
2052   {
2053     /* Clear all the static flags */
2054     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2055     hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2056     hmmc->State = HAL_MMC_STATE_READY;
2057     return HAL_ERROR;
2058   }
2059 
2060   pCSD->EraseGrSize = (uint8_t)((hmmc->CSD[2] & 0x00004000U) >> 14U);
2061 
2062   pCSD->EraseGrMul = (uint8_t)((hmmc->CSD[2] & 0x00003F80U) >> 7U);
2063 
2064   pCSD->WrProtectGrSize = (uint8_t)(hmmc->CSD[2] & 0x0000007FU);
2065 
2066   pCSD->WrProtectGrEnable = (uint8_t)((hmmc->CSD[3] & 0x80000000U) >> 31U);
2067 
2068   pCSD->ManDeflECC = (uint8_t)((hmmc->CSD[3] & 0x60000000U) >> 29U);
2069 
2070   pCSD->WrSpeedFact = (uint8_t)((hmmc->CSD[3] & 0x1C000000U) >> 26U);
2071 
2072   pCSD->MaxWrBlockLen= (uint8_t)((hmmc->CSD[3] & 0x03C00000U) >> 22U);
2073 
2074   pCSD->WriteBlockPaPartial = (uint8_t)((hmmc->CSD[3] & 0x00200000U) >> 21U);
2075 
2076   pCSD->Reserved3 = 0;
2077 
2078   pCSD->ContentProtectAppli = (uint8_t)((hmmc->CSD[3] & 0x00010000U) >> 16U);
2079 
2080   pCSD->FileFormatGroup = (uint8_t)((hmmc->CSD[3] & 0x00008000U) >> 15U);
2081 
2082   pCSD->CopyFlag = (uint8_t)((hmmc->CSD[3] & 0x00004000U) >> 14U);
2083 
2084   pCSD->PermWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00002000U) >> 13U);
2085 
2086   pCSD->TempWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00001000U) >> 12U);
2087 
2088   pCSD->FileFormat = (uint8_t)((hmmc->CSD[3] & 0x00000C00U) >> 10U);
2089 
2090   pCSD->ECC= (uint8_t)((hmmc->CSD[3] & 0x00000300U) >> 8U);
2091 
2092   pCSD->CSD_CRC = (uint8_t)((hmmc->CSD[3] & 0x000000FEU) >> 1U);
2093 
2094   pCSD->Reserved4 = 1;
2095 
2096   return HAL_OK;
2097 }
2098 
2099 /**
2100   * @brief  Gets the MMC card info.
2101   * @param  hmmc: Pointer to MMC handle
2102   * @param  pCardInfo: Pointer to the HAL_MMC_CardInfoTypeDef structure that
2103   *         will contain the MMC card status information
2104   * @retval HAL status
2105   */
HAL_MMC_GetCardInfo(MMC_HandleTypeDef * hmmc,HAL_MMC_CardInfoTypeDef * pCardInfo)2106 HAL_StatusTypeDef HAL_MMC_GetCardInfo(MMC_HandleTypeDef *hmmc, HAL_MMC_CardInfoTypeDef *pCardInfo)
2107 {
2108   pCardInfo->CardType     = (uint32_t)(hmmc->MmcCard.CardType);
2109   pCardInfo->Class        = (uint32_t)(hmmc->MmcCard.Class);
2110   pCardInfo->RelCardAdd   = (uint32_t)(hmmc->MmcCard.RelCardAdd);
2111   pCardInfo->BlockNbr     = (uint32_t)(hmmc->MmcCard.BlockNbr);
2112   pCardInfo->BlockSize    = (uint32_t)(hmmc->MmcCard.BlockSize);
2113   pCardInfo->LogBlockNbr  = (uint32_t)(hmmc->MmcCard.LogBlockNbr);
2114   pCardInfo->LogBlockSize = (uint32_t)(hmmc->MmcCard.LogBlockSize);
2115 
2116   return HAL_OK;
2117 }
2118 
2119 /**
2120   * @brief  Returns information the information of the card which are stored on
2121   *         the Extended CSD register.
2122   * @param  hmmc Pointer to MMC handle
2123   * @param  pExtCSD Pointer to a memory area (512 bytes) that contains all
2124   *         Extended CSD register parameters
2125   * @param  Timeout Specify timeout value
2126   * @retval HAL status
2127   */
HAL_MMC_GetCardExtCSD(MMC_HandleTypeDef * hmmc,uint32_t * pExtCSD,uint32_t Timeout)2128 HAL_StatusTypeDef HAL_MMC_GetCardExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pExtCSD, uint32_t Timeout)
2129 {
2130   SDMMC_DataInitTypeDef config;
2131   uint32_t errorstate;
2132   uint32_t tickstart = HAL_GetTick();
2133   uint32_t count;
2134   uint32_t *tmp_buf;
2135 
2136   if(NULL == pExtCSD)
2137   {
2138     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
2139     return HAL_ERROR;
2140   }
2141 
2142   if(hmmc->State == HAL_MMC_STATE_READY)
2143   {
2144     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
2145 
2146     hmmc->State = HAL_MMC_STATE_BUSY;
2147 
2148     /* Initialize data control register */
2149     hmmc->Instance->DCTRL = 0;
2150 
2151     /* Initiaize the destination pointer */
2152     tmp_buf = pExtCSD;
2153 
2154     /* Configure the MMC DPSM (Data Path State Machine) */
2155     config.DataTimeOut   = SDMMC_DATATIMEOUT;
2156     config.DataLength    = 512;
2157     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
2158     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
2159     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
2160     config.DPSM          = SDMMC_DPSM_ENABLE;
2161     (void)SDMMC_ConfigData(hmmc->Instance, &config);
2162 
2163     /* Send ExtCSD Read command to Card */
2164     errorstate = SDMMC_CmdSendEXTCSD(hmmc->Instance, 0);
2165     if(errorstate != HAL_MMC_ERROR_NONE)
2166     {
2167       /* Clear all the static flags */
2168       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2169       hmmc->ErrorCode |= errorstate;
2170       hmmc->State = HAL_MMC_STATE_READY;
2171       return HAL_ERROR;
2172     }
2173 
2174     /* Poll on SDMMC flags */
2175     while(!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
2176     {
2177       if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF))
2178       {
2179         /* Read data from SDMMC Rx FIFO */
2180         for(count = 0U; count < 8U; count++)
2181         {
2182           *tmp_buf = SDMMC_ReadFIFO(hmmc->Instance);
2183           tmp_buf++;
2184         }
2185       }
2186 
2187       if(((HAL_GetTick()-tickstart) >=  Timeout) || (Timeout == 0U))
2188       {
2189         /* Clear all the static flags */
2190         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2191         hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
2192         hmmc->State= HAL_MMC_STATE_READY;
2193         return HAL_TIMEOUT;
2194       }
2195     }
2196 
2197     /* Get error state */
2198     if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
2199     {
2200       /* Clear all the static flags */
2201       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2202       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
2203       hmmc->State = HAL_MMC_STATE_READY;
2204       return HAL_ERROR;
2205     }
2206     else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
2207     {
2208       /* Clear all the static flags */
2209       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2210       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
2211       hmmc->State = HAL_MMC_STATE_READY;
2212       return HAL_ERROR;
2213     }
2214     else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR))
2215     {
2216       /* Clear all the static flags */
2217       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2218       hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
2219       hmmc->State = HAL_MMC_STATE_READY;
2220       return HAL_ERROR;
2221     }
2222     else
2223     {
2224       /* Nothing to do */
2225     }
2226 
2227     /* Clear all the static flags */
2228     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2229     hmmc->State = HAL_MMC_STATE_READY;
2230   }
2231 
2232   return HAL_OK;
2233 }
2234 
2235 /**
2236   * @brief  Enables wide bus operation for the requested card if supported by
2237   *         card.
2238   * @param  hmmc: Pointer to MMC handle
2239   * @param  WideMode: Specifies the MMC card wide bus mode
2240   *          This parameter can be one of the following values:
2241   *            @arg SDMMC_BUS_WIDE_8B: 8-bit data transfer
2242   *            @arg SDMMC_BUS_WIDE_4B: 4-bit data transfer
2243   *            @arg SDMMC_BUS_WIDE_1B: 1-bit data transfer
2244   * @retval HAL status
2245   */
HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef * hmmc,uint32_t WideMode)2246 HAL_StatusTypeDef HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef *hmmc, uint32_t WideMode)
2247 {
2248   uint32_t count;
2249   SDMMC_InitTypeDef Init;
2250   uint32_t errorstate;
2251   uint32_t response = 0U;
2252 
2253   /* Check the parameters */
2254   assert_param(IS_SDMMC_BUS_WIDE(WideMode));
2255 
2256   /* Change State */
2257   hmmc->State = HAL_MMC_STATE_BUSY;
2258 
2259   errorstate = MMC_PwrClassUpdate(hmmc, WideMode);
2260 
2261   if(errorstate == HAL_MMC_ERROR_NONE)
2262   {
2263     if(WideMode == SDMMC_BUS_WIDE_8B)
2264     {
2265       errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U);
2266     }
2267     else if(WideMode == SDMMC_BUS_WIDE_4B)
2268     {
2269       errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U);
2270     }
2271     else if(WideMode == SDMMC_BUS_WIDE_1B)
2272     {
2273       errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70000U);
2274     }
2275     else
2276     {
2277       /* WideMode is not a valid argument*/
2278       errorstate = HAL_MMC_ERROR_PARAM;
2279     }
2280 
2281     /* Check for switch error and violation of the trial number of sending CMD 13 */
2282     if(errorstate == HAL_MMC_ERROR_NONE)
2283     {
2284       /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2285       count = SDMMC_MAX_TRIAL;
2286       do
2287       {
2288         errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2289         if(errorstate != HAL_MMC_ERROR_NONE)
2290         {
2291           break;
2292         }
2293 
2294         /* Get command response */
2295         response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
2296         count--;
2297       }while(((response & 0x100U) == 0U) && (count != 0U));
2298 
2299       /* Check the status after the switch command execution */
2300       if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
2301       {
2302         /* Check the bit SWITCH_ERROR of the device status */
2303         if ((response & 0x80U) != 0U)
2304         {
2305           errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
2306         }
2307         else
2308         {
2309           /* Configure the SDMMC peripheral */
2310           Init = hmmc->Init;
2311           Init.BusWide = WideMode;
2312           (void)SDMMC_Init(hmmc->Instance, Init);
2313         }
2314       }
2315       else if (count == 0U)
2316       {
2317         errorstate = SDMMC_ERROR_TIMEOUT;
2318       }
2319       else
2320       {
2321         /* Nothing to do */
2322       }
2323     }
2324   }
2325 
2326   /* Change State */
2327   hmmc->State = HAL_MMC_STATE_READY;
2328 
2329   if(errorstate != HAL_MMC_ERROR_NONE)
2330   {
2331     /* Clear all the static flags */
2332     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2333     hmmc->ErrorCode |= errorstate;
2334     return HAL_ERROR;
2335   }
2336 
2337   return HAL_OK;
2338 }
2339 
2340 /**
2341   * @brief  Gets the current mmc card data state.
2342   * @param  hmmc: pointer to MMC handle
2343   * @retval Card state
2344   */
HAL_MMC_GetCardState(MMC_HandleTypeDef * hmmc)2345 HAL_MMC_CardStateTypeDef HAL_MMC_GetCardState(MMC_HandleTypeDef *hmmc)
2346 {
2347   uint32_t cardstate;
2348   uint32_t errorstate;
2349   uint32_t resp1 = 0U;
2350 
2351   errorstate = MMC_SendStatus(hmmc, &resp1);
2352   if(errorstate != HAL_MMC_ERROR_NONE)
2353   {
2354     hmmc->ErrorCode |= errorstate;
2355   }
2356 
2357   cardstate = ((resp1 >> 9U) & 0x0FU);
2358 
2359   return (HAL_MMC_CardStateTypeDef)cardstate;
2360 }
2361 
2362 /**
2363   * @brief  Abort the current transfer and disable the MMC.
2364   * @param  hmmc: pointer to a MMC_HandleTypeDef structure that contains
2365   *                the configuration information for MMC module.
2366   * @retval HAL status
2367   */
HAL_MMC_Abort(MMC_HandleTypeDef * hmmc)2368 HAL_StatusTypeDef HAL_MMC_Abort(MMC_HandleTypeDef *hmmc)
2369 {
2370   HAL_MMC_CardStateTypeDef CardState;
2371 
2372   /* DIsable All interrupts */
2373   __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\
2374                              SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR);
2375 
2376   /* Clear All flags */
2377   __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2378 
2379   if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL))
2380   {
2381     /* Disable the MMC DMA request */
2382     hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN);
2383 
2384     /* Abort the MMC DMA Tx Stream */
2385     if(hmmc->hdmatx != NULL)
2386     {
2387       if(HAL_DMA_Abort(hmmc->hdmatx) != HAL_OK)
2388       {
2389         hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
2390       }
2391     }
2392     /* Abort the MMC DMA Rx Stream */
2393     if(hmmc->hdmarx != NULL)
2394     {
2395       if(HAL_DMA_Abort(hmmc->hdmarx) != HAL_OK)
2396       {
2397         hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
2398       }
2399     }
2400   }
2401 
2402   hmmc->State = HAL_MMC_STATE_READY;
2403 
2404   /* Initialize the MMC operation */
2405   hmmc->Context = MMC_CONTEXT_NONE;
2406 
2407   CardState = HAL_MMC_GetCardState(hmmc);
2408   if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2409   {
2410     hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
2411   }
2412   if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2413   {
2414     return HAL_ERROR;
2415   }
2416   return HAL_OK;
2417 }
2418 
2419 /**
2420   * @brief  Abort the current transfer and disable the MMC (IT mode).
2421   * @param  hmmc: pointer to a MMC_HandleTypeDef structure that contains
2422   *                the configuration information for MMC module.
2423   * @retval HAL status
2424   */
HAL_MMC_Abort_IT(MMC_HandleTypeDef * hmmc)2425 HAL_StatusTypeDef HAL_MMC_Abort_IT(MMC_HandleTypeDef *hmmc)
2426 {
2427   HAL_MMC_CardStateTypeDef CardState;
2428 
2429   /* DIsable All interrupts */
2430   __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\
2431                            SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR);
2432 
2433   /* Clear All flags */
2434   __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2435 
2436   if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL))
2437   {
2438     /* Disable the MMC DMA request */
2439     hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN);
2440 
2441     /* Abort the MMC DMA Tx Stream */
2442     if(hmmc->hdmatx != NULL)
2443     {
2444       hmmc->hdmatx->XferAbortCallback =  MMC_DMATxAbort;
2445       if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
2446       {
2447         hmmc->hdmatx = NULL;
2448       }
2449     }
2450     /* Abort the MMC DMA Rx Stream */
2451     if(hmmc->hdmarx != NULL)
2452     {
2453       hmmc->hdmarx->XferAbortCallback =  MMC_DMARxAbort;
2454       if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
2455       {
2456         hmmc->hdmarx = NULL;
2457       }
2458     }
2459   }
2460 
2461   /* No transfer ongoing on both DMA channels*/
2462   if((hmmc->hdmatx == NULL) && (hmmc->hdmarx == NULL))
2463   {
2464     CardState = HAL_MMC_GetCardState(hmmc);
2465     hmmc->State = HAL_MMC_STATE_READY;
2466 
2467     if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2468     {
2469       hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
2470     }
2471     if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2472     {
2473       return HAL_ERROR;
2474     }
2475     else
2476     {
2477 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2478       hmmc->AbortCpltCallback(hmmc);
2479 #else
2480       HAL_MMC_AbortCallback(hmmc);
2481 #endif
2482     }
2483   }
2484 
2485   return HAL_OK;
2486 }
2487 
2488 /**
2489   * @}
2490   */
2491 
2492 /**
2493   * @}
2494   */
2495 
2496 /* Private function ----------------------------------------------------------*/
2497 /** @addtogroup MMC_Private_Functions
2498   * @{
2499   */
2500 
2501 /**
2502   * @brief  DMA MMC transmit process complete callback
2503   * @param  hdma: DMA handle
2504   * @retval None
2505   */
MMC_DMATransmitCplt(DMA_HandleTypeDef * hdma)2506 static void MMC_DMATransmitCplt(DMA_HandleTypeDef *hdma)
2507 {
2508   MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2509 
2510   /* Enable DATAEND Interrupt */
2511   __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DATAEND));
2512 }
2513 
2514 /**
2515   * @brief  DMA MMC receive process complete callback
2516   * @param  hdma: DMA handle
2517   * @retval None
2518   */
MMC_DMAReceiveCplt(DMA_HandleTypeDef * hdma)2519 static void MMC_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
2520 {
2521   MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2522   uint32_t errorstate;
2523 
2524   /* Send stop command in multiblock write */
2525   if(hmmc->Context == (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA))
2526   {
2527     errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
2528     if(errorstate != HAL_MMC_ERROR_NONE)
2529     {
2530       hmmc->ErrorCode |= errorstate;
2531 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2532       hmmc->ErrorCallback(hmmc);
2533 #else
2534       HAL_MMC_ErrorCallback(hmmc);
2535 #endif
2536     }
2537   }
2538 
2539   /* Disable the DMA transfer for transmit request by setting the DMAEN bit
2540   in the MMC DCTRL register */
2541   hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN);
2542 
2543   /* Clear all the static flags */
2544   __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2545 
2546   hmmc->State = HAL_MMC_STATE_READY;
2547 
2548 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2549   hmmc->RxCpltCallback(hmmc);
2550 #else
2551   HAL_MMC_RxCpltCallback(hmmc);
2552 #endif
2553 }
2554 
2555 /**
2556   * @brief  DMA MMC communication error callback
2557   * @param  hdma: DMA handle
2558   * @retval None
2559   */
MMC_DMAError(DMA_HandleTypeDef * hdma)2560 static void MMC_DMAError(DMA_HandleTypeDef *hdma)
2561 {
2562   MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2563   HAL_MMC_CardStateTypeDef CardState;
2564   uint32_t RxErrorCode, TxErrorCode;
2565 
2566   /* if DMA error is FIFO error ignore it */
2567   if(HAL_DMA_GetError(hdma) != HAL_DMA_ERROR_FE)
2568   {
2569     RxErrorCode = hmmc->hdmarx->ErrorCode;
2570     TxErrorCode = hmmc->hdmatx->ErrorCode;
2571     if((RxErrorCode == HAL_DMA_ERROR_TE) || (TxErrorCode == HAL_DMA_ERROR_TE))
2572     {
2573       /* Clear All flags */
2574       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2575 
2576       /* Disable All interrupts */
2577       __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\
2578         SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR);
2579 
2580       hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
2581       CardState = HAL_MMC_GetCardState(hmmc);
2582       if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2583       {
2584         hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
2585       }
2586 
2587       hmmc->State= HAL_MMC_STATE_READY;
2588     }
2589 
2590 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2591     hmmc->ErrorCallback(hmmc);
2592 #else
2593     HAL_MMC_ErrorCallback(hmmc);
2594 #endif
2595   }
2596 }
2597 
2598 /**
2599   * @brief  DMA MMC Tx Abort callback
2600   * @param  hdma: DMA handle
2601   * @retval None
2602   */
MMC_DMATxAbort(DMA_HandleTypeDef * hdma)2603 static void MMC_DMATxAbort(DMA_HandleTypeDef *hdma)
2604 {
2605   MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2606   HAL_MMC_CardStateTypeDef CardState;
2607 
2608   if(hmmc->hdmatx != NULL)
2609   {
2610     hmmc->hdmatx = NULL;
2611   }
2612 
2613   /* All DMA channels are aborted */
2614   if(hmmc->hdmarx == NULL)
2615   {
2616     CardState = HAL_MMC_GetCardState(hmmc);
2617     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
2618     hmmc->State = HAL_MMC_STATE_READY;
2619     if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2620     {
2621       hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
2622 
2623       if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2624       {
2625 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2626         hmmc->AbortCpltCallback(hmmc);
2627 #else
2628         HAL_MMC_AbortCallback(hmmc);
2629 #endif
2630       }
2631       else
2632       {
2633 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2634         hmmc->ErrorCallback(hmmc);
2635 #else
2636         HAL_MMC_ErrorCallback(hmmc);
2637 #endif
2638       }
2639     }
2640   }
2641 }
2642 
2643 /**
2644   * @brief  DMA MMC Rx Abort callback
2645   * @param  hdma: DMA handle
2646   * @retval None
2647   */
MMC_DMARxAbort(DMA_HandleTypeDef * hdma)2648 static void MMC_DMARxAbort(DMA_HandleTypeDef *hdma)
2649 {
2650   MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2651   HAL_MMC_CardStateTypeDef CardState;
2652 
2653   if(hmmc->hdmarx != NULL)
2654   {
2655     hmmc->hdmarx = NULL;
2656   }
2657 
2658   /* All DMA channels are aborted */
2659   if(hmmc->hdmatx == NULL)
2660   {
2661     CardState = HAL_MMC_GetCardState(hmmc);
2662     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
2663     hmmc->State = HAL_MMC_STATE_READY;
2664     if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2665     {
2666       hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
2667 
2668       if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2669       {
2670 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2671         hmmc->AbortCpltCallback(hmmc);
2672 #else
2673         HAL_MMC_AbortCallback(hmmc);
2674 #endif
2675       }
2676       else
2677       {
2678 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2679         hmmc->ErrorCallback(hmmc);
2680 #else
2681         HAL_MMC_ErrorCallback(hmmc);
2682 #endif
2683       }
2684     }
2685   }
2686 }
2687 
2688 /**
2689   * @brief  Initializes the mmc card.
2690   * @param  hmmc: Pointer to MMC handle
2691   * @retval MMC Card error state
2692   */
MMC_InitCard(MMC_HandleTypeDef * hmmc)2693 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc)
2694 {
2695   HAL_MMC_CardCSDTypeDef CSD;
2696   uint32_t errorstate;
2697   uint16_t mmc_rca = 2U;
2698   MMC_InitTypeDef Init;
2699 
2700   /* Check the power State */
2701   if(SDMMC_GetPowerState(hmmc->Instance) == 0U)
2702   {
2703     /* Power off */
2704     return HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
2705   }
2706 
2707   /* Send CMD2 ALL_SEND_CID */
2708   errorstate = SDMMC_CmdSendCID(hmmc->Instance);
2709   if(errorstate != HAL_MMC_ERROR_NONE)
2710   {
2711     return errorstate;
2712   }
2713   else
2714   {
2715     /* Get Card identification number data */
2716     hmmc->CID[0U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
2717     hmmc->CID[1U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2);
2718     hmmc->CID[2U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP3);
2719     hmmc->CID[3U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP4);
2720   }
2721 
2722   /* Send CMD3 SET_REL_ADDR with RCA = 2 (should be greater than 1) */
2723   /* MMC Card publishes its RCA. */
2724   errorstate = SDMMC_CmdSetRelAddMmc(hmmc->Instance, mmc_rca);
2725   if(errorstate != HAL_MMC_ERROR_NONE)
2726   {
2727     return errorstate;
2728   }
2729 
2730   /* Get the MMC card RCA */
2731   hmmc->MmcCard.RelCardAdd = mmc_rca;
2732 
2733   /* Send CMD9 SEND_CSD with argument as card's RCA */
2734   errorstate = SDMMC_CmdSendCSD(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
2735   if(errorstate != HAL_MMC_ERROR_NONE)
2736   {
2737     return errorstate;
2738   }
2739   else
2740   {
2741     /* Get Card Specific Data */
2742     hmmc->CSD[0U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
2743     hmmc->CSD[1U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2);
2744     hmmc->CSD[2U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP3);
2745     hmmc->CSD[3U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP4);
2746   }
2747 
2748   /* Get the Card Class */
2749   hmmc->MmcCard.Class = (SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2) >> 20U);
2750 
2751   /* Select the Card */
2752   errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2753   if(errorstate != HAL_MMC_ERROR_NONE)
2754   {
2755     return errorstate;
2756   }
2757 
2758   /* Get CSD parameters */
2759   if (HAL_MMC_GetCardCSD(hmmc, &CSD) != HAL_OK)
2760   {
2761     return hmmc->ErrorCode;
2762   }
2763 
2764   /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2765   errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2766   if(errorstate != HAL_MMC_ERROR_NONE)
2767   {
2768     hmmc->ErrorCode |= errorstate;
2769   }
2770 
2771   /* Get Extended CSD parameters */
2772   if (HAL_MMC_GetCardExtCSD(hmmc, hmmc->Ext_CSD, SDMMC_DATATIMEOUT) != HAL_OK)
2773   {
2774     return hmmc->ErrorCode;
2775   }
2776 
2777   /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2778   errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2779   if(errorstate != HAL_MMC_ERROR_NONE)
2780   {
2781     hmmc->ErrorCode |= errorstate;
2782   }
2783 
2784   /* Configure the SDMMC peripheral */
2785   Init = hmmc->Init;
2786   Init.BusWide = SDMMC_BUS_WIDE_1B;
2787   (void)SDMMC_Init(hmmc->Instance, Init);
2788 
2789   /* All cards are initialized */
2790   return HAL_MMC_ERROR_NONE;
2791 }
2792 
2793 /**
2794   * @brief  Enquires cards about their operating voltage and configures clock
2795   *         controls and stores MMC information that will be needed in future
2796   *         in the MMC handle.
2797   * @param  hmmc: Pointer to MMC handle
2798   * @retval error state
2799   */
MMC_PowerON(MMC_HandleTypeDef * hmmc)2800 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc)
2801 {
2802   __IO uint32_t count = 0U;
2803   uint32_t response = 0U, validvoltage = 0U;
2804   uint32_t errorstate;
2805 
2806   /* CMD0: GO_IDLE_STATE */
2807   errorstate = SDMMC_CmdGoIdleState(hmmc->Instance);
2808   if(errorstate != HAL_MMC_ERROR_NONE)
2809   {
2810     return errorstate;
2811   }
2812 
2813   while(validvoltage == 0U)
2814   {
2815     if(count++ == SDMMC_MAX_VOLT_TRIAL)
2816     {
2817       return HAL_MMC_ERROR_INVALID_VOLTRANGE;
2818     }
2819 
2820     /* SEND CMD1 APP_CMD with voltage range as argument */
2821     errorstate = SDMMC_CmdOpCondition(hmmc->Instance, MMC_VOLTAGE_RANGE);
2822     if(errorstate != HAL_MMC_ERROR_NONE)
2823     {
2824       return HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2825     }
2826 
2827     /* Get command response */
2828     response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
2829 
2830     /* Get operating voltage*/
2831     validvoltage = (((response >> 31U) == 1U) ? 1U : 0U);
2832   }
2833 
2834   /* When power routine is finished and command returns valid voltage */
2835   if (((response & (0xFF000000U)) >> 24U) == 0xC0U)
2836   {
2837     hmmc->MmcCard.CardType = MMC_HIGH_CAPACITY_CARD;
2838   }
2839   else
2840   {
2841     hmmc->MmcCard.CardType = MMC_LOW_CAPACITY_CARD;
2842   }
2843 
2844   return HAL_MMC_ERROR_NONE;
2845 }
2846 
2847 /**
2848   * @brief  Turns the SDMMC output signals off.
2849   * @param  hmmc: Pointer to MMC handle
2850   * @retval None
2851   */
MMC_PowerOFF(MMC_HandleTypeDef * hmmc)2852 static void MMC_PowerOFF(MMC_HandleTypeDef *hmmc)
2853 {
2854   /* Set Power State to OFF */
2855   (void)SDMMC_PowerState_OFF(hmmc->Instance);
2856 }
2857 
2858 /**
2859   * @brief  Returns the current card's status.
2860   * @param  hmmc: Pointer to MMC handle
2861   * @param  pCardStatus: pointer to the buffer that will contain the MMC card
2862   *         status (Card Status register)
2863   * @retval error state
2864   */
MMC_SendStatus(MMC_HandleTypeDef * hmmc,uint32_t * pCardStatus)2865 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus)
2866 {
2867   uint32_t errorstate;
2868 
2869   if(pCardStatus == NULL)
2870   {
2871     return HAL_MMC_ERROR_PARAM;
2872   }
2873 
2874   /* Send Status command */
2875   errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
2876   if(errorstate != HAL_MMC_ERROR_NONE)
2877   {
2878     return errorstate;
2879   }
2880 
2881   /* Get MMC card status */
2882   *pCardStatus = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
2883 
2884   return HAL_MMC_ERROR_NONE;
2885 }
2886 
2887 /**
2888   * @brief  Reads extended CSD register to get the sectors number of the device
2889   * @param  hmmc: Pointer to MMC handle
2890   * @param  pFieldData: Pointer to the read buffer
2891   * @param  FieldIndex: Index of the field to be read
2892   * @param  Timeout: Specify timeout value
2893   * @retval HAL status
2894   */
MMC_ReadExtCSD(MMC_HandleTypeDef * hmmc,uint32_t * pFieldData,uint16_t FieldIndex,uint32_t Timeout)2895 static uint32_t MMC_ReadExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pFieldData, uint16_t FieldIndex, uint32_t Timeout)
2896 {
2897   SDMMC_DataInitTypeDef config;
2898   uint32_t errorstate;
2899   uint32_t tickstart = HAL_GetTick();
2900   uint32_t count;
2901   uint32_t i = 0;
2902   uint32_t tmp_data;
2903 
2904   hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
2905 
2906   /* Initialize data control register */
2907   hmmc->Instance->DCTRL = 0;
2908 
2909   /* Configure the MMC DPSM (Data Path State Machine) */
2910   config.DataTimeOut   = SDMMC_DATATIMEOUT;
2911   config.DataLength    = 512;
2912   config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
2913   config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
2914   config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
2915   config.DPSM          = SDMMC_DPSM_ENABLE;
2916   (void)SDMMC_ConfigData(hmmc->Instance, &config);
2917 
2918   /* Set Block Size for Card */
2919   errorstate = SDMMC_CmdSendEXTCSD(hmmc->Instance, 0);
2920   if(errorstate != HAL_MMC_ERROR_NONE)
2921   {
2922     /* Clear all the static flags */
2923     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2924     hmmc->ErrorCode |= errorstate;
2925     hmmc->State = HAL_MMC_STATE_READY;
2926     return HAL_ERROR;
2927   }
2928 
2929   /* Poll on SDMMC flags */
2930   while(!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
2931   {
2932     if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF))
2933     {
2934       /* Read data from SDMMC Rx FIFO */
2935       for(count = 0U; count < 8U; count++)
2936       {
2937         tmp_data = SDMMC_ReadFIFO(hmmc->Instance);
2938         /* eg : SEC_COUNT   : FieldIndex = 212 => i+count = 53 */
2939         /*      DEVICE_TYPE : FieldIndex = 196 => i+count = 49 */
2940         if ((i + count) == ((uint32_t)FieldIndex/4U))
2941         {
2942           *pFieldData = tmp_data;
2943         }
2944       }
2945       i += 8U;
2946     }
2947 
2948     if(((HAL_GetTick()-tickstart) >=  Timeout) || (Timeout == 0U))
2949     {
2950       /* Clear all the static flags */
2951       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2952       hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
2953       hmmc->State= HAL_MMC_STATE_READY;
2954       return HAL_TIMEOUT;
2955     }
2956   }
2957 
2958   /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2959   errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16));
2960   if(errorstate != HAL_MMC_ERROR_NONE)
2961   {
2962     hmmc->ErrorCode |= errorstate;
2963   }
2964 
2965   /* Clear all the static flags */
2966   __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2967 
2968   hmmc->State = HAL_MMC_STATE_READY;
2969 
2970   return HAL_OK;
2971 }
2972 
2973 
2974 /**
2975   * @brief  Wrap up reading in non-blocking mode.
2976   * @param  hmmc: pointer to a MMC_HandleTypeDef structure that contains
2977   *              the configuration information.
2978   * @retval None
2979   */
MMC_Read_IT(MMC_HandleTypeDef * hmmc)2980 static void MMC_Read_IT(MMC_HandleTypeDef *hmmc)
2981 {
2982   uint32_t count, data, dataremaining;
2983   uint8_t* tmp;
2984 
2985   tmp = hmmc->pRxBuffPtr;
2986   dataremaining = hmmc->RxXferSize;
2987 
2988   if (dataremaining > 0U)
2989   {
2990     /* Read data from SDMMC Rx FIFO */
2991     for(count = 0U; count < 8U; count++)
2992     {
2993       data = SDMMC_ReadFIFO(hmmc->Instance);
2994       *tmp = (uint8_t)(data & 0xFFU);
2995       tmp++;
2996       dataremaining--;
2997       *tmp = (uint8_t)((data >> 8U) & 0xFFU);
2998       tmp++;
2999       dataremaining--;
3000       *tmp = (uint8_t)((data >> 16U) & 0xFFU);
3001       tmp++;
3002       dataremaining--;
3003       *tmp = (uint8_t)((data >> 24U) & 0xFFU);
3004       tmp++;
3005       dataremaining--;
3006     }
3007 
3008     hmmc->pRxBuffPtr = tmp;
3009     hmmc->RxXferSize = dataremaining;
3010   }
3011 }
3012 
3013 /**
3014   * @brief  Wrap up writing in non-blocking mode.
3015   * @param  hmmc: pointer to a MMC_HandleTypeDef structure that contains
3016   *              the configuration information.
3017   * @retval None
3018   */
MMC_Write_IT(MMC_HandleTypeDef * hmmc)3019 static void MMC_Write_IT(MMC_HandleTypeDef *hmmc)
3020 {
3021   uint32_t count, data, dataremaining;
3022   uint8_t* tmp;
3023 
3024   tmp = hmmc->pTxBuffPtr;
3025   dataremaining = hmmc->TxXferSize;
3026 
3027   if (dataremaining > 0U)
3028   {
3029     /* Write data to SDMMC Tx FIFO */
3030     for(count = 0U; count < 8U; count++)
3031     {
3032       data = (uint32_t)(*tmp);
3033       tmp++;
3034       dataremaining--;
3035       data |= ((uint32_t)(*tmp) << 8U);
3036       tmp++;
3037       dataremaining--;
3038       data |= ((uint32_t)(*tmp) << 16U);
3039       tmp++;
3040       dataremaining--;
3041       data |= ((uint32_t)(*tmp) << 24U);
3042       tmp++;
3043       dataremaining--;
3044       (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
3045     }
3046 
3047     hmmc->pTxBuffPtr = tmp;
3048     hmmc->TxXferSize = dataremaining;
3049   }
3050 }
3051 
3052 /**
3053   * @brief  Update the power class of the device.
3054   * @param  hmmc MMC handle
3055   * @param  Wide Wide of MMC bus
3056   * @param  Speed Speed of the MMC bus
3057   * @retval MMC Card error state
3058   */
MMC_PwrClassUpdate(MMC_HandleTypeDef * hmmc,uint32_t Wide)3059 static uint32_t MMC_PwrClassUpdate(MMC_HandleTypeDef *hmmc, uint32_t Wide)
3060 {
3061   uint32_t count;
3062   uint32_t response = 0U;
3063   uint32_t errorstate = HAL_MMC_ERROR_NONE;
3064   uint32_t power_class, supported_pwr_class;
3065 
3066   if((Wide == SDMMC_BUS_WIDE_8B) || (Wide == SDMMC_BUS_WIDE_4B))
3067   {
3068     power_class = 0U; /* Default value after power-on or software reset */
3069 
3070     /* Read the PowerClass field of the Extended CSD register */
3071     if(MMC_ReadExtCSD(hmmc, &power_class, 187, SDMMC_DATATIMEOUT) != HAL_OK) /* Field POWER_CLASS [187] */
3072     {
3073       errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
3074     }
3075     else
3076     {
3077       power_class = ((power_class >> 24U) & 0x000000FFU);
3078     }
3079 
3080     /* Get the supported PowerClass field of the Extended CSD register */
3081     /* Field PWR_CL_26_xxx [201 or 203] */
3082     supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_26_INDEX/4)] >> MMC_EXT_CSD_PWR_CL_26_POS) & 0x000000FFU);
3083 
3084     if(errorstate == HAL_MMC_ERROR_NONE)
3085     {
3086       if(Wide == SDMMC_BUS_WIDE_8B)
3087       {
3088         /* Bit [7:4] : power class for 8-bits bus configuration - Bit [3:0] : power class for 4-bits bus configuration */
3089         supported_pwr_class = (supported_pwr_class >> 4U);
3090       }
3091 
3092       if ((power_class & 0x0FU) != (supported_pwr_class & 0x0FU))
3093       {
3094         /* Need to change current power class */
3095         errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03BB0000U | ((supported_pwr_class & 0x0FU) << 8U)));
3096 
3097         if(errorstate == HAL_MMC_ERROR_NONE)
3098         {
3099           /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3100           count = SDMMC_MAX_TRIAL;
3101           do
3102           {
3103             errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3104             if(errorstate != HAL_MMC_ERROR_NONE)
3105             {
3106               break;
3107             }
3108 
3109             /* Get command response */
3110             response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3111             count--;
3112           }while(((response & 0x100U) == 0U) && (count != 0U));
3113 
3114           /* Check the status after the switch command execution */
3115           if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
3116           {
3117             /* Check the bit SWITCH_ERROR of the device status */
3118             if ((response & 0x80U) != 0U)
3119             {
3120               errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3121             }
3122           }
3123           else if (count == 0U)
3124           {
3125             errorstate = SDMMC_ERROR_TIMEOUT;
3126           }
3127           else
3128           {
3129             /* Nothing to do */
3130           }
3131         }
3132       }
3133     }
3134   }
3135 
3136   return errorstate;
3137 }
3138 
3139 /**
3140   * @}
3141   */
3142 
3143 #endif /* SDMMC1 */
3144 
3145 #endif /* HAL_MMC_MODULE_ENABLED */
3146 
3147 /**
3148   * @}
3149   */
3150 
3151 /**
3152   * @}
3153   */
3154