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