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   *** MMC Card Initialization and configuration ***
60   ================================================
61   [..]
62     To initialize the MMC Card, use the HAL_MMC_Init() function. It Initializes
63     SDMMC Peripheral (STM32 side) and the MMC Card, and put it into StandBy State (Ready for data transfer).
64     This function provide the following operations:
65 
66     (#) Initialize the SDMMC peripheral interface with default configuration.
67         The initialization process is done at 400KHz. You can change or adapt
68         this frequency by adjusting the "ClockDiv" field.
69         The MMC Card frequency (SDMMC_CK) is computed as follows:
70 
71            SDMMC_CK = SDMMCCLK / (2 * ClockDiv)
72 
73         In initialization mode and according to the MMC Card standard,
74         make sure that the SDMMC_CK frequency doesn't exceed 400KHz.
75 
76         This phase of initialization is done through SDMMC_Init() and
77         SDMMC_PowerState_ON() SDMMC low level APIs.
78 
79     (#) Initialize the MMC card. The API used is HAL_MMC_InitCard().
80         This phase allows the card initialization and identification
81         and check the MMC Card type (Standard Capacity or High Capacity)
82         The initialization flow is compatible with MMC standard.
83 
84         This API (HAL_MMC_InitCard()) could be used also to reinitialize the card in case
85         of plug-off plug-in.
86 
87     (#) Configure the MMC Card Data transfer frequency. By Default, the card transfer
88         frequency by adjusting the "ClockDiv" field.
89         In transfer mode and according to the MMC Card standard, make sure that the
90         SDMMC_CK frequency doesn't exceed 25MHz and 100MHz in High-speed mode switch.
91 
92     (#) Select the corresponding MMC Card according to the address read with the step 2.
93 
94     (#) Configure the MMC Card in wide bus mode: 4-bits data.
95     (#) Select the MMC Card partition using HAL_MMC_SwitchPartition()
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 Card Reply Protected Memory Block (RPMB) Key Programming operation ***
173   ==============================
174   [..]
175     (+) You can program the authentication key of RPMB area in polling mode by using function
176         HAL_MMC_RPMB_ProgramAuthenticationKey().
177         This function is only used once during the life of an MMC card.
178         After this, you have to ensure that the transfer is done correctly. The check is done
179         through HAL_MMC_GetRPMBError() function for operation state.
180     (+) You can program the authentication key of RPMB area in Interrupt mode by using function
181         HAL_MMC_RPMB_ProgramAuthenticationKey_IT().
182         This function is only used once during the life of an MMC card.
183         After this, you have to ensure that the transfer is done correctly. The check is done
184         through HAL_MMC_GetRPMBError() function for operation state.
185 
186   *** MMC Card Reply Protected Memory Block (RPMB) write counter operation ***
187   ==============================
188   [..]
189     (+) You can get the write counter value of RPMB area in polling mode by using function
190         HAL_MMC_RPMB_GetWriteCounter().
191     (+) You can get the write counter value of RPMB area in Interrupt mode by using function
192         HAL_MMC_RPMB_GetWriteCounter_IT().
193 
194   *** MMC Card Reply Protected Memory Block (RPMB) write operation ***
195   ==============================
196   [..]
197     (+) You can write to the RPMB area of MMC card in polling mode by using function
198         HAL_MMC_WriteBlocks().
199         This function supports the one, two, or thirty two blocks write operation
200         (with 512-bytes block length).
201         You can choose the number of blocks at the multiple block read operation by adjusting
202         the "NumberOfBlocks" parameter.
203         After this, you have to ensure that the transfer is done correctly. The check is done
204         through HAL_MMC_GetRPMBError() function for operation state.
205     (+) You can write to the RPMB area of MMC card in Interrupt mode by using function
206         HAL_MMC_WriteBlocks_IT().
207         This function supports the one, two, or thirty two blocks write operation
208         (with 512-bytes block length).
209         You can choose the number of blocks at the multiple block read operation by adjusting
210         the "NumberOfBlocks" parameter.
211         After this, you have to ensure that the transfer is done correctly. The check is done
212         through HAL_MMC_GetRPMBError() function for operation state.
213 
214   *** MMC Card Reply Protected Memory Block (RPMB) read operation ***
215   ==============================
216   [..]
217     (+) You can read from the RPMB area of MMC card in polling mode by using function
218         HAL_MMC_RPMB_ReadBlocks().
219         The block size should be chosen as multiple of 512 bytes.
220         You can choose the number of blocks by adjusting the "NumberOfBlocks" parameter.
221         After this, you have to ensure that the transfer is done correctly. The check is done
222         through HAL_MMC_GetRPMBError() function for MMC card state.
223     (+) You can read from the RPMB area of MMC card in Interrupt mode by using function
224         HAL_MMC_RPMB_ReadBlocks_IT().
225         The block size should be chosen as multiple of 512 bytes.
226         You can choose the number of blocks by adjusting the "NumberOfBlocks" parameter.
227         After this, you have to ensure that the transfer is done correctly. The check is done
228         through HAL_MMC_GetRPMBError() function for MMC card state.
229 
230   *** MMC HAL driver macros list ***
231   ==================================
232   [..]
233     Below the list of most used macros in MMC HAL driver.
234 
235     (+) __HAL_MMC_ENABLE_IT: Enable the MMC device interrupt
236     (+) __HAL_MMC_DISABLE_IT: Disable the MMC device interrupt
237     (+) __HAL_MMC_GET_FLAG:Check whether the specified MMC flag is set or not
238     (+) __HAL_MMC_CLEAR_FLAG: Clear the MMC's pending flags
239 
240   [..]
241     (@) You can refer to the MMC HAL driver header file for more useful macros
242 
243   *** Callback registration ***
244   =============================================
245   [..]
246     The compilation define USE_HAL_MMC_REGISTER_CALLBACKS when set to 1
247     allows the user to configure dynamically the driver callbacks.
248 
249     Use Functions HAL_MMC_RegisterCallback() to register a user callback,
250     it allows to register following callbacks:
251       (+) TxCpltCallback : callback when a transmission transfer is completed.
252       (+) RxCpltCallback : callback when a reception transfer is completed.
253       (+) ErrorCallback : callback when error occurs.
254       (+) AbortCpltCallback : callback when abort is completed.
255       (+) Read_DMADblBuf0CpltCallback : callback when the DMA reception of first buffer is completed.
256       (+) Read_DMADblBuf1CpltCallback : callback when the DMA reception of second buffer is completed.
257       (+) Write_DMADblBuf0CpltCallback : callback when the DMA transmission of first buffer is completed.
258       (+) Write_DMADblBuf1CpltCallback : callback when the DMA transmission of second buffer is completed.
259       (+) MspInitCallback    : MMC MspInit.
260       (+) MspDeInitCallback  : MMC MspDeInit.
261     This function takes as parameters the HAL peripheral handle, the Callback ID
262     and a pointer to the user callback function.
263 
264     Use function HAL_MMC_UnRegisterCallback() to reset a callback to the default
265     weak (overridden) function. It allows to reset following callbacks:
266       (+) TxCpltCallback : callback when a transmission transfer is completed.
267       (+) RxCpltCallback : callback when a reception transfer is completed.
268       (+) ErrorCallback : callback when error occurs.
269       (+) AbortCpltCallback : callback when abort is completed.
270       (+) Read_DMADblBuf0CpltCallback : callback when the DMA reception of first buffer is completed.
271       (+) Read_DMADblBuf1CpltCallback : callback when the DMA reception of second buffer is completed.
272       (+) Write_DMADblBuf0CpltCallback : callback when the DMA transmission of first buffer is completed.
273       (+) Write_DMADblBuf1CpltCallback : callback when the DMA transmission of second buffer is completed.
274       (+) MspInitCallback    : MMC MspInit.
275       (+) MspDeInitCallback  : MMC MspDeInit.
276     This function) takes as parameters the HAL peripheral handle and the Callback ID.
277 
278     By default, after the HAL_MMC_Init and if the state is HAL_MMC_STATE_RESET
279     all callbacks are reset to the corresponding legacy weak (overridden) functions.
280     Exception done for MspInit and MspDeInit callbacks that are respectively
281     reset to the legacy weak (overridden) functions in the HAL_MMC_Init
282     and HAL_MMC_DeInit only when these callbacks are null (not registered beforehand).
283     If not, MspInit or MspDeInit are not null, the HAL_MMC_Init and HAL_MMC_DeInit
284     keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
285 
286     Callbacks can be registered/unregistered in READY state only.
287     Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
288     in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
289     during the Init/DeInit.
290     In that case first register the MspInit/MspDeInit user callbacks
291     using HAL_MMC_RegisterCallback before calling HAL_MMC_DeInit
292     or HAL_MMC_Init function.
293 
294     When The compilation define USE_HAL_MMC_REGISTER_CALLBACKS is set to 0 or
295     not defined, the callback registering feature is not available
296     and weak (overridden) callbacks are used.
297 
298   @endverbatim
299   ******************************************************************************
300   */
301 
302 /* Includes ------------------------------------------------------------------*/
303 #include "stm32h7xx_hal.h"
304 
305 /** @addtogroup STM32H7xx_HAL_Driver
306   * @{
307   */
308 
309 /** @defgroup MMC MMC
310   * @brief MMC HAL module driver
311   * @{
312   */
313 
314 #if defined (SDMMC1) || defined (SDMMC2)
315 #ifdef HAL_MMC_MODULE_ENABLED
316 
317 /* Private typedef -----------------------------------------------------------*/
318 /* Private define ------------------------------------------------------------*/
319 /** @addtogroup MMC_Private_Defines
320   * @{
321   */
322 #if defined (VDD_VALUE) && (VDD_VALUE <= 1950U)
323 #define MMC_VOLTAGE_RANGE               EMMC_LOW_VOLTAGE_RANGE
324 
325 #define MMC_EXT_CSD_PWR_CL_26_INDEX     201
326 #define MMC_EXT_CSD_PWR_CL_52_INDEX     200
327 #define MMC_EXT_CSD_PWR_CL_DDR_52_INDEX 238
328 
329 #define MMC_EXT_CSD_PWR_CL_26_POS       8
330 #define MMC_EXT_CSD_PWR_CL_52_POS       0
331 #define MMC_EXT_CSD_PWR_CL_DDR_52_POS   16
332 #else
333 #define MMC_VOLTAGE_RANGE               EMMC_HIGH_VOLTAGE_RANGE
334 
335 #define MMC_EXT_CSD_PWR_CL_26_INDEX     203
336 #define MMC_EXT_CSD_PWR_CL_52_INDEX     202
337 #define MMC_EXT_CSD_PWR_CL_DDR_52_INDEX 239
338 
339 #define MMC_EXT_CSD_PWR_CL_26_POS       24
340 #define MMC_EXT_CSD_PWR_CL_52_POS       16
341 #define MMC_EXT_CSD_PWR_CL_DDR_52_POS   24
342 #endif /* (VDD_VALUE) && (VDD_VALUE <= 1950U)*/
343 
344 #define MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_INDEX 216
345 #define MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_POS   0
346 #define MMC_EXT_CSD_S_A_TIMEOUT_INDEX             217
347 #define MMC_EXT_CSD_S_A_TIMEOUT_POS               8
348 
349 /* Frequencies used in the driver for clock divider calculation */
350 #define MMC_INIT_FREQ                   400000U   /* Initialization phase : 400 kHz max */
351 #define MMC_HIGH_SPEED_FREQ             52000000U /* High speed phase : 52 MHz max */
352 
353 /* The Data elements' postitions in the frame Frame for RPMB area */
354 #define MMC_RPMB_KEYMAC_POSITION         196U
355 #define MMC_RPMB_DATA_POSITION           228U
356 #define MMC_RPMB_NONCE_POSITION          484U
357 #define MMC_RPMB_WRITE_COUNTER_POSITION  500U
358 /**
359   * @}
360   */
361 
362 /* Private macro -------------------------------------------------------------*/
363 /* Private variables ---------------------------------------------------------*/
364 /* Private function prototypes -----------------------------------------------*/
365 /* Private functions ---------------------------------------------------------*/
366 /** @defgroup MMC_Private_Functions MMC Private Functions
367   * @{
368   */
369 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc);
370 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc);
371 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus);
372 static void     MMC_PowerOFF(MMC_HandleTypeDef *hmmc);
373 static void     MMC_Write_IT(MMC_HandleTypeDef *hmmc);
374 static void     MMC_Read_IT(MMC_HandleTypeDef *hmmc);
375 static uint32_t MMC_HighSpeed(MMC_HandleTypeDef *hmmc, FunctionalState state);
376 static uint32_t MMC_DDR_Mode(MMC_HandleTypeDef *hmmc, FunctionalState state);
377 static HAL_StatusTypeDef MMC_ReadExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pFieldData, uint16_t FieldIndex,
378                                         uint32_t Timeout);
379 static uint32_t MMC_PwrClassUpdate(MMC_HandleTypeDef *hmmc, uint32_t Wide, uint32_t Speed);
380 
381 /**
382   * @}
383   */
384 /* Exported functions --------------------------------------------------------*/
385 /** @addtogroup MMC_Exported_Functions
386   * @{
387   */
388 
389 /** @addtogroup MMC_Exported_Functions_Group1
390   *  @brief   Initialization and de-initialization functions
391   *
392 @verbatim
393   ==============================================================================
394           ##### Initialization and de-initialization functions #####
395   ==============================================================================
396   [..]
397     This section provides functions allowing to initialize/de-initialize the MMC
398     card device to be ready for use.
399 
400 @endverbatim
401   * @{
402   */
403 
404 /**
405   * @brief  Initializes the MMC according to the specified parameters in the
406             MMC_HandleTypeDef and create the associated handle.
407   * @param  hmmc: Pointer to the MMC handle
408   * @retval HAL status
409   */
HAL_MMC_Init(MMC_HandleTypeDef * hmmc)410 HAL_StatusTypeDef HAL_MMC_Init(MMC_HandleTypeDef *hmmc)
411 {
412   /* Check the MMC handle allocation */
413   if (hmmc == NULL)
414   {
415     return HAL_ERROR;
416   }
417 
418   /* Check the parameters */
419   assert_param(IS_SDMMC_ALL_INSTANCE(hmmc->Instance));
420   assert_param(IS_SDMMC_CLOCK_EDGE(hmmc->Init.ClockEdge));
421   assert_param(IS_SDMMC_CLOCK_POWER_SAVE(hmmc->Init.ClockPowerSave));
422   assert_param(IS_SDMMC_BUS_WIDE(hmmc->Init.BusWide));
423   assert_param(IS_SDMMC_HARDWARE_FLOW_CONTROL(hmmc->Init.HardwareFlowControl));
424   assert_param(IS_SDMMC_CLKDIV(hmmc->Init.ClockDiv));
425 
426   if (hmmc->State == HAL_MMC_STATE_RESET)
427   {
428     /* Allocate lock resource and initialize it */
429     hmmc->Lock = HAL_UNLOCKED;
430 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
431     /* Reset Callback pointers in HAL_MMC_STATE_RESET only */
432     hmmc->TxCpltCallback    = HAL_MMC_TxCpltCallback;
433     hmmc->RxCpltCallback    = HAL_MMC_RxCpltCallback;
434     hmmc->ErrorCallback     = HAL_MMC_ErrorCallback;
435     hmmc->AbortCpltCallback = HAL_MMC_AbortCallback;
436     hmmc->Read_DMADblBuf0CpltCallback = HAL_MMCEx_Read_DMADoubleBuf0CpltCallback;
437     hmmc->Read_DMADblBuf1CpltCallback = HAL_MMCEx_Read_DMADoubleBuf1CpltCallback;
438     hmmc->Write_DMADblBuf0CpltCallback = HAL_MMCEx_Write_DMADoubleBuf0CpltCallback;
439     hmmc->Write_DMADblBuf1CpltCallback = HAL_MMCEx_Write_DMADoubleBuf1CpltCallback;
440 
441     if (hmmc->MspInitCallback == NULL)
442     {
443       hmmc->MspInitCallback = HAL_MMC_MspInit;
444     }
445 
446     /* Init the low level hardware */
447     hmmc->MspInitCallback(hmmc);
448 #else
449     /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
450     HAL_MMC_MspInit(hmmc);
451 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
452   }
453 
454   hmmc->State = HAL_MMC_STATE_BUSY;
455 
456   /* Initialize the Card parameters */
457   if (HAL_MMC_InitCard(hmmc) == HAL_ERROR)
458   {
459     return HAL_ERROR;
460   }
461 
462   /* Initialize the error code */
463   hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
464 
465   /* Initialize the MMC operation */
466   hmmc->Context = MMC_CONTEXT_NONE;
467 
468   /* Initialize the MMC state */
469   hmmc->State = HAL_MMC_STATE_READY;
470 
471   /* Configure bus width */
472   if (hmmc->Init.BusWide != SDMMC_BUS_WIDE_1B)
473   {
474     if (HAL_MMC_ConfigWideBusOperation(hmmc, hmmc->Init.BusWide) != HAL_OK)
475     {
476       return HAL_ERROR;
477     }
478   }
479 
480   return HAL_OK;
481 }
482 
483 /**
484   * @brief  Initializes the MMC Card.
485   * @param  hmmc: Pointer to MMC handle
486   * @note   This function initializes the MMC card. It could be used when a card
487             re-initialization is needed.
488   * @retval HAL status
489   */
HAL_MMC_InitCard(MMC_HandleTypeDef * hmmc)490 HAL_StatusTypeDef HAL_MMC_InitCard(MMC_HandleTypeDef *hmmc)
491 {
492   uint32_t errorstate;
493   MMC_InitTypeDef Init;
494   uint32_t sdmmc_clk;
495 
496   /* Default SDMMC peripheral configuration for MMC card initialization */
497   Init.ClockEdge           = SDMMC_CLOCK_EDGE_RISING;
498   Init.ClockPowerSave      = SDMMC_CLOCK_POWER_SAVE_DISABLE;
499   Init.BusWide             = SDMMC_BUS_WIDE_1B;
500   Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
501 
502   /* Init Clock should be less or equal to 400Khz*/
503   sdmmc_clk     = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC);
504   if (sdmmc_clk == 0U)
505   {
506     hmmc->State = HAL_MMC_STATE_READY;
507     hmmc->ErrorCode = SDMMC_ERROR_INVALID_PARAMETER;
508     return HAL_ERROR;
509   }
510   Init.ClockDiv = sdmmc_clk / (2U * MMC_INIT_FREQ);
511 
512 #if (USE_SD_TRANSCEIVER != 0U)
513   Init.TranceiverPresent = SDMMC_TRANSCEIVER_NOT_PRESENT;
514 #endif /* USE_SD_TRANSCEIVER */
515 
516   /* Initialize SDMMC peripheral interface with default configuration */
517   (void)SDMMC_Init(hmmc->Instance, Init);
518 
519   /* Set Power State to ON */
520   (void)SDMMC_PowerState_ON(hmmc->Instance);
521 
522   /* wait 74 Cycles: required power up waiting time before starting
523      the MMC initialization sequence */
524   if (Init.ClockDiv != 0U)
525   {
526     sdmmc_clk = sdmmc_clk / (2U * Init.ClockDiv);
527   }
528 
529   if (sdmmc_clk != 0U)
530   {
531     HAL_Delay(1U + (74U * 1000U / (sdmmc_clk)));
532   }
533 
534   /* Identify card operating voltage */
535   errorstate = MMC_PowerON(hmmc);
536   if (errorstate != HAL_MMC_ERROR_NONE)
537   {
538     hmmc->State = HAL_MMC_STATE_READY;
539     hmmc->ErrorCode |= errorstate;
540     return HAL_ERROR;
541   }
542 
543   /* Card initialization */
544   errorstate = MMC_InitCard(hmmc);
545   if (errorstate != HAL_MMC_ERROR_NONE)
546   {
547     hmmc->State = HAL_MMC_STATE_READY;
548     hmmc->ErrorCode |= errorstate;
549     return HAL_ERROR;
550   }
551 
552   /* Set Block Size for Card */
553   errorstate = SDMMC_CmdBlockLength(hmmc->Instance, MMC_BLOCKSIZE);
554   if (errorstate != HAL_MMC_ERROR_NONE)
555   {
556     /* Clear all the static flags */
557     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
558     hmmc->ErrorCode |= errorstate;
559     hmmc->State = HAL_MMC_STATE_READY;
560     return HAL_ERROR;
561   }
562 
563   return HAL_OK;
564 }
565 
566 /**
567   * @brief  De-Initializes the MMC card.
568   * @param  hmmc: Pointer to MMC handle
569   * @retval HAL status
570   */
HAL_MMC_DeInit(MMC_HandleTypeDef * hmmc)571 HAL_StatusTypeDef HAL_MMC_DeInit(MMC_HandleTypeDef *hmmc)
572 {
573   /* Check the MMC handle allocation */
574   if (hmmc == NULL)
575   {
576     return HAL_ERROR;
577   }
578 
579   /* Check the parameters */
580   assert_param(IS_SDMMC_ALL_INSTANCE(hmmc->Instance));
581 
582   hmmc->State = HAL_MMC_STATE_BUSY;
583 
584   /* Set MMC power state to off */
585   MMC_PowerOFF(hmmc);
586 
587 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
588   if (hmmc->MspDeInitCallback == NULL)
589   {
590     hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
591   }
592 
593   /* DeInit the low level hardware */
594   hmmc->MspDeInitCallback(hmmc);
595 #else
596   /* De-Initialize the MSP layer */
597   HAL_MMC_MspDeInit(hmmc);
598 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
599 
600   hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
601   hmmc->State = HAL_MMC_STATE_RESET;
602 
603   return HAL_OK;
604 }
605 
606 /**
607   * @brief  Initializes the MMC MSP.
608   * @param  hmmc: Pointer to MMC handle
609   * @retval None
610   */
HAL_MMC_MspInit(MMC_HandleTypeDef * hmmc)611 __weak void HAL_MMC_MspInit(MMC_HandleTypeDef *hmmc)
612 {
613   /* Prevent unused argument(s) compilation warning */
614   UNUSED(hmmc);
615 
616   /* NOTE : This function Should not be modified, when the callback is needed,
617             the HAL_MMC_MspInit could be implemented in the user file
618    */
619 }
620 
621 /**
622   * @brief  De-Initialize MMC MSP.
623   * @param  hmmc: Pointer to MMC handle
624   * @retval None
625   */
HAL_MMC_MspDeInit(MMC_HandleTypeDef * hmmc)626 __weak void HAL_MMC_MspDeInit(MMC_HandleTypeDef *hmmc)
627 {
628   /* Prevent unused argument(s) compilation warning */
629   UNUSED(hmmc);
630 
631   /* NOTE : This function Should not be modified, when the callback is needed,
632             the HAL_MMC_MspDeInit could be implemented in the user file
633    */
634 }
635 
636 /**
637   * @}
638   */
639 
640 /** @addtogroup MMC_Exported_Functions_Group2
641   *  @brief   Data transfer functions
642   *
643 @verbatim
644   ==============================================================================
645                         ##### IO operation functions #####
646   ==============================================================================
647   [..]
648     This subsection provides a set of functions allowing to manage the data
649     transfer from/to MMC card.
650 
651 @endverbatim
652   * @{
653   */
654 
655 /**
656   * @brief  Reads block(s) from a specified address in a card. The Data transfer
657   *         is managed by polling mode.
658   * @note   This API should be followed by a check on the card state through
659   *         HAL_MMC_GetCardState().
660   * @param  hmmc: Pointer to MMC handle
661   * @param  pData: pointer to the buffer that will contain the received data
662   * @param  BlockAdd: Block Address from where data is to be read
663   * @param  NumberOfBlocks: Number of MMC blocks to read
664   * @param  Timeout: Specify timeout value
665   * @retval HAL status
666   */
HAL_MMC_ReadBlocks(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks,uint32_t Timeout)667 HAL_StatusTypeDef HAL_MMC_ReadBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd,
668                                      uint32_t NumberOfBlocks,
669                                      uint32_t Timeout)
670 {
671   SDMMC_DataInitTypeDef config;
672   uint32_t errorstate;
673   uint32_t tickstart = HAL_GetTick();
674   uint32_t count;
675   uint32_t data;
676   uint32_t dataremaining;
677   uint32_t add = BlockAdd;
678   uint8_t *tempbuff = pData;
679 
680   if (NULL == pData)
681   {
682     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
683     return HAL_ERROR;
684   }
685 
686   if (hmmc->State == HAL_MMC_STATE_READY)
687   {
688     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
689 
690     if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
691     {
692       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
693       return HAL_ERROR;
694     }
695 
696     /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
697     if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS)
698          & 0x000000FFU) != 0x0U)
699     {
700       if ((NumberOfBlocks % 8U) != 0U)
701       {
702         /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */
703         hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR;
704         return HAL_ERROR;
705       }
706 
707       if ((BlockAdd % 8U) != 0U)
708       {
709         /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
710         hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
711         return HAL_ERROR;
712       }
713     }
714 
715     hmmc->State = HAL_MMC_STATE_BUSY;
716 
717     /* Initialize data control register */
718     hmmc->Instance->DCTRL = 0U;
719 
720     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
721     {
722       add *= MMC_BLOCKSIZE;
723     }
724 
725     /* Configure the MMC DPSM (Data Path State Machine) */
726     config.DataTimeOut   = SDMMC_DATATIMEOUT;
727     config.DataLength    = NumberOfBlocks * MMC_BLOCKSIZE;
728     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
729     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
730     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
731     config.DPSM          = SDMMC_DPSM_DISABLE;
732     (void)SDMMC_ConfigData(hmmc->Instance, &config);
733     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
734 
735     /* Read block(s) in polling mode */
736     if (NumberOfBlocks > 1U)
737     {
738       hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
739 
740       /* Read Multi Block command */
741       errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
742     }
743     else
744     {
745       hmmc->Context = MMC_CONTEXT_READ_SINGLE_BLOCK;
746 
747       /* Read Single Block command */
748       errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
749     }
750     if (errorstate != HAL_MMC_ERROR_NONE)
751     {
752       /* Clear all the static flags */
753       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
754       hmmc->ErrorCode |= errorstate;
755       hmmc->State = HAL_MMC_STATE_READY;
756       return HAL_ERROR;
757     }
758 
759     /* Poll on SDMMC flags */
760     dataremaining = config.DataLength;
761     while (!__HAL_MMC_GET_FLAG(hmmc,
762                                SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
763     {
764       if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= SDMMC_FIFO_SIZE))
765       {
766         /* Read data from SDMMC Rx FIFO */
767         for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
768         {
769           data = SDMMC_ReadFIFO(hmmc->Instance);
770           *tempbuff = (uint8_t)(data & 0xFFU);
771           tempbuff++;
772           *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
773           tempbuff++;
774           *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
775           tempbuff++;
776           *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
777           tempbuff++;
778         }
779         dataremaining -= SDMMC_FIFO_SIZE;
780       }
781 
782       if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
783       {
784         /* Clear all the static flags */
785         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
786         hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
787         hmmc->State = HAL_MMC_STATE_READY;
788         return HAL_TIMEOUT;
789       }
790     }
791     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
792 
793     /* Send stop transmission command in case of multiblock read */
794     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U))
795     {
796       /* Send stop transmission command */
797       errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
798       if (errorstate != HAL_MMC_ERROR_NONE)
799       {
800         /* Clear all the static flags */
801         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
802         hmmc->ErrorCode |= errorstate;
803         hmmc->State = HAL_MMC_STATE_READY;
804         return HAL_ERROR;
805       }
806     }
807 
808     /* Get error state */
809     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
810     {
811       /* Clear all the static flags */
812       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
813       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
814       hmmc->State = HAL_MMC_STATE_READY;
815       return HAL_ERROR;
816     }
817     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
818     {
819       /* Clear all the static flags */
820       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
821       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
822       hmmc->State = HAL_MMC_STATE_READY;
823       return HAL_ERROR;
824     }
825     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR))
826     {
827       /* Clear all the static flags */
828       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
829       hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
830       hmmc->State = HAL_MMC_STATE_READY;
831       return HAL_ERROR;
832     }
833     else
834     {
835       /* Nothing to do */
836     }
837 
838     /* Clear all the static flags */
839     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
840 
841     hmmc->State = HAL_MMC_STATE_READY;
842 
843     return HAL_OK;
844   }
845   else
846   {
847     hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
848     return HAL_ERROR;
849   }
850 }
851 
852 /**
853   * @brief  Allows to write block(s) to a specified address in a card. The Data
854   *         transfer is managed by polling mode.
855   * @note   This API should be followed by a check on the card state through
856   *         HAL_MMC_GetCardState().
857   * @param  hmmc: Pointer to MMC handle
858   * @param  pData: pointer to the buffer that will contain the data to transmit
859   * @param  BlockAdd: Block Address where data will be written
860   * @param  NumberOfBlocks: Number of MMC blocks to write
861   * @param  Timeout: Specify timeout value
862   * @retval HAL status
863   */
HAL_MMC_WriteBlocks(MMC_HandleTypeDef * hmmc,const uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks,uint32_t Timeout)864 HAL_StatusTypeDef HAL_MMC_WriteBlocks(MMC_HandleTypeDef *hmmc, const uint8_t *pData, uint32_t BlockAdd,
865                                       uint32_t NumberOfBlocks, uint32_t Timeout)
866 {
867   SDMMC_DataInitTypeDef config;
868   uint32_t errorstate;
869   uint32_t tickstart = HAL_GetTick();
870   uint32_t count;
871   uint32_t data;
872   uint32_t dataremaining;
873   uint32_t add = BlockAdd;
874   const uint8_t *tempbuff = pData;
875 
876   if (NULL == pData)
877   {
878     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
879     return HAL_ERROR;
880   }
881 
882   if (hmmc->State == HAL_MMC_STATE_READY)
883   {
884     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
885 
886     if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
887     {
888       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
889       return HAL_ERROR;
890     }
891 
892     /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
893     if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U)
894     {
895       if ((NumberOfBlocks % 8U) != 0U)
896       {
897         /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */
898         hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR;
899         return HAL_ERROR;
900       }
901 
902       if ((BlockAdd % 8U) != 0U)
903       {
904         /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
905         hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
906         return HAL_ERROR;
907       }
908     }
909 
910     hmmc->State = HAL_MMC_STATE_BUSY;
911 
912     /* Initialize data control register */
913     hmmc->Instance->DCTRL = 0U;
914 
915     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
916     {
917       add *= MMC_BLOCKSIZE;
918     }
919 
920     /* Configure the MMC DPSM (Data Path State Machine) */
921     config.DataTimeOut   = SDMMC_DATATIMEOUT;
922     config.DataLength    = NumberOfBlocks * MMC_BLOCKSIZE;
923     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
924     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
925     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
926     config.DPSM          = SDMMC_DPSM_DISABLE;
927     (void)SDMMC_ConfigData(hmmc->Instance, &config);
928     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
929 
930     /* Write Blocks in Polling mode */
931     if (NumberOfBlocks > 1U)
932     {
933       hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
934 
935       /* Write Multi Block command */
936       errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
937     }
938     else
939     {
940       hmmc->Context = MMC_CONTEXT_WRITE_SINGLE_BLOCK;
941 
942       /* Write Single Block command */
943       errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
944     }
945     if (errorstate != HAL_MMC_ERROR_NONE)
946     {
947       /* Clear all the static flags */
948       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
949       hmmc->ErrorCode |= errorstate;
950       hmmc->State = HAL_MMC_STATE_READY;
951       return HAL_ERROR;
952     }
953 
954     /* Write block(s) in polling mode */
955     dataremaining = config.DataLength;
956     while (!__HAL_MMC_GET_FLAG(hmmc,
957                                SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
958     {
959       if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= SDMMC_FIFO_SIZE))
960       {
961         /* Write data to SDMMC Tx FIFO */
962         for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
963         {
964           data = (uint32_t)(*tempbuff);
965           tempbuff++;
966           data |= ((uint32_t)(*tempbuff) << 8U);
967           tempbuff++;
968           data |= ((uint32_t)(*tempbuff) << 16U);
969           tempbuff++;
970           data |= ((uint32_t)(*tempbuff) << 24U);
971           tempbuff++;
972           (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
973         }
974         dataremaining -= SDMMC_FIFO_SIZE;
975       }
976 
977       if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
978       {
979         /* Clear all the static flags */
980         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
981         hmmc->ErrorCode |= errorstate;
982         hmmc->State = HAL_MMC_STATE_READY;
983         return HAL_TIMEOUT;
984       }
985     }
986     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
987 
988     /* Send stop transmission command in case of multiblock write */
989     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U))
990     {
991       /* Send stop transmission command */
992       errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
993       if (errorstate != HAL_MMC_ERROR_NONE)
994       {
995         /* Clear all the static flags */
996         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
997         hmmc->ErrorCode |= errorstate;
998         hmmc->State = HAL_MMC_STATE_READY;
999         return HAL_ERROR;
1000       }
1001     }
1002 
1003     /* Get error state */
1004     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
1005     {
1006       /* Clear all the static flags */
1007       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1008       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
1009       hmmc->State = HAL_MMC_STATE_READY;
1010       return HAL_ERROR;
1011     }
1012     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
1013     {
1014       /* Clear all the static flags */
1015       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1016       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
1017       hmmc->State = HAL_MMC_STATE_READY;
1018       return HAL_ERROR;
1019     }
1020     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
1021     {
1022       /* Clear all the static flags */
1023       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1024       hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
1025       hmmc->State = HAL_MMC_STATE_READY;
1026       return HAL_ERROR;
1027     }
1028     else
1029     {
1030       /* Nothing to do */
1031     }
1032 
1033     /* Clear all the static flags */
1034     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
1035 
1036     hmmc->State = HAL_MMC_STATE_READY;
1037 
1038     return HAL_OK;
1039   }
1040   else
1041   {
1042     hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
1043     return HAL_ERROR;
1044   }
1045 }
1046 
1047 /**
1048   * @brief  Reads block(s) from a specified address in a card. The Data transfer
1049   *         is managed in interrupt mode.
1050   * @note   This API should be followed by a check on the card state through
1051   *         HAL_MMC_GetCardState().
1052   * @note   You could also check the IT transfer process through the MMC Rx
1053   *         interrupt event.
1054   * @param  hmmc: Pointer to MMC handle
1055   * @param  pData: Pointer to the buffer that will contain the received data
1056   * @param  BlockAdd: Block Address from where data is to be read
1057   * @param  NumberOfBlocks: Number of blocks to read.
1058   * @retval HAL status
1059   */
HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)1060 HAL_StatusTypeDef HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd,
1061                                         uint32_t NumberOfBlocks)
1062 {
1063   SDMMC_DataInitTypeDef config;
1064   uint32_t errorstate;
1065   uint32_t add = BlockAdd;
1066 
1067   if (NULL == pData)
1068   {
1069     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1070     return HAL_ERROR;
1071   }
1072 
1073   if (hmmc->State == HAL_MMC_STATE_READY)
1074   {
1075     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1076 
1077     if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1078     {
1079       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1080       return HAL_ERROR;
1081     }
1082 
1083     /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
1084     if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U)
1085     {
1086       if ((NumberOfBlocks % 8U) != 0U)
1087       {
1088         /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */
1089         hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR;
1090         return HAL_ERROR;
1091       }
1092 
1093       if ((BlockAdd % 8U) != 0U)
1094       {
1095         /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
1096         hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
1097         return HAL_ERROR;
1098       }
1099     }
1100 
1101     hmmc->State = HAL_MMC_STATE_BUSY;
1102 
1103     /* Initialize data control register */
1104     hmmc->Instance->DCTRL = 0U;
1105 
1106     hmmc->pRxBuffPtr = pData;
1107     hmmc->RxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1108 
1109     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1110     {
1111       add *= MMC_BLOCKSIZE;
1112     }
1113 
1114     /* Configure the MMC DPSM (Data Path State Machine) */
1115     config.DataTimeOut   = SDMMC_DATATIMEOUT;
1116     config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
1117     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1118     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
1119     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
1120     config.DPSM          = SDMMC_DPSM_DISABLE;
1121     (void)SDMMC_ConfigData(hmmc->Instance, &config);
1122     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
1123 
1124     /* Read Blocks in IT mode */
1125     if (NumberOfBlocks > 1U)
1126     {
1127       hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_IT);
1128 
1129       /* Read Multi Block command */
1130       errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
1131     }
1132     else
1133     {
1134       hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_IT);
1135 
1136       /* Read Single Block command */
1137       errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
1138     }
1139 
1140     if (errorstate != HAL_MMC_ERROR_NONE)
1141     {
1142       /* Clear all the static flags */
1143       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1144       hmmc->ErrorCode |= errorstate;
1145       hmmc->State = HAL_MMC_STATE_READY;
1146       return HAL_ERROR;
1147     }
1148 
1149     __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND |
1150                                SDMMC_FLAG_RXFIFOHF));
1151 
1152     return HAL_OK;
1153   }
1154   else
1155   {
1156     return HAL_BUSY;
1157   }
1158 }
1159 
1160 /**
1161   * @brief  Writes block(s) to a specified address in a card. The Data transfer
1162   *         is managed in interrupt mode.
1163   * @note   This API should be followed by a check on the card state through
1164   *         HAL_MMC_GetCardState().
1165   * @note   You could also check the IT transfer process through the MMC Tx
1166   *         interrupt event.
1167   * @param  hmmc: Pointer to MMC handle
1168   * @param  pData: Pointer to the buffer that will contain the data to transmit
1169   * @param  BlockAdd: Block Address where data will be written
1170   * @param  NumberOfBlocks: Number of blocks to write
1171   * @retval HAL status
1172   */
HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef * hmmc,const uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)1173 HAL_StatusTypeDef HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef *hmmc, const uint8_t *pData,
1174                                          uint32_t BlockAdd, uint32_t NumberOfBlocks)
1175 {
1176   SDMMC_DataInitTypeDef config;
1177   uint32_t errorstate;
1178   uint32_t add = BlockAdd;
1179 
1180   if (NULL == pData)
1181   {
1182     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1183     return HAL_ERROR;
1184   }
1185 
1186   if (hmmc->State == HAL_MMC_STATE_READY)
1187   {
1188     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1189 
1190     if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1191     {
1192       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1193       return HAL_ERROR;
1194     }
1195 
1196     /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
1197     if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U)
1198     {
1199       if ((NumberOfBlocks % 8U) != 0U)
1200       {
1201         /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */
1202         hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR;
1203         return HAL_ERROR;
1204       }
1205 
1206       if ((BlockAdd % 8U) != 0U)
1207       {
1208         /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
1209         hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
1210         return HAL_ERROR;
1211       }
1212     }
1213 
1214     hmmc->State = HAL_MMC_STATE_BUSY;
1215 
1216     /* Initialize data control register */
1217     hmmc->Instance->DCTRL = 0U;
1218 
1219     hmmc->pTxBuffPtr = pData;
1220     hmmc->TxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1221 
1222     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1223     {
1224       add *= MMC_BLOCKSIZE;
1225     }
1226 
1227     /* Configure the MMC DPSM (Data Path State Machine) */
1228     config.DataTimeOut   = SDMMC_DATATIMEOUT;
1229     config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
1230     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1231     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
1232     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
1233     config.DPSM          = SDMMC_DPSM_DISABLE;
1234     (void)SDMMC_ConfigData(hmmc->Instance, &config);
1235 
1236     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
1237 
1238     /* Write Blocks in Polling mode */
1239     if (NumberOfBlocks > 1U)
1240     {
1241       hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_IT);
1242 
1243       /* Write Multi Block command */
1244       errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
1245     }
1246     else
1247     {
1248       hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_IT);
1249 
1250       /* Write Single Block command */
1251       errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
1252     }
1253     if (errorstate != HAL_MMC_ERROR_NONE)
1254     {
1255       /* Clear all the static flags */
1256       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1257       hmmc->ErrorCode |= errorstate;
1258       hmmc->State = HAL_MMC_STATE_READY;
1259       return HAL_ERROR;
1260     }
1261 
1262     /* Enable transfer interrupts */
1263     __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND |
1264                                SDMMC_FLAG_TXFIFOHE));
1265 
1266     return HAL_OK;
1267   }
1268   else
1269   {
1270     return HAL_BUSY;
1271   }
1272 }
1273 
1274 /**
1275   * @brief  Reads block(s) from a specified address in a card. The Data transfer
1276   *         is managed by DMA mode.
1277   * @note   This API should be followed by a check on the card state through
1278   *         HAL_MMC_GetCardState().
1279   * @note   You could also check the DMA transfer process through the MMC Rx
1280   *         interrupt event.
1281   * @param  hmmc: Pointer MMC handle
1282   * @param  pData: Pointer to the buffer that will contain the received data
1283   * @param  BlockAdd: Block Address from where data is to be read
1284   * @param  NumberOfBlocks: Number of blocks to read.
1285   * @retval HAL status
1286   */
HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)1287 HAL_StatusTypeDef HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd,
1288                                          uint32_t NumberOfBlocks)
1289 {
1290   SDMMC_DataInitTypeDef config;
1291   uint32_t errorstate;
1292   uint32_t add = BlockAdd;
1293 
1294   if (NULL == pData)
1295   {
1296     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1297     return HAL_ERROR;
1298   }
1299 
1300   if (hmmc->State == HAL_MMC_STATE_READY)
1301   {
1302     hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
1303 
1304     if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1305     {
1306       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1307       return HAL_ERROR;
1308     }
1309 
1310     /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
1311     if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U)
1312     {
1313       if ((NumberOfBlocks % 8U) != 0U)
1314       {
1315         /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */
1316         hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR;
1317         return HAL_ERROR;
1318       }
1319 
1320       if ((BlockAdd % 8U) != 0U)
1321       {
1322         /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
1323         hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
1324         return HAL_ERROR;
1325       }
1326     }
1327 
1328     hmmc->State = HAL_MMC_STATE_BUSY;
1329 
1330     /* Initialize data control register */
1331     hmmc->Instance->DCTRL = 0U;
1332 
1333     hmmc->pRxBuffPtr = pData;
1334     hmmc->RxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1335 
1336     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1337     {
1338       add *= MMC_BLOCKSIZE;
1339     }
1340 
1341     /* Configure the MMC DPSM (Data Path State Machine) */
1342     config.DataTimeOut   = SDMMC_DATATIMEOUT;
1343     config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
1344     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1345     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
1346     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
1347     config.DPSM          = SDMMC_DPSM_DISABLE;
1348     (void)SDMMC_ConfigData(hmmc->Instance, &config);
1349 
1350     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
1351     hmmc->Instance->IDMABASE0 = (uint32_t) pData ;
1352     hmmc->Instance->IDMACTRL  = SDMMC_ENABLE_IDMA_SINGLE_BUFF;
1353 
1354     /* Read Blocks in DMA mode */
1355     if (NumberOfBlocks > 1U)
1356     {
1357       hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
1358 
1359       /* Read Multi Block command */
1360       errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
1361     }
1362     else
1363     {
1364       hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_DMA);
1365 
1366       /* Read Single Block command */
1367       errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
1368     }
1369     if (errorstate != HAL_MMC_ERROR_NONE)
1370     {
1371       /* Clear all the static flags */
1372       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1373       hmmc->ErrorCode = errorstate;
1374       hmmc->State = HAL_MMC_STATE_READY;
1375       return HAL_ERROR;
1376     }
1377 
1378     /* Enable transfer interrupts */
1379     __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND));
1380 
1381     return HAL_OK;
1382   }
1383   else
1384   {
1385     return HAL_BUSY;
1386   }
1387 }
1388 
1389 /**
1390   * @brief  Writes block(s) to a specified address in a card. The Data transfer
1391   *         is managed by DMA mode.
1392   * @note   This API should be followed by a check on the card state through
1393   *         HAL_MMC_GetCardState().
1394   * @note   You could also check the DMA transfer process through the MMC Tx
1395   *         interrupt event.
1396   * @param  hmmc: Pointer to MMC handle
1397   * @param  pData: Pointer to the buffer that will contain the data to transmit
1398   * @param  BlockAdd: Block Address where data will be written
1399   * @param  NumberOfBlocks: Number of blocks to write
1400   * @retval HAL status
1401   */
HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef * hmmc,const uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)1402 HAL_StatusTypeDef HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef *hmmc, const uint8_t *pData,
1403                                           uint32_t BlockAdd, uint32_t NumberOfBlocks)
1404 {
1405   SDMMC_DataInitTypeDef config;
1406   uint32_t errorstate;
1407   uint32_t add = BlockAdd;
1408 
1409   if (NULL == pData)
1410   {
1411     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1412     return HAL_ERROR;
1413   }
1414 
1415   if (hmmc->State == HAL_MMC_STATE_READY)
1416   {
1417     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1418 
1419     if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1420     {
1421       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1422       return HAL_ERROR;
1423     }
1424 
1425     /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
1426     if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U)
1427     {
1428       if ((NumberOfBlocks % 8U) != 0U)
1429       {
1430         /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */
1431         hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR;
1432         return HAL_ERROR;
1433       }
1434 
1435       if ((BlockAdd % 8U) != 0U)
1436       {
1437         /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
1438         hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
1439         return HAL_ERROR;
1440       }
1441     }
1442 
1443     hmmc->State = HAL_MMC_STATE_BUSY;
1444 
1445     /* Initialize data control register */
1446     hmmc->Instance->DCTRL = 0U;
1447 
1448     hmmc->pTxBuffPtr = pData;
1449     hmmc->TxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1450 
1451     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1452     {
1453       add *= MMC_BLOCKSIZE;
1454     }
1455 
1456     /* Configure the MMC DPSM (Data Path State Machine) */
1457     config.DataTimeOut   = SDMMC_DATATIMEOUT;
1458     config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
1459     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1460     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
1461     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
1462     config.DPSM          = SDMMC_DPSM_DISABLE;
1463     (void)SDMMC_ConfigData(hmmc->Instance, &config);
1464 
1465     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
1466 
1467     hmmc->Instance->IDMABASE0 = (uint32_t) pData ;
1468     hmmc->Instance->IDMACTRL  = SDMMC_ENABLE_IDMA_SINGLE_BUFF;
1469 
1470     /* Write Blocks in Polling mode */
1471     if (NumberOfBlocks > 1U)
1472     {
1473       hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
1474 
1475       /* Write Multi Block command */
1476       errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
1477     }
1478     else
1479     {
1480       hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_DMA);
1481 
1482       /* Write Single Block command */
1483       errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
1484     }
1485     if (errorstate != HAL_MMC_ERROR_NONE)
1486     {
1487       /* Clear all the static flags */
1488       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1489       hmmc->ErrorCode |= errorstate;
1490       hmmc->State = HAL_MMC_STATE_READY;
1491       return HAL_ERROR;
1492     }
1493 
1494     /* Enable transfer interrupts */
1495     __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND));
1496 
1497     return HAL_OK;
1498   }
1499   else
1500   {
1501     return HAL_BUSY;
1502   }
1503 }
1504 
1505 /**
1506   * @brief  Erases the specified memory area of the given MMC card.
1507   * @note   This API should be followed by a check on the card state through
1508   *         HAL_MMC_GetCardState().
1509   * @param  hmmc: Pointer to MMC handle
1510   * @param  BlockStartAdd: Start Block address
1511   * @param  BlockEndAdd: End Block address
1512   * @retval HAL status
1513   */
HAL_MMC_Erase(MMC_HandleTypeDef * hmmc,uint32_t BlockStartAdd,uint32_t BlockEndAdd)1514 HAL_StatusTypeDef HAL_MMC_Erase(MMC_HandleTypeDef *hmmc, uint32_t BlockStartAdd, uint32_t BlockEndAdd)
1515 {
1516   uint32_t errorstate;
1517   uint32_t start_add = BlockStartAdd;
1518   uint32_t end_add = BlockEndAdd;
1519 
1520   if (hmmc->State == HAL_MMC_STATE_READY)
1521   {
1522     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1523 
1524     if (end_add < start_add)
1525     {
1526       hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1527       return HAL_ERROR;
1528     }
1529 
1530     if (end_add > (hmmc->MmcCard.LogBlockNbr))
1531     {
1532       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1533       return HAL_ERROR;
1534     }
1535 
1536     /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
1537     if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS)
1538          & 0x000000FFU) != 0x0U)
1539     {
1540       if (((start_add % 8U) != 0U) || ((end_add % 8U) != 0U))
1541       {
1542         /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
1543         hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
1544         return HAL_ERROR;
1545       }
1546     }
1547 
1548     hmmc->State = HAL_MMC_STATE_BUSY;
1549 
1550     /* Check if the card command class supports erase command */
1551     if (((hmmc->MmcCard.Class) & SDMMC_CCCC_ERASE) == 0U)
1552     {
1553       /* Clear all the static flags */
1554       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1555       hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
1556       hmmc->State = HAL_MMC_STATE_READY;
1557       return HAL_ERROR;
1558     }
1559 
1560     if ((SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
1561     {
1562       /* Clear all the static flags */
1563       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1564       hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED;
1565       hmmc->State = HAL_MMC_STATE_READY;
1566       return HAL_ERROR;
1567     }
1568 
1569     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1570     {
1571       start_add *= MMC_BLOCKSIZE;
1572       end_add   *= MMC_BLOCKSIZE;
1573     }
1574 
1575     /* Send CMD35 MMC_ERASE_GRP_START with argument as addr  */
1576     errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, start_add);
1577     if (errorstate != HAL_MMC_ERROR_NONE)
1578     {
1579       /* Clear all the static flags */
1580       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1581       hmmc->ErrorCode |= errorstate;
1582       hmmc->State = HAL_MMC_STATE_READY;
1583       return HAL_ERROR;
1584     }
1585 
1586     /* Send CMD36 MMC_ERASE_GRP_END with argument as addr  */
1587     errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, end_add);
1588     if (errorstate != HAL_MMC_ERROR_NONE)
1589     {
1590       /* Clear all the static flags */
1591       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1592       hmmc->ErrorCode |= errorstate;
1593       hmmc->State = HAL_MMC_STATE_READY;
1594       return HAL_ERROR;
1595     }
1596 
1597     /* Send CMD38 ERASE */
1598     errorstate = SDMMC_CmdErase(hmmc->Instance, 0UL);
1599     if (errorstate != HAL_MMC_ERROR_NONE)
1600     {
1601       /* Clear all the static flags */
1602       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1603       hmmc->ErrorCode |= errorstate;
1604       hmmc->State = HAL_MMC_STATE_READY;
1605       return HAL_ERROR;
1606     }
1607 
1608     hmmc->State = HAL_MMC_STATE_READY;
1609 
1610     return HAL_OK;
1611   }
1612   else
1613   {
1614     return HAL_BUSY;
1615   }
1616 }
1617 
1618 /**
1619   * @brief  This function handles MMC card interrupt request.
1620   * @param  hmmc: Pointer to MMC handle
1621   * @retval None
1622   */
HAL_MMC_IRQHandler(MMC_HandleTypeDef * hmmc)1623 void HAL_MMC_IRQHandler(MMC_HandleTypeDef *hmmc)
1624 {
1625   uint32_t errorstate;
1626   uint32_t context = hmmc->Context;
1627 
1628   /* Check for SDMMC interrupt flags */
1629   if ((__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) != RESET) && ((context & MMC_CONTEXT_IT) != 0U))
1630   {
1631     MMC_Read_IT(hmmc);
1632   }
1633 
1634   else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) != RESET)
1635   {
1636     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_DATAEND);
1637 
1638     __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND  | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | \
1639                          SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR  | SDMMC_IT_TXFIFOHE | \
1640                          SDMMC_IT_RXFIFOHF);
1641 
1642     __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_IDMABTC);
1643     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
1644 
1645     if ((context & MMC_CONTEXT_DMA) != 0U)
1646     {
1647       hmmc->Instance->DLEN = 0;
1648       hmmc->Instance->DCTRL = 0;
1649       hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA ;
1650 
1651       /* Stop Transfer for Write Multi blocks or Read Multi blocks */
1652       if (((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
1653       {
1654         errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
1655         if (errorstate != HAL_MMC_ERROR_NONE)
1656         {
1657           hmmc->ErrorCode |= errorstate;
1658 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1659           hmmc->ErrorCallback(hmmc);
1660 #else
1661           HAL_MMC_ErrorCallback(hmmc);
1662 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1663         }
1664       }
1665 
1666       /* Clear all the static flags */
1667       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
1668 
1669       hmmc->State = HAL_MMC_STATE_READY;
1670       if (((context & MMC_CONTEXT_WRITE_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
1671       {
1672 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1673         hmmc->TxCpltCallback(hmmc);
1674 #else
1675         HAL_MMC_TxCpltCallback(hmmc);
1676 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1677       }
1678       if (((context & MMC_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
1679       {
1680 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1681         hmmc->RxCpltCallback(hmmc);
1682 #else
1683         HAL_MMC_RxCpltCallback(hmmc);
1684 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1685       }
1686     }
1687     else if ((context & MMC_CONTEXT_IT) != 0U)
1688     {
1689       /* Stop Transfer for Write Multi blocks or Read Multi blocks */
1690       if (((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
1691       {
1692         errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
1693         if (errorstate != HAL_MMC_ERROR_NONE)
1694         {
1695           hmmc->ErrorCode |= errorstate;
1696 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1697           hmmc->ErrorCallback(hmmc);
1698 #else
1699           HAL_MMC_ErrorCallback(hmmc);
1700 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1701         }
1702       }
1703 
1704       /* Clear all the static flags */
1705       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
1706 
1707       hmmc->State = HAL_MMC_STATE_READY;
1708       if (((context & MMC_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
1709       {
1710 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1711         hmmc->RxCpltCallback(hmmc);
1712 #else
1713         HAL_MMC_RxCpltCallback(hmmc);
1714 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1715       }
1716       else
1717       {
1718 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1719         hmmc->TxCpltCallback(hmmc);
1720 #else
1721         HAL_MMC_TxCpltCallback(hmmc);
1722 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1723       }
1724     }
1725     else
1726     {
1727       /* Nothing to do */
1728     }
1729   }
1730 
1731   else if ((__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) != RESET) && ((context & MMC_CONTEXT_IT) != 0U))
1732   {
1733     MMC_Write_IT(hmmc);
1734   }
1735 
1736   else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL |
1737                               SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_RXOVERR | SDMMC_FLAG_TXUNDERR) != RESET)
1738   {
1739     /* Set Error code */
1740     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_DCRCFAIL) != RESET)
1741     {
1742       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
1743     }
1744     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_DTIMEOUT) != RESET)
1745     {
1746       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
1747     }
1748     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_RXOVERR) != RESET)
1749     {
1750       hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
1751     }
1752     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_TXUNDERR) != RESET)
1753     {
1754       hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
1755     }
1756 
1757     /* Clear All flags */
1758     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
1759 
1760     /* Disable all interrupts */
1761     __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | \
1762                          SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR);
1763 
1764     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
1765     hmmc->Instance->DCTRL |= SDMMC_DCTRL_FIFORST;
1766     hmmc->Instance->CMD |= SDMMC_CMD_CMDSTOP;
1767     hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
1768     hmmc->Instance->CMD &= ~(SDMMC_CMD_CMDSTOP);
1769     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_DABORT);
1770 
1771     if ((context & MMC_CONTEXT_IT) != 0U)
1772     {
1773       /* Set the MMC state to ready to be able to start again the process */
1774       hmmc->State = HAL_MMC_STATE_READY;
1775 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1776       hmmc->ErrorCallback(hmmc);
1777 #else
1778       HAL_MMC_ErrorCallback(hmmc);
1779 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1780     }
1781     else if ((context & MMC_CONTEXT_DMA) != 0U)
1782     {
1783       if (hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
1784       {
1785         /* Disable Internal DMA */
1786         __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_IDMABTC);
1787         hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA;
1788 
1789         /* Set the MMC state to ready to be able to start again the process */
1790         hmmc->State = HAL_MMC_STATE_READY;
1791 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1792         hmmc->ErrorCallback(hmmc);
1793 #else
1794         HAL_MMC_ErrorCallback(hmmc);
1795 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1796       }
1797     }
1798     else
1799     {
1800       /* Nothing to do */
1801     }
1802   }
1803 
1804   else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_IDMABTC) != RESET)
1805   {
1806     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_IT_IDMABTC);
1807     if (READ_BIT(hmmc->Instance->IDMACTRL, SDMMC_IDMA_IDMABACT) == 0U)
1808     {
1809       /* Current buffer is buffer0, Transfer complete for buffer1 */
1810       if ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)
1811       {
1812 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1813         hmmc->Write_DMADblBuf1CpltCallback(hmmc);
1814 #else
1815         HAL_MMCEx_Write_DMADoubleBuf1CpltCallback(hmmc);
1816 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1817       }
1818       else /* MMC_CONTEXT_READ_MULTIPLE_BLOCK */
1819       {
1820 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1821         hmmc->Read_DMADblBuf1CpltCallback(hmmc);
1822 #else
1823         HAL_MMCEx_Read_DMADoubleBuf1CpltCallback(hmmc);
1824 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1825       }
1826     }
1827     else /* MMC_DMA_BUFFER1 */
1828     {
1829       /* Current buffer is buffer1, Transfer complete for buffer0 */
1830       if ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)
1831       {
1832 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1833         hmmc->Write_DMADblBuf0CpltCallback(hmmc);
1834 #else
1835         HAL_MMCEx_Write_DMADoubleBuf0CpltCallback(hmmc);
1836 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1837       }
1838       else /* MMC_CONTEXT_READ_MULTIPLE_BLOCK */
1839       {
1840 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1841         hmmc->Read_DMADblBuf0CpltCallback(hmmc);
1842 #else
1843         HAL_MMCEx_Read_DMADoubleBuf0CpltCallback(hmmc);
1844 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1845       }
1846     }
1847   }
1848 
1849   else
1850   {
1851     /* Nothing to do */
1852   }
1853 }
1854 
1855 /**
1856   * @brief return the MMC state
1857   * @param hmmc: Pointer to mmc handle
1858   * @retval HAL state
1859   */
HAL_MMC_GetState(const MMC_HandleTypeDef * hmmc)1860 HAL_MMC_StateTypeDef HAL_MMC_GetState(const MMC_HandleTypeDef *hmmc)
1861 {
1862   return hmmc->State;
1863 }
1864 
1865 /**
1866   * @brief  Return the MMC error code
1867   * @param  hmmc : Pointer to a MMC_HandleTypeDef structure that contains
1868   *              the configuration information.
1869   * @retval MMC Error Code
1870   */
HAL_MMC_GetError(const MMC_HandleTypeDef * hmmc)1871 uint32_t HAL_MMC_GetError(const MMC_HandleTypeDef *hmmc)
1872 {
1873   return hmmc->ErrorCode;
1874 }
1875 
1876 /**
1877   * @brief Tx Transfer completed callbacks
1878   * @param hmmc: Pointer to MMC handle
1879   * @retval None
1880   */
HAL_MMC_TxCpltCallback(MMC_HandleTypeDef * hmmc)1881 __weak void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef *hmmc)
1882 {
1883   /* Prevent unused argument(s) compilation warning */
1884   UNUSED(hmmc);
1885 
1886   /* NOTE : This function should not be modified, when the callback is needed,
1887             the HAL_MMC_TxCpltCallback can be implemented in the user file
1888    */
1889 }
1890 
1891 /**
1892   * @brief Rx Transfer completed callbacks
1893   * @param hmmc: Pointer MMC handle
1894   * @retval None
1895   */
HAL_MMC_RxCpltCallback(MMC_HandleTypeDef * hmmc)1896 __weak void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef *hmmc)
1897 {
1898   /* Prevent unused argument(s) compilation warning */
1899   UNUSED(hmmc);
1900 
1901   /* NOTE : This function should not be modified, when the callback is needed,
1902             the HAL_MMC_RxCpltCallback can be implemented in the user file
1903    */
1904 }
1905 
1906 /**
1907   * @brief MMC error callbacks
1908   * @param hmmc: Pointer MMC handle
1909   * @retval None
1910   */
HAL_MMC_ErrorCallback(MMC_HandleTypeDef * hmmc)1911 __weak void HAL_MMC_ErrorCallback(MMC_HandleTypeDef *hmmc)
1912 {
1913   /* Prevent unused argument(s) compilation warning */
1914   UNUSED(hmmc);
1915 
1916   /* NOTE : This function should not be modified, when the callback is needed,
1917             the HAL_MMC_ErrorCallback can be implemented in the user file
1918    */
1919 }
1920 
1921 /**
1922   * @brief MMC Abort callbacks
1923   * @param hmmc: Pointer MMC handle
1924   * @retval None
1925   */
HAL_MMC_AbortCallback(MMC_HandleTypeDef * hmmc)1926 __weak void HAL_MMC_AbortCallback(MMC_HandleTypeDef *hmmc)
1927 {
1928   /* Prevent unused argument(s) compilation warning */
1929   UNUSED(hmmc);
1930 
1931   /* NOTE : This function should not be modified, when the callback is needed,
1932             the HAL_MMC_AbortCallback can be implemented in the user file
1933    */
1934 }
1935 
1936 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1937 /**
1938   * @brief  Register a User MMC Callback
1939   *         To be used instead of the weak (overridden) predefined callback
1940   * @note   The HAL_MMC_RegisterCallback() may be called before HAL_MMC_Init() in
1941   *         HAL_MMC_STATE_RESET to register callbacks for HAL_MMC_MSP_INIT_CB_ID
1942   *         and HAL_MMC_MSP_DEINIT_CB_ID.
1943   * @param hmmc : MMC handle
1944   * @param CallbackId : ID of the callback to be registered
1945   *        This parameter can be one of the following values:
1946   *          @arg @ref HAL_MMC_TX_CPLT_CB_ID                 MMC Tx Complete Callback ID
1947   *          @arg @ref HAL_MMC_RX_CPLT_CB_ID                 MMC Rx Complete Callback ID
1948   *          @arg @ref HAL_MMC_ERROR_CB_ID                   MMC Error Callback ID
1949   *          @arg @ref HAL_MMC_ABORT_CB_ID                   MMC Abort Callback ID
1950   *          @arg @ref HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID  MMC DMA Rx Double buffer 0 Callback ID
1951   *          @arg @ref HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID  MMC DMA Rx Double buffer 1 Callback ID
1952   *          @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID MMC DMA Tx Double buffer 0 Callback ID
1953   *          @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID MMC DMA Tx Double buffer 1 Callback ID
1954   *          @arg @ref HAL_MMC_MSP_INIT_CB_ID                MMC MspInit Callback ID
1955   *          @arg @ref HAL_MMC_MSP_DEINIT_CB_ID              MMC MspDeInit Callback ID
1956   * @param pCallback : pointer to the Callback function
1957   * @retval status
1958   */
HAL_MMC_RegisterCallback(MMC_HandleTypeDef * hmmc,HAL_MMC_CallbackIDTypeDef CallbackId,pMMC_CallbackTypeDef pCallback)1959 HAL_StatusTypeDef HAL_MMC_RegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId,
1960                                            pMMC_CallbackTypeDef pCallback)
1961 {
1962   HAL_StatusTypeDef status = HAL_OK;
1963 
1964   if (pCallback == NULL)
1965   {
1966     /* Update the error code */
1967     hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1968     return HAL_ERROR;
1969   }
1970 
1971   if (hmmc->State == HAL_MMC_STATE_READY)
1972   {
1973     switch (CallbackId)
1974     {
1975       case HAL_MMC_TX_CPLT_CB_ID :
1976         hmmc->TxCpltCallback = pCallback;
1977         break;
1978       case HAL_MMC_RX_CPLT_CB_ID :
1979         hmmc->RxCpltCallback = pCallback;
1980         break;
1981       case HAL_MMC_ERROR_CB_ID :
1982         hmmc->ErrorCallback = pCallback;
1983         break;
1984       case HAL_MMC_ABORT_CB_ID :
1985         hmmc->AbortCpltCallback = pCallback;
1986         break;
1987       case HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID :
1988         hmmc->Read_DMADblBuf0CpltCallback = pCallback;
1989         break;
1990       case HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID :
1991         hmmc->Read_DMADblBuf1CpltCallback = pCallback;
1992         break;
1993       case HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID :
1994         hmmc->Write_DMADblBuf0CpltCallback = pCallback;
1995         break;
1996       case HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID :
1997         hmmc->Write_DMADblBuf1CpltCallback = pCallback;
1998         break;
1999       case HAL_MMC_MSP_INIT_CB_ID :
2000         hmmc->MspInitCallback = pCallback;
2001         break;
2002       case HAL_MMC_MSP_DEINIT_CB_ID :
2003         hmmc->MspDeInitCallback = pCallback;
2004         break;
2005       default :
2006         /* Update the error code */
2007         hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
2008         /* update return status */
2009         status =  HAL_ERROR;
2010         break;
2011     }
2012   }
2013   else if (hmmc->State == HAL_MMC_STATE_RESET)
2014   {
2015     switch (CallbackId)
2016     {
2017       case HAL_MMC_MSP_INIT_CB_ID :
2018         hmmc->MspInitCallback = pCallback;
2019         break;
2020       case HAL_MMC_MSP_DEINIT_CB_ID :
2021         hmmc->MspDeInitCallback = pCallback;
2022         break;
2023       default :
2024         /* Update the error code */
2025         hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
2026         /* update return status */
2027         status =  HAL_ERROR;
2028         break;
2029     }
2030   }
2031   else
2032   {
2033     /* Update the error code */
2034     hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
2035     /* update return status */
2036     status =  HAL_ERROR;
2037   }
2038 
2039   return status;
2040 }
2041 
2042 /**
2043   * @brief  Unregister a User MMC Callback
2044   *         MMC Callback is redirected to the weak (overridden) predefined callback
2045   * @note   The HAL_MMC_UnRegisterCallback() may be called before HAL_MMC_Init() in
2046   *         HAL_MMC_STATE_RESET to register callbacks for HAL_MMC_MSP_INIT_CB_ID
2047   *         and HAL_MMC_MSP_DEINIT_CB_ID.
2048   * @param hmmc : MMC handle
2049   * @param CallbackId : ID of the callback to be unregistered
2050   *        This parameter can be one of the following values:
2051   *          @arg @ref HAL_MMC_TX_CPLT_CB_ID                 MMC Tx Complete Callback ID
2052   *          @arg @ref HAL_MMC_RX_CPLT_CB_ID                 MMC Rx Complete Callback ID
2053   *          @arg @ref HAL_MMC_ERROR_CB_ID                   MMC Error Callback ID
2054   *          @arg @ref HAL_MMC_ABORT_CB_ID                   MMC Abort Callback ID
2055   *          @arg @ref HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID  MMC DMA Rx Double buffer 0 Callback ID
2056   *          @arg @ref HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID  MMC DMA Rx Double buffer 1 Callback ID
2057   *          @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID MMC DMA Tx Double buffer 0 Callback ID
2058   *          @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID MMC DMA Tx Double buffer 1 Callback ID
2059   *          @arg @ref HAL_MMC_MSP_INIT_CB_ID                MMC MspInit Callback ID
2060   *          @arg @ref HAL_MMC_MSP_DEINIT_CB_ID              MMC MspDeInit Callback ID
2061   * @retval status
2062   */
HAL_MMC_UnRegisterCallback(MMC_HandleTypeDef * hmmc,HAL_MMC_CallbackIDTypeDef CallbackId)2063 HAL_StatusTypeDef HAL_MMC_UnRegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId)
2064 {
2065   HAL_StatusTypeDef status = HAL_OK;
2066 
2067   if (hmmc->State == HAL_MMC_STATE_READY)
2068   {
2069     switch (CallbackId)
2070     {
2071       case HAL_MMC_TX_CPLT_CB_ID :
2072         hmmc->TxCpltCallback = HAL_MMC_TxCpltCallback;
2073         break;
2074       case HAL_MMC_RX_CPLT_CB_ID :
2075         hmmc->RxCpltCallback = HAL_MMC_RxCpltCallback;
2076         break;
2077       case HAL_MMC_ERROR_CB_ID :
2078         hmmc->ErrorCallback = HAL_MMC_ErrorCallback;
2079         break;
2080       case HAL_MMC_ABORT_CB_ID :
2081         hmmc->AbortCpltCallback = HAL_MMC_AbortCallback;
2082         break;
2083       case HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID :
2084         hmmc->Read_DMADblBuf0CpltCallback = HAL_MMCEx_Read_DMADoubleBuf0CpltCallback;
2085         break;
2086       case HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID :
2087         hmmc->Read_DMADblBuf1CpltCallback = HAL_MMCEx_Read_DMADoubleBuf1CpltCallback;
2088         break;
2089       case HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID :
2090         hmmc->Write_DMADblBuf0CpltCallback = HAL_MMCEx_Write_DMADoubleBuf0CpltCallback;
2091         break;
2092       case HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID :
2093         hmmc->Write_DMADblBuf1CpltCallback = HAL_MMCEx_Write_DMADoubleBuf1CpltCallback;
2094         break;
2095       case HAL_MMC_MSP_INIT_CB_ID :
2096         hmmc->MspInitCallback = HAL_MMC_MspInit;
2097         break;
2098       case HAL_MMC_MSP_DEINIT_CB_ID :
2099         hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
2100         break;
2101       default :
2102         /* Update the error code */
2103         hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
2104         /* update return status */
2105         status =  HAL_ERROR;
2106         break;
2107     }
2108   }
2109   else if (hmmc->State == HAL_MMC_STATE_RESET)
2110   {
2111     switch (CallbackId)
2112     {
2113       case HAL_MMC_MSP_INIT_CB_ID :
2114         hmmc->MspInitCallback = HAL_MMC_MspInit;
2115         break;
2116       case HAL_MMC_MSP_DEINIT_CB_ID :
2117         hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
2118         break;
2119       default :
2120         /* Update the error code */
2121         hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
2122         /* update return status */
2123         status =  HAL_ERROR;
2124         break;
2125     }
2126   }
2127   else
2128   {
2129     /* Update the error code */
2130     hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
2131     /* update return status */
2132     status =  HAL_ERROR;
2133   }
2134 
2135   return status;
2136 }
2137 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
2138 
2139 /**
2140   * @}
2141   */
2142 
2143 /** @addtogroup MMC_Exported_Functions_Group3
2144   *  @brief   management functions
2145   *
2146 @verbatim
2147   ==============================================================================
2148                       ##### Peripheral Control functions #####
2149   ==============================================================================
2150   [..]
2151     This subsection provides a set of functions allowing to control the MMC card
2152     operations and get the related information
2153 
2154 @endverbatim
2155   * @{
2156   */
2157 
2158 /**
2159   * @brief  Returns information the information of the card which are stored on
2160   *         the CID register.
2161   * @param  hmmc: Pointer to MMC handle
2162   * @param  pCID: Pointer to a HAL_MMC_CIDTypedef structure that
2163   *         contains all CID register parameters
2164   * @retval HAL status
2165   */
HAL_MMC_GetCardCID(const MMC_HandleTypeDef * hmmc,HAL_MMC_CardCIDTypeDef * pCID)2166 HAL_StatusTypeDef HAL_MMC_GetCardCID(const MMC_HandleTypeDef *hmmc, HAL_MMC_CardCIDTypeDef *pCID)
2167 {
2168   pCID->ManufacturerID = (uint8_t)((hmmc->CID[0] & 0xFF000000U) >> 24U);
2169 
2170   pCID->OEM_AppliID = (uint16_t)((hmmc->CID[0] & 0x00FFFF00U) >> 8U);
2171 
2172   pCID->ProdName1 = (((hmmc->CID[0] & 0x000000FFU) << 24U) | ((hmmc->CID[1] & 0xFFFFFF00U) >> 8U));
2173 
2174   pCID->ProdName2 = (uint8_t)(hmmc->CID[1] & 0x000000FFU);
2175 
2176   pCID->ProdRev = (uint8_t)((hmmc->CID[2] & 0xFF000000U) >> 24U);
2177 
2178   pCID->ProdSN = (((hmmc->CID[2] & 0x00FFFFFFU) << 8U) | ((hmmc->CID[3] & 0xFF000000U) >> 24U));
2179 
2180   pCID->Reserved1 = (uint8_t)((hmmc->CID[3] & 0x00F00000U) >> 20U);
2181 
2182   pCID->ManufactDate = (uint16_t)((hmmc->CID[3] & 0x000FFF00U) >> 8U);
2183 
2184   pCID->CID_CRC = (uint8_t)((hmmc->CID[3] & 0x000000FEU) >> 1U);
2185 
2186   pCID->Reserved2 = 1U;
2187 
2188   return HAL_OK;
2189 }
2190 
2191 /**
2192   * @brief  Returns information the information of the card which are stored on
2193   *         the CSD register.
2194   * @param  hmmc: Pointer to MMC handle
2195   * @param  pCSD: Pointer to a HAL_MMC_CardCSDTypeDef structure that
2196   *         contains all CSD register parameters
2197   * @retval HAL status
2198   */
HAL_MMC_GetCardCSD(MMC_HandleTypeDef * hmmc,HAL_MMC_CardCSDTypeDef * pCSD)2199 HAL_StatusTypeDef HAL_MMC_GetCardCSD(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCSDTypeDef *pCSD)
2200 {
2201   uint32_t block_nbr = 0;
2202 
2203   pCSD->CSDStruct = (uint8_t)((hmmc->CSD[0] & 0xC0000000U) >> 30U);
2204 
2205   pCSD->SysSpecVersion = (uint8_t)((hmmc->CSD[0] & 0x3C000000U) >> 26U);
2206 
2207   pCSD->Reserved1 = (uint8_t)((hmmc->CSD[0] & 0x03000000U) >> 24U);
2208 
2209   pCSD->TAAC = (uint8_t)((hmmc->CSD[0] & 0x00FF0000U) >> 16U);
2210 
2211   pCSD->NSAC = (uint8_t)((hmmc->CSD[0] & 0x0000FF00U) >> 8U);
2212 
2213   pCSD->MaxBusClkFrec = (uint8_t)(hmmc->CSD[0] & 0x000000FFU);
2214 
2215   pCSD->CardComdClasses = (uint16_t)((hmmc->CSD[1] & 0xFFF00000U) >> 20U);
2216 
2217   pCSD->RdBlockLen = (uint8_t)((hmmc->CSD[1] & 0x000F0000U) >> 16U);
2218 
2219   pCSD->PartBlockRead   = (uint8_t)((hmmc->CSD[1] & 0x00008000U) >> 15U);
2220 
2221   pCSD->WrBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00004000U) >> 14U);
2222 
2223   pCSD->RdBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00002000U) >> 13U);
2224 
2225   pCSD->DSRImpl = (uint8_t)((hmmc->CSD[1] & 0x00001000U) >> 12U);
2226 
2227   pCSD->Reserved2 = 0U; /*!< Reserved */
2228 
2229   if (MMC_ReadExtCSD(hmmc, &block_nbr, 212, 0x0FFFFFFFU) != HAL_OK) /* Field SEC_COUNT [215:212] */
2230   {
2231     return HAL_ERROR;
2232   }
2233 
2234   if (hmmc->MmcCard.CardType == MMC_LOW_CAPACITY_CARD)
2235   {
2236     pCSD->DeviceSize = (((hmmc->CSD[1] & 0x000003FFU) << 2U) | ((hmmc->CSD[2] & 0xC0000000U) >> 30U));
2237 
2238     pCSD->MaxRdCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x38000000U) >> 27U);
2239 
2240     pCSD->MaxRdCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x07000000U) >> 24U);
2241 
2242     pCSD->MaxWrCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x00E00000U) >> 21U);
2243 
2244     pCSD->MaxWrCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x001C0000U) >> 18U);
2245 
2246     pCSD->DeviceSizeMul = (uint8_t)((hmmc->CSD[2] & 0x00038000U) >> 15U);
2247 
2248     hmmc->MmcCard.BlockNbr  = (pCSD->DeviceSize + 1U) ;
2249     hmmc->MmcCard.BlockNbr *= (1UL << ((pCSD->DeviceSizeMul & 0x07U) + 2U));
2250     hmmc->MmcCard.BlockSize = (1UL << (pCSD->RdBlockLen & 0x0FU));
2251 
2252     hmmc->MmcCard.LogBlockNbr = (hmmc->MmcCard.BlockNbr) * ((hmmc->MmcCard.BlockSize) / MMC_BLOCKSIZE);
2253     hmmc->MmcCard.LogBlockSize = MMC_BLOCKSIZE;
2254   }
2255   else if (hmmc->MmcCard.CardType == MMC_HIGH_CAPACITY_CARD)
2256   {
2257     hmmc->MmcCard.BlockNbr = block_nbr;
2258     hmmc->MmcCard.LogBlockNbr = hmmc->MmcCard.BlockNbr;
2259     hmmc->MmcCard.BlockSize = MMC_BLOCKSIZE;
2260     hmmc->MmcCard.LogBlockSize = hmmc->MmcCard.BlockSize;
2261   }
2262   else
2263   {
2264     /* Clear all the static flags */
2265     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2266     hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2267     hmmc->State = HAL_MMC_STATE_READY;
2268     return HAL_ERROR;
2269   }
2270 
2271   pCSD->EraseGrSize = (uint8_t)((hmmc->CSD[2] & 0x00004000U) >> 14U);
2272 
2273   pCSD->EraseGrMul = (uint8_t)((hmmc->CSD[2] & 0x00003F80U) >> 7U);
2274 
2275   pCSD->WrProtectGrSize = (uint8_t)(hmmc->CSD[2] & 0x0000007FU);
2276 
2277   pCSD->WrProtectGrEnable = (uint8_t)((hmmc->CSD[3] & 0x80000000U) >> 31U);
2278 
2279   pCSD->ManDeflECC = (uint8_t)((hmmc->CSD[3] & 0x60000000U) >> 29U);
2280 
2281   pCSD->WrSpeedFact = (uint8_t)((hmmc->CSD[3] & 0x1C000000U) >> 26U);
2282 
2283   pCSD->MaxWrBlockLen = (uint8_t)((hmmc->CSD[3] & 0x03C00000U) >> 22U);
2284 
2285   pCSD->WriteBlockPaPartial = (uint8_t)((hmmc->CSD[3] & 0x00200000U) >> 21U);
2286 
2287   pCSD->Reserved3 = 0;
2288 
2289   pCSD->ContentProtectAppli = (uint8_t)((hmmc->CSD[3] & 0x00010000U) >> 16U);
2290 
2291   pCSD->FileFormatGroup = (uint8_t)((hmmc->CSD[3] & 0x00008000U) >> 15U);
2292 
2293   pCSD->CopyFlag = (uint8_t)((hmmc->CSD[3] & 0x00004000U) >> 14U);
2294 
2295   pCSD->PermWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00002000U) >> 13U);
2296 
2297   pCSD->TempWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00001000U) >> 12U);
2298 
2299   pCSD->FileFormat = (uint8_t)((hmmc->CSD[3] & 0x00000C00U) >> 10U);
2300 
2301   pCSD->ECC = (uint8_t)((hmmc->CSD[3] & 0x00000300U) >> 8U);
2302 
2303   pCSD->CSD_CRC = (uint8_t)((hmmc->CSD[3] & 0x000000FEU) >> 1U);
2304 
2305   pCSD->Reserved4 = 1;
2306 
2307   return HAL_OK;
2308 }
2309 
2310 /**
2311   * @brief  Gets the MMC card info.
2312   * @param  hmmc: Pointer to MMC handle
2313   * @param  pCardInfo: Pointer to the HAL_MMC_CardInfoTypeDef structure that
2314   *         will contain the MMC card status information
2315   * @retval HAL status
2316   */
HAL_MMC_GetCardInfo(const MMC_HandleTypeDef * hmmc,HAL_MMC_CardInfoTypeDef * pCardInfo)2317 HAL_StatusTypeDef HAL_MMC_GetCardInfo(const MMC_HandleTypeDef *hmmc, HAL_MMC_CardInfoTypeDef *pCardInfo)
2318 {
2319   pCardInfo->CardType     = (uint32_t)(hmmc->MmcCard.CardType);
2320   pCardInfo->Class        = (uint32_t)(hmmc->MmcCard.Class);
2321   pCardInfo->RelCardAdd   = (uint32_t)(hmmc->MmcCard.RelCardAdd);
2322   pCardInfo->BlockNbr     = (uint32_t)(hmmc->MmcCard.BlockNbr);
2323   pCardInfo->BlockSize    = (uint32_t)(hmmc->MmcCard.BlockSize);
2324   pCardInfo->LogBlockNbr  = (uint32_t)(hmmc->MmcCard.LogBlockNbr);
2325   pCardInfo->LogBlockSize = (uint32_t)(hmmc->MmcCard.LogBlockSize);
2326 
2327   return HAL_OK;
2328 }
2329 
2330 /**
2331   * @brief  Returns information the information of the card which are stored on
2332   *         the Extended CSD register.
2333   * @param  hmmc Pointer to MMC handle
2334   * @param  pExtCSD Pointer to a memory area (512 bytes) that contains all
2335   *         Extended CSD register parameters
2336   * @param  Timeout Specify timeout value
2337   * @retval HAL status
2338   */
HAL_MMC_GetCardExtCSD(MMC_HandleTypeDef * hmmc,uint32_t * pExtCSD,uint32_t Timeout)2339 HAL_StatusTypeDef HAL_MMC_GetCardExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pExtCSD, uint32_t Timeout)
2340 {
2341   SDMMC_DataInitTypeDef config;
2342   uint32_t errorstate;
2343   uint32_t tickstart = HAL_GetTick();
2344   uint32_t count;
2345   uint32_t *tmp_buf;
2346 
2347   if (NULL == pExtCSD)
2348   {
2349     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
2350     return HAL_ERROR;
2351   }
2352 
2353   if (hmmc->State == HAL_MMC_STATE_READY)
2354   {
2355     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
2356 
2357     hmmc->State = HAL_MMC_STATE_BUSY;
2358 
2359     /* Initialize data control register */
2360     hmmc->Instance->DCTRL = 0;
2361 
2362     /* Initiaize the destination pointer */
2363     tmp_buf = pExtCSD;
2364 
2365     /* Configure the MMC DPSM (Data Path State Machine) */
2366     config.DataTimeOut   = SDMMC_DATATIMEOUT;
2367     config.DataLength    = MMC_BLOCKSIZE;
2368     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
2369     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
2370     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
2371     config.DPSM          = SDMMC_DPSM_DISABLE;
2372     (void)SDMMC_ConfigData(hmmc->Instance, &config);
2373     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
2374 
2375     /* Send ExtCSD Read command to Card */
2376     errorstate = SDMMC_CmdSendEXTCSD(hmmc->Instance, 0);
2377     if (errorstate != HAL_MMC_ERROR_NONE)
2378     {
2379       /* Clear all the static flags */
2380       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2381       hmmc->ErrorCode |= errorstate;
2382       hmmc->State = HAL_MMC_STATE_READY;
2383       return HAL_ERROR;
2384     }
2385 
2386     /* Poll on SDMMC flags */
2387     while (!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR |
2388                                SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
2389     {
2390       if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF))
2391       {
2392         /* Read data from SDMMC Rx FIFO */
2393         for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
2394         {
2395           *tmp_buf = SDMMC_ReadFIFO(hmmc->Instance);
2396           tmp_buf++;
2397         }
2398       }
2399 
2400       if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
2401       {
2402         /* Clear all the static flags */
2403         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2404         hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
2405         hmmc->State = HAL_MMC_STATE_READY;
2406         return HAL_TIMEOUT;
2407       }
2408     }
2409 
2410     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
2411 
2412     /* Get error state */
2413     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
2414     {
2415       /* Clear all the static flags */
2416       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2417       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
2418       hmmc->State = HAL_MMC_STATE_READY;
2419       return HAL_ERROR;
2420     }
2421     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
2422     {
2423       /* Clear all the static flags */
2424       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2425       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
2426       hmmc->State = HAL_MMC_STATE_READY;
2427       return HAL_ERROR;
2428     }
2429     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR))
2430     {
2431       /* Clear all the static flags */
2432       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2433       hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
2434       hmmc->State = HAL_MMC_STATE_READY;
2435       return HAL_ERROR;
2436     }
2437     else
2438     {
2439       /* Nothing to do */
2440     }
2441 
2442     /* Clear all the static flags */
2443     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2444     hmmc->State = HAL_MMC_STATE_READY;
2445   }
2446 
2447   return HAL_OK;
2448 }
2449 
2450 /**
2451   * @brief  Enables wide bus operation for the requested card if supported by
2452   *         card.
2453   * @param  hmmc: Pointer to MMC handle
2454   * @param  WideMode: Specifies the MMC card wide bus mode
2455   *          This parameter can be one of the following values:
2456   *            @arg SDMMC_BUS_WIDE_8B: 8-bit data transfer
2457   *            @arg SDMMC_BUS_WIDE_4B: 4-bit data transfer
2458   *            @arg SDMMC_BUS_WIDE_1B: 1-bit data transfer
2459   * @retval HAL status
2460   */
HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef * hmmc,uint32_t WideMode)2461 HAL_StatusTypeDef HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef *hmmc, uint32_t WideMode)
2462 {
2463   uint32_t count;
2464   SDMMC_InitTypeDef Init;
2465   uint32_t errorstate;
2466   uint32_t response = 0U;
2467 
2468   /* Check the parameters */
2469   assert_param(IS_SDMMC_BUS_WIDE(WideMode));
2470 
2471   /* Change State */
2472   hmmc->State = HAL_MMC_STATE_BUSY;
2473 
2474   /* Check and update the power class if needed */
2475   if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) != 0U)
2476   {
2477     if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) != 0U)
2478     {
2479       errorstate = MMC_PwrClassUpdate(hmmc, WideMode, SDMMC_SPEED_MODE_DDR);
2480     }
2481     else
2482     {
2483       errorstate = MMC_PwrClassUpdate(hmmc, WideMode, SDMMC_SPEED_MODE_HIGH);
2484     }
2485   }
2486   else
2487   {
2488     errorstate = MMC_PwrClassUpdate(hmmc, WideMode, SDMMC_SPEED_MODE_DEFAULT);
2489   }
2490 
2491   if (errorstate == HAL_MMC_ERROR_NONE)
2492   {
2493     if (WideMode == SDMMC_BUS_WIDE_8B)
2494     {
2495       errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U);
2496     }
2497     else if (WideMode == SDMMC_BUS_WIDE_4B)
2498     {
2499       errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U);
2500     }
2501     else if (WideMode == SDMMC_BUS_WIDE_1B)
2502     {
2503       errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70000U);
2504     }
2505     else
2506     {
2507       /* WideMode is not a valid argument*/
2508       errorstate = HAL_MMC_ERROR_PARAM;
2509     }
2510 
2511     /* Check for switch error and violation of the trial number of sending CMD 13 */
2512     if (errorstate == HAL_MMC_ERROR_NONE)
2513     {
2514       /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2515       count = SDMMC_MAX_TRIAL;
2516       do
2517       {
2518         errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2519         if (errorstate != HAL_MMC_ERROR_NONE)
2520         {
2521           break;
2522         }
2523 
2524         /* Get command response */
2525         response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
2526         count--;
2527       } while (((response & 0x100U) == 0U) && (count != 0U));
2528 
2529       /* Check the status after the switch command execution */
2530       if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
2531       {
2532         /* Check the bit SWITCH_ERROR of the device status */
2533         if ((response & 0x80U) != 0U)
2534         {
2535           errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
2536         }
2537         else
2538         {
2539           /* Configure the SDMMC peripheral */
2540           Init = hmmc->Init;
2541           Init.BusWide = WideMode;
2542           (void)SDMMC_Init(hmmc->Instance, Init);
2543         }
2544       }
2545       else if (count == 0U)
2546       {
2547         errorstate = SDMMC_ERROR_TIMEOUT;
2548       }
2549       else
2550       {
2551         /* Nothing to do */
2552       }
2553     }
2554   }
2555 
2556   /* Change State */
2557   hmmc->State = HAL_MMC_STATE_READY;
2558 
2559   if (errorstate != HAL_MMC_ERROR_NONE)
2560   {
2561     /* Clear all the static flags */
2562     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2563     hmmc->ErrorCode |= errorstate;
2564     return HAL_ERROR;
2565   }
2566 
2567   return HAL_OK;
2568 }
2569 
2570 /**
2571   * @brief  Configure the speed bus mode
2572   * @param  hmmc: Pointer to the MMC handle
2573   * @param  SpeedMode: Specifies the MMC card speed bus mode
2574   *          This parameter can be one of the following values:
2575   *            @arg SDMMC_SPEED_MODE_AUTO: Max speed mode supported by the card
2576   *            @arg SDMMC_SPEED_MODE_DEFAULT: Default Speed (MMC @ 26MHz)
2577   *            @arg SDMMC_SPEED_MODE_HIGH: High Speed (MMC @ 52 MHz)
2578   *            @arg SDMMC_SPEED_MODE_DDR: High Speed DDR (MMC DDR @ 52 MHz)
2579   * @retval HAL status
2580   */
2581 
HAL_MMC_ConfigSpeedBusOperation(MMC_HandleTypeDef * hmmc,uint32_t SpeedMode)2582 HAL_StatusTypeDef HAL_MMC_ConfigSpeedBusOperation(MMC_HandleTypeDef *hmmc, uint32_t SpeedMode)
2583 {
2584   uint32_t tickstart;
2585   HAL_StatusTypeDef status = HAL_OK;
2586   uint32_t device_type;
2587   uint32_t errorstate;
2588 
2589   /* Check the parameters */
2590   assert_param(IS_SDMMC_SPEED_MODE(SpeedMode));
2591 
2592   /* Change State */
2593   hmmc->State = HAL_MMC_STATE_BUSY;
2594 
2595   /* Field DEVICE_TYPE [196 = 49*4] of Extended CSD register */
2596   device_type = (hmmc->Ext_CSD[49] & 0x000000FFU);
2597 
2598   switch (SpeedMode)
2599   {
2600     case SDMMC_SPEED_MODE_AUTO:
2601     {
2602       if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS) != 0U) && ((device_type & 0x04U) != 0U))
2603       {
2604         /* High Speed DDR mode allowed */
2605         errorstate = MMC_HighSpeed(hmmc, ENABLE);
2606         if (errorstate != HAL_MMC_ERROR_NONE)
2607         {
2608           hmmc->ErrorCode |= errorstate;
2609         }
2610         else
2611         {
2612           if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_CLKDIV) != 0U)
2613           {
2614             /* DDR mode not supported with CLKDIV = 0 */
2615             errorstate = MMC_DDR_Mode(hmmc, ENABLE);
2616             if (errorstate != HAL_MMC_ERROR_NONE)
2617             {
2618               hmmc->ErrorCode |= errorstate;
2619             }
2620           }
2621         }
2622       }
2623       else if ((device_type & 0x02U) != 0U)
2624       {
2625         /* High Speed mode allowed */
2626         errorstate = MMC_HighSpeed(hmmc, ENABLE);
2627         if (errorstate != HAL_MMC_ERROR_NONE)
2628         {
2629           hmmc->ErrorCode |= errorstate;
2630         }
2631       }
2632       else
2633       {
2634         /* Nothing to do : keep current speed */
2635       }
2636       break;
2637     }
2638     case SDMMC_SPEED_MODE_DDR:
2639     {
2640       if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS) != 0U) && ((device_type & 0x04U) != 0U))
2641       {
2642         /* High Speed DDR mode allowed */
2643         errorstate = MMC_HighSpeed(hmmc, ENABLE);
2644         if (errorstate != HAL_MMC_ERROR_NONE)
2645         {
2646           hmmc->ErrorCode |= errorstate;
2647         }
2648         else
2649         {
2650           if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_CLKDIV) != 0U)
2651           {
2652             /* DDR mode not supported with CLKDIV = 0 */
2653             errorstate = MMC_DDR_Mode(hmmc, ENABLE);
2654             if (errorstate != HAL_MMC_ERROR_NONE)
2655             {
2656               hmmc->ErrorCode |= errorstate;
2657             }
2658           }
2659         }
2660       }
2661       else
2662       {
2663         /* High Speed DDR mode not allowed */
2664         hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2665         status = HAL_ERROR;
2666       }
2667       break;
2668     }
2669     case SDMMC_SPEED_MODE_HIGH:
2670     {
2671       if ((device_type & 0x02U) != 0U)
2672       {
2673         /* High Speed mode allowed */
2674         errorstate = MMC_HighSpeed(hmmc, ENABLE);
2675         if (errorstate != HAL_MMC_ERROR_NONE)
2676         {
2677           hmmc->ErrorCode |= errorstate;
2678         }
2679       }
2680       else
2681       {
2682         /* High Speed mode not allowed */
2683         hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2684         status = HAL_ERROR;
2685       }
2686       break;
2687     }
2688     case SDMMC_SPEED_MODE_DEFAULT:
2689     {
2690       if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) != 0U)
2691       {
2692         /* High Speed DDR mode activated */
2693         errorstate = MMC_DDR_Mode(hmmc, DISABLE);
2694         if (errorstate != HAL_MMC_ERROR_NONE)
2695         {
2696           hmmc->ErrorCode |= errorstate;
2697         }
2698       }
2699       if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) != 0U)
2700       {
2701         /* High Speed mode activated */
2702         errorstate = MMC_HighSpeed(hmmc, DISABLE);
2703         if (errorstate != HAL_MMC_ERROR_NONE)
2704         {
2705           hmmc->ErrorCode |= errorstate;
2706         }
2707       }
2708       break;
2709     }
2710     default:
2711       hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
2712       status = HAL_ERROR;
2713       break;
2714   }
2715 
2716   /* Verify that MMC card is ready to use after Speed mode switch*/
2717   tickstart = HAL_GetTick();
2718   while ((HAL_MMC_GetCardState(hmmc) != HAL_MMC_CARD_TRANSFER))
2719   {
2720     if ((HAL_GetTick() - tickstart) >=  SDMMC_DATATIMEOUT)
2721     {
2722       hmmc->ErrorCode = HAL_MMC_ERROR_TIMEOUT;
2723       hmmc->State = HAL_MMC_STATE_READY;
2724       return HAL_TIMEOUT;
2725     }
2726   }
2727 
2728   /* Change State */
2729   hmmc->State = HAL_MMC_STATE_READY;
2730   return status;
2731 }
2732 
2733 /**
2734   * @brief  Gets the current mmc card data state.
2735   * @param  hmmc: pointer to MMC handle
2736   * @retval Card state
2737   */
HAL_MMC_GetCardState(MMC_HandleTypeDef * hmmc)2738 HAL_MMC_CardStateTypeDef HAL_MMC_GetCardState(MMC_HandleTypeDef *hmmc)
2739 {
2740   uint32_t cardstate;
2741   uint32_t errorstate;
2742   uint32_t resp1 = 0U;
2743 
2744   errorstate = MMC_SendStatus(hmmc, &resp1);
2745   if (errorstate != HAL_MMC_ERROR_NONE)
2746   {
2747     hmmc->ErrorCode |= errorstate;
2748   }
2749 
2750   cardstate = ((resp1 >> 9U) & 0x0FU);
2751 
2752   return (HAL_MMC_CardStateTypeDef)cardstate;
2753 }
2754 
2755 /**
2756   * @brief  Abort the current transfer and disable the MMC.
2757   * @param  hmmc: pointer to a MMC_HandleTypeDef structure that contains
2758   *                the configuration information for MMC module.
2759   * @retval HAL status
2760   */
HAL_MMC_Abort(MMC_HandleTypeDef * hmmc)2761 HAL_StatusTypeDef HAL_MMC_Abort(MMC_HandleTypeDef *hmmc)
2762 {
2763   uint32_t error_code;
2764   uint32_t tickstart;
2765 
2766   if (hmmc->State == HAL_MMC_STATE_BUSY)
2767   {
2768     /* DIsable All interrupts */
2769     __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | \
2770                          SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR);
2771     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
2772 
2773     /*we will send the CMD12 in all cases in order to stop the data transfers*/
2774     /*In case the data transfer just finished, the external memory will not respond
2775       and will return HAL_MMC_ERROR_CMD_RSP_TIMEOUT*/
2776     /*In case the data transfer aborted , the external memory will respond and will return HAL_MMC_ERROR_NONE*/
2777     /*Other scenario will return HAL_ERROR*/
2778 
2779     hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
2780     error_code = hmmc->ErrorCode;
2781     if ((error_code != HAL_MMC_ERROR_NONE) && (error_code != HAL_MMC_ERROR_CMD_RSP_TIMEOUT))
2782     {
2783       return HAL_ERROR;
2784     }
2785 
2786     tickstart = HAL_GetTick();
2787     if ((hmmc->Instance->DCTRL & SDMMC_DCTRL_DTDIR) == SDMMC_TRANSFER_DIR_TO_CARD)
2788     {
2789       if (hmmc->ErrorCode == HAL_MMC_ERROR_NONE)
2790       {
2791         while (!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DABORT | SDMMC_FLAG_BUSYD0END))
2792         {
2793           if ((HAL_GetTick() - tickstart) >=  SDMMC_DATATIMEOUT)
2794           {
2795             hmmc->ErrorCode = HAL_MMC_ERROR_TIMEOUT;
2796             hmmc->State = HAL_MMC_STATE_READY;
2797             return HAL_TIMEOUT;
2798           }
2799         }
2800       }
2801 
2802       if (hmmc->ErrorCode == HAL_MMC_ERROR_CMD_RSP_TIMEOUT)
2803       {
2804         while (!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND))
2805         {
2806           if ((HAL_GetTick() - tickstart) >=  SDMMC_DATATIMEOUT)
2807           {
2808             hmmc->ErrorCode = HAL_MMC_ERROR_TIMEOUT;
2809             hmmc->State = HAL_MMC_STATE_READY;
2810             return HAL_TIMEOUT;
2811           }
2812         }
2813       }
2814     }
2815     else if ((hmmc->Instance->DCTRL & SDMMC_DCTRL_DTDIR) == SDMMC_TRANSFER_DIR_TO_SDMMC)
2816     {
2817       while (!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DABORT | SDMMC_FLAG_DATAEND))
2818       {
2819         if ((HAL_GetTick() - tickstart) >=  SDMMC_DATATIMEOUT)
2820         {
2821           hmmc->ErrorCode = HAL_MMC_ERROR_TIMEOUT;
2822           hmmc->State = HAL_MMC_STATE_READY;
2823           return HAL_TIMEOUT;
2824         }
2825       }
2826     }
2827     else
2828     {
2829       /* Nothing to do*/
2830     }
2831 
2832     /*The reason of all these while conditions previously is that we need to wait the SDMMC and clear
2833       the appropriate flags that will be set depending of the abort/non abort of the memory */
2834     /*Not waiting the SDMMC flags will cause the next SDMMC_DISABLE_IDMA to not get cleared and will result
2835       in next SDMMC read/write operation to fail */
2836 
2837     /*SDMMC ready for clear data flags*/
2838     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
2839     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2840     /* If IDMA Context, disable Internal DMA */
2841     hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA;
2842 
2843     hmmc->State = HAL_MMC_STATE_READY;
2844 
2845     /* Initialize the MMC operation */
2846     hmmc->Context = MMC_CONTEXT_NONE;
2847   }
2848   return HAL_OK;
2849 }
2850 /**
2851   * @brief  Abort the current transfer and disable the MMC (IT mode).
2852   * @param  hmmc: pointer to a MMC_HandleTypeDef structure that contains
2853   *                the configuration information for MMC module.
2854   * @retval HAL status
2855   */
HAL_MMC_Abort_IT(MMC_HandleTypeDef * hmmc)2856 HAL_StatusTypeDef HAL_MMC_Abort_IT(MMC_HandleTypeDef *hmmc)
2857 {
2858   HAL_MMC_CardStateTypeDef CardState;
2859 
2860   /* DIsable All interrupts */
2861   __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | \
2862                        SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR);
2863 
2864   /* If IDMA Context, disable Internal DMA */
2865   hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA;
2866 
2867   /* Clear All flags */
2868   __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2869 
2870   CardState = HAL_MMC_GetCardState(hmmc);
2871   hmmc->State = HAL_MMC_STATE_READY;
2872 
2873   if ((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2874   {
2875     hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
2876   }
2877   if (hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2878   {
2879     return HAL_ERROR;
2880   }
2881   else
2882   {
2883 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2884     hmmc->AbortCpltCallback(hmmc);
2885 #else
2886     HAL_MMC_AbortCallback(hmmc);
2887 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
2888   }
2889 
2890   return HAL_OK;
2891 }
2892 
2893 /**
2894   * @brief  Perform specific commands sequence for the different type of erase.
2895   * @note   This API should be followed by a check on the card state through
2896   *         HAL_MMC_GetCardState().
2897   * @param  hmmc Pointer to MMC handle
2898   * @param  EraseType Specifies the type of erase to be performed
2899   *          This parameter can be one of the following values:
2900   *             @arg HAL_MMC_TRIM Erase the write blocks identified by CMD35 & 36
2901   *             @arg HAL_MMC_ERASE Erase the erase groups identified by CMD35 & 36
2902   *             @arg HAL_MMC_DISCARD Discard the write blocks identified by CMD35 & 36
2903   *             @arg HAL_MMC_SECURE_ERASE Perform a secure purge according SRT on the erase groups identified
2904   *                  by CMD35 & 36
2905   *             @arg HAL_MMC_SECURE_TRIM_STEP1 Mark the write blocks identified by CMD35 & 36 for secure erase
2906   *             @arg HAL_MMC_SECURE_TRIM_STEP2 Perform a secure purge according SRT on the write blocks
2907   *                  previously identified
2908   * @param  BlockStartAdd Start Block address
2909   * @param  BlockEndAdd End Block address
2910   * @retval HAL status
2911   */
HAL_MMC_EraseSequence(MMC_HandleTypeDef * hmmc,uint32_t EraseType,uint32_t BlockStartAdd,uint32_t BlockEndAdd)2912 HAL_StatusTypeDef HAL_MMC_EraseSequence(MMC_HandleTypeDef *hmmc, uint32_t EraseType,
2913                                         uint32_t BlockStartAdd, uint32_t BlockEndAdd)
2914 {
2915   uint32_t errorstate;
2916   uint32_t start_add = BlockStartAdd;
2917   uint32_t end_add = BlockEndAdd;
2918   uint32_t tickstart = HAL_GetTick();
2919 
2920   /* Check the erase type value is correct */
2921   assert_param(IS_MMC_ERASE_TYPE(EraseType));
2922 
2923   /* Check the coherence between start and end address */
2924   if (end_add < start_add)
2925   {
2926     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
2927     return HAL_ERROR;
2928   }
2929 
2930   /* Check that the end address is not out of range of device memory */
2931   if (end_add > (hmmc->MmcCard.LogBlockNbr))
2932   {
2933     hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
2934     return HAL_ERROR;
2935   }
2936 
2937   /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
2938   if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U)
2939   {
2940     if (((start_add % 8U) != 0U) || ((end_add % 8U) != 0U))
2941     {
2942       /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
2943       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
2944       return HAL_ERROR;
2945     }
2946   }
2947 
2948   /* Check if the card command class supports erase command */
2949   if (((hmmc->MmcCard.Class) & SDMMC_CCCC_ERASE) == 0U)
2950   {
2951     hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
2952     return HAL_ERROR;
2953   }
2954 
2955   /* Check the state of the driver */
2956   if (hmmc->State == HAL_MMC_STATE_READY)
2957   {
2958     /* Change State */
2959     hmmc->State = HAL_MMC_STATE_BUSY;
2960 
2961     /* Check that the card is not locked */
2962     if ((SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
2963     {
2964       hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED;
2965       hmmc->State = HAL_MMC_STATE_READY;
2966       return HAL_ERROR;
2967     }
2968 
2969     /* In case of low capacity card, the address is not block number but bytes */
2970     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
2971     {
2972       start_add *= MMC_BLOCKSIZE;
2973       end_add   *= MMC_BLOCKSIZE;
2974     }
2975 
2976     /* Send CMD35 MMC_ERASE_GRP_START with start address as argument */
2977     errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, start_add);
2978     if (errorstate == HAL_MMC_ERROR_NONE)
2979     {
2980       /* Send CMD36 MMC_ERASE_GRP_END with end address as argument */
2981       errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, end_add);
2982       if (errorstate == HAL_MMC_ERROR_NONE)
2983       {
2984         /* Send CMD38 ERASE with erase type as argument */
2985         errorstate = SDMMC_CmdErase(hmmc->Instance, EraseType);
2986         if (errorstate == HAL_MMC_ERROR_NONE)
2987         {
2988           if ((EraseType == HAL_MMC_SECURE_ERASE) || (EraseType == HAL_MMC_SECURE_TRIM_STEP2))
2989           {
2990             /* Wait that the device is ready by checking the D0 line */
2991             while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
2992             {
2993               if ((HAL_GetTick() - tickstart) >= SDMMC_MAXERASETIMEOUT)
2994               {
2995                 errorstate = HAL_MMC_ERROR_TIMEOUT;
2996               }
2997             }
2998 
2999             /* Clear the flag corresponding to end D0 bus line */
3000             __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
3001           }
3002         }
3003       }
3004     }
3005 
3006     /* Change State */
3007     hmmc->State = HAL_MMC_STATE_READY;
3008 
3009     /* Manage errors */
3010     if (errorstate != HAL_MMC_ERROR_NONE)
3011     {
3012       /* Clear all the static flags */
3013       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3014       hmmc->ErrorCode |= errorstate;
3015 
3016       if (errorstate != HAL_MMC_ERROR_TIMEOUT)
3017       {
3018         return HAL_ERROR;
3019       }
3020       else
3021       {
3022         return HAL_TIMEOUT;
3023       }
3024     }
3025     else
3026     {
3027       return HAL_OK;
3028     }
3029   }
3030   else
3031   {
3032     return HAL_BUSY;
3033   }
3034 }
3035 
3036 /**
3037   * @brief  Perform sanitize operation on the device.
3038   * @note   This API should be followed by a check on the card state through
3039   *         HAL_MMC_GetCardState().
3040   * @param  hmmc Pointer to MMC handle
3041   * @retval HAL status
3042   */
HAL_MMC_Sanitize(MMC_HandleTypeDef * hmmc)3043 HAL_StatusTypeDef HAL_MMC_Sanitize(MMC_HandleTypeDef *hmmc)
3044 {
3045   uint32_t errorstate;
3046   uint32_t response = 0U;
3047   uint32_t count;
3048   uint32_t tickstart = HAL_GetTick();
3049 
3050   /* Check the state of the driver */
3051   if (hmmc->State == HAL_MMC_STATE_READY)
3052   {
3053     /* Change State */
3054     hmmc->State = HAL_MMC_STATE_BUSY;
3055 
3056     /* Index : 165 - Value : 0x01 */
3057     errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03A50100U);
3058     if (errorstate == HAL_MMC_ERROR_NONE)
3059     {
3060       /* Wait that the device is ready by checking the D0 line */
3061       while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
3062       {
3063         if ((HAL_GetTick() - tickstart) >= SDMMC_MAXERASETIMEOUT)
3064         {
3065           errorstate = HAL_MMC_ERROR_TIMEOUT;
3066         }
3067       }
3068 
3069       /* Clear the flag corresponding to end D0 bus line */
3070       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
3071 
3072       if (errorstate == HAL_MMC_ERROR_NONE)
3073       {
3074         /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3075         count = SDMMC_MAX_TRIAL;
3076         do
3077         {
3078           errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3079           if (errorstate != HAL_MMC_ERROR_NONE)
3080           {
3081             break;
3082           }
3083 
3084           /* Get command response */
3085           response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3086           count--;
3087         } while (((response & 0x100U) == 0U) && (count != 0U));
3088 
3089         /* Check the status after the switch command execution */
3090         if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
3091         {
3092           /* Check the bit SWITCH_ERROR of the device status */
3093           if ((response & 0x80U) != 0U)
3094           {
3095             errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
3096           }
3097         }
3098         else if (count == 0U)
3099         {
3100           errorstate = SDMMC_ERROR_TIMEOUT;
3101         }
3102         else
3103         {
3104           /* Nothing to do */
3105         }
3106       }
3107     }
3108 
3109     /* Change State */
3110     hmmc->State = HAL_MMC_STATE_READY;
3111 
3112     /* Manage errors */
3113     if (errorstate != HAL_MMC_ERROR_NONE)
3114     {
3115       /* Clear all the static flags */
3116       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3117       hmmc->ErrorCode |= errorstate;
3118 
3119       if (errorstate != HAL_MMC_ERROR_TIMEOUT)
3120       {
3121         return HAL_ERROR;
3122       }
3123       else
3124       {
3125         return HAL_TIMEOUT;
3126       }
3127     }
3128     else
3129     {
3130       return HAL_OK;
3131     }
3132   }
3133   else
3134   {
3135     return HAL_BUSY;
3136   }
3137 }
3138 
3139 /**
3140   * @brief  Configure the Secure Removal Type (SRT) in the Extended CSD register.
3141   * @note   This API should be followed by a check on the card state through
3142   *         HAL_MMC_GetCardState().
3143   * @param  hmmc Pointer to MMC handle
3144   * @param  SRTMode Specifies the type of erase to be performed
3145   *          This parameter can be one of the following values:
3146   *            @arg HAL_MMC_SRT_ERASE Information removed by an erase
3147   *            @arg HAL_MMC_SRT_WRITE_CHAR_ERASE Information removed by an overwriting with a character
3148   *                 followed by an erase
3149   *            @arg HAL_MMC_SRT_WRITE_CHAR_COMPL_RANDOM Information removed by an overwriting with a character,
3150   *                 its complement then a random character
3151   *            @arg HAL_MMC_SRT_VENDOR_DEFINED Information removed using a vendor defined
3152   * @retval HAL status
3153   */
HAL_MMC_ConfigSecRemovalType(MMC_HandleTypeDef * hmmc,uint32_t SRTMode)3154 HAL_StatusTypeDef HAL_MMC_ConfigSecRemovalType(MMC_HandleTypeDef *hmmc, uint32_t SRTMode)
3155 {
3156   uint32_t srt;
3157   uint32_t errorstate;
3158   uint32_t response = 0U;
3159   uint32_t count;
3160 
3161   /* Check the erase type value is correct */
3162   assert_param(IS_MMC_SRT_TYPE(SRTMode));
3163 
3164   /* Check the state of the driver */
3165   if (hmmc->State == HAL_MMC_STATE_READY)
3166   {
3167     /* Get the supported values by the device */
3168     if (HAL_MMC_GetSupportedSecRemovalType(hmmc, &srt) == HAL_OK)
3169     {
3170       /* Change State */
3171       hmmc->State = HAL_MMC_STATE_BUSY;
3172 
3173       /* Check the value passed as parameter is supported by the device */
3174       if ((SRTMode & srt) != 0U)
3175       {
3176         /* Index : 16 - Value : SRTMode */
3177         srt |= ((POSITION_VAL(SRTMode)) << 4U);
3178         errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03100000U | (srt << 8U)));
3179         if (errorstate == HAL_MMC_ERROR_NONE)
3180         {
3181           /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3182           count = SDMMC_MAX_TRIAL;
3183           do
3184           {
3185             errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3186             if (errorstate != HAL_MMC_ERROR_NONE)
3187             {
3188               break;
3189             }
3190 
3191             /* Get command response */
3192             response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3193             count--;
3194           } while (((response & 0x100U) == 0U) && (count != 0U));
3195 
3196           /* Check the status after the switch command execution */
3197           if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
3198           {
3199             /* Check the bit SWITCH_ERROR of the device status */
3200             if ((response & 0x80U) != 0U)
3201             {
3202               errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
3203             }
3204           }
3205           else if (count == 0U)
3206           {
3207             errorstate = SDMMC_ERROR_TIMEOUT;
3208           }
3209           else
3210           {
3211             /* Nothing to do */
3212           }
3213         }
3214       }
3215       else
3216       {
3217         errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3218       }
3219 
3220       /* Change State */
3221       hmmc->State = HAL_MMC_STATE_READY;
3222     }
3223     else
3224     {
3225       errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
3226     }
3227 
3228     /* Manage errors */
3229     if (errorstate != HAL_MMC_ERROR_NONE)
3230     {
3231       /* Clear all the static flags */
3232       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3233       hmmc->ErrorCode |= errorstate;
3234       return HAL_ERROR;
3235     }
3236     else
3237     {
3238       return HAL_OK;
3239     }
3240   }
3241   else
3242   {
3243     return HAL_BUSY;
3244   }
3245 }
3246 
3247 /**
3248   * @brief  Gets the supported values of the the Secure Removal Type (SRT).
3249   * @param  hmmc pointer to MMC handle
3250   * @param  SupportedSRT pointer for supported SRT value
3251   *          This parameter is a bit field of the following values:
3252   *            @arg HAL_MMC_SRT_ERASE Information removed by an erase
3253   *            @arg HAL_MMC_SRT_WRITE_CHAR_ERASE Information removed by an overwriting with a character followed
3254   *                  by an erase
3255   *            @arg HAL_MMC_SRT_WRITE_CHAR_COMPL_RANDOM Information removed by an overwriting with a character,
3256   *                 its complement then a random character
3257   *            @arg HAL_MMC_SRT_VENDOR_DEFINED Information removed using a vendor defined
3258   * @retval HAL status
3259   */
HAL_MMC_GetSupportedSecRemovalType(MMC_HandleTypeDef * hmmc,uint32_t * SupportedSRT)3260 HAL_StatusTypeDef HAL_MMC_GetSupportedSecRemovalType(MMC_HandleTypeDef *hmmc, uint32_t *SupportedSRT)
3261 {
3262   /* Check the state of the driver */
3263   if (hmmc->State == HAL_MMC_STATE_READY)
3264   {
3265     /* Change State */
3266     hmmc->State = HAL_MMC_STATE_BUSY;
3267 
3268     /* Read field SECURE_REMOVAL_TYPE [16 = 4*4] of the Extended CSD register */
3269     *SupportedSRT = (hmmc->Ext_CSD[4] & 0x0000000FU); /* Bits [3:0] of field 16 */
3270 
3271     /* Change State */
3272     hmmc->State = HAL_MMC_STATE_READY;
3273 
3274     return HAL_OK;
3275   }
3276   else
3277   {
3278     return HAL_BUSY;
3279   }
3280 }
3281 
3282 /**
3283   * @brief  Switch the device from Standby State to Sleep State.
3284   * @param  hmmc pointer to MMC handle
3285   * @retval HAL status
3286   */
HAL_MMC_SleepDevice(MMC_HandleTypeDef * hmmc)3287 HAL_StatusTypeDef HAL_MMC_SleepDevice(MMC_HandleTypeDef *hmmc)
3288 {
3289   uint32_t errorstate,
3290            sleep_timeout,
3291            timeout,
3292            count,
3293            response = 0U  ;
3294   uint32_t tickstart = HAL_GetTick();
3295 
3296   /* Check the state of the driver */
3297   if (hmmc->State == HAL_MMC_STATE_READY)
3298   {
3299     /* Change State */
3300     hmmc->State = HAL_MMC_STATE_BUSY;
3301 
3302     /* Set the power-off notification to powered-on : Ext_CSD[34] = 1 */
3303     errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03220100U));
3304     if (errorstate == HAL_MMC_ERROR_NONE)
3305     {
3306       /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3307       count = SDMMC_MAX_TRIAL;
3308       do
3309       {
3310         errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3311         if (errorstate != HAL_MMC_ERROR_NONE)
3312         {
3313           break;
3314         }
3315 
3316         /* Get command response */
3317         response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3318         count--;
3319       } while (((response & 0x100U) == 0U) && (count != 0U));
3320 
3321       /* Check the status after the switch command execution */
3322       if (count == 0U)
3323       {
3324         errorstate = SDMMC_ERROR_TIMEOUT;
3325       }
3326       else if (errorstate == HAL_MMC_ERROR_NONE)
3327       {
3328         /* Check the bit SWITCH_ERROR of the device status */
3329         if ((response & 0x80U) != 0U)
3330         {
3331           errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3332         }
3333         else
3334         {
3335           /* Set the power-off notification to sleep notification : Ext_CSD[34] = 4 */
3336           errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03220400U));
3337           if (errorstate == HAL_MMC_ERROR_NONE)
3338           {
3339             /* Field SLEEP_NOTIFICATION_TIME [216] */
3340             sleep_timeout = ((hmmc->Ext_CSD[(MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_INDEX / 4)] >>
3341                               MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_POS) & 0x000000FFU);
3342 
3343             /* Sleep/Awake Timeout = 10us * 2^SLEEP_NOTIFICATION_TIME */
3344             /* In HAL, the tick interrupt occurs each ms */
3345             if ((sleep_timeout == 0U) || (sleep_timeout > 0x17U))
3346             {
3347               sleep_timeout = 0x17U; /* Max register value defined is 0x17 */
3348             }
3349             timeout = (((1UL << sleep_timeout) / 100U) + 1U);
3350 
3351             /* Wait that the device is ready by checking the D0 line */
3352             while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
3353             {
3354               if ((HAL_GetTick() - tickstart) >= timeout)
3355               {
3356                 errorstate = SDMMC_ERROR_TIMEOUT;
3357               }
3358             }
3359 
3360             /* Clear the flag corresponding to end D0 bus line */
3361             __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
3362 
3363             if (errorstate == HAL_MMC_ERROR_NONE)
3364             {
3365               /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3366               count = SDMMC_MAX_TRIAL;
3367               do
3368               {
3369                 errorstate = SDMMC_CmdSendStatus(hmmc->Instance,
3370                                                  (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3371                 if (errorstate != HAL_MMC_ERROR_NONE)
3372                 {
3373                   break;
3374                 }
3375 
3376                 /* Get command response */
3377                 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3378                 count--;
3379               } while (((response & 0x100U) == 0U) && (count != 0U));
3380 
3381               /* Check the status after the switch command execution */
3382               if (count == 0U)
3383               {
3384                 errorstate = SDMMC_ERROR_TIMEOUT;
3385               }
3386               else if (errorstate == HAL_MMC_ERROR_NONE)
3387               {
3388                 /* Check the bit SWITCH_ERROR of the device status */
3389                 if ((response & 0x80U) != 0U)
3390                 {
3391                   errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3392                 }
3393                 else
3394                 {
3395                   /* Switch the device in stand-by mode */
3396                   (void)SDMMC_CmdSelDesel(hmmc->Instance, 0U);
3397 
3398                   /* Field S_A_TIEMOUT [217] */
3399                   sleep_timeout = ((hmmc->Ext_CSD[(MMC_EXT_CSD_S_A_TIMEOUT_INDEX / 4)] >>
3400                                     MMC_EXT_CSD_S_A_TIMEOUT_POS) & 0x000000FFU);
3401 
3402                   /* Sleep/Awake Timeout = 100ns * 2^S_A_TIMEOUT */
3403                   /* In HAL, the tick interrupt occurs each ms */
3404                   if ((sleep_timeout == 0U) || (sleep_timeout > 0x17U))
3405                   {
3406                     sleep_timeout = 0x17U; /* Max register value defined is 0x17 */
3407                   }
3408                   timeout = (((1UL << sleep_timeout) / 10000U) + 1U);
3409 
3410                   if (HAL_MMC_GetCardState(hmmc) == HAL_MMC_CARD_STANDBY)
3411                   {
3412                     /* Send CMD5 CMD_MMC_SLEEP_AWAKE with RCA and SLEEP as argument */
3413                     errorstate = SDMMC_CmdSleepMmc(hmmc->Instance,
3414                                                    ((hmmc->MmcCard.RelCardAdd << 16U) | (0x1U << 15U)));
3415                     if (errorstate == HAL_MMC_ERROR_NONE)
3416                     {
3417                       /* Wait that the device is ready by checking the D0 line */
3418                       while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
3419                       {
3420                         if ((HAL_GetTick() - tickstart) >= timeout)
3421                         {
3422                           errorstate = SDMMC_ERROR_TIMEOUT;
3423                         }
3424                       }
3425 
3426                       /* Clear the flag corresponding to end D0 bus line */
3427                       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
3428                     }
3429                   }
3430                   else
3431                   {
3432                     errorstate = SDMMC_ERROR_REQUEST_NOT_APPLICABLE;
3433                   }
3434                 }
3435               }
3436               else
3437               {
3438                 /* Nothing to do */
3439               }
3440             }
3441           }
3442         }
3443       }
3444       else
3445       {
3446         /* Nothing to do */
3447       }
3448     }
3449 
3450     /* Change State */
3451     hmmc->State = HAL_MMC_STATE_READY;
3452 
3453     /* Manage errors */
3454     if (errorstate != HAL_MMC_ERROR_NONE)
3455     {
3456       /* Clear all the static flags */
3457       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3458       hmmc->ErrorCode |= errorstate;
3459 
3460       if (errorstate != HAL_MMC_ERROR_TIMEOUT)
3461       {
3462         return HAL_ERROR;
3463       }
3464       else
3465       {
3466         return HAL_TIMEOUT;
3467       }
3468     }
3469     else
3470     {
3471       return HAL_OK;
3472     }
3473   }
3474   else
3475   {
3476     return HAL_BUSY;
3477   }
3478 }
3479 
3480 /**
3481   * @brief  Switch the device from Sleep State to Standby State.
3482   * @param  hmmc pointer to MMC handle
3483   * @retval HAL status
3484   */
HAL_MMC_AwakeDevice(MMC_HandleTypeDef * hmmc)3485 HAL_StatusTypeDef HAL_MMC_AwakeDevice(MMC_HandleTypeDef *hmmc)
3486 {
3487   uint32_t errorstate;
3488   uint32_t sleep_timeout;
3489   uint32_t timeout;
3490   uint32_t count;
3491   uint32_t response = 0U;
3492   uint32_t tickstart = HAL_GetTick();
3493 
3494   /* Check the state of the driver */
3495   if (hmmc->State == HAL_MMC_STATE_READY)
3496   {
3497     /* Change State */
3498     hmmc->State = HAL_MMC_STATE_BUSY;
3499 
3500     /* Field S_A_TIEMOUT [217] */
3501     sleep_timeout = ((hmmc->Ext_CSD[(MMC_EXT_CSD_S_A_TIMEOUT_INDEX / 4)] >> MMC_EXT_CSD_S_A_TIMEOUT_POS) &
3502                      0x000000FFU);
3503 
3504     /* Sleep/Awake Timeout = 100ns * 2^S_A_TIMEOUT */
3505     /* In HAL, the tick interrupt occurs each ms */
3506     if ((sleep_timeout == 0U) || (sleep_timeout > 0x17U))
3507     {
3508       sleep_timeout = 0x17U; /* Max register value defined is 0x17 */
3509     }
3510     timeout = (((1UL << sleep_timeout) / 10000U) + 1U);
3511 
3512     /* Send CMD5 CMD_MMC_SLEEP_AWAKE with RCA and AWAKE as argument */
3513     errorstate = SDMMC_CmdSleepMmc(hmmc->Instance, (hmmc->MmcCard.RelCardAdd << 16U));
3514     if (errorstate == HAL_MMC_ERROR_NONE)
3515     {
3516       /* Wait that the device is ready by checking the D0 line */
3517       while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
3518       {
3519         if ((HAL_GetTick() - tickstart) >= timeout)
3520         {
3521           errorstate = SDMMC_ERROR_TIMEOUT;
3522         }
3523       }
3524 
3525       /* Clear the flag corresponding to end D0 bus line */
3526       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
3527 
3528       if (errorstate == HAL_MMC_ERROR_NONE)
3529       {
3530         if (HAL_MMC_GetCardState(hmmc) == HAL_MMC_CARD_STANDBY)
3531         {
3532           /* Switch the device in transfer mode */
3533           errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (hmmc->MmcCard.RelCardAdd << 16U));
3534           if (errorstate == HAL_MMC_ERROR_NONE)
3535           {
3536             if (HAL_MMC_GetCardState(hmmc) == HAL_MMC_CARD_TRANSFER)
3537             {
3538               /* Set the power-off notification to powered-on : Ext_CSD[34] = 1 */
3539               errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03220100U));
3540               if (errorstate == HAL_MMC_ERROR_NONE)
3541               {
3542                 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3543                 count = SDMMC_MAX_TRIAL;
3544                 do
3545                 {
3546                   errorstate = SDMMC_CmdSendStatus(hmmc->Instance,
3547                                                    (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3548                   if (errorstate != HAL_MMC_ERROR_NONE)
3549                   {
3550                     break;
3551                   }
3552 
3553                   /* Get command response */
3554                   response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3555                   count--;
3556                 } while (((response & 0x100U) == 0U) && (count != 0U));
3557 
3558                 /* Check the status after the switch command execution */
3559                 if (count == 0U)
3560                 {
3561                   errorstate = SDMMC_ERROR_TIMEOUT;
3562                 }
3563                 else if (errorstate == HAL_MMC_ERROR_NONE)
3564                 {
3565                   /* Check the bit SWITCH_ERROR of the device status */
3566                   if ((response & 0x80U) != 0U)
3567                   {
3568                     errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3569                   }
3570                 }
3571                 else
3572                 {
3573                   /* NOthing to do */
3574                 }
3575               }
3576             }
3577             else
3578             {
3579               errorstate = SDMMC_ERROR_REQUEST_NOT_APPLICABLE;
3580             }
3581           }
3582         }
3583         else
3584         {
3585           errorstate = SDMMC_ERROR_REQUEST_NOT_APPLICABLE;
3586         }
3587       }
3588     }
3589 
3590     /* Change State */
3591     hmmc->State = HAL_MMC_STATE_READY;
3592 
3593     /* Manage errors */
3594     if (errorstate != HAL_MMC_ERROR_NONE)
3595     {
3596       /* Clear all the static flags */
3597       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3598       hmmc->ErrorCode |= errorstate;
3599 
3600       if (errorstate != HAL_MMC_ERROR_TIMEOUT)
3601       {
3602         return HAL_ERROR;
3603       }
3604       else
3605       {
3606         return HAL_TIMEOUT;
3607       }
3608     }
3609     else
3610     {
3611       return HAL_OK;
3612     }
3613   }
3614   else
3615   {
3616     return HAL_BUSY;
3617   }
3618 }
3619 /**
3620   * @}
3621   */
3622 
3623 /**
3624   * @}
3625   */
3626 
3627 /* Private function ----------------------------------------------------------*/
3628 /** @addtogroup MMC_Private_Functions
3629   * @{
3630   */
3631 
3632 /**
3633   * @brief  Initializes the mmc card.
3634   * @param  hmmc: Pointer to MMC handle
3635   * @retval MMC Card error state
3636   */
MMC_InitCard(MMC_HandleTypeDef * hmmc)3637 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc)
3638 {
3639   HAL_MMC_CardCSDTypeDef CSD;
3640   uint32_t errorstate;
3641   uint16_t mmc_rca = 2U;
3642   MMC_InitTypeDef Init;
3643 
3644   /* Check the power State */
3645   if (SDMMC_GetPowerState(hmmc->Instance) == 0U)
3646   {
3647     /* Power off */
3648     return HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
3649   }
3650 
3651   /* Send CMD2 ALL_SEND_CID */
3652   errorstate = SDMMC_CmdSendCID(hmmc->Instance);
3653   if (errorstate != HAL_MMC_ERROR_NONE)
3654   {
3655     return errorstate;
3656   }
3657   else
3658   {
3659     /* Get Card identification number data */
3660     hmmc->CID[0U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3661     hmmc->CID[1U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2);
3662     hmmc->CID[2U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP3);
3663     hmmc->CID[3U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP4);
3664   }
3665 
3666   /* Send CMD3 SET_REL_ADDR with RCA = 2 (should be greater than 1) */
3667   /* MMC Card publishes its RCA. */
3668   errorstate = SDMMC_CmdSetRelAddMmc(hmmc->Instance, mmc_rca);
3669   if (errorstate != HAL_MMC_ERROR_NONE)
3670   {
3671     return errorstate;
3672   }
3673 
3674   /* Get the MMC card RCA */
3675   hmmc->MmcCard.RelCardAdd = mmc_rca;
3676 
3677   /* Send CMD9 SEND_CSD with argument as card's RCA */
3678   errorstate = SDMMC_CmdSendCSD(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
3679   if (errorstate != HAL_MMC_ERROR_NONE)
3680   {
3681     return errorstate;
3682   }
3683   else
3684   {
3685     /* Get Card Specific Data */
3686     hmmc->CSD[0U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3687     hmmc->CSD[1U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2);
3688     hmmc->CSD[2U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP3);
3689     hmmc->CSD[3U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP4);
3690   }
3691 
3692   /* Get the Card Class */
3693   hmmc->MmcCard.Class = (SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2) >> 20U);
3694 
3695   /* Select the Card */
3696   errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3697   if (errorstate != HAL_MMC_ERROR_NONE)
3698   {
3699     return errorstate;
3700   }
3701 
3702   /* Get CSD parameters */
3703   if (HAL_MMC_GetCardCSD(hmmc, &CSD) != HAL_OK)
3704   {
3705     return hmmc->ErrorCode;
3706   }
3707 
3708   /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3709   errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3710   if (errorstate != HAL_MMC_ERROR_NONE)
3711   {
3712     hmmc->ErrorCode |= errorstate;
3713   }
3714 
3715   /* Get Extended CSD parameters */
3716   if (HAL_MMC_GetCardExtCSD(hmmc, hmmc->Ext_CSD, SDMMC_DATATIMEOUT) != HAL_OK)
3717   {
3718     return hmmc->ErrorCode;
3719   }
3720 
3721   /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3722   errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3723   if (errorstate != HAL_MMC_ERROR_NONE)
3724   {
3725     hmmc->ErrorCode |= errorstate;
3726   }
3727 
3728   /* Configure the SDMMC peripheral */
3729   Init = hmmc->Init;
3730   Init.BusWide = SDMMC_BUS_WIDE_1B;
3731   (void)SDMMC_Init(hmmc->Instance, Init);
3732 
3733   /* All cards are initialized */
3734   return HAL_MMC_ERROR_NONE;
3735 }
3736 
3737 /**
3738   * @brief  Enquires cards about their operating voltage and configures clock
3739   *         controls and stores MMC information that will be needed in future
3740   *         in the MMC handle.
3741   * @param  hmmc: Pointer to MMC handle
3742   * @retval error state
3743   */
MMC_PowerON(MMC_HandleTypeDef * hmmc)3744 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc)
3745 {
3746   __IO uint32_t count = 0U;
3747   uint32_t response = 0U;
3748   uint32_t validvoltage = 0U;
3749   uint32_t errorstate;
3750 
3751   /* CMD0: GO_IDLE_STATE */
3752   errorstate = SDMMC_CmdGoIdleState(hmmc->Instance);
3753   if (errorstate != HAL_MMC_ERROR_NONE)
3754   {
3755     return errorstate;
3756   }
3757 
3758   while (validvoltage == 0U)
3759   {
3760     if (count++ == SDMMC_MAX_VOLT_TRIAL)
3761     {
3762       return HAL_MMC_ERROR_INVALID_VOLTRANGE;
3763     }
3764 
3765     /* SEND CMD1 APP_CMD with voltage range as argument */
3766     errorstate = SDMMC_CmdOpCondition(hmmc->Instance, MMC_VOLTAGE_RANGE);
3767     if (errorstate != HAL_MMC_ERROR_NONE)
3768     {
3769       return HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
3770     }
3771 
3772     /* Get command response */
3773     response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3774 
3775     /* Get operating voltage*/
3776     validvoltage = (((response >> 31U) == 1U) ? 1U : 0U);
3777   }
3778 
3779   /* When power routine is finished and command returns valid voltage */
3780   if (((response & (0xFF000000U)) >> 24) == 0xC0U)
3781   {
3782     hmmc->MmcCard.CardType = MMC_HIGH_CAPACITY_CARD;
3783   }
3784   else
3785   {
3786     hmmc->MmcCard.CardType = MMC_LOW_CAPACITY_CARD;
3787   }
3788 
3789   return HAL_MMC_ERROR_NONE;
3790 }
3791 
3792 /**
3793   * @brief  Turns the SDMMC output signals off.
3794   * @param  hmmc: Pointer to MMC handle
3795   * @retval None
3796   */
MMC_PowerOFF(MMC_HandleTypeDef * hmmc)3797 static void MMC_PowerOFF(MMC_HandleTypeDef *hmmc)
3798 {
3799   /* Set Power State to OFF */
3800   (void)SDMMC_PowerState_OFF(hmmc->Instance);
3801 }
3802 
3803 /**
3804   * @brief  Returns the current card's status.
3805   * @param  hmmc: Pointer to MMC handle
3806   * @param  pCardStatus: pointer to the buffer that will contain the MMC card
3807   *         status (Card Status register)
3808   * @retval error state
3809   */
MMC_SendStatus(MMC_HandleTypeDef * hmmc,uint32_t * pCardStatus)3810 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus)
3811 {
3812   uint32_t errorstate;
3813 
3814   if (pCardStatus == NULL)
3815   {
3816     return HAL_MMC_ERROR_PARAM;
3817   }
3818 
3819   /* Send Status command */
3820   errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
3821   if (errorstate != HAL_MMC_ERROR_NONE)
3822   {
3823     return errorstate;
3824   }
3825 
3826   /* Get MMC card status */
3827   *pCardStatus = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3828 
3829   return HAL_MMC_ERROR_NONE;
3830 }
3831 
3832 /**
3833   * @brief  Reads extended CSD register to get the sectors number of the device
3834   * @param  hmmc: Pointer to MMC handle
3835   * @param  pFieldData: Pointer to the read buffer
3836   * @param  FieldIndex: Index of the field to be read
3837   * @param  Timeout: Specify timeout value
3838   * @retval HAL status
3839   */
MMC_ReadExtCSD(MMC_HandleTypeDef * hmmc,uint32_t * pFieldData,uint16_t FieldIndex,uint32_t Timeout)3840 static HAL_StatusTypeDef MMC_ReadExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pFieldData,
3841                                         uint16_t FieldIndex, uint32_t Timeout)
3842 {
3843   SDMMC_DataInitTypeDef config;
3844   uint32_t errorstate;
3845   uint32_t tickstart = HAL_GetTick();
3846   uint32_t count;
3847   uint32_t i = 0;
3848   uint32_t tmp_data;
3849 
3850   hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
3851 
3852   /* Initialize data control register */
3853   hmmc->Instance->DCTRL = 0;
3854 
3855   /* Configure the MMC DPSM (Data Path State Machine) */
3856   config.DataTimeOut   = SDMMC_DATATIMEOUT;
3857   config.DataLength    = MMC_BLOCKSIZE;
3858   config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
3859   config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
3860   config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
3861   config.DPSM          = SDMMC_DPSM_ENABLE;
3862   (void)SDMMC_ConfigData(hmmc->Instance, &config);
3863 
3864   /* Set Block Size for Card */
3865   errorstate = SDMMC_CmdSendEXTCSD(hmmc->Instance, 0);
3866   if (errorstate != HAL_MMC_ERROR_NONE)
3867   {
3868     /* Clear all the static flags */
3869     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3870     hmmc->ErrorCode |= errorstate;
3871     hmmc->State = HAL_MMC_STATE_READY;
3872     return HAL_ERROR;
3873   }
3874 
3875   /* Poll on SDMMC flags */
3876   while (!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT |
3877                              SDMMC_FLAG_DATAEND))
3878   {
3879     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF))
3880     {
3881       /* Read data from SDMMC Rx FIFO */
3882       for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
3883       {
3884         tmp_data = SDMMC_ReadFIFO(hmmc->Instance);
3885         /* eg : SEC_COUNT   : FieldIndex = 212 => i+count = 53 */
3886         /*      DEVICE_TYPE : FieldIndex = 196 => i+count = 49 */
3887         if ((i + count) == ((uint32_t)FieldIndex / 4U))
3888         {
3889           *pFieldData = tmp_data;
3890         }
3891       }
3892       i += 8U;
3893     }
3894 
3895     if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
3896     {
3897       /* Clear all the static flags */
3898       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3899       hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
3900       hmmc->State = HAL_MMC_STATE_READY;
3901       return HAL_TIMEOUT;
3902     }
3903   }
3904 
3905   /* Get error state */
3906   if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
3907   {
3908     /* Clear all the static flags */
3909     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3910     hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
3911     hmmc->State = HAL_MMC_STATE_READY;
3912     return HAL_ERROR;
3913   }
3914   else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
3915   {
3916     /* Clear all the static flags */
3917     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3918     hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
3919     hmmc->State = HAL_MMC_STATE_READY;
3920     return HAL_ERROR;
3921   }
3922   else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR))
3923   {
3924     /* Clear all the static flags */
3925     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3926     hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
3927     hmmc->State = HAL_MMC_STATE_READY;
3928     return HAL_ERROR;
3929   }
3930   else
3931   {
3932     /* Nothing to do */
3933   }
3934 
3935   /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3936   errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16));
3937   if (errorstate != HAL_MMC_ERROR_NONE)
3938   {
3939     hmmc->ErrorCode |= errorstate;
3940   }
3941 
3942   /* Clear all the static flags */
3943   __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
3944 
3945   hmmc->State = HAL_MMC_STATE_READY;
3946 
3947   return HAL_OK;
3948 }
3949 
3950 /**
3951   * @brief  Wrap up reading in non-blocking mode.
3952   * @param  hmmc: pointer to a MMC_HandleTypeDef structure that contains
3953   *              the configuration information.
3954   * @retval None
3955   */
MMC_Read_IT(MMC_HandleTypeDef * hmmc)3956 static void MMC_Read_IT(MMC_HandleTypeDef *hmmc)
3957 {
3958   uint32_t count;
3959   uint32_t data;
3960   uint8_t *tmp;
3961 
3962   tmp = hmmc->pRxBuffPtr;
3963 
3964   if (hmmc->RxXferSize >= SDMMC_FIFO_SIZE)
3965   {
3966     /* Read data from SDMMC Rx FIFO */
3967     for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
3968     {
3969       data = SDMMC_ReadFIFO(hmmc->Instance);
3970       *tmp = (uint8_t)(data & 0xFFU);
3971       tmp++;
3972       *tmp = (uint8_t)((data >> 8U) & 0xFFU);
3973       tmp++;
3974       *tmp = (uint8_t)((data >> 16U) & 0xFFU);
3975       tmp++;
3976       *tmp = (uint8_t)((data >> 24U) & 0xFFU);
3977       tmp++;
3978     }
3979 
3980     hmmc->pRxBuffPtr = tmp;
3981     hmmc->RxXferSize -= SDMMC_FIFO_SIZE;
3982   }
3983 }
3984 
3985 /**
3986   * @brief  Wrap up writing in non-blocking mode.
3987   * @param  hmmc: pointer to a MMC_HandleTypeDef structure that contains
3988   *              the configuration information.
3989   * @retval None
3990   */
MMC_Write_IT(MMC_HandleTypeDef * hmmc)3991 static void MMC_Write_IT(MMC_HandleTypeDef *hmmc)
3992 {
3993   uint32_t count;
3994   uint32_t data;
3995   const uint8_t *tmp;
3996 
3997   tmp = hmmc->pTxBuffPtr;
3998 
3999   if (hmmc->TxXferSize >= SDMMC_FIFO_SIZE)
4000   {
4001     /* Write data to SDMMC Tx FIFO */
4002     for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
4003     {
4004       data = (uint32_t)(*tmp);
4005       tmp++;
4006       data |= ((uint32_t)(*tmp) << 8U);
4007       tmp++;
4008       data |= ((uint32_t)(*tmp) << 16U);
4009       tmp++;
4010       data |= ((uint32_t)(*tmp) << 24U);
4011       tmp++;
4012       (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
4013     }
4014 
4015     hmmc->pTxBuffPtr = tmp;
4016     hmmc->TxXferSize -= SDMMC_FIFO_SIZE;
4017   }
4018 }
4019 
4020 /**
4021   * @brief  Switches the MMC card to high speed mode.
4022   * @param  hmmc: MMC handle
4023   * @param  state: State of high speed mode
4024   * @retval MMC Card error state
4025   */
MMC_HighSpeed(MMC_HandleTypeDef * hmmc,FunctionalState state)4026 static uint32_t MMC_HighSpeed(MMC_HandleTypeDef *hmmc, FunctionalState state)
4027 {
4028   uint32_t errorstate = HAL_MMC_ERROR_NONE;
4029   uint32_t response = 0U;
4030   uint32_t count;
4031   uint32_t sdmmc_clk;
4032   SDMMC_InitTypeDef Init;
4033 
4034   if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) != 0U) && (state == DISABLE))
4035   {
4036     errorstate = MMC_PwrClassUpdate(hmmc, (hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS), SDMMC_SPEED_MODE_DEFAULT);
4037     if (errorstate == HAL_MMC_ERROR_NONE)
4038     {
4039       /* Index : 185 - Value : 0 */
4040       errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B90000U);
4041     }
4042   }
4043 
4044   if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) == 0U) && (state != DISABLE))
4045   {
4046     errorstate = MMC_PwrClassUpdate(hmmc, (hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS), SDMMC_SPEED_MODE_HIGH);
4047     if (errorstate == HAL_MMC_ERROR_NONE)
4048     {
4049       /* Index : 185 - Value : 1 */
4050       errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B90100U);
4051     }
4052   }
4053 
4054   if (errorstate == HAL_MMC_ERROR_NONE)
4055   {
4056     /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
4057     count = SDMMC_MAX_TRIAL;
4058     do
4059     {
4060       errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
4061       if (errorstate != HAL_MMC_ERROR_NONE)
4062       {
4063         break;
4064       }
4065 
4066       /* Get command response */
4067       response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
4068       count--;
4069     } while (((response & 0x100U) == 0U) && (count != 0U));
4070 
4071     /* Check the status after the switch command execution */
4072     if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
4073     {
4074       /* Check the bit SWITCH_ERROR of the device status */
4075       if ((response & 0x80U) != 0U)
4076       {
4077         errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
4078       }
4079       else
4080       {
4081         /* Configure high speed */
4082         Init.ClockEdge           = hmmc->Init.ClockEdge;
4083         Init.ClockPowerSave      = hmmc->Init.ClockPowerSave;
4084         Init.BusWide             = (hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS);
4085         Init.HardwareFlowControl = hmmc->Init.HardwareFlowControl;
4086 
4087         if (state == DISABLE)
4088         {
4089           Init.ClockDiv = hmmc->Init.ClockDiv;
4090           (void)SDMMC_Init(hmmc->Instance, Init);
4091 
4092           CLEAR_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_BUSSPEED);
4093         }
4094         else
4095         {
4096           /* High Speed Clock should be less or equal to 52MHz*/
4097           sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC);
4098 
4099           if (sdmmc_clk == 0U)
4100           {
4101             errorstate = SDMMC_ERROR_INVALID_PARAMETER;
4102           }
4103           else
4104           {
4105             if (sdmmc_clk <= MMC_HIGH_SPEED_FREQ)
4106             {
4107               Init.ClockDiv = 0;
4108             }
4109             else
4110             {
4111               Init.ClockDiv = (sdmmc_clk / (2U * MMC_HIGH_SPEED_FREQ)) + 1U;
4112             }
4113             (void)SDMMC_Init(hmmc->Instance, Init);
4114 
4115             SET_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_BUSSPEED);
4116           }
4117         }
4118       }
4119     }
4120     else if (count == 0U)
4121     {
4122       errorstate = SDMMC_ERROR_TIMEOUT;
4123     }
4124     else
4125     {
4126       /* Nothing to do */
4127     }
4128   }
4129 
4130   return errorstate;
4131 }
4132 
4133 /**
4134   * @brief  Switches the MMC card to Double Data Rate (DDR) mode.
4135   * @param  hmmc: MMC handle
4136   * @param  state: State of DDR mode
4137   * @retval MMC Card error state
4138   */
MMC_DDR_Mode(MMC_HandleTypeDef * hmmc,FunctionalState state)4139 static uint32_t MMC_DDR_Mode(MMC_HandleTypeDef *hmmc, FunctionalState state)
4140 {
4141   uint32_t errorstate = HAL_MMC_ERROR_NONE;
4142   uint32_t response = 0U;
4143   uint32_t count;
4144 
4145   if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) != 0U) && (state == DISABLE))
4146   {
4147     if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS_0) != 0U)
4148     {
4149       errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_4B, SDMMC_SPEED_MODE_HIGH);
4150       if (errorstate == HAL_MMC_ERROR_NONE)
4151       {
4152         /* Index : 183 - Value : 1 */
4153         errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U);
4154       }
4155     }
4156     else
4157     {
4158       errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_8B, SDMMC_SPEED_MODE_HIGH);
4159       if (errorstate == HAL_MMC_ERROR_NONE)
4160       {
4161         /* Index : 183 - Value : 2 */
4162         errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U);
4163       }
4164     }
4165   }
4166 
4167   if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) == 0U) && (state != DISABLE))
4168   {
4169     if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS_0) != 0U)
4170     {
4171       errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_4B, SDMMC_SPEED_MODE_DDR);
4172       if (errorstate == HAL_MMC_ERROR_NONE)
4173       {
4174         /* Index : 183 - Value : 5 */
4175         errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70500U);
4176       }
4177     }
4178     else
4179     {
4180       errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_8B, SDMMC_SPEED_MODE_DDR);
4181       if (errorstate == HAL_MMC_ERROR_NONE)
4182       {
4183         /* Index : 183 - Value : 6 */
4184         errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70600U);
4185       }
4186     }
4187   }
4188 
4189   if (errorstate == HAL_MMC_ERROR_NONE)
4190   {
4191     /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
4192     count = SDMMC_MAX_TRIAL;
4193     do
4194     {
4195       errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
4196       if (errorstate != HAL_MMC_ERROR_NONE)
4197       {
4198         break;
4199       }
4200 
4201       /* Get command response */
4202       response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
4203       count--;
4204     } while (((response & 0x100U) == 0U) && (count != 0U));
4205 
4206     /* Check the status after the switch command execution */
4207     if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
4208     {
4209       /* Check the bit SWITCH_ERROR of the device status */
4210       if ((response & 0x80U) != 0U)
4211       {
4212         errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
4213       }
4214       else
4215       {
4216         /* Configure DDR mode */
4217         if (state == DISABLE)
4218         {
4219           CLEAR_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_DDR);
4220         }
4221         else
4222         {
4223           SET_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_DDR);
4224         }
4225       }
4226     }
4227     else if (count == 0U)
4228     {
4229       errorstate = SDMMC_ERROR_TIMEOUT;
4230     }
4231     else
4232     {
4233       /* Nothing to do */
4234     }
4235   }
4236 
4237   return errorstate;
4238 }
4239 
4240 /**
4241   * @brief  Update the power class of the device.
4242   * @param  hmmc MMC handle
4243   * @param  Wide Wide of MMC bus
4244   * @param  Speed Speed of the MMC bus
4245   * @retval MMC Card error state
4246   */
MMC_PwrClassUpdate(MMC_HandleTypeDef * hmmc,uint32_t Wide,uint32_t Speed)4247 static uint32_t MMC_PwrClassUpdate(MMC_HandleTypeDef *hmmc, uint32_t Wide, uint32_t Speed)
4248 {
4249   uint32_t count;
4250   uint32_t response = 0U;
4251   uint32_t errorstate = HAL_MMC_ERROR_NONE;
4252   uint32_t power_class;
4253   uint32_t supported_pwr_class;
4254 
4255   if ((Wide == SDMMC_BUS_WIDE_8B) || (Wide == SDMMC_BUS_WIDE_4B))
4256   {
4257     power_class = 0U; /* Default value after power-on or software reset */
4258 
4259     /* Read the PowerClass field of the Extended CSD register */
4260     if (MMC_ReadExtCSD(hmmc, &power_class, 187, SDMMC_DATATIMEOUT) != HAL_OK) /* Field POWER_CLASS [187] */
4261     {
4262       errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
4263     }
4264     else
4265     {
4266       power_class = ((power_class >> 24U) & 0x000000FFU);
4267     }
4268 
4269     /* Get the supported PowerClass field of the Extended CSD register */
4270     if (Speed == SDMMC_SPEED_MODE_DDR)
4271     {
4272       /* Field PWR_CL_DDR_52_xxx [238 or 239] */
4273       supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_DDR_52_INDEX / 4)] >> MMC_EXT_CSD_PWR_CL_DDR_52_POS) &
4274                              0x000000FFU);
4275     }
4276     else if (Speed == SDMMC_SPEED_MODE_HIGH)
4277     {
4278       /* Field PWR_CL_52_xxx [200 or 202] */
4279       supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_52_INDEX / 4)] >> MMC_EXT_CSD_PWR_CL_52_POS) &
4280                              0x000000FFU);
4281     }
4282     else
4283     {
4284       /* Field PWR_CL_26_xxx [201 or 203] */
4285       supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_26_INDEX / 4)] >> MMC_EXT_CSD_PWR_CL_26_POS) &
4286                              0x000000FFU);
4287     }
4288 
4289     if (errorstate == HAL_MMC_ERROR_NONE)
4290     {
4291       if (Wide == SDMMC_BUS_WIDE_8B)
4292       {
4293         /* Bit [7:4]: power class for 8-bits bus configuration - Bit [3:0]: power class for 4-bits bus configuration */
4294         supported_pwr_class = (supported_pwr_class >> 4U);
4295       }
4296 
4297       if ((power_class & 0x0FU) != (supported_pwr_class & 0x0FU))
4298       {
4299         /* Need to change current power class */
4300         errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03BB0000U | ((supported_pwr_class & 0x0FU) << 8U)));
4301 
4302         if (errorstate == HAL_MMC_ERROR_NONE)
4303         {
4304           /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
4305           count = SDMMC_MAX_TRIAL;
4306           do
4307           {
4308             errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
4309             if (errorstate != HAL_MMC_ERROR_NONE)
4310             {
4311               break;
4312             }
4313 
4314             /* Get command response */
4315             response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
4316             count--;
4317           } while (((response & 0x100U) == 0U) && (count != 0U));
4318 
4319           /* Check the status after the switch command execution */
4320           if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
4321           {
4322             /* Check the bit SWITCH_ERROR of the device status */
4323             if ((response & 0x80U) != 0U)
4324             {
4325               errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
4326             }
4327           }
4328           else if (count == 0U)
4329           {
4330             errorstate = SDMMC_ERROR_TIMEOUT;
4331           }
4332           else
4333           {
4334             /* Nothing to do */
4335           }
4336         }
4337       }
4338     }
4339   }
4340 
4341   return errorstate;
4342 }
4343 
4344 /**
4345   * @brief  Used to select the partition.
4346   * @param  hmmc: Pointer to MMC handle
4347   * @param  Partition: Partition type
4348   * @retval HAL status
4349   */
HAL_MMC_SwitchPartition(MMC_HandleTypeDef * hmmc,HAL_MMC_PartitionTypeDef Partition)4350 HAL_StatusTypeDef HAL_MMC_SwitchPartition(MMC_HandleTypeDef *hmmc, HAL_MMC_PartitionTypeDef Partition)
4351 {
4352   uint32_t errorstate;
4353   uint32_t response = 0U;
4354   uint32_t count;
4355   uint32_t tickstart = HAL_GetTick();
4356   uint32_t arg = Partition | 0x03B30000U;
4357 
4358   /* Check the state of the driver */
4359   if (hmmc->State == HAL_MMC_STATE_READY)
4360   {
4361     /* Change State */
4362     hmmc->State = HAL_MMC_STATE_BUSY;
4363 
4364     /* Index : 179 - Value : partition */
4365     errorstate = SDMMC_CmdSwitch(hmmc->Instance, arg);
4366     if (errorstate == HAL_MMC_ERROR_NONE)
4367     {
4368       /* Wait that the device is ready by checking the D0 line */
4369       while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
4370       {
4371         if ((HAL_GetTick() - tickstart) >= SDMMC_MAXERASETIMEOUT)
4372         {
4373           errorstate = HAL_MMC_ERROR_TIMEOUT;
4374         }
4375       }
4376 
4377       /* Clear the flag corresponding to end D0 bus line */
4378       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
4379 
4380       if (errorstate == HAL_MMC_ERROR_NONE)
4381       {
4382         /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
4383         count = SDMMC_MAX_TRIAL;
4384         do
4385         {
4386           errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
4387           if (errorstate != HAL_MMC_ERROR_NONE)
4388           {
4389             break;
4390           }
4391 
4392           /* Get command response */
4393           response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
4394           count--;
4395         } while (((response & 0x100U) == 0U) && (count != 0U));
4396 
4397         /* Check the status after the switch command execution */
4398         if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
4399         {
4400           /* Check the bit SWITCH_ERROR of the device status */
4401           if ((response & 0x80U) != 0U)
4402           {
4403             errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
4404           }
4405         }
4406         else if (count == 0U)
4407         {
4408           errorstate = SDMMC_ERROR_TIMEOUT;
4409         }
4410         else
4411         {
4412           /* Nothing to do */
4413         }
4414       }
4415     }
4416 
4417     /* Change State */
4418     hmmc->State = HAL_MMC_STATE_READY;
4419 
4420     /* Manage errors */
4421     if (errorstate != HAL_MMC_ERROR_NONE)
4422     {
4423       /* Clear all the static flags */
4424       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4425       hmmc->ErrorCode |= errorstate;
4426 
4427       if (errorstate != HAL_MMC_ERROR_TIMEOUT)
4428       {
4429         return HAL_ERROR;
4430       }
4431       else
4432       {
4433         return HAL_TIMEOUT;
4434       }
4435     }
4436     else
4437     {
4438       return HAL_OK;
4439     }
4440   }
4441   else
4442   {
4443     return HAL_BUSY;
4444   }
4445 }
4446 
4447 /**
4448   * @brief  Allows to program the authentication key within the RPMB partition
4449   * @param  hmmc: Pointer to MMC handle
4450   * @param  pKey: pointer to the authentication key (32 bytes)
4451   * @param  Timeout: Specify timeout value
4452   * @retval HAL status
4453   */
HAL_MMC_RPMB_ProgramAuthenticationKey(MMC_HandleTypeDef * hmmc,const uint8_t * pKey,uint32_t Timeout)4454 HAL_StatusTypeDef HAL_MMC_RPMB_ProgramAuthenticationKey(MMC_HandleTypeDef *hmmc, const uint8_t *pKey, uint32_t Timeout)
4455 {
4456   SDMMC_DataInitTypeDef config;
4457   uint32_t errorstate;
4458   uint32_t tickstart = HAL_GetTick();
4459   uint32_t count;
4460   uint32_t byte_count = 0;
4461   uint32_t data;
4462   uint32_t dataremaining;
4463   uint8_t tail_pack[12] = {0};
4464   uint8_t zero_pack[4] = {0};
4465   const uint8_t *rtempbuff;
4466   uint8_t  *tempbuff;
4467 
4468   tail_pack[11] = 0x01;
4469 
4470   if (NULL == pKey)
4471   {
4472     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
4473     return HAL_ERROR;
4474   }
4475 
4476   if (hmmc->State == HAL_MMC_STATE_READY)
4477   {
4478     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
4479 
4480     hmmc->State = HAL_MMC_STATE_BUSY;
4481 
4482     /* Initialize data control register */
4483     hmmc->Instance->DCTRL = 0U;
4484 
4485     errorstate = SDMMC_CmdBlockCount(hmmc->Instance,  0x80000001U);
4486     if (errorstate != HAL_MMC_ERROR_NONE)
4487     {
4488       /* Clear all the static flags */
4489       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4490       hmmc->ErrorCode |= errorstate;
4491       hmmc->State = HAL_MMC_STATE_READY;
4492       return HAL_ERROR;
4493     }
4494 
4495     /* Configure the MMC DPSM (Data Path State Machine) */
4496     config.DataTimeOut   = SDMMC_DATATIMEOUT;
4497     config.DataLength    = MMC_BLOCKSIZE;
4498     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
4499     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
4500     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
4501     config.DPSM          = SDMMC_DPSM_DISABLE;
4502     (void)SDMMC_ConfigData(hmmc->Instance, &config);
4503     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
4504 
4505     /* Write Blocks in Polling mode */
4506     {
4507       hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
4508 
4509       /* Write Multi Block command */
4510       errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, 0);
4511     }
4512 
4513     if (errorstate != HAL_MMC_ERROR_NONE)
4514     {
4515       /* Clear all the static flags */
4516       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4517       hmmc->ErrorCode |= errorstate;
4518       hmmc->State = HAL_MMC_STATE_READY;
4519       return HAL_ERROR;
4520     }
4521 
4522     /* Write block(s) in polling mode */
4523     rtempbuff = zero_pack;
4524     dataremaining = config.DataLength;
4525     while (!__HAL_MMC_GET_FLAG(hmmc,
4526                                SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
4527     {
4528       if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= SDMMC_FIFO_SIZE))
4529       {
4530         /* Write data to SDMMC Tx FIFO */
4531         for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
4532         {
4533           data = (uint32_t)(*rtempbuff);
4534           rtempbuff++;
4535           byte_count++;
4536           data |= ((uint32_t)(*rtempbuff) << 8U);
4537           rtempbuff++;
4538           byte_count++;
4539           data |= ((uint32_t)(*rtempbuff) << 16U);
4540           rtempbuff++;
4541           byte_count++;
4542           data |= ((uint32_t)(*rtempbuff) << 24U);
4543           rtempbuff++;
4544           byte_count++;
4545           (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
4546           if (byte_count < MMC_RPMB_KEYMAC_POSITION)
4547           {
4548             rtempbuff = zero_pack;
4549           }
4550           else if (byte_count == MMC_RPMB_KEYMAC_POSITION)
4551           {
4552             rtempbuff = pKey;
4553           }
4554           else if ((byte_count < MMC_RPMB_WRITE_COUNTER_POSITION) && \
4555                    (byte_count >= MMC_RPMB_DATA_POSITION))
4556           {
4557             rtempbuff = zero_pack;
4558           }
4559           else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
4560           {
4561             rtempbuff = tail_pack;
4562           }
4563           else
4564           {
4565             /* Nothing to do */
4566           }
4567 
4568         }
4569         dataremaining -= SDMMC_FIFO_SIZE;
4570       }
4571 
4572       if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
4573       {
4574         /* Clear all the static flags */
4575         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4576         hmmc->ErrorCode |= errorstate;
4577         hmmc->State = HAL_MMC_STATE_READY;
4578         return HAL_TIMEOUT;
4579       }
4580     }
4581     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
4582 
4583     /* Read Response Packet */
4584     errorstate = SDMMC_CmdBlockCount(hmmc->Instance,  0x00000001);
4585     if (errorstate != HAL_MMC_ERROR_NONE)
4586     {
4587       /* Clear all the static flags */
4588       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4589       hmmc->ErrorCode |= errorstate;
4590       hmmc->State = HAL_MMC_STATE_READY;
4591       return HAL_ERROR;
4592     }
4593 
4594     /* Configure the MMC DPSM (Data Path State Machine) */
4595     config.DataTimeOut   = SDMMC_DATATIMEOUT;
4596     config.DataLength    = MMC_BLOCKSIZE;
4597     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
4598     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
4599     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
4600     config.DPSM          = SDMMC_DPSM_DISABLE;
4601     (void)SDMMC_ConfigData(hmmc->Instance, &config);
4602     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
4603 
4604     /* Write Blocks in Polling mode */
4605     hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
4606 
4607     /* Write Multi Block command */
4608     errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, 0);
4609 
4610     if (errorstate != HAL_MMC_ERROR_NONE)
4611     {
4612       /* Clear all the static flags */
4613       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4614       hmmc->ErrorCode |= errorstate;
4615       hmmc->State = HAL_MMC_STATE_READY;
4616       return HAL_ERROR;
4617     }
4618 
4619     /* Clear all the static flags */
4620     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
4621     /* Poll on SDMMC flags */
4622     tempbuff = zero_pack;
4623     byte_count = 0;
4624 
4625     dataremaining = config.DataLength;
4626     while (!__HAL_MMC_GET_FLAG(hmmc,
4627                                SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
4628     {
4629       if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= SDMMC_FIFO_SIZE))
4630       {
4631         /* Read data from SDMMC Rx FIFO */
4632         for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
4633         {
4634           data = SDMMC_ReadFIFO(hmmc->Instance);
4635           *tempbuff = (uint8_t)(data & 0xFFU);
4636           tempbuff++;
4637           byte_count++;
4638           *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
4639           tempbuff++;
4640           byte_count++;
4641           *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
4642           tempbuff++;
4643           byte_count++;
4644           *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
4645           tempbuff++;
4646           byte_count++;
4647           if (byte_count < MMC_RPMB_WRITE_COUNTER_POSITION)
4648           {
4649             tempbuff = zero_pack;
4650           }
4651           else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
4652           {
4653             tempbuff = tail_pack;
4654           }
4655           else
4656           {
4657             /* Nothing to do */
4658           }
4659         }
4660         dataremaining -= SDMMC_FIFO_SIZE;
4661       }
4662 
4663       if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
4664       {
4665         /* Clear all the static flags */
4666         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4667         hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
4668         hmmc->State = HAL_MMC_STATE_READY;
4669         return HAL_TIMEOUT;
4670       }
4671     }
4672     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
4673 
4674     /* Get error state */
4675     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
4676     {
4677       /* Clear all the static flags */
4678       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4679       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
4680       hmmc->State = HAL_MMC_STATE_READY;
4681       return HAL_ERROR;
4682     }
4683     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
4684     {
4685       /* Clear all the static flags */
4686       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4687       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
4688       hmmc->State = HAL_MMC_STATE_READY;
4689       return HAL_ERROR;
4690     }
4691     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
4692     {
4693       /* Clear all the static flags */
4694       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4695       hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
4696       hmmc->State = HAL_MMC_STATE_READY;
4697       return HAL_ERROR;
4698     }
4699     else
4700     {
4701       /* Nothing to do */
4702     }
4703 
4704     /* Clear all the static flags */
4705     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
4706 
4707     hmmc->State = HAL_MMC_STATE_READY;
4708 
4709     /* Check result of operation */
4710     if ((tail_pack[9] != 0x00U) || (tail_pack[10] != 0x01U))
4711     {
4712       hmmc->RPMBErrorCode |= tail_pack[9];
4713       return HAL_ERROR;
4714     }
4715 
4716     return HAL_OK;
4717   }
4718   else
4719   {
4720     hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
4721     return HAL_ERROR;
4722   }
4723 }
4724 
4725 /**
4726   * @brief  Allows to get the value of write counter within the RPMB partition.
4727   * @param  hmmc: Pointer to MMC handle
4728   * @param  pNonce: pointer to the value of nonce (16 bytes)
4729   * @param  Timeout: Specify timeout value
4730   * @retval write counter value.
4731   */
HAL_MMC_RPMB_GetWriteCounter(MMC_HandleTypeDef * hmmc,uint8_t * pNonce,uint32_t Timeout)4732 uint32_t HAL_MMC_RPMB_GetWriteCounter(MMC_HandleTypeDef *hmmc, uint8_t *pNonce, uint32_t Timeout)
4733 {
4734   SDMMC_DataInitTypeDef config;
4735   uint32_t errorstate;
4736   uint32_t tickstart = HAL_GetTick();
4737   uint32_t count;
4738   uint32_t byte_count = 0;
4739   uint32_t data;
4740   uint32_t dataremaining;
4741   uint8_t tail_pack[12] = {0};
4742   uint8_t zero_pack[4] = {0};
4743   uint8_t echo_nonce[16] = {0};
4744   uint8_t *tempbuff = zero_pack;
4745 
4746   tail_pack[11] = 0x02;
4747 
4748   if (NULL == pNonce)
4749   {
4750     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
4751     hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4752     return 0;
4753   }
4754 
4755   if (hmmc->State == HAL_MMC_STATE_READY)
4756   {
4757     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
4758     hmmc->State = HAL_MMC_STATE_BUSY;
4759 
4760     /* Initialize data control register */
4761     hmmc->Instance->DCTRL = 0U;
4762 
4763     errorstate = SDMMC_CmdBlockCount(hmmc->Instance,  0x00000001U);
4764     if (errorstate != HAL_MMC_ERROR_NONE)
4765     {
4766       /* Clear all the static flags */
4767       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4768       hmmc->ErrorCode |= errorstate;
4769       hmmc->State = HAL_MMC_STATE_READY;
4770       hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4771       return 0;
4772     }
4773 
4774     /* Send Request Packet */
4775 
4776     /* Configure the MMC DPSM (Data Path State Machine) */
4777     config.DataTimeOut   = SDMMC_DATATIMEOUT;
4778     config.DataLength    = MMC_BLOCKSIZE;
4779     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
4780     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
4781     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
4782     config.DPSM          = SDMMC_DPSM_DISABLE;
4783     (void)SDMMC_ConfigData(hmmc->Instance, &config);
4784     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
4785 
4786     /* Write Blocks in Polling mode */
4787     hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
4788 
4789     /* Write Multi Block command */
4790     errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, 0);
4791 
4792     if (errorstate != HAL_MMC_ERROR_NONE)
4793     {
4794       /* Clear all the static flags */
4795       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4796       hmmc->ErrorCode |= errorstate;
4797       hmmc->State = HAL_MMC_STATE_READY;
4798       hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4799       return 0;
4800     }
4801 
4802     /* Write block(s) in polling mode */
4803     dataremaining = config.DataLength;
4804     while (!__HAL_MMC_GET_FLAG(hmmc,
4805                                SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
4806     {
4807       if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= SDMMC_FIFO_SIZE))
4808       {
4809 
4810         /* Write data to SDMMC Tx FIFO */
4811         for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
4812         {
4813           data = (uint32_t)(*tempbuff);
4814           tempbuff++;
4815           byte_count++;
4816           data |= ((uint32_t)(*tempbuff) << 8U);
4817           tempbuff++;
4818           byte_count++;
4819           data |= ((uint32_t)(*tempbuff) << 16U);
4820           tempbuff++;
4821           byte_count++;
4822           data |= ((uint32_t)(*tempbuff) << 24U);
4823           tempbuff++;
4824           byte_count++;
4825           (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
4826           if (byte_count < MMC_RPMB_NONCE_POSITION)
4827           {
4828             tempbuff = zero_pack;
4829           }
4830           else if (byte_count == MMC_RPMB_NONCE_POSITION)
4831           {
4832             tempbuff = (uint8_t *)pNonce;
4833           }
4834           else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
4835           {
4836             tempbuff = tail_pack;
4837           }
4838           else
4839           {
4840             /* Nothing to do */
4841           }
4842 
4843         }
4844         dataremaining -= SDMMC_FIFO_SIZE;
4845       }
4846 
4847       if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
4848       {
4849         /* Clear all the static flags */
4850         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4851         hmmc->ErrorCode |= errorstate;
4852         hmmc->State = HAL_MMC_STATE_READY;
4853         hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4854         return 0;
4855       }
4856     }
4857     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
4858 
4859     /* Read Response Packt */
4860     errorstate = SDMMC_CmdBlockCount(hmmc->Instance,  0x00000001U);
4861     if (errorstate != HAL_MMC_ERROR_NONE)
4862     {
4863       /* Clear all the static flags */
4864       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4865       hmmc->ErrorCode |= errorstate;
4866       hmmc->State = HAL_MMC_STATE_READY;
4867       hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4868       return 0;
4869     }
4870 
4871     /* Configure the MMC DPSM (Data Path State Machine) */
4872     config.DataTimeOut   = SDMMC_DATATIMEOUT;
4873     config.DataLength    = MMC_BLOCKSIZE;
4874     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
4875     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
4876     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
4877     config.DPSM          = SDMMC_DPSM_DISABLE;
4878     (void)SDMMC_ConfigData(hmmc->Instance, &config);
4879     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
4880 
4881     /* Write Blocks in Polling mode */
4882     hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
4883 
4884     /* Write Multi Block command */
4885     errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, 0);
4886 
4887     if (errorstate != HAL_MMC_ERROR_NONE)
4888     {
4889       /* Clear all the static flags */
4890       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4891       hmmc->ErrorCode |= errorstate;
4892       hmmc->State = HAL_MMC_STATE_READY;
4893       hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4894       return 0;
4895     }
4896 
4897     /* Clear all the static flags */
4898     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
4899     /* Poll on SDMMC flags */
4900     tempbuff = zero_pack;
4901 
4902     byte_count = 0;
4903     dataremaining = config.DataLength;
4904     while (!__HAL_MMC_GET_FLAG(hmmc,
4905                                SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
4906     {
4907       if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= SDMMC_FIFO_SIZE))
4908       {
4909         /* Read data from SDMMC Rx FIFO */
4910         for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
4911         {
4912           data = SDMMC_ReadFIFO(hmmc->Instance);
4913           *tempbuff = (uint8_t)(data & 0xFFU);
4914           tempbuff++;
4915           byte_count++;
4916           *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
4917           tempbuff++;
4918           byte_count++;
4919           *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
4920           tempbuff++;
4921           byte_count++;
4922           *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
4923           tempbuff++;
4924           byte_count++;
4925           if (byte_count < MMC_RPMB_NONCE_POSITION)
4926           {
4927             tempbuff = zero_pack;
4928           }
4929           else if (byte_count == MMC_RPMB_NONCE_POSITION)
4930           {
4931             tempbuff = echo_nonce;
4932           }
4933           else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
4934           {
4935             tempbuff = tail_pack;
4936           }
4937           else
4938           {
4939             /* Nothing to do */
4940           }
4941         }
4942         dataremaining -= SDMMC_FIFO_SIZE;
4943       }
4944 
4945       if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
4946       {
4947         /* Clear all the static flags */
4948         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4949         hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
4950         hmmc->State = HAL_MMC_STATE_READY;
4951         hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4952         return 0;
4953       }
4954     }
4955     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
4956 
4957     /* Get error state */
4958     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
4959     {
4960       /* Clear all the static flags */
4961       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4962       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
4963       hmmc->State = HAL_MMC_STATE_READY;
4964       hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4965       return 0;
4966     }
4967     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
4968     {
4969       /* Clear all the static flags */
4970       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4971       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
4972       hmmc->State = HAL_MMC_STATE_READY;
4973       hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4974       return 0;
4975     }
4976     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
4977     {
4978       /* Clear all the static flags */
4979       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4980       hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
4981       hmmc->State = HAL_MMC_STATE_READY;
4982       hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4983       return 0;
4984     }
4985     else
4986     {
4987       /* Nothing to do */
4988     }
4989 
4990     /* Clear all the static flags */
4991     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
4992 
4993     hmmc->State = HAL_MMC_STATE_READY;
4994 
4995     for (uint8_t i = 0; i < 16U; i++)
4996     {
4997       if (pNonce[i] != echo_nonce[i])
4998       {
4999         hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
5000         return 0;
5001       }
5002     }
5003 
5004     return ((uint32_t)tail_pack[3] | ((uint32_t)tail_pack[2] << 8) | ((uint32_t)tail_pack[1] << 16) | \
5005             ((uint32_t)tail_pack[0] << 24));
5006   }
5007   else
5008   {
5009     hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
5010     hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
5011     return 0;
5012   }
5013 }
5014 
5015 /**
5016   * @brief  Allows to write block(s) to a specified address in the RPMB partition. The Data
5017   *         transfer is managed by polling mode.
5018   * @param  hmmc: Pointer to MMC handle
5019   * @param  pData: Pointer to the buffer that will contain the data to transmit
5020   * @param  BlockAdd: Block Address where data will be written
5021   * @param  NumberOfBlocks: Number of blocks to write
5022   * @param  pMAC: Pointer to the authentication MAC buffer
5023   * @param  Timeout: Specify timeout value
5024   * @retval HAL status
5025   */
HAL_MMC_RPMB_WriteBlocks(MMC_HandleTypeDef * hmmc,const uint8_t * pData,uint16_t BlockAdd,uint16_t NumberOfBlocks,const uint8_t * pMAC,uint32_t Timeout)5026 HAL_StatusTypeDef HAL_MMC_RPMB_WriteBlocks(MMC_HandleTypeDef *hmmc, const uint8_t *pData, uint16_t BlockAdd,
5027                                            uint16_t NumberOfBlocks, const uint8_t *pMAC, uint32_t Timeout)
5028 {
5029 
5030   SDMMC_DataInitTypeDef config;
5031   uint32_t errorstate;
5032   uint32_t tickstart = HAL_GetTick();
5033   uint32_t count;
5034   uint32_t byte_count = 0;
5035   uint32_t data;
5036   uint32_t dataremaining;
5037   uint8_t tail_pack[12] = {0};
5038   uint8_t zero_pack[4] = {0};
5039   uint8_t echo_nonce[16] = {0};
5040   const uint8_t local_nonce[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x00, 0x01, 0x02,
5041                                    0x03, 0x04, 0x00, 0x01, 0x02, 0x03, 0x04, 0x08
5042                                   };
5043   const uint8_t *rtempbuff;
5044   uint8_t  *tempbuff;
5045   uint32_t arg = 0x80000000U;
5046   uint32_t offset = 0;
5047 
5048   if ((NumberOfBlocks != 0x1U) && (NumberOfBlocks != 0x2U) && (NumberOfBlocks != 0x20U))
5049   {
5050     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
5051     return HAL_ERROR;
5052   }
5053 
5054   if ((NULL == pData) || (NULL == pMAC))
5055   {
5056     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
5057     return HAL_ERROR;
5058   }
5059 
5060   tail_pack[11] = 0x02;
5061 
5062   if (hmmc->State == HAL_MMC_STATE_READY)
5063   {
5064     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
5065     hmmc->State = HAL_MMC_STATE_BUSY;
5066 
5067     /* Initialize data control register */
5068     hmmc->Instance->DCTRL = 0U;
5069 
5070     errorstate = SDMMC_CmdBlockCount(hmmc->Instance,  0x00000001U);
5071     if (errorstate != HAL_MMC_ERROR_NONE)
5072     {
5073       /* Clear all the static flags */
5074       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5075       hmmc->ErrorCode |= errorstate;
5076       hmmc->State = HAL_MMC_STATE_READY;
5077       return HAL_ERROR;
5078     }
5079 
5080     /* Send Request Packet */
5081 
5082     /* Configure the MMC DPSM (Data Path State Machine) */
5083     config.DataTimeOut   = SDMMC_DATATIMEOUT;
5084     config.DataLength    = MMC_BLOCKSIZE;
5085     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
5086     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
5087     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
5088     config.DPSM          = SDMMC_DPSM_DISABLE;
5089     (void)SDMMC_ConfigData(hmmc->Instance, &config);
5090     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
5091 
5092     /* Write Blocks in Polling mode */
5093     hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
5094 
5095     /* Write Multi Block command */
5096     errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, 0);
5097 
5098     if (errorstate != HAL_MMC_ERROR_NONE)
5099     {
5100       /* Clear all the static flags */
5101       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5102       hmmc->ErrorCode |= errorstate;
5103       hmmc->State = HAL_MMC_STATE_READY;
5104       return HAL_ERROR;
5105     }
5106 
5107     /* Write block(s) in polling mode */
5108     rtempbuff = zero_pack;
5109     dataremaining = config.DataLength;
5110     while (!__HAL_MMC_GET_FLAG(hmmc,
5111                                SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
5112     {
5113       if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= SDMMC_FIFO_SIZE))
5114       {
5115 
5116         /* Write data to SDMMC Tx FIFO */
5117         for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
5118         {
5119           data = (uint32_t)(*rtempbuff);
5120           rtempbuff++;
5121           byte_count++;
5122           data |= ((uint32_t)(*rtempbuff) << 8U);
5123           rtempbuff++;
5124           byte_count++;
5125           data |= ((uint32_t)(*rtempbuff) << 16U);
5126           rtempbuff++;
5127           byte_count++;
5128           data |= ((uint32_t)(*rtempbuff) << 24U);
5129           rtempbuff++;
5130           byte_count++;
5131           (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
5132           if (byte_count < MMC_RPMB_NONCE_POSITION)
5133           {
5134             rtempbuff = zero_pack;
5135           }
5136           else if (byte_count == MMC_RPMB_NONCE_POSITION)
5137           {
5138             rtempbuff = local_nonce;
5139           }
5140           else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
5141           {
5142             rtempbuff = tail_pack;
5143           }
5144           else
5145           {
5146             /* Nothing to do */
5147           }
5148         }
5149         dataremaining -= SDMMC_FIFO_SIZE;
5150       }
5151 
5152       if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
5153       {
5154         /* Clear all the static flags */
5155         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5156         hmmc->ErrorCode |= errorstate;
5157         hmmc->State = HAL_MMC_STATE_READY;
5158         return HAL_TIMEOUT;
5159       }
5160     }
5161     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
5162 
5163     /* Read Response Packt */
5164     errorstate = SDMMC_CmdBlockCount(hmmc->Instance,  0x00000001);
5165     if (errorstate != HAL_MMC_ERROR_NONE)
5166     {
5167       /* Clear all the static flags */
5168       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5169       hmmc->ErrorCode |= errorstate;
5170       hmmc->State = HAL_MMC_STATE_READY;
5171       return HAL_ERROR;
5172     }
5173 
5174     /* Configure the MMC DPSM (Data Path State Machine) */
5175     config.DataTimeOut   = SDMMC_DATATIMEOUT;
5176     config.DataLength    = MMC_BLOCKSIZE;
5177     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
5178     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
5179     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
5180     config.DPSM          = SDMMC_DPSM_DISABLE;
5181     (void)SDMMC_ConfigData(hmmc->Instance, &config);
5182     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
5183 
5184     /* Write Blocks in Polling mode */
5185     hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
5186 
5187     /* Write Multi Block command */
5188     errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, 0);
5189 
5190     if (errorstate != HAL_MMC_ERROR_NONE)
5191     {
5192       /* Clear all the static flags */
5193       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5194       hmmc->ErrorCode |= errorstate;
5195       hmmc->State = HAL_MMC_STATE_READY;
5196       return HAL_ERROR;
5197     }
5198 
5199     /* Clear all the static flags */
5200     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
5201     /* Poll on SDMMC flags */
5202     tempbuff = zero_pack;
5203 
5204     byte_count = 0;
5205     dataremaining = config.DataLength;
5206     while (!__HAL_MMC_GET_FLAG(hmmc,
5207                                SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
5208     {
5209       if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= SDMMC_FIFO_SIZE))
5210       {
5211         /* Read data from SDMMC Rx FIFO */
5212         for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
5213         {
5214           data = SDMMC_ReadFIFO(hmmc->Instance);
5215           *tempbuff = (uint8_t)(data & 0xFFU);
5216           tempbuff++;
5217           byte_count++;
5218           *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
5219           tempbuff++;
5220           byte_count++;
5221           *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
5222           tempbuff++;
5223           byte_count++;
5224           *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
5225           tempbuff++;
5226           byte_count++;
5227           if (byte_count < MMC_RPMB_NONCE_POSITION)
5228           {
5229             tempbuff = zero_pack;
5230           }
5231           else if (byte_count == MMC_RPMB_NONCE_POSITION)
5232           {
5233             tempbuff = echo_nonce;
5234           }
5235           else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
5236           {
5237             tempbuff = tail_pack;
5238           }
5239           else
5240           {
5241             /* Nothing to do */
5242           }
5243         }
5244         dataremaining -= SDMMC_FIFO_SIZE;
5245       }
5246 
5247       if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
5248       {
5249         /* Clear all the static flags */
5250         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5251         hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
5252         hmmc->State = HAL_MMC_STATE_READY;
5253         return HAL_TIMEOUT;
5254       }
5255     }
5256     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
5257 
5258     /* Get error state */
5259     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
5260     {
5261       /* Clear all the static flags */
5262       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5263       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
5264       hmmc->State = HAL_MMC_STATE_READY;
5265       return HAL_ERROR;
5266     }
5267     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
5268     {
5269       /* Clear all the static flags */
5270       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5271       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
5272       hmmc->State = HAL_MMC_STATE_READY;
5273       return HAL_ERROR;
5274     }
5275     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
5276     {
5277       /* Clear all the static flags */
5278       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5279       hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
5280       hmmc->State = HAL_MMC_STATE_READY;
5281       return HAL_ERROR;
5282     }
5283     else
5284     {
5285       /* Nothing to do */
5286     }
5287 
5288     /* Clear all the static flags */
5289     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
5290 
5291     hmmc->State = HAL_MMC_STATE_READY;
5292 
5293     for (uint8_t i = 0; i < 16U; i++)
5294     {
5295       if (local_nonce[i] != echo_nonce[i])
5296       {
5297         return HAL_ERROR;
5298       }
5299     }
5300   }
5301   else
5302   {
5303     hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
5304     return HAL_ERROR;
5305   }
5306   tail_pack[11]  = 0x03;
5307   tail_pack[10]  = 0x00;
5308   tail_pack[7]   = (uint8_t)(NumberOfBlocks) & 0xFFU;
5309   tail_pack[6]   = (uint8_t)(NumberOfBlocks >> 8) & 0xFFU;
5310   tail_pack[5]   = (uint8_t)(BlockAdd) & 0xFFU;
5311   tail_pack[4]   = (uint8_t)(BlockAdd >> 8) & 0xFFU;
5312 
5313   rtempbuff = zero_pack;
5314   byte_count = 0;
5315   arg |= NumberOfBlocks;
5316 
5317   if (hmmc->State == HAL_MMC_STATE_READY)
5318   {
5319     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
5320 
5321 
5322     hmmc->State = HAL_MMC_STATE_BUSY;
5323 
5324     /* Initialize data control register */
5325     hmmc->Instance->DCTRL = 0U;
5326 
5327     errorstate = SDMMC_CmdBlockCount(hmmc->Instance, arg);
5328     if (errorstate != HAL_MMC_ERROR_NONE)
5329     {
5330       /* Clear all the static flags */
5331       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5332       hmmc->ErrorCode |= errorstate;
5333       hmmc->State = HAL_MMC_STATE_READY;
5334       return HAL_ERROR;
5335     }
5336 
5337     /* Send Request Packet */
5338     /* Configure the MMC DPSM (Data Path State Machine) */
5339     config.DataTimeOut   = SDMMC_DATATIMEOUT;
5340     config.DataLength    = NumberOfBlocks * MMC_BLOCKSIZE;
5341     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
5342     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
5343     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
5344     config.DPSM          = SDMMC_DPSM_DISABLE;
5345     (void)SDMMC_ConfigData(hmmc->Instance, &config);
5346     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
5347 
5348     /* Write Blocks in Polling mode */
5349 
5350     {
5351       hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
5352 
5353       /* Write Multi Block command */
5354       errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, 0);
5355     }
5356 
5357     if (errorstate != HAL_MMC_ERROR_NONE)
5358     {
5359       /* Clear all the static flags */
5360       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5361       hmmc->ErrorCode |= errorstate;
5362       hmmc->State = HAL_MMC_STATE_READY;
5363       return HAL_ERROR;
5364     }
5365 
5366 
5367     /* Write block(s) in polling mode */
5368     dataremaining = config.DataLength;
5369     while (!__HAL_MMC_GET_FLAG(hmmc,
5370                                SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
5371     {
5372       if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= SDMMC_FIFO_SIZE))
5373       {
5374 
5375         /* Write data to SDMMC Tx FIFO */
5376         for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
5377         {
5378           data = (uint32_t)(*rtempbuff);
5379           rtempbuff++;
5380           byte_count++;
5381           data |= ((uint32_t)(*rtempbuff) << 8U);
5382           rtempbuff++;
5383           byte_count++;
5384           data |= ((uint32_t)(*rtempbuff) << 16U);
5385           rtempbuff++;
5386           byte_count++;
5387           data |= ((uint32_t)(*rtempbuff) << 24U);
5388           rtempbuff++;
5389           byte_count++;
5390           (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
5391           if (byte_count == MMC_RPMB_KEYMAC_POSITION)
5392           {
5393             rtempbuff = pMAC;
5394           }
5395           if (byte_count == MMC_RPMB_DATA_POSITION)
5396           {
5397             rtempbuff = &pData[offset];
5398           }
5399           if ((byte_count >= MMC_RPMB_NONCE_POSITION) && \
5400               (byte_count < MMC_RPMB_WRITE_COUNTER_POSITION))
5401           {
5402             rtempbuff = zero_pack;
5403           }
5404           if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
5405           {
5406             rtempbuff = tail_pack;
5407           }
5408           else if (byte_count == MMC_BLOCKSIZE)
5409           {
5410             offset += (uint32_t)256U;
5411             byte_count = 0;
5412           }
5413           else
5414           {
5415             /* Nothing to do */
5416           }
5417         }
5418         dataremaining -= SDMMC_FIFO_SIZE;
5419       }
5420 
5421       if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
5422       {
5423         /* Clear all the static flags */
5424         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5425         hmmc->ErrorCode |= errorstate;
5426         hmmc->State = HAL_MMC_STATE_READY;
5427         return HAL_TIMEOUT;
5428       }
5429     }
5430     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
5431 
5432     /* Response Packet */
5433 
5434     errorstate = SDMMC_CmdBlockCount(hmmc->Instance, arg);
5435     if (errorstate != HAL_MMC_ERROR_NONE)
5436     {
5437       /* Clear all the static flags */
5438       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5439       hmmc->ErrorCode |= errorstate;
5440       hmmc->State = HAL_MMC_STATE_READY;
5441       return HAL_ERROR;
5442     }
5443 
5444     /* Configure the MMC DPSM (Data Path State Machine) */
5445     config.DataTimeOut   = SDMMC_DATATIMEOUT;
5446     config.DataLength    = MMC_BLOCKSIZE;
5447     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
5448     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
5449     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
5450     config.DPSM          = SDMMC_DPSM_DISABLE;
5451     (void)SDMMC_ConfigData(hmmc->Instance, &config);
5452     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
5453 
5454     /* Write Blocks in Polling mode */
5455 
5456     {
5457       hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
5458 
5459       /* Write Multi Block command */
5460       errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, 0);
5461     }
5462 
5463     if (errorstate != HAL_MMC_ERROR_NONE)
5464     {
5465       /* Clear all the static flags */
5466       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5467       hmmc->ErrorCode |= errorstate;
5468       hmmc->State = HAL_MMC_STATE_READY;
5469       return HAL_ERROR;
5470     }
5471 
5472 
5473     /* Clear all the static flags */
5474     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
5475     /* Poll on SDMMC flags */
5476     tempbuff = zero_pack;
5477     byte_count = 0;
5478     dataremaining = config.DataLength;
5479     while (!__HAL_MMC_GET_FLAG(hmmc,
5480                                SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
5481     {
5482       if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= SDMMC_FIFO_SIZE))
5483       {
5484         /* Read data from SDMMC Rx FIFO */
5485         for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
5486         {
5487           data = SDMMC_ReadFIFO(hmmc->Instance);
5488           *tempbuff = (uint8_t)(data & 0xFFU);
5489           tempbuff++;
5490           byte_count++;
5491           *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
5492           tempbuff++;
5493           byte_count++;
5494           *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
5495           tempbuff++;
5496           byte_count++;
5497           *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
5498           tempbuff++;
5499           byte_count++;
5500           if (byte_count < MMC_RPMB_WRITE_COUNTER_POSITION)
5501           {
5502             tempbuff = zero_pack;
5503           }
5504           else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
5505           {
5506             tempbuff = tail_pack;
5507           }
5508           else
5509           {
5510             /* Nothing to do */
5511           }
5512         }
5513         dataremaining -= SDMMC_FIFO_SIZE;
5514       }
5515 
5516       if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
5517       {
5518         /* Clear all the static flags */
5519         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5520         hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
5521         hmmc->State = HAL_MMC_STATE_READY;
5522         return HAL_TIMEOUT;
5523       }
5524     }
5525     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
5526 
5527     /* Get error state */
5528     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
5529     {
5530       /* Clear all the static flags */
5531       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5532       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
5533       hmmc->State = HAL_MMC_STATE_READY;
5534       return HAL_ERROR;
5535     }
5536     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
5537     {
5538       /* Clear all the static flags */
5539       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5540       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
5541       hmmc->State = HAL_MMC_STATE_READY;
5542       return HAL_ERROR;
5543     }
5544     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
5545     {
5546       /* Clear all the static flags */
5547       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5548       hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
5549       hmmc->State = HAL_MMC_STATE_READY;
5550       return HAL_ERROR;
5551     }
5552     else
5553     {
5554       /* Nothing to do */
5555     }
5556 
5557     /* Clear all the static flags */
5558     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
5559 
5560     hmmc->State = HAL_MMC_STATE_READY;
5561 
5562     /* Check result of operation */
5563     if (((tail_pack[9] & (uint8_t)0xFEU) != 0x00U) || (tail_pack[10] != 0x03U))
5564     {
5565       hmmc->RPMBErrorCode |= tail_pack[9];
5566       return HAL_ERROR;
5567     }
5568 
5569     return HAL_OK;
5570   }
5571   else
5572   {
5573     hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
5574     return HAL_ERROR;
5575   }
5576 }
5577 
5578 /**
5579   * @brief  Allows to read block(s) to a specified address in the RPMB partition. The Data
5580   *         transfer is managed by polling mode.
5581   * @param  hmmc: Pointer to MMC handle
5582   * @param  pData: Pointer to the buffer that will contain the data to transmit
5583   * @param  BlockAdd: Block Address where data will be written
5584   * @param  NumberOfBlocks: Number of blocks to write
5585   * @param  pNonce: Pointer to the buffer that will contain the nonce to transmit
5586   * @param  pMAC: Pointer to the authentication MAC buffer
5587   * @param  Timeout: Specify timeout value
5588   * @retval HAL status
5589   */
HAL_MMC_RPMB_ReadBlocks(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint16_t BlockAdd,uint16_t NumberOfBlocks,const uint8_t * pNonce,uint8_t * pMAC,uint32_t Timeout)5590 HAL_StatusTypeDef HAL_MMC_RPMB_ReadBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint16_t BlockAdd,
5591                                           uint16_t NumberOfBlocks, const uint8_t *pNonce, uint8_t *pMAC,
5592                                           uint32_t Timeout)
5593 {
5594   SDMMC_DataInitTypeDef config;
5595   uint32_t errorstate;
5596   uint32_t tickstart = HAL_GetTick();
5597   uint32_t count;
5598   uint32_t byte_count = 0;
5599   uint32_t data;
5600   uint8_t tail_pack[12] = {0};
5601   uint8_t zero_pack[4] = {0};
5602   uint8_t echo_nonce[16] = {0};
5603   uint32_t dataremaining;
5604   const uint8_t *rtempbuff;
5605   uint8_t  *tempbuff;
5606   uint32_t arg = 0;
5607   uint32_t offset = 0;
5608 
5609   arg |= NumberOfBlocks;
5610 
5611   tail_pack[11] = 0x04;
5612   tail_pack[10] = 0x00;
5613   tail_pack[7]  = 0x00;
5614   tail_pack[6]  = 0x00;
5615   tail_pack[5]  = (uint8_t)(BlockAdd) & 0xFFU;
5616   tail_pack[4]  = (uint8_t)(BlockAdd >> 8) & 0xFFU;
5617   tail_pack[3]  = 0x00;
5618   tail_pack[2]  = 0x00;
5619   tail_pack[1]  = 0x00;
5620   tail_pack[0]  = 0x00;
5621 
5622   if (hmmc->State == HAL_MMC_STATE_READY)
5623   {
5624     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
5625     hmmc->State = HAL_MMC_STATE_BUSY;
5626 
5627     /* Initialize data control register */
5628     hmmc->Instance->DCTRL = 0U;
5629 
5630     errorstate = SDMMC_CmdBlockCount(hmmc->Instance, 1);
5631     if (errorstate != HAL_MMC_ERROR_NONE)
5632     {
5633       /* Clear all the static flags */
5634       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5635       hmmc->ErrorCode |= errorstate;
5636       hmmc->State = HAL_MMC_STATE_READY;
5637       return HAL_ERROR;
5638     }
5639 
5640     /* Send Request Packet */
5641 
5642     /* Configure the MMC DPSM (Data Path State Machine) */
5643     config.DataTimeOut   = SDMMC_DATATIMEOUT;
5644     config.DataLength    = MMC_BLOCKSIZE;
5645     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
5646     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
5647     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
5648     config.DPSM          = SDMMC_DPSM_DISABLE;
5649     (void)SDMMC_ConfigData(hmmc->Instance, &config);
5650     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
5651 
5652     /* Write Blocks in Polling mode */
5653     hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
5654 
5655     /* Write Multi Block command */
5656     errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, 0);
5657 
5658     if (errorstate != HAL_MMC_ERROR_NONE)
5659     {
5660       /* Clear all the static flags */
5661       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5662       hmmc->ErrorCode |= errorstate;
5663       hmmc->State = HAL_MMC_STATE_READY;
5664       return HAL_ERROR;
5665     }
5666 
5667     /* Write block(s) in polling mode */
5668     rtempbuff = zero_pack;
5669     dataremaining = config.DataLength;
5670     while (!__HAL_MMC_GET_FLAG(hmmc,
5671                                SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
5672     {
5673       if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= SDMMC_FIFO_SIZE))
5674       {
5675 
5676         /* Write data to SDMMC Tx FIFO */
5677         for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
5678         {
5679           data = (uint32_t)(*rtempbuff);
5680           rtempbuff++;
5681           byte_count++;
5682           data |= ((uint32_t)(*rtempbuff) << 8U);
5683           rtempbuff++;
5684           byte_count++;
5685           data |= ((uint32_t)(*rtempbuff) << 16U);
5686           rtempbuff++;
5687           byte_count++;
5688           data |= ((uint32_t)(*rtempbuff) << 24U);
5689           rtempbuff++;
5690           byte_count++;
5691           (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
5692           if (byte_count < MMC_RPMB_NONCE_POSITION)
5693           {
5694             rtempbuff = zero_pack;
5695           }
5696           else if (byte_count == MMC_RPMB_NONCE_POSITION)
5697           {
5698             rtempbuff = pNonce;
5699           }
5700           else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
5701           {
5702             rtempbuff = tail_pack;
5703           }
5704           else
5705           {
5706             /* Nothing to do */
5707           }
5708         }
5709         dataremaining -= SDMMC_FIFO_SIZE;
5710       }
5711 
5712       if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
5713       {
5714         /* Clear all the static flags */
5715         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5716         hmmc->ErrorCode |= errorstate;
5717         hmmc->State = HAL_MMC_STATE_READY;
5718         return HAL_TIMEOUT;
5719       }
5720     }
5721     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
5722 
5723     /* Read Response Packet */
5724     errorstate = SDMMC_CmdBlockCount(hmmc->Instance, arg);
5725     if (errorstate != HAL_MMC_ERROR_NONE)
5726     {
5727       /* Clear all the static flags */
5728       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5729       hmmc->ErrorCode |= errorstate;
5730       hmmc->State = HAL_MMC_STATE_READY;
5731       return HAL_ERROR;
5732     }
5733 
5734     /* Configure the MMC DPSM (Data Path State Machine) */
5735     config.DataTimeOut   = SDMMC_DATATIMEOUT;
5736     config.DataLength    = NumberOfBlocks * MMC_BLOCKSIZE;
5737     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
5738     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
5739     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
5740     config.DPSM          = SDMMC_DPSM_DISABLE;
5741     (void)SDMMC_ConfigData(hmmc->Instance, &config);
5742     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
5743 
5744     /* Write Blocks in Polling mode */
5745     hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
5746 
5747     /* Write Multi Block command */
5748     errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, 0);
5749 
5750     if (errorstate != HAL_MMC_ERROR_NONE)
5751     {
5752       /* Clear all the static flags */
5753       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5754       hmmc->ErrorCode |= errorstate;
5755       hmmc->State = HAL_MMC_STATE_READY;
5756       return HAL_ERROR;
5757     }
5758 
5759     /* Clear all the static flags */
5760     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
5761     /* Poll on SDMMC flags */
5762     tempbuff = zero_pack;
5763     byte_count = 0;
5764 
5765     dataremaining = config.DataLength;
5766     while (!__HAL_MMC_GET_FLAG(hmmc,
5767                                SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
5768     {
5769       if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= SDMMC_FIFO_SIZE))
5770       {
5771         /* Read data from SDMMC Rx FIFO */
5772         for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
5773         {
5774           data = SDMMC_ReadFIFO(hmmc->Instance);
5775           *tempbuff = (uint8_t)(data & 0xFFU);
5776           tempbuff++;
5777           byte_count++;
5778           *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
5779           tempbuff++;
5780           byte_count++;
5781           *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
5782           tempbuff++;
5783           byte_count++;
5784           *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
5785           tempbuff++;
5786           byte_count++;
5787           if (byte_count < MMC_RPMB_KEYMAC_POSITION)
5788           {
5789             tempbuff = zero_pack;
5790           }
5791           else if (byte_count == MMC_RPMB_KEYMAC_POSITION)
5792           {
5793             tempbuff = (uint8_t *)pMAC;
5794           }
5795           else if (byte_count == MMC_RPMB_DATA_POSITION)
5796           {
5797             tempbuff = &pData[offset];
5798           }
5799           else if (byte_count == MMC_RPMB_NONCE_POSITION)
5800           {
5801             tempbuff = echo_nonce;
5802           }
5803           else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
5804           {
5805             tempbuff = tail_pack;
5806           }
5807           else if (byte_count == MMC_BLOCKSIZE)
5808           {
5809             byte_count = 0;
5810             offset += (uint32_t)256U;
5811           }
5812           else
5813           {
5814             /* Nothing to do */
5815           }
5816         }
5817         dataremaining -= SDMMC_FIFO_SIZE;
5818       }
5819 
5820       if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
5821       {
5822         /* Clear all the static flags */
5823         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5824         hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
5825         hmmc->State = HAL_MMC_STATE_READY;
5826         return HAL_TIMEOUT;
5827       }
5828     }
5829     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
5830 
5831     /* Get error state */
5832     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
5833     {
5834       /* Clear all the static flags */
5835       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5836       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
5837       hmmc->State = HAL_MMC_STATE_READY;
5838       return HAL_ERROR;
5839     }
5840     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
5841     {
5842       /* Clear all the static flags */
5843       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5844       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
5845       hmmc->State = HAL_MMC_STATE_READY;
5846       return HAL_ERROR;
5847     }
5848     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
5849     {
5850       /* Clear all the static flags */
5851       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5852       hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
5853       hmmc->State = HAL_MMC_STATE_READY;
5854       return HAL_ERROR;
5855     }
5856     else
5857     {
5858       /* Nothing to do */
5859     }
5860 
5861     /* Clear all the static flags */
5862     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
5863 
5864     hmmc->State = HAL_MMC_STATE_READY;
5865 
5866     for (uint8_t i = 0; i < 16U; i++)
5867     {
5868       if (pNonce[i] != echo_nonce[i])
5869       {
5870         return HAL_ERROR;
5871       }
5872     }
5873 
5874     /* Check result of operation */
5875     if ((tail_pack[9] != 0x00U) || (tail_pack[10] != 0x04U))
5876     {
5877       hmmc->RPMBErrorCode |= tail_pack[9];
5878       return HAL_ERROR;
5879     }
5880 
5881     return HAL_OK;
5882   }
5883   else
5884   {
5885     hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
5886     return HAL_ERROR;
5887   }
5888 }
5889 
5890 
5891 /**
5892   * @brief Read DMA Buffer 0 Transfer completed callbacks
5893   * @param hmmc: MMC handle
5894   * @retval None
5895   */
HAL_MMCEx_Read_DMADoubleBuf0CpltCallback(MMC_HandleTypeDef * hmmc)5896 __weak void HAL_MMCEx_Read_DMADoubleBuf0CpltCallback(MMC_HandleTypeDef *hmmc)
5897 {
5898   /* Prevent unused argument(s) compilation warning */
5899   UNUSED(hmmc);
5900 
5901   /* NOTE : This function should not be modified, when the callback is needed,
5902             the HAL_MMCEx_Read_DMADoubleBuf0CpltCallback can be implemented in the user file
5903    */
5904 }
5905 
5906 /**
5907   * @brief Read DMA Buffer 1 Transfer completed callbacks
5908   * @param hmmc: MMC handle
5909   * @retval None
5910   */
HAL_MMCEx_Read_DMADoubleBuf1CpltCallback(MMC_HandleTypeDef * hmmc)5911 __weak void HAL_MMCEx_Read_DMADoubleBuf1CpltCallback(MMC_HandleTypeDef *hmmc)
5912 {
5913   /* Prevent unused argument(s) compilation warning */
5914   UNUSED(hmmc);
5915 
5916   /* NOTE : This function should not be modified, when the callback is needed,
5917             the HAL_MMCEx_Read_DMADoubleBuf1CpltCallback can be implemented in the user file
5918    */
5919 }
5920 
5921 /**
5922   * @brief Write DMA Buffer 0 Transfer completed callbacks
5923   * @param hmmc: MMC handle
5924   * @retval None
5925   */
HAL_MMCEx_Write_DMADoubleBuf0CpltCallback(MMC_HandleTypeDef * hmmc)5926 __weak void HAL_MMCEx_Write_DMADoubleBuf0CpltCallback(MMC_HandleTypeDef *hmmc)
5927 {
5928   /* Prevent unused argument(s) compilation warning */
5929   UNUSED(hmmc);
5930 
5931   /* NOTE : This function should not be modified, when the callback is needed,
5932             the HAL_MMCEx_Write_DMADoubleBuf0CpltCallback can be implemented in the user file
5933    */
5934 }
5935 
5936 /**
5937   * @brief Write DMA Buffer 1 Transfer completed callbacks
5938   * @param hmmc: MMC handle
5939   * @retval None
5940   */
HAL_MMCEx_Write_DMADoubleBuf1CpltCallback(MMC_HandleTypeDef * hmmc)5941 __weak void HAL_MMCEx_Write_DMADoubleBuf1CpltCallback(MMC_HandleTypeDef *hmmc)
5942 {
5943   /* Prevent unused argument(s) compilation warning */
5944   UNUSED(hmmc);
5945 
5946   /* NOTE : This function should not be modified, when the callback is needed,
5947             the HAL_MMCEx_Write_DMADoubleBuf1CpltCallback can be implemented in the user file
5948    */
5949 }
5950 
5951 /**
5952   * @}
5953   */
5954 
5955 #endif /* HAL_MMC_MODULE_ENABLED */
5956 #endif /* SDMMC1 || SDMMC2 */
5957 
5958 /**
5959   * @}
5960   */
5961 
5962 /**
5963   * @}
5964   */
5965