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