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