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