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