1 /**
2   ******************************************************************************
3   * @file    stm32l5xx_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) 2019 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         (##) NVIC configuration if you need to use interrupt process (HAL_MMC_ReadBlocks_IT()
48              and HAL_MMC_WriteBlocks_IT() APIs).
49             (+++) Configure the SDMMC interrupt priorities using function HAL_NVIC_SetPriority();
50             (+++) Enable the NVIC SDMMC IRQs using function HAL_NVIC_EnableIRQ()
51             (+++) SDMMC interrupts are managed using the macros __HAL_MMC_ENABLE_IT()
52                   and __HAL_MMC_DISABLE_IT() inside the communication process.
53             (+++) SDMMC interrupts pending bits are managed using the macros __HAL_MMC_GET_IT()
54                   and __HAL_MMC_CLEAR_IT()
55         (##) No general propose DMA Configuration is needed, an Internal DMA for SDMMC Peripheral are used.
56 
57     (#) At this stage, you can perform MMC read/write/erase operations after MMC card initialization
58 
59 
60   *** MMC Card Initialization and configuration ***
61   ================================================
62   [..]
63     To initialize the MMC Card, use the HAL_MMC_Init() function. It Initializes
64     SDMMC Peripheral (STM32 side) and the MMC Card, and put it into StandBy State (Ready for data transfer).
65     This function provide the following operations:
66 
67     (#) Initialize the SDMMC peripheral interface with default configuration.
68         The initialization process is done at 400KHz. You can change or adapt
69         this frequency by adjusting the "ClockDiv" field.
70         The MMC Card frequency (SDMMC_CK) is computed as follows:
71 
72            SDMMC_CK = SDMMCCLK / (2 * ClockDiv)
73 
74         In initialization mode and according to the MMC Card standard,
75         make sure that the SDMMC_CK frequency doesn't exceed 400KHz.
76 
77         This phase of initialization is done through SDMMC_Init() and
78         SDMMC_PowerState_ON() SDMMC low level APIs.
79 
80     (#) Initialize the MMC card. The API used is HAL_MMC_InitCard().
81         This phase allows the card initialization and identification
82         and check the MMC Card type (Standard Capacity or High Capacity)
83         The initialization flow is compatible with MMC standard.
84 
85         This API (HAL_MMC_InitCard()) could be used also to reinitialize the card in case
86         of plug-off plug-in.
87 
88     (#) Configure the MMC Card Data transfer frequency. By Default, the card transfer
89         frequency by adjusting the "ClockDiv" field.
90         In transfer mode and according to the MMC Card standard, make sure that the
91         SDMMC_CK frequency doesn't exceed 25MHz and 100MHz in High-speed mode switch.
92 
93     (#) Select the corresponding MMC Card according to the address read with the step 2.
94 
95     (#) Configure the MMC Card in wide bus mode: 4-bits data.
96 
97   *** MMC Card Read operation ***
98   ==============================
99   [..]
100     (+) You can read from MMC card in polling mode by using function HAL_MMC_ReadBlocks().
101         This function support only 512-bytes block length (the block size should be
102         chosen as 512 bytes).
103         You can choose either one block read operation or multiple block read operation
104         by adjusting the "NumberOfBlocks" parameter.
105         After this, you have to ensure that the transfer is done correctly. The check is done
106         through HAL_MMC_GetCardState() function for MMC card state.
107 
108     (+) You can read from MMC card in DMA mode by using function HAL_MMC_ReadBlocks_DMA().
109         This function support only 512-bytes block length (the block size should be
110         chosen as 512 bytes).
111         You can choose either one block read operation or multiple block read operation
112         by adjusting the "NumberOfBlocks" parameter.
113         After this, you have to ensure that the transfer is done correctly. The check is done
114         through HAL_MMC_GetCardState() function for MMC card state.
115         You could also check the DMA transfer process through the MMC Rx interrupt event.
116 
117     (+) You can read from MMC card in Interrupt mode by using function HAL_MMC_ReadBlocks_IT().
118         This function allows the read of 512 bytes blocks.
119         You can choose either one block read operation or multiple block read operation
120         by adjusting the "NumberOfBlocks" parameter.
121         After this, you have to ensure that the transfer is done correctly. The check is done
122         through HAL_MMC_GetCardState() function for MMC card state.
123         You could also check the IT transfer process through the MMC Rx interrupt event.
124 
125   *** MMC Card Write operation ***
126   ===============================
127   [..]
128     (+) You can write to MMC card in polling mode by using function HAL_MMC_WriteBlocks().
129         This function support only 512-bytes block length (the block size should be
130         chosen as 512 bytes).
131         You can choose either one block read operation or multiple block read operation
132         by adjusting the "NumberOfBlocks" parameter.
133         After this, you have to ensure that the transfer is done correctly. The check is done
134         through HAL_MMC_GetCardState() function for MMC card state.
135 
136     (+) You can write to MMC card in DMA mode by using function HAL_MMC_WriteBlocks_DMA().
137         This function support only 512-bytes block length (the block size should be
138         chosen as 512 byte).
139         You can choose either one block read operation or multiple block read operation
140         by adjusting the "NumberOfBlocks" parameter.
141         After this, you have to ensure that the transfer is done correctly. The check is done
142         through HAL_MMC_GetCardState() function for MMC card state.
143         You could also check the DMA transfer process through the MMC Tx interrupt event.
144 
145     (+) You can write to MMC card in Interrupt mode by using function HAL_MMC_WriteBlocks_IT().
146         This function allows the read of 512 bytes blocks.
147         You can choose either one block read operation or multiple block read operation
148         by adjusting the "NumberOfBlocks" parameter.
149         After this, you have to ensure that the transfer is done correctly. The check is done
150         through HAL_MMC_GetCardState() function for MMC card state.
151         You could also check the IT transfer process through the MMC Tx interrupt event.
152 
153   *** MMC card information ***
154   ===========================
155   [..]
156     (+) To get MMC card information, you can use the function HAL_MMC_GetCardInfo().
157         It returns useful information about the MMC card such as block size, card type,
158         block number ...
159 
160   *** MMC card CSD register ***
161   ============================
162   [..]
163     (+) The HAL_MMC_GetCardCSD() API allows to get the parameters of the CSD register.
164         Some of the CSD parameters are useful for card initialization and identification.
165 
166   *** MMC card CID register ***
167   ============================
168   [..]
169     (+) The HAL_MMC_GetCardCID() API allows to get the parameters of the CID register.
170         Some of the CID parameters are useful for card initialization and identification.
171 
172   *** MMC HAL driver macros list ***
173   ==================================
174   [..]
175     Below the list of most used macros in MMC HAL driver.
176 
177     (+) __HAL_MMC_ENABLE_IT: Enable the MMC device interrupt
178     (+) __HAL_MMC_DISABLE_IT: Disable the MMC device interrupt
179     (+) __HAL_MMC_GET_FLAG:Check whether the specified MMC flag is set or not
180     (+) __HAL_MMC_CLEAR_FLAG: Clear the MMC's pending flags
181 
182   [..]
183     (@) You can refer to the MMC HAL driver header file for more useful macros
184 
185   *** Callback registration ***
186   =============================================
187   [..]
188     The compilation define USE_HAL_MMC_REGISTER_CALLBACKS when set to 1
189     allows the user to configure dynamically the driver callbacks.
190 
191     Use Functions HAL_MMC_RegisterCallback() to register a user callback,
192     it allows to register following callbacks:
193       (+) TxCpltCallback : callback when a transmission transfer is completed.
194       (+) RxCpltCallback : callback when a reception transfer is completed.
195       (+) ErrorCallback : callback when error occurs.
196       (+) AbortCpltCallback : callback when abort is completed.
197       (+) Read_DMADblBuf0CpltCallback : callback when the DMA reception of first buffer is completed.
198       (+) Read_DMADblBuf1CpltCallback : callback when the DMA reception of second buffer is completed.
199       (+) Write_DMADblBuf0CpltCallback : callback when the DMA transmission of first buffer is completed.
200       (+) Write_DMADblBuf1CpltCallback : callback when the DMA transmission of second buffer is completed.
201       (+) MspInitCallback    : MMC MspInit.
202       (+) MspDeInitCallback  : MMC MspDeInit.
203     This function takes as parameters the HAL peripheral handle, the Callback ID
204     and a pointer to the user callback function.
205 
206     Use function HAL_MMC_UnRegisterCallback() to reset a callback to the default
207     weak (surcharged) function. It allows to reset following callbacks:
208       (+) TxCpltCallback : callback when a transmission transfer is completed.
209       (+) RxCpltCallback : callback when a reception transfer is completed.
210       (+) ErrorCallback : callback when error occurs.
211       (+) AbortCpltCallback : callback when abort is completed.
212       (+) Read_DMADblBuf0CpltCallback : callback when the DMA reception of first buffer is completed.
213       (+) Read_DMADblBuf1CpltCallback : callback when the DMA reception of second buffer is completed.
214       (+) Write_DMADblBuf0CpltCallback : callback when the DMA transmission of first buffer is completed.
215       (+) Write_DMADblBuf1CpltCallback : callback when the DMA transmission of second buffer is completed.
216       (+) MspInitCallback    : MMC MspInit.
217       (+) MspDeInitCallback  : MMC MspDeInit.
218     This function) takes as parameters the HAL peripheral handle and the Callback ID.
219 
220     By default, after the HAL_MMC_Init and if the state is HAL_MMC_STATE_RESET
221     all callbacks are reset to the corresponding legacy weak (surcharged) functions.
222     Exception done for MspInit and MspDeInit callbacks that are respectively
223     reset to the legacy weak (surcharged) functions in the HAL_MMC_Init
224     and HAL_MMC_DeInit only when these callbacks are null (not registered beforehand).
225     If not, MspInit or MspDeInit are not null, the HAL_MMC_Init and HAL_MMC_DeInit
226     keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
227 
228     Callbacks can be registered/unregistered in READY state only.
229     Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
230     in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
231     during the Init/DeInit.
232     In that case first register the MspInit/MspDeInit user callbacks
233     using HAL_MMC_RegisterCallback before calling HAL_MMC_DeInit
234     or HAL_MMC_Init function.
235 
236     When The compilation define USE_HAL_MMC_REGISTER_CALLBACKS is set to 0 or
237     not defined, the callback registering feature is not available
238     and weak (surcharged) callbacks are used.
239 
240   @endverbatim
241   ******************************************************************************
242   */
243 
244 /* Includes ------------------------------------------------------------------*/
245 #include "stm32l5xx_hal.h"
246 
247 /** @addtogroup STM32L5xx_HAL_Driver
248   * @{
249   */
250 
251 /** @defgroup MMC MMC
252   * @brief MMC HAL module driver
253   * @{
254   */
255 
256 #ifdef HAL_MMC_MODULE_ENABLED
257 
258 /* Private typedef -----------------------------------------------------------*/
259 /* Private define ------------------------------------------------------------*/
260 /** @addtogroup MMC_Private_Defines
261   * @{
262   */
263 #if defined (VDD_VALUE) && (VDD_VALUE <= 1950U)
264 #define MMC_VOLTAGE_RANGE               EMMC_LOW_VOLTAGE_RANGE
265 
266 #define MMC_EXT_CSD_PWR_CL_26_INDEX     201
267 #define MMC_EXT_CSD_PWR_CL_52_INDEX     200
268 #define MMC_EXT_CSD_PWR_CL_DDR_52_INDEX 238
269 
270 #define MMC_EXT_CSD_PWR_CL_26_POS       8
271 #define MMC_EXT_CSD_PWR_CL_52_POS       0
272 #define MMC_EXT_CSD_PWR_CL_DDR_52_POS   16
273 #else
274 #define MMC_VOLTAGE_RANGE               EMMC_HIGH_VOLTAGE_RANGE
275 
276 #define MMC_EXT_CSD_PWR_CL_26_INDEX     203
277 #define MMC_EXT_CSD_PWR_CL_52_INDEX     202
278 #define MMC_EXT_CSD_PWR_CL_DDR_52_INDEX 239
279 
280 #define MMC_EXT_CSD_PWR_CL_26_POS       24
281 #define MMC_EXT_CSD_PWR_CL_52_POS       16
282 #define MMC_EXT_CSD_PWR_CL_DDR_52_POS   24
283 #endif /* (VDD_VALUE) && (VDD_VALUE <= 1950U)*/
284 
285 #define MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_INDEX 216
286 #define MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_POS   0
287 #define MMC_EXT_CSD_S_A_TIMEOUT_INDEX             217
288 #define MMC_EXT_CSD_S_A_TIMEOUT_POS               8
289 
290 /* Frequencies used in the driver for clock divider calculation */
291 #define MMC_INIT_FREQ                   400000U   /* Initialization phase : 400 kHz max */
292 #define MMC_HIGH_SPEED_FREQ             52000000U /* High speed phase : 52 MHz max */
293 /**
294   * @}
295   */
296 
297 /* Private macro -------------------------------------------------------------*/
298 /* Private variables ---------------------------------------------------------*/
299 /* Private function prototypes -----------------------------------------------*/
300 /* Private functions ---------------------------------------------------------*/
301 /** @defgroup MMC_Private_Functions MMC Private Functions
302   * @{
303   */
304 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc);
305 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc);
306 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus);
307 static void     MMC_PowerOFF(MMC_HandleTypeDef *hmmc);
308 static void     MMC_Write_IT(MMC_HandleTypeDef *hmmc);
309 static void     MMC_Read_IT(MMC_HandleTypeDef *hmmc);
310 static uint32_t MMC_HighSpeed(MMC_HandleTypeDef *hmmc, FunctionalState state);
311 static uint32_t MMC_DDR_Mode(MMC_HandleTypeDef *hmmc, FunctionalState state);
312 static HAL_StatusTypeDef MMC_ReadExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pFieldData, uint16_t FieldIndex,
313                                         uint32_t Timeout);
314 static uint32_t MMC_PwrClassUpdate(MMC_HandleTypeDef *hmmc, uint32_t Wide, uint32_t Speed);
315 
316 /**
317   * @}
318   */
319 /* Exported functions --------------------------------------------------------*/
320 /** @addtogroup MMC_Exported_Functions
321   * @{
322   */
323 
324 /** @addtogroup MMC_Exported_Functions_Group1
325   *  @brief   Initialization and de-initialization functions
326   *
327 @verbatim
328   ==============================================================================
329           ##### Initialization and de-initialization functions #####
330   ==============================================================================
331   [..]
332     This section provides functions allowing to initialize/de-initialize the MMC
333     card device to be ready for use.
334 
335 @endverbatim
336   * @{
337   */
338 
339 /**
340   * @brief  Initializes the MMC according to the specified parameters in the
341             MMC_HandleTypeDef and create the associated handle.
342   * @param  hmmc: Pointer to the MMC handle
343   * @retval HAL status
344   */
HAL_MMC_Init(MMC_HandleTypeDef * hmmc)345 HAL_StatusTypeDef HAL_MMC_Init(MMC_HandleTypeDef *hmmc)
346 {
347   /* Check the MMC handle allocation */
348   if (hmmc == NULL)
349   {
350     return HAL_ERROR;
351   }
352 
353   /* Check the parameters */
354   assert_param(IS_SDMMC_ALL_INSTANCE(hmmc->Instance));
355   assert_param(IS_SDMMC_CLOCK_EDGE(hmmc->Init.ClockEdge));
356   assert_param(IS_SDMMC_CLOCK_POWER_SAVE(hmmc->Init.ClockPowerSave));
357   assert_param(IS_SDMMC_BUS_WIDE(hmmc->Init.BusWide));
358   assert_param(IS_SDMMC_HARDWARE_FLOW_CONTROL(hmmc->Init.HardwareFlowControl));
359   assert_param(IS_SDMMC_CLKDIV(hmmc->Init.ClockDiv));
360 
361   if (hmmc->State == HAL_MMC_STATE_RESET)
362   {
363     /* Allocate lock resource and initialize it */
364     hmmc->Lock = HAL_UNLOCKED;
365 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
366     /* Reset Callback pointers in HAL_MMC_STATE_RESET only */
367     hmmc->TxCpltCallback    = HAL_MMC_TxCpltCallback;
368     hmmc->RxCpltCallback    = HAL_MMC_RxCpltCallback;
369     hmmc->ErrorCallback     = HAL_MMC_ErrorCallback;
370     hmmc->AbortCpltCallback = HAL_MMC_AbortCallback;
371     hmmc->Read_DMADblBuf0CpltCallback = HAL_MMCEx_Read_DMADoubleBuf0CpltCallback;
372     hmmc->Read_DMADblBuf1CpltCallback = HAL_MMCEx_Read_DMADoubleBuf1CpltCallback;
373     hmmc->Write_DMADblBuf0CpltCallback = HAL_MMCEx_Write_DMADoubleBuf0CpltCallback;
374     hmmc->Write_DMADblBuf1CpltCallback = HAL_MMCEx_Write_DMADoubleBuf1CpltCallback;
375 
376     if (hmmc->MspInitCallback == NULL)
377     {
378       hmmc->MspInitCallback = HAL_MMC_MspInit;
379     }
380 
381     /* Init the low level hardware */
382     hmmc->MspInitCallback(hmmc);
383 #else
384     /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
385     HAL_MMC_MspInit(hmmc);
386 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
387   }
388 
389   hmmc->State = HAL_MMC_STATE_BUSY;
390 
391   /* Initialize the Card parameters */
392   if (HAL_MMC_InitCard(hmmc) == HAL_ERROR)
393   {
394     return HAL_ERROR;
395   }
396 
397   /* Initialize the error code */
398   hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
399 
400   /* Initialize the MMC operation */
401   hmmc->Context = MMC_CONTEXT_NONE;
402 
403   /* Initialize the MMC state */
404   hmmc->State = HAL_MMC_STATE_READY;
405 
406   /* Configure bus width */
407   if (hmmc->Init.BusWide != SDMMC_BUS_WIDE_1B)
408   {
409     if (HAL_MMC_ConfigWideBusOperation(hmmc, hmmc->Init.BusWide) != HAL_OK)
410     {
411       return HAL_ERROR;
412     }
413   }
414 
415   return HAL_OK;
416 }
417 
418 /**
419   * @brief  Initializes the MMC Card.
420   * @param  hmmc: Pointer to MMC handle
421   * @note   This function initializes the MMC card. It could be used when a card
422             re-initialization is needed.
423   * @retval HAL status
424   */
HAL_MMC_InitCard(MMC_HandleTypeDef * hmmc)425 HAL_StatusTypeDef HAL_MMC_InitCard(MMC_HandleTypeDef *hmmc)
426 {
427   uint32_t errorstate;
428   MMC_InitTypeDef Init;
429   uint32_t sdmmc_clk;
430 
431   /* Default SDMMC peripheral configuration for MMC card initialization */
432   Init.ClockEdge           = SDMMC_CLOCK_EDGE_RISING;
433   Init.ClockPowerSave      = SDMMC_CLOCK_POWER_SAVE_DISABLE;
434   Init.BusWide             = SDMMC_BUS_WIDE_1B;
435   Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
436 
437   /* Init Clock should be less or equal to 400Khz*/
438   sdmmc_clk     = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC1);
439   if (sdmmc_clk == 0U)
440   {
441     hmmc->State = HAL_MMC_STATE_READY;
442     hmmc->ErrorCode = SDMMC_ERROR_INVALID_PARAMETER;
443     return HAL_ERROR;
444   }
445   Init.ClockDiv = sdmmc_clk / (2U * MMC_INIT_FREQ);
446 
447 #if (USE_SD_TRANSCEIVER != 0U)
448   Init.TranceiverPresent = SDMMC_TRANSCEIVER_NOT_PRESENT;
449 #endif /* USE_SD_TRANSCEIVER */
450 
451   /* Initialize SDMMC peripheral interface with default configuration */
452   (void)SDMMC_Init(hmmc->Instance, Init);
453 
454   /* Set Power State to ON */
455   (void)SDMMC_PowerState_ON(hmmc->Instance);
456 
457   /* wait 74 Cycles: required power up waiting time before starting
458      the MMC initialization sequence */
459   sdmmc_clk = sdmmc_clk / (2U * Init.ClockDiv);
460   HAL_Delay(1U + (74U * 1000U / (sdmmc_clk)));
461 
462   /* Identify card operating voltage */
463   errorstate = MMC_PowerON(hmmc);
464   if (errorstate != HAL_MMC_ERROR_NONE)
465   {
466     hmmc->State = HAL_MMC_STATE_READY;
467     hmmc->ErrorCode |= errorstate;
468     return HAL_ERROR;
469   }
470 
471   /* Card initialization */
472   errorstate = MMC_InitCard(hmmc);
473   if (errorstate != HAL_MMC_ERROR_NONE)
474   {
475     hmmc->State = HAL_MMC_STATE_READY;
476     hmmc->ErrorCode |= errorstate;
477     return HAL_ERROR;
478   }
479 
480   /* Set Block Size for Card */
481   errorstate = SDMMC_CmdBlockLength(hmmc->Instance, MMC_BLOCKSIZE);
482   if (errorstate != HAL_MMC_ERROR_NONE)
483   {
484     /* Clear all the static flags */
485     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
486     hmmc->ErrorCode |= errorstate;
487     hmmc->State = HAL_MMC_STATE_READY;
488     return HAL_ERROR;
489   }
490 
491   return HAL_OK;
492 }
493 
494 /**
495   * @brief  De-Initializes the MMC card.
496   * @param  hmmc: Pointer to MMC handle
497   * @retval HAL status
498   */
HAL_MMC_DeInit(MMC_HandleTypeDef * hmmc)499 HAL_StatusTypeDef HAL_MMC_DeInit(MMC_HandleTypeDef *hmmc)
500 {
501   /* Check the MMC handle allocation */
502   if (hmmc == NULL)
503   {
504     return HAL_ERROR;
505   }
506 
507   /* Check the parameters */
508   assert_param(IS_SDMMC_ALL_INSTANCE(hmmc->Instance));
509 
510   hmmc->State = HAL_MMC_STATE_BUSY;
511 
512   /* Set MMC power state to off */
513   MMC_PowerOFF(hmmc);
514 
515 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
516   if (hmmc->MspDeInitCallback == NULL)
517   {
518     hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
519   }
520 
521   /* DeInit the low level hardware */
522   hmmc->MspDeInitCallback(hmmc);
523 #else
524   /* De-Initialize the MSP layer */
525   HAL_MMC_MspDeInit(hmmc);
526 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
527 
528   hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
529   hmmc->State = HAL_MMC_STATE_RESET;
530 
531   return HAL_OK;
532 }
533 
534 
535 /**
536   * @brief  Initializes the MMC MSP.
537   * @param  hmmc: Pointer to MMC handle
538   * @retval None
539   */
HAL_MMC_MspInit(MMC_HandleTypeDef * hmmc)540 __weak void HAL_MMC_MspInit(MMC_HandleTypeDef *hmmc)
541 {
542   /* Prevent unused argument(s) compilation warning */
543   UNUSED(hmmc);
544 
545   /* NOTE : This function Should not be modified, when the callback is needed,
546             the HAL_MMC_MspInit could be implemented in the user file
547    */
548 }
549 
550 /**
551   * @brief  De-Initialize MMC MSP.
552   * @param  hmmc: Pointer to MMC handle
553   * @retval None
554   */
HAL_MMC_MspDeInit(MMC_HandleTypeDef * hmmc)555 __weak void HAL_MMC_MspDeInit(MMC_HandleTypeDef *hmmc)
556 {
557   /* Prevent unused argument(s) compilation warning */
558   UNUSED(hmmc);
559 
560   /* NOTE : This function Should not be modified, when the callback is needed,
561             the HAL_MMC_MspDeInit could be implemented in the user file
562    */
563 }
564 
565 /**
566   * @}
567   */
568 
569 /** @addtogroup MMC_Exported_Functions_Group2
570   *  @brief   Data transfer functions
571   *
572 @verbatim
573   ==============================================================================
574                         ##### IO operation functions #####
575   ==============================================================================
576   [..]
577     This subsection provides a set of functions allowing to manage the data
578     transfer from/to MMC card.
579 
580 @endverbatim
581   * @{
582   */
583 
584 /**
585   * @brief  Reads block(s) from a specified address in a card. The Data transfer
586   *         is managed by polling mode.
587   * @note   This API should be followed by a check on the card state through
588   *         HAL_MMC_GetCardState().
589   * @param  hmmc: Pointer to MMC handle
590   * @param  pData: pointer to the buffer that will contain the received data
591   * @param  BlockAdd: Block Address from where data is to be read
592   * @param  NumberOfBlocks: Number of MMC blocks to read
593   * @param  Timeout: Specify timeout value
594   * @retval HAL status
595   */
HAL_MMC_ReadBlocks(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks,uint32_t Timeout)596 HAL_StatusTypeDef HAL_MMC_ReadBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd,
597                                      uint32_t NumberOfBlocks, uint32_t Timeout)
598 {
599   SDMMC_DataInitTypeDef config;
600   uint32_t errorstate;
601   uint32_t tickstart = HAL_GetTick();
602   uint32_t count;
603   uint32_t data;
604   uint32_t dataremaining;
605   uint32_t add = BlockAdd;
606   uint8_t *tempbuff = pData;
607 
608   if (NULL == pData)
609   {
610     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
611     return HAL_ERROR;
612   }
613 
614   if (hmmc->State == HAL_MMC_STATE_READY)
615   {
616     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
617 
618     if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
619     {
620       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
621       return HAL_ERROR;
622     }
623 
624     /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
625     if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS)
626          & 0x000000FFU) != 0x0U)
627     {
628       if ((NumberOfBlocks % 8U) != 0U)
629       {
630         /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */
631         hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR;
632         return HAL_ERROR;
633       }
634 
635       if ((BlockAdd % 8U) != 0U)
636       {
637         /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
638         hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
639         return HAL_ERROR;
640       }
641     }
642 
643     hmmc->State = HAL_MMC_STATE_BUSY;
644 
645     /* Initialize data control register */
646     hmmc->Instance->DCTRL = 0U;
647 
648     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
649     {
650       add *= 512U;
651     }
652 
653     /* Configure the MMC DPSM (Data Path State Machine) */
654     config.DataTimeOut   = SDMMC_DATATIMEOUT;
655     config.DataLength    = NumberOfBlocks * MMC_BLOCKSIZE;
656     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
657     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
658     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
659     config.DPSM          = SDMMC_DPSM_DISABLE;
660     (void)SDMMC_ConfigData(hmmc->Instance, &config);
661     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
662 
663     /* Read block(s) in polling mode */
664     if (NumberOfBlocks > 1U)
665     {
666       hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
667 
668       /* Read Multi Block command */
669       errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
670     }
671     else
672     {
673       hmmc->Context = MMC_CONTEXT_READ_SINGLE_BLOCK;
674 
675       /* Read Single Block command */
676       errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
677     }
678     if (errorstate != HAL_MMC_ERROR_NONE)
679     {
680       /* Clear all the static flags */
681       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
682       hmmc->ErrorCode |= errorstate;
683       hmmc->State = HAL_MMC_STATE_READY;
684       return HAL_ERROR;
685     }
686 
687     /* Poll on SDMMC flags */
688     dataremaining = config.DataLength;
689     while (!__HAL_MMC_GET_FLAG(hmmc,
690                                SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
691     {
692       if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= 32U))
693       {
694         /* Read data from SDMMC Rx FIFO */
695         for (count = 0U; count < 8U; count++)
696         {
697           data = SDMMC_ReadFIFO(hmmc->Instance);
698           *tempbuff = (uint8_t)(data & 0xFFU);
699           tempbuff++;
700           *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
701           tempbuff++;
702           *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
703           tempbuff++;
704           *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
705           tempbuff++;
706         }
707         dataremaining -= 32U;
708       }
709 
710       if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
711       {
712         /* Clear all the static flags */
713         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
714         hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
715         hmmc->State = HAL_MMC_STATE_READY;
716         return HAL_TIMEOUT;
717       }
718     }
719     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
720 
721     /* Send stop transmission command in case of multiblock read */
722     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U))
723     {
724       /* Send stop transmission command */
725       errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
726       if (errorstate != HAL_MMC_ERROR_NONE)
727       {
728         /* Clear all the static flags */
729         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
730         hmmc->ErrorCode |= errorstate;
731         hmmc->State = HAL_MMC_STATE_READY;
732         return HAL_ERROR;
733       }
734     }
735 
736     /* Get error state */
737     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
738     {
739       /* Clear all the static flags */
740       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
741       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
742       hmmc->State = HAL_MMC_STATE_READY;
743       return HAL_ERROR;
744     }
745     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
746     {
747       /* Clear all the static flags */
748       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
749       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
750       hmmc->State = HAL_MMC_STATE_READY;
751       return HAL_ERROR;
752     }
753     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR))
754     {
755       /* Clear all the static flags */
756       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
757       hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
758       hmmc->State = HAL_MMC_STATE_READY;
759       return HAL_ERROR;
760     }
761     else
762     {
763       /* Nothing to do */
764     }
765 
766     /* Clear all the static flags */
767     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
768 
769     hmmc->State = HAL_MMC_STATE_READY;
770 
771     return HAL_OK;
772   }
773   else
774   {
775     hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
776     return HAL_ERROR;
777   }
778 }
779 
780 /**
781   * @brief  Allows to write block(s) to a specified address in a card. The Data
782   *         transfer is managed by polling mode.
783   * @note   This API should be followed by a check on the card state through
784   *         HAL_MMC_GetCardState().
785   * @param  hmmc: Pointer to MMC handle
786   * @param  pData: pointer to the buffer that will contain the data to transmit
787   * @param  BlockAdd: Block Address where data will be written
788   * @param  NumberOfBlocks: Number of MMC blocks to write
789   * @param  Timeout: Specify timeout value
790   * @retval HAL status
791   */
HAL_MMC_WriteBlocks(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks,uint32_t Timeout)792 HAL_StatusTypeDef HAL_MMC_WriteBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd,
793                                       uint32_t NumberOfBlocks, uint32_t Timeout)
794 {
795   SDMMC_DataInitTypeDef config;
796   uint32_t errorstate;
797   uint32_t tickstart = HAL_GetTick();
798   uint32_t count;
799   uint32_t data;
800   uint32_t dataremaining;
801   uint32_t add = BlockAdd;
802   uint8_t *tempbuff = pData;
803 
804   if (NULL == pData)
805   {
806     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
807     return HAL_ERROR;
808   }
809 
810   if (hmmc->State == HAL_MMC_STATE_READY)
811   {
812     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
813 
814     if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
815     {
816       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
817       return HAL_ERROR;
818     }
819 
820     /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
821     if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U)
822     {
823       if ((NumberOfBlocks % 8U) != 0U)
824       {
825         /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */
826         hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR;
827         return HAL_ERROR;
828       }
829 
830       if ((BlockAdd % 8U) != 0U)
831       {
832         /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
833         hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
834         return HAL_ERROR;
835       }
836     }
837 
838     hmmc->State = HAL_MMC_STATE_BUSY;
839 
840     /* Initialize data control register */
841     hmmc->Instance->DCTRL = 0U;
842 
843     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
844     {
845       add *= 512U;
846     }
847 
848     /* Configure the MMC DPSM (Data Path State Machine) */
849     config.DataTimeOut   = SDMMC_DATATIMEOUT;
850     config.DataLength    = NumberOfBlocks * MMC_BLOCKSIZE;
851     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
852     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
853     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
854     config.DPSM          = SDMMC_DPSM_DISABLE;
855     (void)SDMMC_ConfigData(hmmc->Instance, &config);
856     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
857 
858     /* Write Blocks in Polling mode */
859     if (NumberOfBlocks > 1U)
860     {
861       hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
862 
863       /* Write Multi Block command */
864       errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
865     }
866     else
867     {
868       hmmc->Context = MMC_CONTEXT_WRITE_SINGLE_BLOCK;
869 
870       /* Write Single Block command */
871       errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
872     }
873     if (errorstate != HAL_MMC_ERROR_NONE)
874     {
875       /* Clear all the static flags */
876       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
877       hmmc->ErrorCode |= errorstate;
878       hmmc->State = HAL_MMC_STATE_READY;
879       return HAL_ERROR;
880     }
881 
882     /* Write block(s) in polling mode */
883     dataremaining = config.DataLength;
884     while (!__HAL_MMC_GET_FLAG(hmmc,
885                                SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
886     {
887       if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= 32U))
888       {
889         /* Write data to SDMMC Tx FIFO */
890         for (count = 0U; count < 8U; count++)
891         {
892           data = (uint32_t)(*tempbuff);
893           tempbuff++;
894           data |= ((uint32_t)(*tempbuff) << 8U);
895           tempbuff++;
896           data |= ((uint32_t)(*tempbuff) << 16U);
897           tempbuff++;
898           data |= ((uint32_t)(*tempbuff) << 24U);
899           tempbuff++;
900           (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
901         }
902         dataremaining -= 32U;
903       }
904 
905       if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
906       {
907         /* Clear all the static flags */
908         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
909         hmmc->ErrorCode |= errorstate;
910         hmmc->State = HAL_MMC_STATE_READY;
911         return HAL_TIMEOUT;
912       }
913     }
914     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
915 
916     /* Send stop transmission command in case of multiblock write */
917     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U))
918     {
919       /* Send stop transmission command */
920       errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
921       if (errorstate != HAL_MMC_ERROR_NONE)
922       {
923         /* Clear all the static flags */
924         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
925         hmmc->ErrorCode |= errorstate;
926         hmmc->State = HAL_MMC_STATE_READY;
927         return HAL_ERROR;
928       }
929     }
930 
931     /* Get error state */
932     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
933     {
934       /* Clear all the static flags */
935       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
936       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
937       hmmc->State = HAL_MMC_STATE_READY;
938       return HAL_ERROR;
939     }
940     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
941     {
942       /* Clear all the static flags */
943       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
944       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
945       hmmc->State = HAL_MMC_STATE_READY;
946       return HAL_ERROR;
947     }
948     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
949     {
950       /* Clear all the static flags */
951       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
952       hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
953       hmmc->State = HAL_MMC_STATE_READY;
954       return HAL_ERROR;
955     }
956     else
957     {
958       /* Nothing to do */
959     }
960 
961     /* Clear all the static flags */
962     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
963 
964     hmmc->State = HAL_MMC_STATE_READY;
965 
966     return HAL_OK;
967   }
968   else
969   {
970     hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
971     return HAL_ERROR;
972   }
973 }
974 
975 /**
976   * @brief  Reads block(s) from a specified address in a card. The Data transfer
977   *         is managed in interrupt mode.
978   * @note   This API should be followed by a check on the card state through
979   *         HAL_MMC_GetCardState().
980   * @note   You could also check the IT transfer process through the MMC Rx
981   *         interrupt event.
982   * @param  hmmc: Pointer to MMC handle
983   * @param  pData: Pointer to the buffer that will contain the received data
984   * @param  BlockAdd: Block Address from where data is to be read
985   * @param  NumberOfBlocks: Number of blocks to read.
986   * @retval HAL status
987   */
HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)988 HAL_StatusTypeDef HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData,
989                                         uint32_t BlockAdd, uint32_t NumberOfBlocks)
990 {
991   SDMMC_DataInitTypeDef config;
992   uint32_t errorstate;
993   uint32_t add = BlockAdd;
994 
995   if (NULL == pData)
996   {
997     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
998     return HAL_ERROR;
999   }
1000 
1001   if (hmmc->State == HAL_MMC_STATE_READY)
1002   {
1003     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1004 
1005     if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1006     {
1007       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1008       return HAL_ERROR;
1009     }
1010 
1011     /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
1012     if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U)
1013     {
1014       if ((NumberOfBlocks % 8U) != 0U)
1015       {
1016         /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */
1017         hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR;
1018         return HAL_ERROR;
1019       }
1020 
1021       if ((BlockAdd % 8U) != 0U)
1022       {
1023         /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
1024         hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
1025         return HAL_ERROR;
1026       }
1027     }
1028 
1029     hmmc->State = HAL_MMC_STATE_BUSY;
1030 
1031     /* Initialize data control register */
1032     hmmc->Instance->DCTRL = 0U;
1033 
1034     hmmc->pRxBuffPtr = pData;
1035     hmmc->RxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1036 
1037     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1038     {
1039       add *= 512U;
1040     }
1041 
1042     /* Configure the MMC DPSM (Data Path State Machine) */
1043     config.DataTimeOut   = SDMMC_DATATIMEOUT;
1044     config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
1045     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1046     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
1047     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
1048     config.DPSM          = SDMMC_DPSM_DISABLE;
1049     (void)SDMMC_ConfigData(hmmc->Instance, &config);
1050     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
1051 
1052     /* Read Blocks in IT mode */
1053     if (NumberOfBlocks > 1U)
1054     {
1055       hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_IT);
1056 
1057       /* Read Multi Block command */
1058       errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
1059     }
1060     else
1061     {
1062       hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_IT);
1063 
1064       /* Read Single Block command */
1065       errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
1066     }
1067 
1068     if (errorstate != HAL_MMC_ERROR_NONE)
1069     {
1070       /* Clear all the static flags */
1071       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1072       hmmc->ErrorCode |= errorstate;
1073       hmmc->State = HAL_MMC_STATE_READY;
1074       return HAL_ERROR;
1075     }
1076 
1077     __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND |
1078                                SDMMC_FLAG_RXFIFOHF));
1079 
1080     return HAL_OK;
1081   }
1082   else
1083   {
1084     return HAL_BUSY;
1085   }
1086 }
1087 
1088 /**
1089   * @brief  Writes block(s) to a specified address in a card. The Data transfer
1090   *         is managed in interrupt mode.
1091   * @note   This API should be followed by a check on the card state through
1092   *         HAL_MMC_GetCardState().
1093   * @note   You could also check the IT transfer process through the MMC Tx
1094   *         interrupt event.
1095   * @param  hmmc: Pointer to MMC handle
1096   * @param  pData: Pointer to the buffer that will contain the data to transmit
1097   * @param  BlockAdd: Block Address where data will be written
1098   * @param  NumberOfBlocks: Number of blocks to write
1099   * @retval HAL status
1100   */
HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)1101 HAL_StatusTypeDef HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData,
1102                                          uint32_t BlockAdd, uint32_t NumberOfBlocks)
1103 {
1104   SDMMC_DataInitTypeDef config;
1105   uint32_t errorstate;
1106   uint32_t add = BlockAdd;
1107 
1108   if (NULL == pData)
1109   {
1110     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1111     return HAL_ERROR;
1112   }
1113 
1114   if (hmmc->State == HAL_MMC_STATE_READY)
1115   {
1116     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1117 
1118     if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1119     {
1120       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1121       return HAL_ERROR;
1122     }
1123 
1124     /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
1125     if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U)
1126     {
1127       if ((NumberOfBlocks % 8U) != 0U)
1128       {
1129         /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */
1130         hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR;
1131         return HAL_ERROR;
1132       }
1133 
1134       if ((BlockAdd % 8U) != 0U)
1135       {
1136         /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
1137         hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
1138         return HAL_ERROR;
1139       }
1140     }
1141 
1142     hmmc->State = HAL_MMC_STATE_BUSY;
1143 
1144     /* Initialize data control register */
1145     hmmc->Instance->DCTRL = 0U;
1146 
1147     hmmc->pTxBuffPtr = pData;
1148     hmmc->TxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1149 
1150     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1151     {
1152       add *= 512U;
1153     }
1154 
1155     /* Configure the MMC DPSM (Data Path State Machine) */
1156     config.DataTimeOut   = SDMMC_DATATIMEOUT;
1157     config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
1158     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1159     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
1160     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
1161     config.DPSM          = SDMMC_DPSM_DISABLE;
1162     (void)SDMMC_ConfigData(hmmc->Instance, &config);
1163 
1164     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
1165 
1166     /* Write Blocks in Polling mode */
1167     if (NumberOfBlocks > 1U)
1168     {
1169       hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_IT);
1170 
1171       /* Write Multi Block command */
1172       errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
1173     }
1174     else
1175     {
1176       hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_IT);
1177 
1178       /* Write Single Block command */
1179       errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
1180     }
1181     if (errorstate != HAL_MMC_ERROR_NONE)
1182     {
1183       /* Clear all the static flags */
1184       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1185       hmmc->ErrorCode |= errorstate;
1186       hmmc->State = HAL_MMC_STATE_READY;
1187       return HAL_ERROR;
1188     }
1189 
1190     /* Enable transfer interrupts */
1191     __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND |
1192                                SDMMC_FLAG_TXFIFOHE));
1193 
1194     return HAL_OK;
1195   }
1196   else
1197   {
1198     return HAL_BUSY;
1199   }
1200 }
1201 
1202 /**
1203   * @brief  Reads block(s) from a specified address in a card. The Data transfer
1204   *         is managed by DMA mode.
1205   * @note   This API should be followed by a check on the card state through
1206   *         HAL_MMC_GetCardState().
1207   * @note   You could also check the DMA transfer process through the MMC Rx
1208   *         interrupt event.
1209   * @param  hmmc: Pointer MMC handle
1210   * @param  pData: Pointer to the buffer that will contain the received data
1211   * @param  BlockAdd: Block Address from where data is to be read
1212   * @param  NumberOfBlocks: Number of blocks to read.
1213   * @retval HAL status
1214   */
HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)1215 HAL_StatusTypeDef HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData,
1216                                          uint32_t BlockAdd, uint32_t NumberOfBlocks)
1217 {
1218   SDMMC_DataInitTypeDef config;
1219   uint32_t errorstate;
1220   uint32_t add = BlockAdd;
1221 
1222   if (NULL == pData)
1223   {
1224     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1225     return HAL_ERROR;
1226   }
1227 
1228   if (hmmc->State == HAL_MMC_STATE_READY)
1229   {
1230     hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
1231 
1232     if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1233     {
1234       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1235       return HAL_ERROR;
1236     }
1237 
1238     /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
1239     if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U)
1240     {
1241       if ((NumberOfBlocks % 8U) != 0U)
1242       {
1243         /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */
1244         hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR;
1245         return HAL_ERROR;
1246       }
1247 
1248       if ((BlockAdd % 8U) != 0U)
1249       {
1250         /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
1251         hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
1252         return HAL_ERROR;
1253       }
1254     }
1255 
1256     hmmc->State = HAL_MMC_STATE_BUSY;
1257 
1258     /* Initialize data control register */
1259     hmmc->Instance->DCTRL = 0U;
1260 
1261     hmmc->pRxBuffPtr = pData;
1262     hmmc->RxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1263 
1264     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1265     {
1266       add *= 512U;
1267     }
1268 
1269     /* Configure the MMC DPSM (Data Path State Machine) */
1270     config.DataTimeOut   = SDMMC_DATATIMEOUT;
1271     config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
1272     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1273     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
1274     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
1275     config.DPSM          = SDMMC_DPSM_DISABLE;
1276     (void)SDMMC_ConfigData(hmmc->Instance, &config);
1277 
1278     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
1279     hmmc->Instance->IDMABASE0 = (uint32_t) pData ;
1280     hmmc->Instance->IDMACTRL  = SDMMC_ENABLE_IDMA_SINGLE_BUFF;
1281 
1282     /* Read Blocks in DMA mode */
1283     if (NumberOfBlocks > 1U)
1284     {
1285       hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
1286 
1287       /* Read Multi Block command */
1288       errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
1289     }
1290     else
1291     {
1292       hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_DMA);
1293 
1294       /* Read Single Block command */
1295       errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
1296     }
1297     if (errorstate != HAL_MMC_ERROR_NONE)
1298     {
1299       /* Clear all the static flags */
1300       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1301       hmmc->ErrorCode = errorstate;
1302       hmmc->State = HAL_MMC_STATE_READY;
1303       return HAL_ERROR;
1304     }
1305 
1306     /* Enable transfer interrupts */
1307     __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND));
1308 
1309     return HAL_OK;
1310   }
1311   else
1312   {
1313     return HAL_BUSY;
1314   }
1315 }
1316 
1317 /**
1318   * @brief  Writes block(s) to a specified address in a card. The Data transfer
1319   *         is managed by DMA mode.
1320   * @note   This API should be followed by a check on the card state through
1321   *         HAL_MMC_GetCardState().
1322   * @note   You could also check the DMA transfer process through the MMC Tx
1323   *         interrupt event.
1324   * @param  hmmc: Pointer to MMC handle
1325   * @param  pData: Pointer to the buffer that will contain the data to transmit
1326   * @param  BlockAdd: Block Address where data will be written
1327   * @param  NumberOfBlocks: Number of blocks to write
1328   * @retval HAL status
1329   */
HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)1330 HAL_StatusTypeDef HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData,
1331                                           uint32_t BlockAdd, uint32_t NumberOfBlocks)
1332 {
1333   SDMMC_DataInitTypeDef config;
1334   uint32_t errorstate;
1335   uint32_t add = BlockAdd;
1336 
1337   if (NULL == pData)
1338   {
1339     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1340     return HAL_ERROR;
1341   }
1342 
1343   if (hmmc->State == HAL_MMC_STATE_READY)
1344   {
1345     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1346 
1347     if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1348     {
1349       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1350       return HAL_ERROR;
1351     }
1352 
1353     /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
1354     if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U)
1355     {
1356       if ((NumberOfBlocks % 8U) != 0U)
1357       {
1358         /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */
1359         hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR;
1360         return HAL_ERROR;
1361       }
1362 
1363       if ((BlockAdd % 8U) != 0U)
1364       {
1365         /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
1366         hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
1367         return HAL_ERROR;
1368       }
1369     }
1370 
1371     hmmc->State = HAL_MMC_STATE_BUSY;
1372 
1373     /* Initialize data control register */
1374     hmmc->Instance->DCTRL = 0U;
1375 
1376     hmmc->pTxBuffPtr = pData;
1377     hmmc->TxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1378 
1379     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1380     {
1381       add *= 512U;
1382     }
1383 
1384     /* Configure the MMC DPSM (Data Path State Machine) */
1385     config.DataTimeOut   = SDMMC_DATATIMEOUT;
1386     config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
1387     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1388     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
1389     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
1390     config.DPSM          = SDMMC_DPSM_DISABLE;
1391     (void)SDMMC_ConfigData(hmmc->Instance, &config);
1392 
1393     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
1394 
1395     hmmc->Instance->IDMABASE0 = (uint32_t) pData ;
1396     hmmc->Instance->IDMACTRL  = SDMMC_ENABLE_IDMA_SINGLE_BUFF;
1397 
1398     /* Write Blocks in Polling mode */
1399     if (NumberOfBlocks > 1U)
1400     {
1401       hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
1402 
1403       /* Write Multi Block command */
1404       errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
1405     }
1406     else
1407     {
1408       hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_DMA);
1409 
1410       /* Write Single Block command */
1411       errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
1412     }
1413     if (errorstate != HAL_MMC_ERROR_NONE)
1414     {
1415       /* Clear all the static flags */
1416       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1417       hmmc->ErrorCode |= errorstate;
1418       hmmc->State = HAL_MMC_STATE_READY;
1419       return HAL_ERROR;
1420     }
1421 
1422     /* Enable transfer interrupts */
1423     __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND));
1424 
1425     return HAL_OK;
1426   }
1427   else
1428   {
1429     return HAL_BUSY;
1430   }
1431 }
1432 
1433 /**
1434   * @brief  Erases the specified memory area of the given MMC card.
1435   * @note   This API should be followed by a check on the card state through
1436   *         HAL_MMC_GetCardState().
1437   * @param  hmmc: Pointer to MMC handle
1438   * @param  BlockStartAdd: Start Block address
1439   * @param  BlockEndAdd: End Block address
1440   * @retval HAL status
1441   */
HAL_MMC_Erase(MMC_HandleTypeDef * hmmc,uint32_t BlockStartAdd,uint32_t BlockEndAdd)1442 HAL_StatusTypeDef HAL_MMC_Erase(MMC_HandleTypeDef *hmmc, uint32_t BlockStartAdd, uint32_t BlockEndAdd)
1443 {
1444   uint32_t errorstate;
1445   uint32_t start_add = BlockStartAdd;
1446   uint32_t end_add = BlockEndAdd;
1447 
1448   if (hmmc->State == HAL_MMC_STATE_READY)
1449   {
1450     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1451 
1452     if (end_add < start_add)
1453     {
1454       hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1455       return HAL_ERROR;
1456     }
1457 
1458     if (end_add > (hmmc->MmcCard.LogBlockNbr))
1459     {
1460       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1461       return HAL_ERROR;
1462     }
1463 
1464     /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
1465     if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS)
1466          & 0x000000FFU) != 0x0U)
1467     {
1468       if (((start_add % 8U) != 0U) || ((end_add % 8U) != 0U))
1469       {
1470         /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
1471         hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
1472         return HAL_ERROR;
1473       }
1474     }
1475 
1476     hmmc->State = HAL_MMC_STATE_BUSY;
1477 
1478     /* Check if the card command class supports erase command */
1479     if (((hmmc->MmcCard.Class) & SDMMC_CCCC_ERASE) == 0U)
1480     {
1481       /* Clear all the static flags */
1482       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1483       hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
1484       hmmc->State = HAL_MMC_STATE_READY;
1485       return HAL_ERROR;
1486     }
1487 
1488     if ((SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
1489     {
1490       /* Clear all the static flags */
1491       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1492       hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED;
1493       hmmc->State = HAL_MMC_STATE_READY;
1494       return HAL_ERROR;
1495     }
1496 
1497     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1498     {
1499       start_add *= 512U;
1500       end_add   *= 512U;
1501     }
1502 
1503     /* Send CMD35 MMC_ERASE_GRP_START with argument as addr  */
1504     errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, start_add);
1505     if (errorstate != HAL_MMC_ERROR_NONE)
1506     {
1507       /* Clear all the static flags */
1508       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1509       hmmc->ErrorCode |= errorstate;
1510       hmmc->State = HAL_MMC_STATE_READY;
1511       return HAL_ERROR;
1512     }
1513 
1514     /* Send CMD36 MMC_ERASE_GRP_END with argument as addr  */
1515     errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, end_add);
1516     if (errorstate != HAL_MMC_ERROR_NONE)
1517     {
1518       /* Clear all the static flags */
1519       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1520       hmmc->ErrorCode |= errorstate;
1521       hmmc->State = HAL_MMC_STATE_READY;
1522       return HAL_ERROR;
1523     }
1524 
1525     /* Send CMD38 ERASE */
1526     errorstate = SDMMC_CmdErase(hmmc->Instance, 0UL);
1527     if (errorstate != HAL_MMC_ERROR_NONE)
1528     {
1529       /* Clear all the static flags */
1530       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1531       hmmc->ErrorCode |= errorstate;
1532       hmmc->State = HAL_MMC_STATE_READY;
1533       return HAL_ERROR;
1534     }
1535 
1536     hmmc->State = HAL_MMC_STATE_READY;
1537 
1538     return HAL_OK;
1539   }
1540   else
1541   {
1542     return HAL_BUSY;
1543   }
1544 }
1545 
1546 /**
1547   * @brief  This function handles MMC card interrupt request.
1548   * @param  hmmc: Pointer to MMC handle
1549   * @retval None
1550   */
HAL_MMC_IRQHandler(MMC_HandleTypeDef * hmmc)1551 void HAL_MMC_IRQHandler(MMC_HandleTypeDef *hmmc)
1552 {
1553   uint32_t errorstate;
1554   uint32_t context = hmmc->Context;
1555 
1556   /* Check for SDMMC interrupt flags */
1557   if ((__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) != RESET) && ((context & MMC_CONTEXT_IT) != 0U))
1558   {
1559     MMC_Read_IT(hmmc);
1560   }
1561 
1562   else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) != RESET)
1563   {
1564     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_DATAEND);
1565 
1566     __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND  | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | \
1567                          SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR  | SDMMC_IT_TXFIFOHE | \
1568                          SDMMC_IT_RXFIFOHF);
1569 
1570     __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_IDMABTC);
1571     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
1572 
1573     if ((context & MMC_CONTEXT_DMA) != 0U)
1574     {
1575       hmmc->Instance->DLEN = 0;
1576       hmmc->Instance->DCTRL = 0;
1577       hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA ;
1578 
1579       /* Stop Transfer for Write Multi blocks or Read Multi blocks */
1580       if (((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
1581       {
1582         errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
1583         if (errorstate != HAL_MMC_ERROR_NONE)
1584         {
1585           hmmc->ErrorCode |= errorstate;
1586 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1587           hmmc->ErrorCallback(hmmc);
1588 #else
1589           HAL_MMC_ErrorCallback(hmmc);
1590 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1591         }
1592       }
1593 
1594       /* Clear all the static flags */
1595       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
1596 
1597       hmmc->State = HAL_MMC_STATE_READY;
1598       if (((context & MMC_CONTEXT_WRITE_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
1599       {
1600 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1601         hmmc->TxCpltCallback(hmmc);
1602 #else
1603         HAL_MMC_TxCpltCallback(hmmc);
1604 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1605       }
1606       if (((context & MMC_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
1607       {
1608 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1609         hmmc->RxCpltCallback(hmmc);
1610 #else
1611         HAL_MMC_RxCpltCallback(hmmc);
1612 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1613       }
1614     }
1615     else if ((context & MMC_CONTEXT_IT) != 0U)
1616     {
1617       /* Stop Transfer for Write Multi blocks or Read Multi blocks */
1618       if (((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
1619       {
1620         errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
1621         if (errorstate != HAL_MMC_ERROR_NONE)
1622         {
1623           hmmc->ErrorCode |= errorstate;
1624 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1625           hmmc->ErrorCallback(hmmc);
1626 #else
1627           HAL_MMC_ErrorCallback(hmmc);
1628 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1629         }
1630       }
1631 
1632       /* Clear all the static flags */
1633       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
1634 
1635       hmmc->State = HAL_MMC_STATE_READY;
1636       if (((context & MMC_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
1637       {
1638 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1639         hmmc->RxCpltCallback(hmmc);
1640 #else
1641         HAL_MMC_RxCpltCallback(hmmc);
1642 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1643       }
1644       else
1645       {
1646 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1647         hmmc->TxCpltCallback(hmmc);
1648 #else
1649         HAL_MMC_TxCpltCallback(hmmc);
1650 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1651       }
1652     }
1653     else
1654     {
1655       /* Nothing to do */
1656     }
1657   }
1658 
1659   else if ((__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) != RESET) && ((context & MMC_CONTEXT_IT) != 0U))
1660   {
1661     MMC_Write_IT(hmmc);
1662   }
1663 
1664   else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL |
1665                               SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_RXOVERR | SDMMC_FLAG_TXUNDERR) != RESET)
1666   {
1667     /* Set Error code */
1668     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_DCRCFAIL) != RESET)
1669     {
1670       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
1671     }
1672     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_DTIMEOUT) != RESET)
1673     {
1674       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
1675     }
1676     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_RXOVERR) != RESET)
1677     {
1678       hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
1679     }
1680     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_TXUNDERR) != RESET)
1681     {
1682       hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
1683     }
1684 
1685     /* Clear All flags */
1686     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
1687 
1688     /* Disable all interrupts */
1689     __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | \
1690                          SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR);
1691 
1692     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
1693     hmmc->Instance->DCTRL |= SDMMC_DCTRL_FIFORST;
1694     hmmc->Instance->CMD |= SDMMC_CMD_CMDSTOP;
1695     hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
1696     hmmc->Instance->CMD &= ~(SDMMC_CMD_CMDSTOP);
1697     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_DABORT);
1698 
1699     if ((context & MMC_CONTEXT_IT) != 0U)
1700     {
1701       /* Set the MMC state to ready to be able to start again the process */
1702       hmmc->State = HAL_MMC_STATE_READY;
1703 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1704       hmmc->ErrorCallback(hmmc);
1705 #else
1706       HAL_MMC_ErrorCallback(hmmc);
1707 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1708     }
1709     else if ((context & MMC_CONTEXT_DMA) != 0U)
1710     {
1711       if (hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
1712       {
1713         /* Disable Internal DMA */
1714         __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_IDMABTC);
1715         hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA;
1716 
1717         /* Set the MMC state to ready to be able to start again the process */
1718         hmmc->State = HAL_MMC_STATE_READY;
1719 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1720         hmmc->ErrorCallback(hmmc);
1721 #else
1722         HAL_MMC_ErrorCallback(hmmc);
1723 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1724       }
1725     }
1726     else
1727     {
1728       /* Nothing to do */
1729     }
1730   }
1731 
1732   else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_IDMABTC) != RESET)
1733   {
1734     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_IT_IDMABTC);
1735     if (READ_BIT(hmmc->Instance->IDMACTRL, SDMMC_IDMA_IDMABACT) == 0U)
1736     {
1737       /* Current buffer is buffer0, Transfer complete for buffer1 */
1738       if ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)
1739       {
1740 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1741         hmmc->Write_DMADblBuf1CpltCallback(hmmc);
1742 #else
1743         HAL_MMCEx_Write_DMADoubleBuf1CpltCallback(hmmc);
1744 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1745       }
1746       else /* MMC_CONTEXT_READ_MULTIPLE_BLOCK */
1747       {
1748 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1749         hmmc->Read_DMADblBuf1CpltCallback(hmmc);
1750 #else
1751         HAL_MMCEx_Read_DMADoubleBuf1CpltCallback(hmmc);
1752 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1753       }
1754     }
1755     else /* MMC_DMA_BUFFER1 */
1756     {
1757       /* Current buffer is buffer1, Transfer complete for buffer0 */
1758       if ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)
1759       {
1760 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1761         hmmc->Write_DMADblBuf0CpltCallback(hmmc);
1762 #else
1763         HAL_MMCEx_Write_DMADoubleBuf0CpltCallback(hmmc);
1764 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1765       }
1766       else /* MMC_CONTEXT_READ_MULTIPLE_BLOCK */
1767       {
1768 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1769         hmmc->Read_DMADblBuf0CpltCallback(hmmc);
1770 #else
1771         HAL_MMCEx_Read_DMADoubleBuf0CpltCallback(hmmc);
1772 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1773       }
1774     }
1775   }
1776 
1777   else
1778   {
1779     /* Nothing to do */
1780   }
1781 }
1782 
1783 /**
1784   * @brief return the MMC state
1785   * @param hmmc: Pointer to mmc handle
1786   * @retval HAL state
1787   */
HAL_MMC_GetState(MMC_HandleTypeDef * hmmc)1788 HAL_MMC_StateTypeDef HAL_MMC_GetState(MMC_HandleTypeDef *hmmc)
1789 {
1790   return hmmc->State;
1791 }
1792 
1793 /**
1794   * @brief  Return the MMC error code
1795   * @param  hmmc : Pointer to a MMC_HandleTypeDef structure that contains
1796   *              the configuration information.
1797   * @retval MMC Error Code
1798   */
HAL_MMC_GetError(MMC_HandleTypeDef * hmmc)1799 uint32_t HAL_MMC_GetError(MMC_HandleTypeDef *hmmc)
1800 {
1801   return hmmc->ErrorCode;
1802 }
1803 
1804 /**
1805   * @brief Tx Transfer completed callbacks
1806   * @param hmmc: Pointer to MMC handle
1807   * @retval None
1808   */
HAL_MMC_TxCpltCallback(MMC_HandleTypeDef * hmmc)1809 __weak void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef *hmmc)
1810 {
1811   /* Prevent unused argument(s) compilation warning */
1812   UNUSED(hmmc);
1813 
1814   /* NOTE : This function should not be modified, when the callback is needed,
1815             the HAL_MMC_TxCpltCallback can be implemented in the user file
1816    */
1817 }
1818 
1819 /**
1820   * @brief Rx Transfer completed callbacks
1821   * @param hmmc: Pointer MMC handle
1822   * @retval None
1823   */
HAL_MMC_RxCpltCallback(MMC_HandleTypeDef * hmmc)1824 __weak void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef *hmmc)
1825 {
1826   /* Prevent unused argument(s) compilation warning */
1827   UNUSED(hmmc);
1828 
1829   /* NOTE : This function should not be modified, when the callback is needed,
1830             the HAL_MMC_RxCpltCallback can be implemented in the user file
1831    */
1832 }
1833 
1834 /**
1835   * @brief MMC error callbacks
1836   * @param hmmc: Pointer MMC handle
1837   * @retval None
1838   */
HAL_MMC_ErrorCallback(MMC_HandleTypeDef * hmmc)1839 __weak void HAL_MMC_ErrorCallback(MMC_HandleTypeDef *hmmc)
1840 {
1841   /* Prevent unused argument(s) compilation warning */
1842   UNUSED(hmmc);
1843 
1844   /* NOTE : This function should not be modified, when the callback is needed,
1845             the HAL_MMC_ErrorCallback can be implemented in the user file
1846    */
1847 }
1848 
1849 /**
1850   * @brief MMC Abort callbacks
1851   * @param hmmc: Pointer MMC handle
1852   * @retval None
1853   */
HAL_MMC_AbortCallback(MMC_HandleTypeDef * hmmc)1854 __weak void HAL_MMC_AbortCallback(MMC_HandleTypeDef *hmmc)
1855 {
1856   /* Prevent unused argument(s) compilation warning */
1857   UNUSED(hmmc);
1858 
1859   /* NOTE : This function should not be modified, when the callback is needed,
1860             the HAL_MMC_AbortCallback can be implemented in the user file
1861    */
1862 }
1863 
1864 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1865 /**
1866   * @brief  Register a User MMC Callback
1867   *         To be used instead of the weak (surcharged) predefined callback
1868   * @param hmmc : MMC handle
1869   * @param CallbackId : ID of the callback to be registered
1870   *        This parameter can be one of the following values:
1871   *          @arg @ref HAL_MMC_TX_CPLT_CB_ID                 MMC Tx Complete Callback ID
1872   *          @arg @ref HAL_MMC_RX_CPLT_CB_ID                 MMC Rx Complete Callback ID
1873   *          @arg @ref HAL_MMC_ERROR_CB_ID                   MMC Error Callback ID
1874   *          @arg @ref HAL_MMC_ABORT_CB_ID                   MMC Abort Callback ID
1875   *          @arg @ref HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID  MMC DMA Rx Double buffer 0 Callback ID
1876   *          @arg @ref HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID  MMC DMA Rx Double buffer 1 Callback ID
1877   *          @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID MMC DMA Tx Double buffer 0 Callback ID
1878   *          @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID MMC DMA Tx Double buffer 1 Callback ID
1879   *          @arg @ref HAL_MMC_MSP_INIT_CB_ID                MMC MspInit Callback ID
1880   *          @arg @ref HAL_MMC_MSP_DEINIT_CB_ID              MMC MspDeInit Callback ID
1881   * @param pCallback : pointer to the Callback function
1882   * @retval status
1883   */
HAL_MMC_RegisterCallback(MMC_HandleTypeDef * hmmc,HAL_MMC_CallbackIDTypeDef CallbackId,pMMC_CallbackTypeDef pCallback)1884 HAL_StatusTypeDef HAL_MMC_RegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId,
1885                                            pMMC_CallbackTypeDef pCallback)
1886 {
1887   HAL_StatusTypeDef status = HAL_OK;
1888 
1889   if (pCallback == NULL)
1890   {
1891     /* Update the error code */
1892     hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1893     return HAL_ERROR;
1894   }
1895 
1896   /* Process locked */
1897   __HAL_LOCK(hmmc);
1898 
1899   if (hmmc->State == HAL_MMC_STATE_READY)
1900   {
1901     switch (CallbackId)
1902     {
1903       case HAL_MMC_TX_CPLT_CB_ID :
1904         hmmc->TxCpltCallback = pCallback;
1905         break;
1906       case HAL_MMC_RX_CPLT_CB_ID :
1907         hmmc->RxCpltCallback = pCallback;
1908         break;
1909       case HAL_MMC_ERROR_CB_ID :
1910         hmmc->ErrorCallback = pCallback;
1911         break;
1912       case HAL_MMC_ABORT_CB_ID :
1913         hmmc->AbortCpltCallback = pCallback;
1914         break;
1915       case HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID :
1916         hmmc->Read_DMADblBuf0CpltCallback = pCallback;
1917         break;
1918       case HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID :
1919         hmmc->Read_DMADblBuf1CpltCallback = pCallback;
1920         break;
1921       case HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID :
1922         hmmc->Write_DMADblBuf0CpltCallback = pCallback;
1923         break;
1924       case HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID :
1925         hmmc->Write_DMADblBuf1CpltCallback = pCallback;
1926         break;
1927       case HAL_MMC_MSP_INIT_CB_ID :
1928         hmmc->MspInitCallback = pCallback;
1929         break;
1930       case HAL_MMC_MSP_DEINIT_CB_ID :
1931         hmmc->MspDeInitCallback = pCallback;
1932         break;
1933       default :
1934         /* Update the error code */
1935         hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1936         /* update return status */
1937         status =  HAL_ERROR;
1938         break;
1939     }
1940   }
1941   else if (hmmc->State == HAL_MMC_STATE_RESET)
1942   {
1943     switch (CallbackId)
1944     {
1945       case HAL_MMC_MSP_INIT_CB_ID :
1946         hmmc->MspInitCallback = pCallback;
1947         break;
1948       case HAL_MMC_MSP_DEINIT_CB_ID :
1949         hmmc->MspDeInitCallback = pCallback;
1950         break;
1951       default :
1952         /* Update the error code */
1953         hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1954         /* update return status */
1955         status =  HAL_ERROR;
1956         break;
1957     }
1958   }
1959   else
1960   {
1961     /* Update the error code */
1962     hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1963     /* update return status */
1964     status =  HAL_ERROR;
1965   }
1966 
1967   /* Release Lock */
1968   __HAL_UNLOCK(hmmc);
1969   return status;
1970 }
1971 
1972 /**
1973   * @brief  Unregister a User MMC Callback
1974   *         MMC Callback is redirected to the weak (surcharged) predefined callback
1975   * @param hmmc : MMC handle
1976   * @param CallbackId : ID of the callback to be unregistered
1977   *        This parameter can be one of the following values:
1978   *          @arg @ref HAL_MMC_TX_CPLT_CB_ID                 MMC Tx Complete Callback ID
1979   *          @arg @ref HAL_MMC_RX_CPLT_CB_ID                 MMC Rx Complete Callback ID
1980   *          @arg @ref HAL_MMC_ERROR_CB_ID                   MMC Error Callback ID
1981   *          @arg @ref HAL_MMC_ABORT_CB_ID                   MMC Abort Callback ID
1982   *          @arg @ref HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID  MMC DMA Rx Double buffer 0 Callback ID
1983   *          @arg @ref HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID  MMC DMA Rx Double buffer 1 Callback ID
1984   *          @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID MMC DMA Tx Double buffer 0 Callback ID
1985   *          @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID MMC DMA Tx Double buffer 1 Callback ID
1986   *          @arg @ref HAL_MMC_MSP_INIT_CB_ID                MMC MspInit Callback ID
1987   *          @arg @ref HAL_MMC_MSP_DEINIT_CB_ID              MMC MspDeInit Callback ID
1988   * @retval status
1989   */
HAL_MMC_UnRegisterCallback(MMC_HandleTypeDef * hmmc,HAL_MMC_CallbackIDTypeDef CallbackId)1990 HAL_StatusTypeDef HAL_MMC_UnRegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId)
1991 {
1992   HAL_StatusTypeDef status = HAL_OK;
1993 
1994   /* Process locked */
1995   __HAL_LOCK(hmmc);
1996 
1997   if (hmmc->State == HAL_MMC_STATE_READY)
1998   {
1999     switch (CallbackId)
2000     {
2001       case HAL_MMC_TX_CPLT_CB_ID :
2002         hmmc->TxCpltCallback = HAL_MMC_TxCpltCallback;
2003         break;
2004       case HAL_MMC_RX_CPLT_CB_ID :
2005         hmmc->RxCpltCallback = HAL_MMC_RxCpltCallback;
2006         break;
2007       case HAL_MMC_ERROR_CB_ID :
2008         hmmc->ErrorCallback = HAL_MMC_ErrorCallback;
2009         break;
2010       case HAL_MMC_ABORT_CB_ID :
2011         hmmc->AbortCpltCallback = HAL_MMC_AbortCallback;
2012         break;
2013       case HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID :
2014         hmmc->Read_DMADblBuf0CpltCallback = HAL_MMCEx_Read_DMADoubleBuf0CpltCallback;
2015         break;
2016       case HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID :
2017         hmmc->Read_DMADblBuf1CpltCallback = HAL_MMCEx_Read_DMADoubleBuf1CpltCallback;
2018         break;
2019       case HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID :
2020         hmmc->Write_DMADblBuf0CpltCallback = HAL_MMCEx_Write_DMADoubleBuf0CpltCallback;
2021         break;
2022       case HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID :
2023         hmmc->Write_DMADblBuf1CpltCallback = HAL_MMCEx_Write_DMADoubleBuf1CpltCallback;
2024         break;
2025       case HAL_MMC_MSP_INIT_CB_ID :
2026         hmmc->MspInitCallback = HAL_MMC_MspInit;
2027         break;
2028       case HAL_MMC_MSP_DEINIT_CB_ID :
2029         hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
2030         break;
2031       default :
2032         /* Update the error code */
2033         hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
2034         /* update return status */
2035         status =  HAL_ERROR;
2036         break;
2037     }
2038   }
2039   else if (hmmc->State == HAL_MMC_STATE_RESET)
2040   {
2041     switch (CallbackId)
2042     {
2043       case HAL_MMC_MSP_INIT_CB_ID :
2044         hmmc->MspInitCallback = HAL_MMC_MspInit;
2045         break;
2046       case HAL_MMC_MSP_DEINIT_CB_ID :
2047         hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
2048         break;
2049       default :
2050         /* Update the error code */
2051         hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
2052         /* update return status */
2053         status =  HAL_ERROR;
2054         break;
2055     }
2056   }
2057   else
2058   {
2059     /* Update the error code */
2060     hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
2061     /* update return status */
2062     status =  HAL_ERROR;
2063   }
2064 
2065   /* Release Lock */
2066   __HAL_UNLOCK(hmmc);
2067   return status;
2068 }
2069 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
2070 
2071 /**
2072   * @}
2073   */
2074 
2075 /** @addtogroup MMC_Exported_Functions_Group3
2076   *  @brief   management functions
2077   *
2078 @verbatim
2079   ==============================================================================
2080                       ##### Peripheral Control functions #####
2081   ==============================================================================
2082   [..]
2083     This subsection provides a set of functions allowing to control the MMC card
2084     operations and get the related information
2085 
2086 @endverbatim
2087   * @{
2088   */
2089 
2090 /**
2091   * @brief  Returns information the information of the card which are stored on
2092   *         the CID register.
2093   * @param  hmmc: Pointer to MMC handle
2094   * @param  pCID: Pointer to a HAL_MMC_CIDTypedef structure that
2095   *         contains all CID register parameters
2096   * @retval HAL status
2097   */
HAL_MMC_GetCardCID(MMC_HandleTypeDef * hmmc,HAL_MMC_CardCIDTypeDef * pCID)2098 HAL_StatusTypeDef HAL_MMC_GetCardCID(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCIDTypeDef *pCID)
2099 {
2100   pCID->ManufacturerID = (uint8_t)((hmmc->CID[0] & 0xFF000000U) >> 24U);
2101 
2102   pCID->OEM_AppliID = (uint16_t)((hmmc->CID[0] & 0x00FFFF00U) >> 8U);
2103 
2104   pCID->ProdName1 = (((hmmc->CID[0] & 0x000000FFU) << 24U) | ((hmmc->CID[1] & 0xFFFFFF00U) >> 8U));
2105 
2106   pCID->ProdName2 = (uint8_t)(hmmc->CID[1] & 0x000000FFU);
2107 
2108   pCID->ProdRev = (uint8_t)((hmmc->CID[2] & 0xFF000000U) >> 24U);
2109 
2110   pCID->ProdSN = (((hmmc->CID[2] & 0x00FFFFFFU) << 8U) | ((hmmc->CID[3] & 0xFF000000U) >> 24U));
2111 
2112   pCID->Reserved1 = (uint8_t)((hmmc->CID[3] & 0x00F00000U) >> 20U);
2113 
2114   pCID->ManufactDate = (uint16_t)((hmmc->CID[3] & 0x000FFF00U) >> 8U);
2115 
2116   pCID->CID_CRC = (uint8_t)((hmmc->CID[3] & 0x000000FEU) >> 1U);
2117 
2118   pCID->Reserved2 = 1U;
2119 
2120   return HAL_OK;
2121 }
2122 
2123 /**
2124   * @brief  Returns information the information of the card which are stored on
2125   *         the CSD register.
2126   * @param  hmmc: Pointer to MMC handle
2127   * @param  pCSD: Pointer to a HAL_MMC_CardCSDTypeDef structure that
2128   *         contains all CSD register parameters
2129   * @retval HAL status
2130   */
HAL_MMC_GetCardCSD(MMC_HandleTypeDef * hmmc,HAL_MMC_CardCSDTypeDef * pCSD)2131 HAL_StatusTypeDef HAL_MMC_GetCardCSD(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCSDTypeDef *pCSD)
2132 {
2133   uint32_t block_nbr = 0;
2134 
2135   pCSD->CSDStruct = (uint8_t)((hmmc->CSD[0] & 0xC0000000U) >> 30U);
2136 
2137   pCSD->SysSpecVersion = (uint8_t)((hmmc->CSD[0] & 0x3C000000U) >> 26U);
2138 
2139   pCSD->Reserved1 = (uint8_t)((hmmc->CSD[0] & 0x03000000U) >> 24U);
2140 
2141   pCSD->TAAC = (uint8_t)((hmmc->CSD[0] & 0x00FF0000U) >> 16U);
2142 
2143   pCSD->NSAC = (uint8_t)((hmmc->CSD[0] & 0x0000FF00U) >> 8U);
2144 
2145   pCSD->MaxBusClkFrec = (uint8_t)(hmmc->CSD[0] & 0x000000FFU);
2146 
2147   pCSD->CardComdClasses = (uint16_t)((hmmc->CSD[1] & 0xFFF00000U) >> 20U);
2148 
2149   pCSD->RdBlockLen = (uint8_t)((hmmc->CSD[1] & 0x000F0000U) >> 16U);
2150 
2151   pCSD->PartBlockRead   = (uint8_t)((hmmc->CSD[1] & 0x00008000U) >> 15U);
2152 
2153   pCSD->WrBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00004000U) >> 14U);
2154 
2155   pCSD->RdBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00002000U) >> 13U);
2156 
2157   pCSD->DSRImpl = (uint8_t)((hmmc->CSD[1] & 0x00001000U) >> 12U);
2158 
2159   pCSD->Reserved2 = 0U; /*!< Reserved */
2160 
2161   if (MMC_ReadExtCSD(hmmc, &block_nbr, 212, 0x0FFFFFFFU) != HAL_OK) /* Field SEC_COUNT [215:212] */
2162   {
2163     return HAL_ERROR;
2164   }
2165 
2166   if (hmmc->MmcCard.CardType == MMC_LOW_CAPACITY_CARD)
2167   {
2168     pCSD->DeviceSize = (((hmmc->CSD[1] & 0x000003FFU) << 2U) | ((hmmc->CSD[2] & 0xC0000000U) >> 30U));
2169 
2170     pCSD->MaxRdCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x38000000U) >> 27U);
2171 
2172     pCSD->MaxRdCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x07000000U) >> 24U);
2173 
2174     pCSD->MaxWrCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x00E00000U) >> 21U);
2175 
2176     pCSD->MaxWrCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x001C0000U) >> 18U);
2177 
2178     pCSD->DeviceSizeMul = (uint8_t)((hmmc->CSD[2] & 0x00038000U) >> 15U);
2179 
2180     hmmc->MmcCard.BlockNbr  = (pCSD->DeviceSize + 1U) ;
2181     hmmc->MmcCard.BlockNbr *= (1UL << ((pCSD->DeviceSizeMul & 0x07U) + 2U));
2182     hmmc->MmcCard.BlockSize = (1UL << (pCSD->RdBlockLen & 0x0FU));
2183 
2184     hmmc->MmcCard.LogBlockNbr = (hmmc->MmcCard.BlockNbr) * ((hmmc->MmcCard.BlockSize) / 512U);
2185     hmmc->MmcCard.LogBlockSize = 512U;
2186   }
2187   else if (hmmc->MmcCard.CardType == MMC_HIGH_CAPACITY_CARD)
2188   {
2189     hmmc->MmcCard.BlockNbr = block_nbr;
2190     hmmc->MmcCard.LogBlockNbr = hmmc->MmcCard.BlockNbr;
2191     hmmc->MmcCard.BlockSize = 512U;
2192     hmmc->MmcCard.LogBlockSize = hmmc->MmcCard.BlockSize;
2193   }
2194   else
2195   {
2196     /* Clear all the static flags */
2197     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2198     hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2199     hmmc->State = HAL_MMC_STATE_READY;
2200     return HAL_ERROR;
2201   }
2202 
2203   pCSD->EraseGrSize = (uint8_t)((hmmc->CSD[2] & 0x00004000U) >> 14U);
2204 
2205   pCSD->EraseGrMul = (uint8_t)((hmmc->CSD[2] & 0x00003F80U) >> 7U);
2206 
2207   pCSD->WrProtectGrSize = (uint8_t)(hmmc->CSD[2] & 0x0000007FU);
2208 
2209   pCSD->WrProtectGrEnable = (uint8_t)((hmmc->CSD[3] & 0x80000000U) >> 31U);
2210 
2211   pCSD->ManDeflECC = (uint8_t)((hmmc->CSD[3] & 0x60000000U) >> 29U);
2212 
2213   pCSD->WrSpeedFact = (uint8_t)((hmmc->CSD[3] & 0x1C000000U) >> 26U);
2214 
2215   pCSD->MaxWrBlockLen = (uint8_t)((hmmc->CSD[3] & 0x03C00000U) >> 22U);
2216 
2217   pCSD->WriteBlockPaPartial = (uint8_t)((hmmc->CSD[3] & 0x00200000U) >> 21U);
2218 
2219   pCSD->Reserved3 = 0;
2220 
2221   pCSD->ContentProtectAppli = (uint8_t)((hmmc->CSD[3] & 0x00010000U) >> 16U);
2222 
2223   pCSD->FileFormatGroup = (uint8_t)((hmmc->CSD[3] & 0x00008000U) >> 15U);
2224 
2225   pCSD->CopyFlag = (uint8_t)((hmmc->CSD[3] & 0x00004000U) >> 14U);
2226 
2227   pCSD->PermWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00002000U) >> 13U);
2228 
2229   pCSD->TempWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00001000U) >> 12U);
2230 
2231   pCSD->FileFormat = (uint8_t)((hmmc->CSD[3] & 0x00000C00U) >> 10U);
2232 
2233   pCSD->ECC = (uint8_t)((hmmc->CSD[3] & 0x00000300U) >> 8U);
2234 
2235   pCSD->CSD_CRC = (uint8_t)((hmmc->CSD[3] & 0x000000FEU) >> 1U);
2236 
2237   pCSD->Reserved4 = 1;
2238 
2239   return HAL_OK;
2240 }
2241 
2242 /**
2243   * @brief  Gets the MMC card info.
2244   * @param  hmmc: Pointer to MMC handle
2245   * @param  pCardInfo: Pointer to the HAL_MMC_CardInfoTypeDef structure that
2246   *         will contain the MMC card status information
2247   * @retval HAL status
2248   */
HAL_MMC_GetCardInfo(MMC_HandleTypeDef * hmmc,HAL_MMC_CardInfoTypeDef * pCardInfo)2249 HAL_StatusTypeDef HAL_MMC_GetCardInfo(MMC_HandleTypeDef *hmmc, HAL_MMC_CardInfoTypeDef *pCardInfo)
2250 {
2251   pCardInfo->CardType     = (uint32_t)(hmmc->MmcCard.CardType);
2252   pCardInfo->Class        = (uint32_t)(hmmc->MmcCard.Class);
2253   pCardInfo->RelCardAdd   = (uint32_t)(hmmc->MmcCard.RelCardAdd);
2254   pCardInfo->BlockNbr     = (uint32_t)(hmmc->MmcCard.BlockNbr);
2255   pCardInfo->BlockSize    = (uint32_t)(hmmc->MmcCard.BlockSize);
2256   pCardInfo->LogBlockNbr  = (uint32_t)(hmmc->MmcCard.LogBlockNbr);
2257   pCardInfo->LogBlockSize = (uint32_t)(hmmc->MmcCard.LogBlockSize);
2258 
2259   return HAL_OK;
2260 }
2261 
2262 /**
2263   * @brief  Returns information the information of the card which are stored on
2264   *         the Extended CSD register.
2265   * @param  hmmc Pointer to MMC handle
2266   * @param  pExtCSD Pointer to a memory area (512 bytes) that contains all
2267   *         Extended CSD register parameters
2268   * @param  Timeout Specify timeout value
2269   * @retval HAL status
2270   */
HAL_MMC_GetCardExtCSD(MMC_HandleTypeDef * hmmc,uint32_t * pExtCSD,uint32_t Timeout)2271 HAL_StatusTypeDef HAL_MMC_GetCardExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pExtCSD, uint32_t Timeout)
2272 {
2273   SDMMC_DataInitTypeDef config;
2274   uint32_t errorstate;
2275   uint32_t tickstart = HAL_GetTick();
2276   uint32_t count;
2277   uint32_t *tmp_buf;
2278 
2279   if (NULL == pExtCSD)
2280   {
2281     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
2282     return HAL_ERROR;
2283   }
2284 
2285   if (hmmc->State == HAL_MMC_STATE_READY)
2286   {
2287     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
2288 
2289     hmmc->State = HAL_MMC_STATE_BUSY;
2290 
2291     /* Initialize data control register */
2292     hmmc->Instance->DCTRL = 0;
2293 
2294     /* Initiaize the destination pointer */
2295     tmp_buf = pExtCSD;
2296 
2297     /* Configure the MMC DPSM (Data Path State Machine) */
2298     config.DataTimeOut   = SDMMC_DATATIMEOUT;
2299     config.DataLength    = 512U;
2300     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
2301     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
2302     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
2303     config.DPSM          = SDMMC_DPSM_DISABLE;
2304     (void)SDMMC_ConfigData(hmmc->Instance, &config);
2305     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
2306 
2307     /* Send ExtCSD Read command to Card */
2308     errorstate = SDMMC_CmdSendEXTCSD(hmmc->Instance, 0);
2309     if (errorstate != HAL_MMC_ERROR_NONE)
2310     {
2311       /* Clear all the static flags */
2312       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2313       hmmc->ErrorCode |= errorstate;
2314       hmmc->State = HAL_MMC_STATE_READY;
2315       return HAL_ERROR;
2316     }
2317 
2318     /* Poll on SDMMC flags */
2319     while (!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR |
2320                                SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
2321     {
2322       if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF))
2323       {
2324         /* Read data from SDMMC Rx FIFO */
2325         for (count = 0U; count < 8U; count++)
2326         {
2327           *tmp_buf = SDMMC_ReadFIFO(hmmc->Instance);
2328           tmp_buf++;
2329         }
2330       }
2331 
2332       if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
2333       {
2334         /* Clear all the static flags */
2335         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2336         hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
2337         hmmc->State = HAL_MMC_STATE_READY;
2338         return HAL_TIMEOUT;
2339       }
2340     }
2341 
2342     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
2343 
2344     /* Get error state */
2345     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
2346     {
2347       /* Clear all the static flags */
2348       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2349       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
2350       hmmc->State = HAL_MMC_STATE_READY;
2351       return HAL_ERROR;
2352     }
2353     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
2354     {
2355       /* Clear all the static flags */
2356       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2357       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
2358       hmmc->State = HAL_MMC_STATE_READY;
2359       return HAL_ERROR;
2360     }
2361     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR))
2362     {
2363       /* Clear all the static flags */
2364       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2365       hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
2366       hmmc->State = HAL_MMC_STATE_READY;
2367       return HAL_ERROR;
2368     }
2369     else
2370     {
2371       /* Nothing to do */
2372     }
2373 
2374     /* Clear all the static flags */
2375     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2376     hmmc->State = HAL_MMC_STATE_READY;
2377   }
2378 
2379   return HAL_OK;
2380 }
2381 
2382 /**
2383   * @brief  Enables wide bus operation for the requested card if supported by
2384   *         card.
2385   * @param  hmmc: Pointer to MMC handle
2386   * @param  WideMode: Specifies the MMC card wide bus mode
2387   *          This parameter can be one of the following values:
2388   *            @arg SDMMC_BUS_WIDE_8B: 8-bit data transfer
2389   *            @arg SDMMC_BUS_WIDE_4B: 4-bit data transfer
2390   *            @arg SDMMC_BUS_WIDE_1B: 1-bit data transfer
2391   * @retval HAL status
2392   */
HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef * hmmc,uint32_t WideMode)2393 HAL_StatusTypeDef HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef *hmmc, uint32_t WideMode)
2394 {
2395   uint32_t count;
2396   SDMMC_InitTypeDef Init;
2397   uint32_t errorstate;
2398   uint32_t response = 0U;
2399 
2400   /* Check the parameters */
2401   assert_param(IS_SDMMC_BUS_WIDE(WideMode));
2402 
2403   /* Change State */
2404   hmmc->State = HAL_MMC_STATE_BUSY;
2405 
2406   /* Check and update the power class if needed */
2407   if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) != 0U)
2408   {
2409     if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) != 0U)
2410     {
2411       errorstate = MMC_PwrClassUpdate(hmmc, WideMode, SDMMC_SPEED_MODE_DDR);
2412     }
2413     else
2414     {
2415       errorstate = MMC_PwrClassUpdate(hmmc, WideMode, SDMMC_SPEED_MODE_HIGH);
2416     }
2417   }
2418   else
2419   {
2420     errorstate = MMC_PwrClassUpdate(hmmc, WideMode, SDMMC_SPEED_MODE_DEFAULT);
2421   }
2422 
2423   if (errorstate == HAL_MMC_ERROR_NONE)
2424   {
2425     if (WideMode == SDMMC_BUS_WIDE_8B)
2426     {
2427       errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U);
2428     }
2429     else if (WideMode == SDMMC_BUS_WIDE_4B)
2430     {
2431       errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U);
2432     }
2433     else if (WideMode == SDMMC_BUS_WIDE_1B)
2434     {
2435       errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70000U);
2436     }
2437     else
2438     {
2439       /* WideMode is not a valid argument*/
2440       errorstate = HAL_MMC_ERROR_PARAM;
2441     }
2442 
2443     /* Check for switch error and violation of the trial number of sending CMD 13 */
2444     if (errorstate == HAL_MMC_ERROR_NONE)
2445     {
2446       /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2447       count = SDMMC_MAX_TRIAL;
2448       do
2449       {
2450         errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2451         if (errorstate != HAL_MMC_ERROR_NONE)
2452         {
2453           break;
2454         }
2455 
2456         /* Get command response */
2457         response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
2458         count--;
2459       } while (((response & 0x100U) == 0U) && (count != 0U));
2460 
2461       /* Check the status after the switch command execution */
2462       if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
2463       {
2464         /* Check the bit SWITCH_ERROR of the device status */
2465         if ((response & 0x80U) != 0U)
2466         {
2467           errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
2468         }
2469         else
2470         {
2471           /* Configure the SDMMC peripheral */
2472           Init = hmmc->Init;
2473           Init.BusWide = WideMode;
2474           (void)SDMMC_Init(hmmc->Instance, Init);
2475         }
2476       }
2477       else if (count == 0U)
2478       {
2479         errorstate = SDMMC_ERROR_TIMEOUT;
2480       }
2481       else
2482       {
2483         /* Nothing to do */
2484       }
2485     }
2486   }
2487 
2488   /* Change State */
2489   hmmc->State = HAL_MMC_STATE_READY;
2490 
2491   if (errorstate != HAL_MMC_ERROR_NONE)
2492   {
2493     /* Clear all the static flags */
2494     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2495     hmmc->ErrorCode |= errorstate;
2496     return HAL_ERROR;
2497   }
2498 
2499   return HAL_OK;
2500 }
2501 
2502 /**
2503   * @brief  Configure the speed bus mode
2504   * @param  hmmc: Pointer to the MMC handle
2505   * @param  SpeedMode: Specifies the MMC card speed bus mode
2506   *          This parameter can be one of the following values:
2507   *            @arg SDMMC_SPEED_MODE_AUTO: Max speed mode supported by the card
2508   *            @arg SDMMC_SPEED_MODE_DEFAULT: Default Speed (MMC @ 26MHz)
2509   *            @arg SDMMC_SPEED_MODE_HIGH: High Speed (MMC @ 52 MHz)
2510   *            @arg SDMMC_SPEED_MODE_DDR: High Speed DDR (MMC DDR @ 52 MHz)
2511   * @retval HAL status
2512   */
2513 
HAL_MMC_ConfigSpeedBusOperation(MMC_HandleTypeDef * hmmc,uint32_t SpeedMode)2514 HAL_StatusTypeDef HAL_MMC_ConfigSpeedBusOperation(MMC_HandleTypeDef *hmmc, uint32_t SpeedMode)
2515 {
2516   uint32_t tickstart;
2517   HAL_StatusTypeDef status = HAL_OK;
2518   uint32_t device_type;
2519   uint32_t errorstate;
2520 
2521   /* Check the parameters */
2522   assert_param(IS_SDMMC_SPEED_MODE(SpeedMode));
2523 
2524   /* Change State */
2525   hmmc->State = HAL_MMC_STATE_BUSY;
2526 
2527   /* Field DEVICE_TYPE [196 = 49*4] of Extended CSD register */
2528   device_type = (hmmc->Ext_CSD[49] & 0x000000FFU);
2529 
2530   switch (SpeedMode)
2531   {
2532     case SDMMC_SPEED_MODE_AUTO:
2533     {
2534       if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS) != 0U) && ((device_type & 0x04U) != 0U))
2535       {
2536         /* High Speed DDR mode allowed */
2537         errorstate = MMC_HighSpeed(hmmc, ENABLE);
2538         if (errorstate != HAL_MMC_ERROR_NONE)
2539         {
2540           hmmc->ErrorCode |= errorstate;
2541         }
2542         else
2543         {
2544           if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_CLKDIV) != 0U)
2545           {
2546             /* DDR mode not supported with CLKDIV = 0 */
2547             errorstate = MMC_DDR_Mode(hmmc, ENABLE);
2548             if (errorstate != HAL_MMC_ERROR_NONE)
2549             {
2550               hmmc->ErrorCode |= errorstate;
2551             }
2552           }
2553         }
2554       }
2555       else if ((device_type & 0x02U) != 0U)
2556       {
2557         /* High Speed mode allowed */
2558         errorstate = MMC_HighSpeed(hmmc, ENABLE);
2559         if (errorstate != HAL_MMC_ERROR_NONE)
2560         {
2561           hmmc->ErrorCode |= errorstate;
2562         }
2563       }
2564       else
2565       {
2566         /* Nothing to do : keep current speed */
2567       }
2568       break;
2569     }
2570     case SDMMC_SPEED_MODE_DDR:
2571     {
2572       if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS) != 0U) && ((device_type & 0x04U) != 0U))
2573       {
2574         /* High Speed DDR mode allowed */
2575         errorstate = MMC_HighSpeed(hmmc, ENABLE);
2576         if (errorstate != HAL_MMC_ERROR_NONE)
2577         {
2578           hmmc->ErrorCode |= errorstate;
2579         }
2580         else
2581         {
2582           if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_CLKDIV) != 0U)
2583           {
2584             /* DDR mode not supported with CLKDIV = 0 */
2585             errorstate = MMC_DDR_Mode(hmmc, ENABLE);
2586             if (errorstate != HAL_MMC_ERROR_NONE)
2587             {
2588               hmmc->ErrorCode |= errorstate;
2589             }
2590           }
2591         }
2592       }
2593       else
2594       {
2595         /* High Speed DDR mode not allowed */
2596         hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2597         status = HAL_ERROR;
2598       }
2599       break;
2600     }
2601     case SDMMC_SPEED_MODE_HIGH:
2602     {
2603       if ((device_type & 0x02U) != 0U)
2604       {
2605         /* High Speed mode allowed */
2606         errorstate = MMC_HighSpeed(hmmc, ENABLE);
2607         if (errorstate != HAL_MMC_ERROR_NONE)
2608         {
2609           hmmc->ErrorCode |= errorstate;
2610         }
2611       }
2612       else
2613       {
2614         /* High Speed mode not allowed */
2615         hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2616         status = HAL_ERROR;
2617       }
2618       break;
2619     }
2620     case SDMMC_SPEED_MODE_DEFAULT:
2621     {
2622       if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) != 0U)
2623       {
2624         /* High Speed DDR mode activated */
2625         errorstate = MMC_DDR_Mode(hmmc, DISABLE);
2626         if (errorstate != HAL_MMC_ERROR_NONE)
2627         {
2628           hmmc->ErrorCode |= errorstate;
2629         }
2630       }
2631       if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) != 0U)
2632       {
2633         /* High Speed mode activated */
2634         errorstate = MMC_HighSpeed(hmmc, DISABLE);
2635         if (errorstate != HAL_MMC_ERROR_NONE)
2636         {
2637           hmmc->ErrorCode |= errorstate;
2638         }
2639       }
2640       break;
2641     }
2642     default:
2643       hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
2644       status = HAL_ERROR;
2645       break;
2646   }
2647 
2648   /* Verify that MMC card is ready to use after Speed mode switch*/
2649   tickstart = HAL_GetTick();
2650   while ((HAL_MMC_GetCardState(hmmc) != HAL_MMC_CARD_TRANSFER))
2651   {
2652     if ((HAL_GetTick() - tickstart) >=  SDMMC_DATATIMEOUT)
2653     {
2654       hmmc->ErrorCode = HAL_MMC_ERROR_TIMEOUT;
2655       hmmc->State = HAL_MMC_STATE_READY;
2656       return HAL_TIMEOUT;
2657     }
2658   }
2659 
2660   /* Change State */
2661   hmmc->State = HAL_MMC_STATE_READY;
2662   return status;
2663 }
2664 
2665 /**
2666   * @brief  Gets the current mmc card data state.
2667   * @param  hmmc: pointer to MMC handle
2668   * @retval Card state
2669   */
HAL_MMC_GetCardState(MMC_HandleTypeDef * hmmc)2670 HAL_MMC_CardStateTypeDef HAL_MMC_GetCardState(MMC_HandleTypeDef *hmmc)
2671 {
2672   uint32_t cardstate;
2673   uint32_t errorstate;
2674   uint32_t resp1 = 0U;
2675 
2676   errorstate = MMC_SendStatus(hmmc, &resp1);
2677   if (errorstate != HAL_MMC_ERROR_NONE)
2678   {
2679     hmmc->ErrorCode |= errorstate;
2680   }
2681 
2682   cardstate = ((resp1 >> 9U) & 0x0FU);
2683 
2684   return (HAL_MMC_CardStateTypeDef)cardstate;
2685 }
2686 
2687 /**
2688   * @brief  Abort the current transfer and disable the MMC.
2689   * @param  hmmc: pointer to a MMC_HandleTypeDef structure that contains
2690   *                the configuration information for MMC module.
2691   * @retval HAL status
2692   */
HAL_MMC_Abort(MMC_HandleTypeDef * hmmc)2693 HAL_StatusTypeDef HAL_MMC_Abort(MMC_HandleTypeDef *hmmc)
2694 {
2695   HAL_MMC_CardStateTypeDef CardState;
2696 
2697   /* DIsable All interrupts */
2698   __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | \
2699                        SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR);
2700 
2701   /* Clear All flags */
2702   __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2703 
2704   /* If IDMA Context, disable Internal DMA */
2705   hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA;
2706 
2707   hmmc->State = HAL_MMC_STATE_READY;
2708 
2709   /* Initialize the MMC operation */
2710   hmmc->Context = MMC_CONTEXT_NONE;
2711 
2712   CardState = HAL_MMC_GetCardState(hmmc);
2713   if ((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2714   {
2715     hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
2716   }
2717   if (hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2718   {
2719     return HAL_ERROR;
2720   }
2721   return HAL_OK;
2722 }
2723 
2724 /**
2725   * @brief  Abort the current transfer and disable the MMC (IT mode).
2726   * @param  hmmc: pointer to a MMC_HandleTypeDef structure that contains
2727   *                the configuration information for MMC module.
2728   * @retval HAL status
2729   */
HAL_MMC_Abort_IT(MMC_HandleTypeDef * hmmc)2730 HAL_StatusTypeDef HAL_MMC_Abort_IT(MMC_HandleTypeDef *hmmc)
2731 {
2732   HAL_MMC_CardStateTypeDef CardState;
2733 
2734   /* DIsable All interrupts */
2735   __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | \
2736                        SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR);
2737 
2738   /* If IDMA Context, disable Internal DMA */
2739   hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA;
2740 
2741   /* Clear All flags */
2742   __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2743 
2744   CardState = HAL_MMC_GetCardState(hmmc);
2745   hmmc->State = HAL_MMC_STATE_READY;
2746 
2747   if ((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2748   {
2749     hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
2750   }
2751   if (hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2752   {
2753     return HAL_ERROR;
2754   }
2755   else
2756   {
2757 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2758     hmmc->AbortCpltCallback(hmmc);
2759 #else
2760     HAL_MMC_AbortCallback(hmmc);
2761 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
2762   }
2763 
2764   return HAL_OK;
2765 }
2766 
2767 /**
2768   * @brief  Perform specific commands sequence for the different type of erase.
2769   * @note   This API should be followed by a check on the card state through
2770   *         HAL_MMC_GetCardState().
2771   * @param  hmmc Pointer to MMC handle
2772   * @param  EraseType Specifies the type of erase to be performed
2773   *          This parameter can be one of the following values:
2774   *             @arg HAL_MMC_TRIM Erase the write blocks identified by CMD35 & 36
2775   *             @arg HAL_MMC_ERASE Erase the erase groups identified by CMD35 & 36
2776   *             @arg HAL_MMC_DISCARD Discard the write blocks identified by CMD35 & 36
2777   *             @arg HAL_MMC_SECURE_ERASE Perform a secure purge according SRT on the erase groups identified
2778   *                  by CMD35 & 36
2779   *             @arg HAL_MMC_SECURE_TRIM_STEP1 Mark the write blocks identified by CMD35 & 36 for secure erase
2780   *             @arg HAL_MMC_SECURE_TRIM_STEP2 Perform a secure purge according SRT on the write blocks
2781   *                  previously identified
2782   * @param  BlockStartAdd Start Block address
2783   * @param  BlockEndAdd End Block address
2784   * @retval HAL status
2785   */
HAL_MMC_EraseSequence(MMC_HandleTypeDef * hmmc,uint32_t EraseType,uint32_t BlockStartAdd,uint32_t BlockEndAdd)2786 HAL_StatusTypeDef HAL_MMC_EraseSequence(MMC_HandleTypeDef *hmmc, uint32_t EraseType,
2787                                         uint32_t BlockStartAdd, uint32_t BlockEndAdd)
2788 {
2789   uint32_t errorstate;
2790   uint32_t start_add = BlockStartAdd;
2791   uint32_t end_add = BlockEndAdd;
2792   uint32_t tickstart = HAL_GetTick();
2793 
2794   /* Check the erase type value is correct */
2795   assert_param(IS_MMC_ERASE_TYPE(EraseType));
2796 
2797   /* Check the coherence between start and end address */
2798   if (end_add < start_add)
2799   {
2800     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
2801     return HAL_ERROR;
2802   }
2803 
2804   /* Check that the end address is not out of range of device memory */
2805   if (end_add > (hmmc->MmcCard.LogBlockNbr))
2806   {
2807     hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
2808     return HAL_ERROR;
2809   }
2810 
2811   /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
2812   if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U)
2813   {
2814     if (((start_add % 8U) != 0U) || ((end_add % 8U) != 0U))
2815     {
2816       /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
2817       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
2818       return HAL_ERROR;
2819     }
2820   }
2821 
2822   /* Check if the card command class supports erase command */
2823   if (((hmmc->MmcCard.Class) & SDMMC_CCCC_ERASE) == 0U)
2824   {
2825     hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
2826     return HAL_ERROR;
2827   }
2828 
2829   /* Check the state of the driver */
2830   if (hmmc->State == HAL_MMC_STATE_READY)
2831   {
2832     /* Change State */
2833     hmmc->State = HAL_MMC_STATE_BUSY;
2834 
2835     /* Check that the card is not locked */
2836     if ((SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
2837     {
2838       hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED;
2839       hmmc->State = HAL_MMC_STATE_READY;
2840       return HAL_ERROR;
2841     }
2842 
2843     /* In case of low capacity card, the address is not block number but bytes */
2844     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
2845     {
2846       start_add *= 512U;
2847       end_add   *= 512U;
2848     }
2849 
2850     /* Send CMD35 MMC_ERASE_GRP_START with start address as argument */
2851     errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, start_add);
2852     if (errorstate == HAL_MMC_ERROR_NONE)
2853     {
2854       /* Send CMD36 MMC_ERASE_GRP_END with end address as argument */
2855       errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, end_add);
2856       if (errorstate == HAL_MMC_ERROR_NONE)
2857       {
2858         /* Send CMD38 ERASE with erase type as argument */
2859         errorstate = SDMMC_CmdErase(hmmc->Instance, EraseType);
2860         if (errorstate == HAL_MMC_ERROR_NONE)
2861         {
2862           if ((EraseType == HAL_MMC_SECURE_ERASE) || (EraseType == HAL_MMC_SECURE_TRIM_STEP2))
2863           {
2864             /* Wait that the device is ready by checking the D0 line */
2865             while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
2866             {
2867               if ((HAL_GetTick() - tickstart) >= SDMMC_MAXERASETIMEOUT)
2868               {
2869                 errorstate = HAL_MMC_ERROR_TIMEOUT;
2870               }
2871             }
2872 
2873             /* Clear the flag corresponding to end D0 bus line */
2874             __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
2875           }
2876         }
2877       }
2878     }
2879 
2880     /* Change State */
2881     hmmc->State = HAL_MMC_STATE_READY;
2882 
2883     /* Manage errors */
2884     if (errorstate != HAL_MMC_ERROR_NONE)
2885     {
2886       /* Clear all the static flags */
2887       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2888       hmmc->ErrorCode |= errorstate;
2889 
2890       if (errorstate != HAL_MMC_ERROR_TIMEOUT)
2891       {
2892         return HAL_ERROR;
2893       }
2894       else
2895       {
2896         return HAL_TIMEOUT;
2897       }
2898     }
2899     else
2900     {
2901       return HAL_OK;
2902     }
2903   }
2904   else
2905   {
2906     return HAL_BUSY;
2907   }
2908 }
2909 
2910 /**
2911   * @brief  Perform sanitize operation on the device.
2912   * @note   This API should be followed by a check on the card state through
2913   *         HAL_MMC_GetCardState().
2914   * @param  hmmc Pointer to MMC handle
2915   * @retval HAL status
2916   */
HAL_MMC_Sanitize(MMC_HandleTypeDef * hmmc)2917 HAL_StatusTypeDef HAL_MMC_Sanitize(MMC_HandleTypeDef *hmmc)
2918 {
2919   uint32_t errorstate;
2920   uint32_t response = 0U;
2921   uint32_t count;
2922   uint32_t tickstart = HAL_GetTick();
2923 
2924   /* Check the state of the driver */
2925   if (hmmc->State == HAL_MMC_STATE_READY)
2926   {
2927     /* Change State */
2928     hmmc->State = HAL_MMC_STATE_BUSY;
2929 
2930     /* Index : 165 - Value : 0x01 */
2931     errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03A50100U);
2932     if (errorstate == HAL_MMC_ERROR_NONE)
2933     {
2934       /* Wait that the device is ready by checking the D0 line */
2935       while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
2936       {
2937         if ((HAL_GetTick() - tickstart) >= SDMMC_MAXERASETIMEOUT)
2938         {
2939           errorstate = HAL_MMC_ERROR_TIMEOUT;
2940         }
2941       }
2942 
2943       /* Clear the flag corresponding to end D0 bus line */
2944       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
2945 
2946       if (errorstate == HAL_MMC_ERROR_NONE)
2947       {
2948         /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2949         count = SDMMC_MAX_TRIAL;
2950         do
2951         {
2952           errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2953           if (errorstate != HAL_MMC_ERROR_NONE)
2954           {
2955             break;
2956           }
2957 
2958           /* Get command response */
2959           response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
2960           count--;
2961         } while (((response & 0x100U) == 0U) && (count != 0U));
2962 
2963         /* Check the status after the switch command execution */
2964         if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
2965         {
2966           /* Check the bit SWITCH_ERROR of the device status */
2967           if ((response & 0x80U) != 0U)
2968           {
2969             errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
2970           }
2971         }
2972         else if (count == 0U)
2973         {
2974           errorstate = SDMMC_ERROR_TIMEOUT;
2975         }
2976         else
2977         {
2978           /* Nothing to do */
2979         }
2980       }
2981     }
2982 
2983     /* Change State */
2984     hmmc->State = HAL_MMC_STATE_READY;
2985 
2986     /* Manage errors */
2987     if (errorstate != HAL_MMC_ERROR_NONE)
2988     {
2989       /* Clear all the static flags */
2990       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2991       hmmc->ErrorCode |= errorstate;
2992 
2993       if (errorstate != HAL_MMC_ERROR_TIMEOUT)
2994       {
2995         return HAL_ERROR;
2996       }
2997       else
2998       {
2999         return HAL_TIMEOUT;
3000       }
3001     }
3002     else
3003     {
3004       return HAL_OK;
3005     }
3006   }
3007   else
3008   {
3009     return HAL_BUSY;
3010   }
3011 }
3012 
3013 /**
3014   * @brief  Configure the Secure Removal Type (SRT) in the Extended CSD register.
3015   * @note   This API should be followed by a check on the card state through
3016   *         HAL_MMC_GetCardState().
3017   * @param  hmmc Pointer to MMC handle
3018   * @param  SRTMode Specifies the type of erase to be performed
3019   *          This parameter can be one of the following values:
3020   *            @arg HAL_MMC_SRT_ERASE Information removed by an erase
3021   *            @arg HAL_MMC_SRT_WRITE_CHAR_ERASE Information removed by an overwriting with a character
3022   *                 followed by an erase
3023   *            @arg HAL_MMC_SRT_WRITE_CHAR_COMPL_RANDOM Information removed by an overwriting with a character,
3024   *                 its complement then a random character
3025   *            @arg HAL_MMC_SRT_VENDOR_DEFINED Information removed using a vendor defined
3026   * @retval HAL status
3027   */
HAL_MMC_ConfigSecRemovalType(MMC_HandleTypeDef * hmmc,uint32_t SRTMode)3028 HAL_StatusTypeDef HAL_MMC_ConfigSecRemovalType(MMC_HandleTypeDef *hmmc, uint32_t SRTMode)
3029 {
3030   uint32_t srt;
3031   uint32_t errorstate;
3032   uint32_t response = 0U;
3033   uint32_t count;
3034 
3035   /* Check the erase type value is correct */
3036   assert_param(IS_MMC_SRT_TYPE(SRTMode));
3037 
3038   /* Check the state of the driver */
3039   if (hmmc->State == HAL_MMC_STATE_READY)
3040   {
3041     /* Get the supported values by the device */
3042     if (HAL_MMC_GetSupportedSecRemovalType(hmmc, &srt) == HAL_OK)
3043     {
3044       /* Change State */
3045       hmmc->State = HAL_MMC_STATE_BUSY;
3046 
3047       /* Check the value passed as parameter is supported by the device */
3048       if ((SRTMode & srt) != 0U)
3049       {
3050         /* Index : 16 - Value : SRTMode */
3051         srt |= ((POSITION_VAL(SRTMode)) << 4U);
3052         errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03100000U | (srt << 8U)));
3053         if (errorstate == HAL_MMC_ERROR_NONE)
3054         {
3055           /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3056           count = SDMMC_MAX_TRIAL;
3057           do
3058           {
3059             errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3060             if (errorstate != HAL_MMC_ERROR_NONE)
3061             {
3062               break;
3063             }
3064 
3065             /* Get command response */
3066             response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3067             count--;
3068           } while (((response & 0x100U) == 0U) && (count != 0U));
3069 
3070           /* Check the status after the switch command execution */
3071           if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
3072           {
3073             /* Check the bit SWITCH_ERROR of the device status */
3074             if ((response & 0x80U) != 0U)
3075             {
3076               errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
3077             }
3078           }
3079           else if (count == 0U)
3080           {
3081             errorstate = SDMMC_ERROR_TIMEOUT;
3082           }
3083           else
3084           {
3085             /* Nothing to do */
3086           }
3087         }
3088       }
3089       else
3090       {
3091         errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3092       }
3093 
3094       /* Change State */
3095       hmmc->State = HAL_MMC_STATE_READY;
3096     }
3097     else
3098     {
3099       errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
3100     }
3101 
3102     /* Manage errors */
3103     if (errorstate != HAL_MMC_ERROR_NONE)
3104     {
3105       /* Clear all the static flags */
3106       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3107       hmmc->ErrorCode |= errorstate;
3108       return HAL_ERROR;
3109     }
3110     else
3111     {
3112       return HAL_OK;
3113     }
3114   }
3115   else
3116   {
3117     return HAL_BUSY;
3118   }
3119 }
3120 
3121 /**
3122   * @brief  Gets the supported values of the the Secure Removal Type (SRT).
3123   * @param  hmmc pointer to MMC handle
3124   * @param  SupportedSRT pointer for supported SRT value
3125   *          This parameter is a bit field of the following values:
3126   *            @arg HAL_MMC_SRT_ERASE Information removed by an erase
3127   *            @arg HAL_MMC_SRT_WRITE_CHAR_ERASE Information removed by an overwriting with a character followed
3128   *                  by an erase
3129   *            @arg HAL_MMC_SRT_WRITE_CHAR_COMPL_RANDOM Information removed by an overwriting with a character,
3130   *                 its complement then a random character
3131   *            @arg HAL_MMC_SRT_VENDOR_DEFINED Information removed using a vendor defined
3132   * @retval HAL status
3133   */
HAL_MMC_GetSupportedSecRemovalType(MMC_HandleTypeDef * hmmc,uint32_t * SupportedSRT)3134 HAL_StatusTypeDef HAL_MMC_GetSupportedSecRemovalType(MMC_HandleTypeDef *hmmc, uint32_t *SupportedSRT)
3135 {
3136   /* Check the state of the driver */
3137   if (hmmc->State == HAL_MMC_STATE_READY)
3138   {
3139     /* Change State */
3140     hmmc->State = HAL_MMC_STATE_BUSY;
3141 
3142     /* Read field SECURE_REMOVAL_TYPE [16 = 4*4] of the Extended CSD register */
3143     *SupportedSRT = (hmmc->Ext_CSD[4] & 0x0000000FU); /* Bits [3:0] of field 16 */
3144 
3145     /* Change State */
3146     hmmc->State = HAL_MMC_STATE_READY;
3147 
3148     return HAL_OK;
3149   }
3150   else
3151   {
3152     return HAL_BUSY;
3153   }
3154 }
3155 
3156 /**
3157   * @brief  Switch the device from Standby State to Sleep State.
3158   * @param  hmmc pointer to MMC handle
3159   * @retval HAL status
3160   */
HAL_MMC_SleepDevice(MMC_HandleTypeDef * hmmc)3161 HAL_StatusTypeDef HAL_MMC_SleepDevice(MMC_HandleTypeDef *hmmc)
3162 {
3163   uint32_t errorstate,
3164            sleep_timeout,
3165            timeout,
3166            count,
3167            response = 0U  ;
3168   uint32_t tickstart = HAL_GetTick();
3169 
3170   /* Check the state of the driver */
3171   if (hmmc->State == HAL_MMC_STATE_READY)
3172   {
3173     /* Change State */
3174     hmmc->State = HAL_MMC_STATE_BUSY;
3175 
3176     /* Set the power-off notification to powered-on : Ext_CSD[34] = 1 */
3177     errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03220100U));
3178     if (errorstate == HAL_MMC_ERROR_NONE)
3179     {
3180       /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3181       count = SDMMC_MAX_TRIAL;
3182       do
3183       {
3184         errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3185         if (errorstate != HAL_MMC_ERROR_NONE)
3186         {
3187           break;
3188         }
3189 
3190         /* Get command response */
3191         response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3192         count--;
3193       } while (((response & 0x100U) == 0U) && (count != 0U));
3194 
3195       /* Check the status after the switch command execution */
3196       if (count == 0U)
3197       {
3198         errorstate = SDMMC_ERROR_TIMEOUT;
3199       }
3200       else if (errorstate == HAL_MMC_ERROR_NONE)
3201       {
3202         /* Check the bit SWITCH_ERROR of the device status */
3203         if ((response & 0x80U) != 0U)
3204         {
3205           errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3206         }
3207         else
3208         {
3209           /* Set the power-off notification to sleep notification : Ext_CSD[34] = 4 */
3210           errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03220400U));
3211           if (errorstate == HAL_MMC_ERROR_NONE)
3212           {
3213             /* Field SLEEP_NOTIFICATION_TIME [216] */
3214             sleep_timeout = ((hmmc->Ext_CSD[(MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_INDEX / 4)] >>
3215                               MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_POS) & 0x000000FFU);
3216 
3217             /* Sleep/Awake Timeout = 10us * 2^SLEEP_NOTIFICATION_TIME */
3218             /* In HAL, the tick interrupt occurs each ms */
3219             if ((sleep_timeout == 0U) || (sleep_timeout > 0x17U))
3220             {
3221               sleep_timeout = 0x17U; /* Max register value defined is 0x17 */
3222             }
3223             timeout = (((1UL << sleep_timeout) / 100U) + 1U);
3224 
3225             /* Wait that the device is ready by checking the D0 line */
3226             while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
3227             {
3228               if ((HAL_GetTick() - tickstart) >= timeout)
3229               {
3230                 errorstate = SDMMC_ERROR_TIMEOUT;
3231               }
3232             }
3233 
3234             /* Clear the flag corresponding to end D0 bus line */
3235             __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
3236 
3237             if (errorstate == HAL_MMC_ERROR_NONE)
3238             {
3239               /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3240               count = SDMMC_MAX_TRIAL;
3241               do
3242               {
3243                 errorstate = SDMMC_CmdSendStatus(hmmc->Instance,
3244                                                  (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3245                 if (errorstate != HAL_MMC_ERROR_NONE)
3246                 {
3247                   break;
3248                 }
3249 
3250                 /* Get command response */
3251                 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3252                 count--;
3253               } while (((response & 0x100U) == 0U) && (count != 0U));
3254 
3255               /* Check the status after the switch command execution */
3256               if (count == 0U)
3257               {
3258                 errorstate = SDMMC_ERROR_TIMEOUT;
3259               }
3260               else if (errorstate == HAL_MMC_ERROR_NONE)
3261               {
3262                 /* Check the bit SWITCH_ERROR of the device status */
3263                 if ((response & 0x80U) != 0U)
3264                 {
3265                   errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3266                 }
3267                 else
3268                 {
3269                   /* Switch the device in stand-by mode */
3270                   (void)SDMMC_CmdSelDesel(hmmc->Instance, 0U);
3271 
3272                   /* Field S_A_TIEMOUT [217] */
3273                   sleep_timeout = ((hmmc->Ext_CSD[(MMC_EXT_CSD_S_A_TIMEOUT_INDEX / 4)] >>
3274                                     MMC_EXT_CSD_S_A_TIMEOUT_POS) & 0x000000FFU);
3275 
3276                   /* Sleep/Awake Timeout = 100ns * 2^S_A_TIMEOUT */
3277                   /* In HAL, the tick interrupt occurs each ms */
3278                   if ((sleep_timeout == 0U) || (sleep_timeout > 0x17U))
3279                   {
3280                     sleep_timeout = 0x17U; /* Max register value defined is 0x17 */
3281                   }
3282                   timeout = (((1UL << sleep_timeout) / 10000U) + 1U);
3283 
3284                   if (HAL_MMC_GetCardState(hmmc) == HAL_MMC_CARD_STANDBY)
3285                   {
3286                     /* Send CMD5 CMD_MMC_SLEEP_AWAKE with RCA and SLEEP as argument */
3287                     errorstate = SDMMC_CmdSleepMmc(hmmc->Instance,
3288                                                    ((hmmc->MmcCard.RelCardAdd << 16U) | (0x1U << 15U)));
3289                     if (errorstate == HAL_MMC_ERROR_NONE)
3290                     {
3291                       /* Wait that the device is ready by checking the D0 line */
3292                       while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
3293                       {
3294                         if ((HAL_GetTick() - tickstart) >= timeout)
3295                         {
3296                           errorstate = SDMMC_ERROR_TIMEOUT;
3297                         }
3298                       }
3299 
3300                       /* Clear the flag corresponding to end D0 bus line */
3301                       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
3302                     }
3303                   }
3304                   else
3305                   {
3306                     errorstate = SDMMC_ERROR_REQUEST_NOT_APPLICABLE;
3307                   }
3308                 }
3309               }
3310               else
3311               {
3312                 /* Nothing to do */
3313               }
3314             }
3315           }
3316         }
3317       }
3318       else
3319       {
3320         /* Nothing to do */
3321       }
3322     }
3323 
3324     /* Change State */
3325     hmmc->State = HAL_MMC_STATE_READY;
3326 
3327     /* Manage errors */
3328     if (errorstate != HAL_MMC_ERROR_NONE)
3329     {
3330       /* Clear all the static flags */
3331       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3332       hmmc->ErrorCode |= errorstate;
3333 
3334       if (errorstate != HAL_MMC_ERROR_TIMEOUT)
3335       {
3336         return HAL_ERROR;
3337       }
3338       else
3339       {
3340         return HAL_TIMEOUT;
3341       }
3342     }
3343     else
3344     {
3345       return HAL_OK;
3346     }
3347   }
3348   else
3349   {
3350     return HAL_BUSY;
3351   }
3352 }
3353 
3354 /**
3355   * @brief  Switch the device from Sleep State to Standby State.
3356   * @param  hmmc pointer to MMC handle
3357   * @retval HAL status
3358   */
HAL_MMC_AwakeDevice(MMC_HandleTypeDef * hmmc)3359 HAL_StatusTypeDef HAL_MMC_AwakeDevice(MMC_HandleTypeDef *hmmc)
3360 {
3361   uint32_t errorstate;
3362   uint32_t sleep_timeout;
3363   uint32_t timeout;
3364   uint32_t count;
3365   uint32_t response = 0U;
3366   uint32_t tickstart = HAL_GetTick();
3367 
3368   /* Check the state of the driver */
3369   if (hmmc->State == HAL_MMC_STATE_READY)
3370   {
3371     /* Change State */
3372     hmmc->State = HAL_MMC_STATE_BUSY;
3373 
3374     /* Field S_A_TIEMOUT [217] */
3375     sleep_timeout = ((hmmc->Ext_CSD[(MMC_EXT_CSD_S_A_TIMEOUT_INDEX / 4)] >> MMC_EXT_CSD_S_A_TIMEOUT_POS) &
3376                      0x000000FFU);
3377 
3378     /* Sleep/Awake Timeout = 100ns * 2^S_A_TIMEOUT */
3379     /* In HAL, the tick interrupt occurs each ms */
3380     if ((sleep_timeout == 0U) || (sleep_timeout > 0x17U))
3381     {
3382       sleep_timeout = 0x17U; /* Max register value defined is 0x17 */
3383     }
3384     timeout = (((1UL << sleep_timeout) / 10000U) + 1U);
3385 
3386     /* Send CMD5 CMD_MMC_SLEEP_AWAKE with RCA and AWAKE as argument */
3387     errorstate = SDMMC_CmdSleepMmc(hmmc->Instance, (hmmc->MmcCard.RelCardAdd << 16U));
3388     if (errorstate == HAL_MMC_ERROR_NONE)
3389     {
3390       /* Wait that the device is ready by checking the D0 line */
3391       while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
3392       {
3393         if ((HAL_GetTick() - tickstart) >= timeout)
3394         {
3395           errorstate = SDMMC_ERROR_TIMEOUT;
3396         }
3397       }
3398 
3399       /* Clear the flag corresponding to end D0 bus line */
3400       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
3401 
3402       if (errorstate == HAL_MMC_ERROR_NONE)
3403       {
3404         if (HAL_MMC_GetCardState(hmmc) == HAL_MMC_CARD_STANDBY)
3405         {
3406           /* Switch the device in transfer mode */
3407           errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (hmmc->MmcCard.RelCardAdd << 16U));
3408           if (errorstate == HAL_MMC_ERROR_NONE)
3409           {
3410             if (HAL_MMC_GetCardState(hmmc) == HAL_MMC_CARD_TRANSFER)
3411             {
3412               /* Set the power-off notification to powered-on : Ext_CSD[34] = 1 */
3413               errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03220100U));
3414               if (errorstate == HAL_MMC_ERROR_NONE)
3415               {
3416                 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3417                 count = SDMMC_MAX_TRIAL;
3418                 do
3419                 {
3420                   errorstate = SDMMC_CmdSendStatus(hmmc->Instance,
3421                                                    (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3422                   if (errorstate != HAL_MMC_ERROR_NONE)
3423                   {
3424                     break;
3425                   }
3426 
3427                   /* Get command response */
3428                   response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3429                   count--;
3430                 } while (((response & 0x100U) == 0U) && (count != 0U));
3431 
3432                 /* Check the status after the switch command execution */
3433                 if (count == 0U)
3434                 {
3435                   errorstate = SDMMC_ERROR_TIMEOUT;
3436                 }
3437                 else if (errorstate == HAL_MMC_ERROR_NONE)
3438                 {
3439                   /* Check the bit SWITCH_ERROR of the device status */
3440                   if ((response & 0x80U) != 0U)
3441                   {
3442                     errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3443                   }
3444                 }
3445                 else
3446                 {
3447                   /* NOthing to do */
3448                 }
3449               }
3450             }
3451             else
3452             {
3453               errorstate = SDMMC_ERROR_REQUEST_NOT_APPLICABLE;
3454             }
3455           }
3456         }
3457         else
3458         {
3459           errorstate = SDMMC_ERROR_REQUEST_NOT_APPLICABLE;
3460         }
3461       }
3462     }
3463 
3464     /* Change State */
3465     hmmc->State = HAL_MMC_STATE_READY;
3466 
3467     /* Manage errors */
3468     if (errorstate != HAL_MMC_ERROR_NONE)
3469     {
3470       /* Clear all the static flags */
3471       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3472       hmmc->ErrorCode |= errorstate;
3473 
3474       if (errorstate != HAL_MMC_ERROR_TIMEOUT)
3475       {
3476         return HAL_ERROR;
3477       }
3478       else
3479       {
3480         return HAL_TIMEOUT;
3481       }
3482     }
3483     else
3484     {
3485       return HAL_OK;
3486     }
3487   }
3488   else
3489   {
3490     return HAL_BUSY;
3491   }
3492 }
3493 /**
3494   * @}
3495   */
3496 
3497 /**
3498   * @}
3499   */
3500 
3501 /* Private function ----------------------------------------------------------*/
3502 /** @addtogroup MMC_Private_Functions
3503   * @{
3504   */
3505 
3506 
3507 /**
3508   * @brief  Initializes the mmc card.
3509   * @param  hmmc: Pointer to MMC handle
3510   * @retval MMC Card error state
3511   */
MMC_InitCard(MMC_HandleTypeDef * hmmc)3512 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc)
3513 {
3514   HAL_MMC_CardCSDTypeDef CSD;
3515   uint32_t errorstate;
3516   uint16_t mmc_rca = 2U;
3517   MMC_InitTypeDef Init;
3518 
3519   /* Check the power State */
3520   if (SDMMC_GetPowerState(hmmc->Instance) == 0U)
3521   {
3522     /* Power off */
3523     return HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
3524   }
3525 
3526   /* Send CMD2 ALL_SEND_CID */
3527   errorstate = SDMMC_CmdSendCID(hmmc->Instance);
3528   if (errorstate != HAL_MMC_ERROR_NONE)
3529   {
3530     return errorstate;
3531   }
3532   else
3533   {
3534     /* Get Card identification number data */
3535     hmmc->CID[0U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3536     hmmc->CID[1U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2);
3537     hmmc->CID[2U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP3);
3538     hmmc->CID[3U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP4);
3539   }
3540 
3541   /* Send CMD3 SET_REL_ADDR with RCA = 2 (should be greater than 1) */
3542   /* MMC Card publishes its RCA. */
3543   errorstate = SDMMC_CmdSetRelAddMmc(hmmc->Instance, mmc_rca);
3544   if (errorstate != HAL_MMC_ERROR_NONE)
3545   {
3546     return errorstate;
3547   }
3548 
3549   /* Get the MMC card RCA */
3550   hmmc->MmcCard.RelCardAdd = mmc_rca;
3551 
3552   /* Send CMD9 SEND_CSD with argument as card's RCA */
3553   errorstate = SDMMC_CmdSendCSD(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
3554   if (errorstate != HAL_MMC_ERROR_NONE)
3555   {
3556     return errorstate;
3557   }
3558   else
3559   {
3560     /* Get Card Specific Data */
3561     hmmc->CSD[0U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3562     hmmc->CSD[1U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2);
3563     hmmc->CSD[2U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP3);
3564     hmmc->CSD[3U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP4);
3565   }
3566 
3567   /* Get the Card Class */
3568   hmmc->MmcCard.Class = (SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2) >> 20U);
3569 
3570   /* Select the Card */
3571   errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3572   if (errorstate != HAL_MMC_ERROR_NONE)
3573   {
3574     return errorstate;
3575   }
3576 
3577   /* Get CSD parameters */
3578   if (HAL_MMC_GetCardCSD(hmmc, &CSD) != HAL_OK)
3579   {
3580     return hmmc->ErrorCode;
3581   }
3582 
3583   /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3584   errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3585   if (errorstate != HAL_MMC_ERROR_NONE)
3586   {
3587     hmmc->ErrorCode |= errorstate;
3588   }
3589 
3590 
3591   /* Get Extended CSD parameters */
3592   if (HAL_MMC_GetCardExtCSD(hmmc, hmmc->Ext_CSD, SDMMC_DATATIMEOUT) != HAL_OK)
3593   {
3594     return hmmc->ErrorCode;
3595   }
3596 
3597   /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3598   errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3599   if (errorstate != HAL_MMC_ERROR_NONE)
3600   {
3601     hmmc->ErrorCode |= errorstate;
3602   }
3603 
3604   /* Configure the SDMMC peripheral */
3605   Init = hmmc->Init;
3606   Init.BusWide = SDMMC_BUS_WIDE_1B;
3607   (void)SDMMC_Init(hmmc->Instance, Init);
3608 
3609   /* All cards are initialized */
3610   return HAL_MMC_ERROR_NONE;
3611 }
3612 
3613 /**
3614   * @brief  Enquires cards about their operating voltage and configures clock
3615   *         controls and stores MMC information that will be needed in future
3616   *         in the MMC handle.
3617   * @param  hmmc: Pointer to MMC handle
3618   * @retval error state
3619   */
MMC_PowerON(MMC_HandleTypeDef * hmmc)3620 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc)
3621 {
3622   __IO uint32_t count = 0U;
3623   uint32_t response = 0U;
3624   uint32_t validvoltage = 0U;
3625   uint32_t errorstate;
3626 
3627   /* CMD0: GO_IDLE_STATE */
3628   errorstate = SDMMC_CmdGoIdleState(hmmc->Instance);
3629   if (errorstate != HAL_MMC_ERROR_NONE)
3630   {
3631     return errorstate;
3632   }
3633 
3634   while (validvoltage == 0U)
3635   {
3636     if (count++ == SDMMC_MAX_VOLT_TRIAL)
3637     {
3638       return HAL_MMC_ERROR_INVALID_VOLTRANGE;
3639     }
3640 
3641     /* SEND CMD1 APP_CMD with voltage range as argument */
3642     errorstate = SDMMC_CmdOpCondition(hmmc->Instance, MMC_VOLTAGE_RANGE);
3643     if (errorstate != HAL_MMC_ERROR_NONE)
3644     {
3645       return HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
3646     }
3647 
3648     /* Get command response */
3649     response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3650 
3651     /* Get operating voltage*/
3652     validvoltage = (((response >> 31U) == 1U) ? 1U : 0U);
3653   }
3654 
3655   /* When power routine is finished and command returns valid voltage */
3656   if (((response & (0xFF000000U)) >> 24) == 0xC0U)
3657   {
3658     hmmc->MmcCard.CardType = MMC_HIGH_CAPACITY_CARD;
3659   }
3660   else
3661   {
3662     hmmc->MmcCard.CardType = MMC_LOW_CAPACITY_CARD;
3663   }
3664 
3665   return HAL_MMC_ERROR_NONE;
3666 }
3667 
3668 /**
3669   * @brief  Turns the SDMMC output signals off.
3670   * @param  hmmc: Pointer to MMC handle
3671   * @retval None
3672   */
MMC_PowerOFF(MMC_HandleTypeDef * hmmc)3673 static void MMC_PowerOFF(MMC_HandleTypeDef *hmmc)
3674 {
3675   /* Set Power State to OFF */
3676   (void)SDMMC_PowerState_OFF(hmmc->Instance);
3677 }
3678 
3679 /**
3680   * @brief  Returns the current card's status.
3681   * @param  hmmc: Pointer to MMC handle
3682   * @param  pCardStatus: pointer to the buffer that will contain the MMC card
3683   *         status (Card Status register)
3684   * @retval error state
3685   */
MMC_SendStatus(MMC_HandleTypeDef * hmmc,uint32_t * pCardStatus)3686 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus)
3687 {
3688   uint32_t errorstate;
3689 
3690   if (pCardStatus == NULL)
3691   {
3692     return HAL_MMC_ERROR_PARAM;
3693   }
3694 
3695   /* Send Status command */
3696   errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
3697   if (errorstate != HAL_MMC_ERROR_NONE)
3698   {
3699     return errorstate;
3700   }
3701 
3702   /* Get MMC card status */
3703   *pCardStatus = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3704 
3705   return HAL_MMC_ERROR_NONE;
3706 }
3707 
3708 /**
3709   * @brief  Reads extended CSD register to get the sectors number of the device
3710   * @param  hmmc: Pointer to MMC handle
3711   * @param  pFieldData: Pointer to the read buffer
3712   * @param  FieldIndex: Index of the field to be read
3713   * @param  Timeout: Specify timeout value
3714   * @retval HAL status
3715   */
MMC_ReadExtCSD(MMC_HandleTypeDef * hmmc,uint32_t * pFieldData,uint16_t FieldIndex,uint32_t Timeout)3716 static HAL_StatusTypeDef MMC_ReadExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pFieldData,
3717                                         uint16_t FieldIndex, uint32_t Timeout)
3718 {
3719   SDMMC_DataInitTypeDef config;
3720   uint32_t errorstate;
3721   uint32_t tickstart = HAL_GetTick();
3722   uint32_t count;
3723   uint32_t i = 0;
3724   uint32_t tmp_data;
3725 
3726   hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
3727 
3728   /* Initialize data control register */
3729   hmmc->Instance->DCTRL = 0;
3730 
3731   /* Configure the MMC DPSM (Data Path State Machine) */
3732   config.DataTimeOut   = SDMMC_DATATIMEOUT;
3733   config.DataLength    = 512U;
3734   config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
3735   config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
3736   config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
3737   config.DPSM          = SDMMC_DPSM_ENABLE;
3738   (void)SDMMC_ConfigData(hmmc->Instance, &config);
3739 
3740   /* Set Block Size for Card */
3741   errorstate = SDMMC_CmdSendEXTCSD(hmmc->Instance, 0);
3742   if (errorstate != HAL_MMC_ERROR_NONE)
3743   {
3744     /* Clear all the static flags */
3745     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3746     hmmc->ErrorCode |= errorstate;
3747     hmmc->State = HAL_MMC_STATE_READY;
3748     return HAL_ERROR;
3749   }
3750 
3751   /* Poll on SDMMC flags */
3752   while (!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT |
3753                              SDMMC_FLAG_DATAEND))
3754   {
3755     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF))
3756     {
3757       /* Read data from SDMMC Rx FIFO */
3758       for (count = 0U; count < 8U; count++)
3759       {
3760         tmp_data = SDMMC_ReadFIFO(hmmc->Instance);
3761         /* eg : SEC_COUNT   : FieldIndex = 212 => i+count = 53 */
3762         /*      DEVICE_TYPE : FieldIndex = 196 => i+count = 49 */
3763         if ((i + count) == ((uint32_t)FieldIndex / 4U))
3764         {
3765           *pFieldData = tmp_data;
3766         }
3767       }
3768       i += 8U;
3769     }
3770 
3771     if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
3772     {
3773       /* Clear all the static flags */
3774       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3775       hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
3776       hmmc->State = HAL_MMC_STATE_READY;
3777       return HAL_TIMEOUT;
3778     }
3779   }
3780 
3781   /* Get error state */
3782   if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
3783   {
3784     /* Clear all the static flags */
3785     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3786     hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
3787     hmmc->State = HAL_MMC_STATE_READY;
3788     return HAL_ERROR;
3789   }
3790   else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
3791   {
3792     /* Clear all the static flags */
3793     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3794     hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
3795     hmmc->State = HAL_MMC_STATE_READY;
3796     return HAL_ERROR;
3797   }
3798   else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR))
3799   {
3800     /* Clear all the static flags */
3801     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3802     hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
3803     hmmc->State = HAL_MMC_STATE_READY;
3804     return HAL_ERROR;
3805   }
3806   else
3807   {
3808     /* Nothing to do */
3809   }
3810 
3811   /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3812   errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16));
3813   if (errorstate != HAL_MMC_ERROR_NONE)
3814   {
3815     hmmc->ErrorCode |= errorstate;
3816   }
3817 
3818   /* Clear all the static flags */
3819   __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
3820 
3821   hmmc->State = HAL_MMC_STATE_READY;
3822 
3823   return HAL_OK;
3824 }
3825 
3826 /**
3827   * @brief  Wrap up reading in non-blocking mode.
3828   * @param  hmmc: pointer to a MMC_HandleTypeDef structure that contains
3829   *              the configuration information.
3830   * @retval None
3831   */
MMC_Read_IT(MMC_HandleTypeDef * hmmc)3832 static void MMC_Read_IT(MMC_HandleTypeDef *hmmc)
3833 {
3834   uint32_t count;
3835   uint32_t data;
3836   uint8_t *tmp;
3837 
3838   tmp = hmmc->pRxBuffPtr;
3839 
3840   if (hmmc->RxXferSize >= 32U)
3841   {
3842     /* Read data from SDMMC Rx FIFO */
3843     for (count = 0U; count < 8U; count++)
3844     {
3845       data = SDMMC_ReadFIFO(hmmc->Instance);
3846       *tmp = (uint8_t)(data & 0xFFU);
3847       tmp++;
3848       *tmp = (uint8_t)((data >> 8U) & 0xFFU);
3849       tmp++;
3850       *tmp = (uint8_t)((data >> 16U) & 0xFFU);
3851       tmp++;
3852       *tmp = (uint8_t)((data >> 24U) & 0xFFU);
3853       tmp++;
3854     }
3855 
3856     hmmc->pRxBuffPtr = tmp;
3857     hmmc->RxXferSize -= 32U;
3858   }
3859 }
3860 
3861 /**
3862   * @brief  Wrap up writing in non-blocking mode.
3863   * @param  hmmc: pointer to a MMC_HandleTypeDef structure that contains
3864   *              the configuration information.
3865   * @retval None
3866   */
MMC_Write_IT(MMC_HandleTypeDef * hmmc)3867 static void MMC_Write_IT(MMC_HandleTypeDef *hmmc)
3868 {
3869   uint32_t count;
3870   uint32_t data;
3871   uint8_t *tmp;
3872 
3873   tmp = hmmc->pTxBuffPtr;
3874 
3875   if (hmmc->TxXferSize >= 32U)
3876   {
3877     /* Write data to SDMMC Tx FIFO */
3878     for (count = 0U; count < 8U; count++)
3879     {
3880       data = (uint32_t)(*tmp);
3881       tmp++;
3882       data |= ((uint32_t)(*tmp) << 8U);
3883       tmp++;
3884       data |= ((uint32_t)(*tmp) << 16U);
3885       tmp++;
3886       data |= ((uint32_t)(*tmp) << 24U);
3887       tmp++;
3888       (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
3889     }
3890 
3891     hmmc->pTxBuffPtr = tmp;
3892     hmmc->TxXferSize -= 32U;
3893   }
3894 }
3895 
3896 /**
3897   * @brief  Switches the MMC card to high speed mode.
3898   * @param  hmmc: MMC handle
3899   * @param  state: State of high speed mode
3900   * @retval MMC Card error state
3901   */
MMC_HighSpeed(MMC_HandleTypeDef * hmmc,FunctionalState state)3902 static uint32_t MMC_HighSpeed(MMC_HandleTypeDef *hmmc, FunctionalState state)
3903 {
3904   uint32_t errorstate = HAL_MMC_ERROR_NONE;
3905   uint32_t response = 0U;
3906   uint32_t count;
3907   uint32_t sdmmc_clk;
3908   SDMMC_InitTypeDef Init;
3909 
3910   if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) != 0U) && (state == DISABLE))
3911   {
3912     errorstate = MMC_PwrClassUpdate(hmmc, (hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS), SDMMC_SPEED_MODE_DEFAULT);
3913     if (errorstate == HAL_MMC_ERROR_NONE)
3914     {
3915       /* Index : 185 - Value : 0 */
3916       errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B90000U);
3917     }
3918   }
3919 
3920   if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) == 0U) && (state != DISABLE))
3921   {
3922     errorstate = MMC_PwrClassUpdate(hmmc, (hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS), SDMMC_SPEED_MODE_HIGH);
3923     if (errorstate == HAL_MMC_ERROR_NONE)
3924     {
3925       /* Index : 185 - Value : 1 */
3926       errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B90100U);
3927     }
3928   }
3929 
3930   if (errorstate == HAL_MMC_ERROR_NONE)
3931   {
3932     /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3933     count = SDMMC_MAX_TRIAL;
3934     do
3935     {
3936       errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3937       if (errorstate != HAL_MMC_ERROR_NONE)
3938       {
3939         break;
3940       }
3941 
3942       /* Get command response */
3943       response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3944       count--;
3945     } while (((response & 0x100U) == 0U) && (count != 0U));
3946 
3947     /* Check the status after the switch command execution */
3948     if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
3949     {
3950       /* Check the bit SWITCH_ERROR of the device status */
3951       if ((response & 0x80U) != 0U)
3952       {
3953         errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3954       }
3955       else
3956       {
3957         /* Configure high speed */
3958         Init.ClockEdge           = hmmc->Init.ClockEdge;
3959         Init.ClockPowerSave      = hmmc->Init.ClockPowerSave;
3960         Init.BusWide             = (hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS);
3961         Init.HardwareFlowControl = hmmc->Init.HardwareFlowControl;
3962 
3963         if (state == DISABLE)
3964         {
3965           Init.ClockDiv = hmmc->Init.ClockDiv;
3966           (void)SDMMC_Init(hmmc->Instance, Init);
3967 
3968           CLEAR_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_BUSSPEED);
3969         }
3970         else
3971         {
3972           /* High Speed Clock should be less or equal to 52MHz*/
3973           sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC1);
3974 
3975           if (sdmmc_clk == 0U)
3976           {
3977             errorstate = SDMMC_ERROR_INVALID_PARAMETER;
3978           }
3979           else
3980           {
3981             if (sdmmc_clk <= MMC_HIGH_SPEED_FREQ)
3982             {
3983               Init.ClockDiv = 0;
3984             }
3985             else
3986             {
3987               Init.ClockDiv = (sdmmc_clk / (2U * MMC_HIGH_SPEED_FREQ)) + 1U;
3988             }
3989             (void)SDMMC_Init(hmmc->Instance, Init);
3990 
3991             SET_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_BUSSPEED);
3992           }
3993         }
3994       }
3995     }
3996     else if (count == 0U)
3997     {
3998       errorstate = SDMMC_ERROR_TIMEOUT;
3999     }
4000     else
4001     {
4002       /* Nothing to do */
4003     }
4004   }
4005 
4006   return errorstate;
4007 }
4008 
4009 /**
4010   * @brief  Switches the MMC card to Double Data Rate (DDR) mode.
4011   * @param  hmmc: MMC handle
4012   * @param  state: State of DDR mode
4013   * @retval MMC Card error state
4014   */
MMC_DDR_Mode(MMC_HandleTypeDef * hmmc,FunctionalState state)4015 static uint32_t MMC_DDR_Mode(MMC_HandleTypeDef *hmmc, FunctionalState state)
4016 {
4017   uint32_t errorstate = HAL_MMC_ERROR_NONE;
4018   uint32_t response = 0U;
4019   uint32_t count;
4020 
4021   if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) != 0U) && (state == DISABLE))
4022   {
4023     if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS_0) != 0U)
4024     {
4025       errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_4B, SDMMC_SPEED_MODE_HIGH);
4026       if (errorstate == HAL_MMC_ERROR_NONE)
4027       {
4028         /* Index : 183 - Value : 1 */
4029         errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U);
4030       }
4031     }
4032     else
4033     {
4034       errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_8B, SDMMC_SPEED_MODE_HIGH);
4035       if (errorstate == HAL_MMC_ERROR_NONE)
4036       {
4037         /* Index : 183 - Value : 2 */
4038         errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U);
4039       }
4040     }
4041   }
4042 
4043   if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) == 0U) && (state != DISABLE))
4044   {
4045     if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS_0) != 0U)
4046     {
4047       errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_4B, SDMMC_SPEED_MODE_DDR);
4048       if (errorstate == HAL_MMC_ERROR_NONE)
4049       {
4050         /* Index : 183 - Value : 5 */
4051         errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70500U);
4052       }
4053     }
4054     else
4055     {
4056       errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_8B, SDMMC_SPEED_MODE_DDR);
4057       if (errorstate == HAL_MMC_ERROR_NONE)
4058       {
4059         /* Index : 183 - Value : 6 */
4060         errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70600U);
4061       }
4062     }
4063   }
4064 
4065   if (errorstate == HAL_MMC_ERROR_NONE)
4066   {
4067     /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
4068     count = SDMMC_MAX_TRIAL;
4069     do
4070     {
4071       errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
4072       if (errorstate != HAL_MMC_ERROR_NONE)
4073       {
4074         break;
4075       }
4076 
4077       /* Get command response */
4078       response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
4079       count--;
4080     } while (((response & 0x100U) == 0U) && (count != 0U));
4081 
4082     /* Check the status after the switch command execution */
4083     if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
4084     {
4085       /* Check the bit SWITCH_ERROR of the device status */
4086       if ((response & 0x80U) != 0U)
4087       {
4088         errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
4089       }
4090       else
4091       {
4092         /* Configure DDR mode */
4093         if (state == DISABLE)
4094         {
4095           CLEAR_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_DDR);
4096         }
4097         else
4098         {
4099           SET_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_DDR);
4100         }
4101       }
4102     }
4103     else if (count == 0U)
4104     {
4105       errorstate = SDMMC_ERROR_TIMEOUT;
4106     }
4107     else
4108     {
4109       /* Nothing to do */
4110     }
4111   }
4112 
4113   return errorstate;
4114 }
4115 
4116 /**
4117   * @brief  Update the power class of the device.
4118   * @param  hmmc MMC handle
4119   * @param  Wide Wide of MMC bus
4120   * @param  Speed Speed of the MMC bus
4121   * @retval MMC Card error state
4122   */
MMC_PwrClassUpdate(MMC_HandleTypeDef * hmmc,uint32_t Wide,uint32_t Speed)4123 static uint32_t MMC_PwrClassUpdate(MMC_HandleTypeDef *hmmc, uint32_t Wide, uint32_t Speed)
4124 {
4125   uint32_t count;
4126   uint32_t response = 0U;
4127   uint32_t errorstate = HAL_MMC_ERROR_NONE;
4128   uint32_t power_class;
4129   uint32_t supported_pwr_class;
4130 
4131   if ((Wide == SDMMC_BUS_WIDE_8B) || (Wide == SDMMC_BUS_WIDE_4B))
4132   {
4133     power_class = 0U; /* Default value after power-on or software reset */
4134 
4135     /* Read the PowerClass field of the Extended CSD register */
4136     if (MMC_ReadExtCSD(hmmc, &power_class, 187, SDMMC_DATATIMEOUT) != HAL_OK) /* Field POWER_CLASS [187] */
4137     {
4138       errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
4139     }
4140     else
4141     {
4142       power_class = ((power_class >> 24U) & 0x000000FFU);
4143     }
4144 
4145     /* Get the supported PowerClass field of the Extended CSD register */
4146     if (Speed == SDMMC_SPEED_MODE_DDR)
4147     {
4148       /* Field PWR_CL_DDR_52_xxx [238 or 239] */
4149       supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_DDR_52_INDEX / 4)] >> MMC_EXT_CSD_PWR_CL_DDR_52_POS) &
4150                              0x000000FFU);
4151     }
4152     else if (Speed == SDMMC_SPEED_MODE_HIGH)
4153     {
4154       /* Field PWR_CL_52_xxx [200 or 202] */
4155       supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_52_INDEX / 4)] >> MMC_EXT_CSD_PWR_CL_52_POS) &
4156                              0x000000FFU);
4157     }
4158     else
4159     {
4160       /* Field PWR_CL_26_xxx [201 or 203] */
4161       supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_26_INDEX / 4)] >> MMC_EXT_CSD_PWR_CL_26_POS) &
4162                              0x000000FFU);
4163     }
4164 
4165     if (errorstate == HAL_MMC_ERROR_NONE)
4166     {
4167       if (Wide == SDMMC_BUS_WIDE_8B)
4168       {
4169         /* Bit [7:4]: power class for 8-bits bus configuration - Bit [3:0]: power class for 4-bits bus configuration */
4170         supported_pwr_class = (supported_pwr_class >> 4U);
4171       }
4172 
4173       if ((power_class & 0x0FU) != (supported_pwr_class & 0x0FU))
4174       {
4175         /* Need to change current power class */
4176         errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03BB0000U | ((supported_pwr_class & 0x0FU) << 8U)));
4177 
4178         if (errorstate == HAL_MMC_ERROR_NONE)
4179         {
4180           /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
4181           count = SDMMC_MAX_TRIAL;
4182           do
4183           {
4184             errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
4185             if (errorstate != HAL_MMC_ERROR_NONE)
4186             {
4187               break;
4188             }
4189 
4190             /* Get command response */
4191             response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
4192             count--;
4193           } while (((response & 0x100U) == 0U) && (count != 0U));
4194 
4195           /* Check the status after the switch command execution */
4196           if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
4197           {
4198             /* Check the bit SWITCH_ERROR of the device status */
4199             if ((response & 0x80U) != 0U)
4200             {
4201               errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
4202             }
4203           }
4204           else if (count == 0U)
4205           {
4206             errorstate = SDMMC_ERROR_TIMEOUT;
4207           }
4208           else
4209           {
4210             /* Nothing to do */
4211           }
4212         }
4213       }
4214     }
4215   }
4216 
4217   return errorstate;
4218 }
4219 
4220 /**
4221   * @brief Read DMA Buffer 0 Transfer completed callbacks
4222   * @param hmmc: MMC handle
4223   * @retval None
4224   */
HAL_MMCEx_Read_DMADoubleBuf0CpltCallback(MMC_HandleTypeDef * hmmc)4225 __weak void HAL_MMCEx_Read_DMADoubleBuf0CpltCallback(MMC_HandleTypeDef *hmmc)
4226 {
4227   /* Prevent unused argument(s) compilation warning */
4228   UNUSED(hmmc);
4229 
4230   /* NOTE : This function should not be modified, when the callback is needed,
4231             the HAL_MMCEx_Read_DMADoubleBuf0CpltCallback can be implemented in the user file
4232    */
4233 }
4234 
4235 /**
4236   * @brief Read DMA Buffer 1 Transfer completed callbacks
4237   * @param hmmc: MMC handle
4238   * @retval None
4239   */
HAL_MMCEx_Read_DMADoubleBuf1CpltCallback(MMC_HandleTypeDef * hmmc)4240 __weak void HAL_MMCEx_Read_DMADoubleBuf1CpltCallback(MMC_HandleTypeDef *hmmc)
4241 {
4242   /* Prevent unused argument(s) compilation warning */
4243   UNUSED(hmmc);
4244 
4245   /* NOTE : This function should not be modified, when the callback is needed,
4246             the HAL_MMCEx_Read_DMADoubleBuf1CpltCallback can be implemented in the user file
4247    */
4248 }
4249 
4250 /**
4251   * @brief Write DMA Buffer 0 Transfer completed callbacks
4252   * @param hmmc: MMC handle
4253   * @retval None
4254   */
HAL_MMCEx_Write_DMADoubleBuf0CpltCallback(MMC_HandleTypeDef * hmmc)4255 __weak void HAL_MMCEx_Write_DMADoubleBuf0CpltCallback(MMC_HandleTypeDef *hmmc)
4256 {
4257   /* Prevent unused argument(s) compilation warning */
4258   UNUSED(hmmc);
4259 
4260   /* NOTE : This function should not be modified, when the callback is needed,
4261             the HAL_MMCEx_Write_DMADoubleBuf0CpltCallback can be implemented in the user file
4262    */
4263 }
4264 
4265 /**
4266   * @brief Write DMA Buffer 1 Transfer completed callbacks
4267   * @param hmmc: MMC handle
4268   * @retval None
4269   */
HAL_MMCEx_Write_DMADoubleBuf1CpltCallback(MMC_HandleTypeDef * hmmc)4270 __weak void HAL_MMCEx_Write_DMADoubleBuf1CpltCallback(MMC_HandleTypeDef *hmmc)
4271 {
4272   /* Prevent unused argument(s) compilation warning */
4273   UNUSED(hmmc);
4274 
4275   /* NOTE : This function should not be modified, when the callback is needed,
4276             the HAL_MMCEx_Write_DMADoubleBuf1CpltCallback can be implemented in the user file
4277    */
4278 }
4279 
4280 /**
4281   * @}
4282   */
4283 
4284 #endif /* HAL_MMC_MODULE_ENABLED */
4285 
4286 /**
4287   * @}
4288   */
4289 
4290 /**
4291   * @}
4292   */
4293