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(const MMC_HandleTypeDef * hmmc,HAL_MMC_CardCIDTypeDef * pCID)2123 HAL_StatusTypeDef HAL_MMC_GetCardCID(const 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(const MMC_HandleTypeDef * hmmc,HAL_MMC_CardInfoTypeDef * pCardInfo)2274 HAL_StatusTypeDef HAL_MMC_GetCardInfo(const 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   * @retval HAL status
4306   */
HAL_MMC_SwitchPartition(MMC_HandleTypeDef * hmmc,HAL_MMC_PartitionTypeDef Partition)4307 HAL_StatusTypeDef HAL_MMC_SwitchPartition(MMC_HandleTypeDef *hmmc, HAL_MMC_PartitionTypeDef Partition)
4308 {
4309   uint32_t errorstate;
4310   uint32_t response = 0U;
4311   uint32_t count;
4312   uint32_t tickstart = HAL_GetTick();
4313   uint32_t arg = Partition | 0x03B30000U;
4314 
4315   /* Check the state of the driver */
4316   if (hmmc->State == HAL_MMC_STATE_READY)
4317   {
4318     /* Change State */
4319     hmmc->State = HAL_MMC_STATE_BUSY;
4320 
4321     /* Index : 179 - Value : partition */
4322     errorstate = SDMMC_CmdSwitch(hmmc->Instance, arg);
4323     if (errorstate == HAL_MMC_ERROR_NONE)
4324     {
4325       /* Wait that the device is ready by checking the D0 line */
4326       while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
4327       {
4328         if ((HAL_GetTick() - tickstart) >= SDMMC_MAXERASETIMEOUT)
4329         {
4330           errorstate = HAL_MMC_ERROR_TIMEOUT;
4331         }
4332       }
4333 
4334       /* Clear the flag corresponding to end D0 bus line */
4335       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
4336 
4337       if (errorstate == HAL_MMC_ERROR_NONE)
4338       {
4339         /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
4340         count = SDMMC_MAX_TRIAL;
4341         do
4342         {
4343           errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
4344           if (errorstate != HAL_MMC_ERROR_NONE)
4345           {
4346             break;
4347           }
4348 
4349           /* Get command response */
4350           response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
4351           count--;
4352         } while (((response & 0x100U) == 0U) && (count != 0U));
4353 
4354         /* Check the status after the switch command execution */
4355         if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
4356         {
4357           /* Check the bit SWITCH_ERROR of the device status */
4358           if ((response & 0x80U) != 0U)
4359           {
4360             errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
4361           }
4362         }
4363         else if (count == 0U)
4364         {
4365           errorstate = SDMMC_ERROR_TIMEOUT;
4366         }
4367         else
4368         {
4369           /* Nothing to do */
4370         }
4371       }
4372     }
4373 
4374     /* Change State */
4375     hmmc->State = HAL_MMC_STATE_READY;
4376 
4377     /* Manage errors */
4378     if (errorstate != HAL_MMC_ERROR_NONE)
4379     {
4380       /* Clear all the static flags */
4381       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4382       hmmc->ErrorCode |= errorstate;
4383 
4384       if (errorstate != HAL_MMC_ERROR_TIMEOUT)
4385       {
4386         return HAL_ERROR;
4387       }
4388       else
4389       {
4390         return HAL_TIMEOUT;
4391       }
4392     }
4393     else
4394     {
4395       return HAL_OK;
4396     }
4397   }
4398   else
4399   {
4400     return HAL_BUSY;
4401   }
4402 }
4403 
4404 /**
4405   * @brief  Allows to program the authentication key within the RPMB partition
4406   * @param  hmmc: Pointer to MMC handle
4407   * @param  pKey: pointer to the authentication key (32 bytes)
4408   * @param  Timeout: Specify timeout value
4409   * @retval HAL status
4410   */
HAL_MMC_RPMB_ProgramAuthenticationKey(MMC_HandleTypeDef * hmmc,const uint8_t * pKey,uint32_t Timeout)4411 HAL_StatusTypeDef HAL_MMC_RPMB_ProgramAuthenticationKey(MMC_HandleTypeDef *hmmc, const uint8_t *pKey, uint32_t Timeout)
4412 {
4413   SDMMC_DataInitTypeDef config;
4414   uint32_t errorstate;
4415   uint32_t tickstart = HAL_GetTick();
4416   uint32_t count;
4417   uint32_t byte_count = 0;
4418   uint32_t data;
4419   uint32_t dataremaining;
4420   uint8_t tail_pack[12] = {0};
4421   uint8_t zero_pack[4] = {0};
4422   const uint8_t *rtempbuff;
4423   uint8_t  *tempbuff;
4424 
4425   tail_pack[11] = 0x01;
4426 
4427   if (NULL == pKey)
4428   {
4429     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
4430     return HAL_ERROR;
4431   }
4432 
4433   if (hmmc->State == HAL_MMC_STATE_READY)
4434   {
4435     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
4436 
4437     hmmc->State = HAL_MMC_STATE_BUSY;
4438 
4439     /* Initialize data control register */
4440     hmmc->Instance->DCTRL = 0U;
4441 
4442     errorstate = SDMMC_CmdBlockCount(hmmc->Instance,  0x80000001U);
4443     if (errorstate != HAL_MMC_ERROR_NONE)
4444     {
4445       /* Clear all the static flags */
4446       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4447       hmmc->ErrorCode |= errorstate;
4448       hmmc->State = HAL_MMC_STATE_READY;
4449       return HAL_ERROR;
4450     }
4451 
4452     /* Configure the MMC DPSM (Data Path State Machine) */
4453     config.DataTimeOut   = SDMMC_DATATIMEOUT;
4454     config.DataLength    = MMC_BLOCKSIZE;
4455     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
4456     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
4457     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
4458     config.DPSM          = SDMMC_DPSM_DISABLE;
4459     (void)SDMMC_ConfigData(hmmc->Instance, &config);
4460     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
4461 
4462     /* Write Blocks in Polling mode */
4463     {
4464       hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
4465 
4466       /* Write Multi Block command */
4467       errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, 0);
4468     }
4469 
4470     if (errorstate != HAL_MMC_ERROR_NONE)
4471     {
4472       /* Clear all the static flags */
4473       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4474       hmmc->ErrorCode |= errorstate;
4475       hmmc->State = HAL_MMC_STATE_READY;
4476       return HAL_ERROR;
4477     }
4478 
4479     /* Write block(s) in polling mode */
4480     rtempbuff = zero_pack;
4481     dataremaining = config.DataLength;
4482     while (!__HAL_MMC_GET_FLAG(hmmc,
4483                                SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
4484     {
4485       if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= SDMMC_FIFO_SIZE))
4486       {
4487         /* Write data to SDMMC Tx FIFO */
4488         for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
4489         {
4490           data = (uint32_t)(*rtempbuff);
4491           rtempbuff++;
4492           byte_count++;
4493           data |= ((uint32_t)(*rtempbuff) << 8U);
4494           rtempbuff++;
4495           byte_count++;
4496           data |= ((uint32_t)(*rtempbuff) << 16U);
4497           rtempbuff++;
4498           byte_count++;
4499           data |= ((uint32_t)(*rtempbuff) << 24U);
4500           rtempbuff++;
4501           byte_count++;
4502           (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
4503           if (byte_count < MMC_RPMB_KEYMAC_POSITION)
4504           {
4505             rtempbuff = zero_pack;
4506           }
4507           else if (byte_count == MMC_RPMB_KEYMAC_POSITION)
4508           {
4509             rtempbuff = pKey;
4510           }
4511           else if ((byte_count < MMC_RPMB_WRITE_COUNTER_POSITION) && \
4512                    (byte_count >= MMC_RPMB_DATA_POSITION))
4513           {
4514             rtempbuff = zero_pack;
4515           }
4516           else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
4517           {
4518             rtempbuff = tail_pack;
4519           }
4520           else
4521           {
4522             /* Nothing to do */
4523           }
4524 
4525         }
4526         dataremaining -= SDMMC_FIFO_SIZE;
4527       }
4528 
4529       if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
4530       {
4531         /* Clear all the static flags */
4532         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4533         hmmc->ErrorCode |= errorstate;
4534         hmmc->State = HAL_MMC_STATE_READY;
4535         return HAL_TIMEOUT;
4536       }
4537     }
4538     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
4539 
4540     /* Read Response Packet */
4541     errorstate = SDMMC_CmdBlockCount(hmmc->Instance,  0x00000001);
4542     if (errorstate != HAL_MMC_ERROR_NONE)
4543     {
4544       /* Clear all the static flags */
4545       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4546       hmmc->ErrorCode |= errorstate;
4547       hmmc->State = HAL_MMC_STATE_READY;
4548       return HAL_ERROR;
4549     }
4550 
4551     /* Configure the MMC DPSM (Data Path State Machine) */
4552     config.DataTimeOut   = SDMMC_DATATIMEOUT;
4553     config.DataLength    = MMC_BLOCKSIZE;
4554     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
4555     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
4556     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
4557     config.DPSM          = SDMMC_DPSM_DISABLE;
4558     (void)SDMMC_ConfigData(hmmc->Instance, &config);
4559     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
4560 
4561     /* Write Blocks in Polling mode */
4562     hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
4563 
4564     /* Write Multi Block command */
4565     errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, 0);
4566 
4567     if (errorstate != HAL_MMC_ERROR_NONE)
4568     {
4569       /* Clear all the static flags */
4570       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4571       hmmc->ErrorCode |= errorstate;
4572       hmmc->State = HAL_MMC_STATE_READY;
4573       return HAL_ERROR;
4574     }
4575 
4576     /* Clear all the static flags */
4577     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
4578     /* Poll on SDMMC flags */
4579     tempbuff = zero_pack;
4580     byte_count = 0;
4581 
4582     dataremaining = config.DataLength;
4583     while (!__HAL_MMC_GET_FLAG(hmmc,
4584                                SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
4585     {
4586       if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= SDMMC_FIFO_SIZE))
4587       {
4588         /* Read data from SDMMC Rx FIFO */
4589         for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
4590         {
4591           data = SDMMC_ReadFIFO(hmmc->Instance);
4592           *tempbuff = (uint8_t)(data & 0xFFU);
4593           tempbuff++;
4594           byte_count++;
4595           *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
4596           tempbuff++;
4597           byte_count++;
4598           *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
4599           tempbuff++;
4600           byte_count++;
4601           *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
4602           tempbuff++;
4603           byte_count++;
4604           if (byte_count < MMC_RPMB_WRITE_COUNTER_POSITION)
4605           {
4606             tempbuff = zero_pack;
4607           }
4608           else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
4609           {
4610             tempbuff = tail_pack;
4611           }
4612           else
4613           {
4614             /* Nothing to do */
4615           }
4616         }
4617         dataremaining -= SDMMC_FIFO_SIZE;
4618       }
4619 
4620       if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
4621       {
4622         /* Clear all the static flags */
4623         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4624         hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
4625         hmmc->State = HAL_MMC_STATE_READY;
4626         return HAL_TIMEOUT;
4627       }
4628     }
4629     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
4630 
4631     /* Get error state */
4632     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
4633     {
4634       /* Clear all the static flags */
4635       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4636       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
4637       hmmc->State = HAL_MMC_STATE_READY;
4638       return HAL_ERROR;
4639     }
4640     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
4641     {
4642       /* Clear all the static flags */
4643       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4644       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
4645       hmmc->State = HAL_MMC_STATE_READY;
4646       return HAL_ERROR;
4647     }
4648     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
4649     {
4650       /* Clear all the static flags */
4651       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4652       hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
4653       hmmc->State = HAL_MMC_STATE_READY;
4654       return HAL_ERROR;
4655     }
4656     else
4657     {
4658       /* Nothing to do */
4659     }
4660 
4661     /* Clear all the static flags */
4662     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
4663 
4664     hmmc->State = HAL_MMC_STATE_READY;
4665 
4666     /* Check result of operation */
4667     if ((tail_pack[9] != 0x00U) || (tail_pack[10] != 0x01U))
4668     {
4669       hmmc->RPMBErrorCode |= tail_pack[9];
4670       return HAL_ERROR;
4671     }
4672 
4673     return HAL_OK;
4674   }
4675   else
4676   {
4677     hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
4678     return HAL_ERROR;
4679   }
4680 }
4681 
4682 /**
4683   * @brief  Allows to get the value of write counter within the RPMB partition.
4684   * @param  hmmc: Pointer to MMC handle
4685   * @param  pNonce: pointer to the value of nonce (16 bytes)
4686   * @param  Timeout: Specify timeout value
4687   * @retval write counter value.
4688   */
HAL_MMC_RPMB_GetWriteCounter(MMC_HandleTypeDef * hmmc,uint8_t * pNonce,uint32_t Timeout)4689 uint32_t HAL_MMC_RPMB_GetWriteCounter(MMC_HandleTypeDef *hmmc, uint8_t *pNonce, uint32_t Timeout)
4690 {
4691   SDMMC_DataInitTypeDef config;
4692   uint32_t errorstate;
4693   uint32_t tickstart = HAL_GetTick();
4694   uint32_t count;
4695   uint32_t byte_count = 0;
4696   uint32_t data;
4697   uint32_t dataremaining;
4698   uint8_t tail_pack[12] = {0};
4699   uint8_t zero_pack[4] = {0};
4700   uint8_t echo_nonce[16] = {0};
4701   uint8_t *tempbuff = zero_pack;
4702 
4703   tail_pack[11] = 0x02;
4704 
4705   if (NULL == pNonce)
4706   {
4707     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
4708     hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4709     return 0;
4710   }
4711 
4712   if (hmmc->State == HAL_MMC_STATE_READY)
4713   {
4714     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
4715     hmmc->State = HAL_MMC_STATE_BUSY;
4716 
4717     /* Initialize data control register */
4718     hmmc->Instance->DCTRL = 0U;
4719 
4720     errorstate = SDMMC_CmdBlockCount(hmmc->Instance,  0x00000001U);
4721     if (errorstate != HAL_MMC_ERROR_NONE)
4722     {
4723       /* Clear all the static flags */
4724       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4725       hmmc->ErrorCode |= errorstate;
4726       hmmc->State = HAL_MMC_STATE_READY;
4727       hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4728       return 0;
4729     }
4730 
4731     /* Send Request Packet */
4732 
4733     /* Configure the MMC DPSM (Data Path State Machine) */
4734     config.DataTimeOut   = SDMMC_DATATIMEOUT;
4735     config.DataLength    = MMC_BLOCKSIZE;
4736     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
4737     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
4738     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
4739     config.DPSM          = SDMMC_DPSM_DISABLE;
4740     (void)SDMMC_ConfigData(hmmc->Instance, &config);
4741     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
4742 
4743     /* Write Blocks in Polling mode */
4744     hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
4745 
4746     /* Write Multi Block command */
4747     errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, 0);
4748 
4749     if (errorstate != HAL_MMC_ERROR_NONE)
4750     {
4751       /* Clear all the static flags */
4752       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4753       hmmc->ErrorCode |= errorstate;
4754       hmmc->State = HAL_MMC_STATE_READY;
4755       hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4756       return 0;
4757     }
4758 
4759     /* Write block(s) in polling mode */
4760     dataremaining = config.DataLength;
4761     while (!__HAL_MMC_GET_FLAG(hmmc,
4762                                SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
4763     {
4764       if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= SDMMC_FIFO_SIZE))
4765       {
4766 
4767         /* Write data to SDMMC Tx FIFO */
4768         for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
4769         {
4770           data = (uint32_t)(*tempbuff);
4771           tempbuff++;
4772           byte_count++;
4773           data |= ((uint32_t)(*tempbuff) << 8U);
4774           tempbuff++;
4775           byte_count++;
4776           data |= ((uint32_t)(*tempbuff) << 16U);
4777           tempbuff++;
4778           byte_count++;
4779           data |= ((uint32_t)(*tempbuff) << 24U);
4780           tempbuff++;
4781           byte_count++;
4782           (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
4783           if (byte_count < MMC_RPMB_NONCE_POSITION)
4784           {
4785             tempbuff = zero_pack;
4786           }
4787           else if (byte_count == MMC_RPMB_NONCE_POSITION)
4788           {
4789             tempbuff = (uint8_t *)pNonce;
4790           }
4791           else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
4792           {
4793             tempbuff = tail_pack;
4794           }
4795           else
4796           {
4797             /* Nothing to do */
4798           }
4799 
4800         }
4801         dataremaining -= SDMMC_FIFO_SIZE;
4802       }
4803 
4804       if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
4805       {
4806         /* Clear all the static flags */
4807         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4808         hmmc->ErrorCode |= errorstate;
4809         hmmc->State = HAL_MMC_STATE_READY;
4810         hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4811         return 0;
4812       }
4813     }
4814     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
4815 
4816     /* Read Response Packt */
4817     errorstate = SDMMC_CmdBlockCount(hmmc->Instance,  0x00000001U);
4818     if (errorstate != HAL_MMC_ERROR_NONE)
4819     {
4820       /* Clear all the static flags */
4821       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4822       hmmc->ErrorCode |= errorstate;
4823       hmmc->State = HAL_MMC_STATE_READY;
4824       hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4825       return 0;
4826     }
4827 
4828     /* Configure the MMC DPSM (Data Path State Machine) */
4829     config.DataTimeOut   = SDMMC_DATATIMEOUT;
4830     config.DataLength    = MMC_BLOCKSIZE;
4831     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
4832     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
4833     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
4834     config.DPSM          = SDMMC_DPSM_DISABLE;
4835     (void)SDMMC_ConfigData(hmmc->Instance, &config);
4836     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
4837 
4838     /* Write Blocks in Polling mode */
4839     hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
4840 
4841     /* Write Multi Block command */
4842     errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, 0);
4843 
4844     if (errorstate != HAL_MMC_ERROR_NONE)
4845     {
4846       /* Clear all the static flags */
4847       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4848       hmmc->ErrorCode |= errorstate;
4849       hmmc->State = HAL_MMC_STATE_READY;
4850       hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4851       return 0;
4852     }
4853 
4854     /* Clear all the static flags */
4855     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
4856     /* Poll on SDMMC flags */
4857     tempbuff = zero_pack;
4858 
4859     byte_count = 0;
4860     dataremaining = config.DataLength;
4861     while (!__HAL_MMC_GET_FLAG(hmmc,
4862                                SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
4863     {
4864       if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= SDMMC_FIFO_SIZE))
4865       {
4866         /* Read data from SDMMC Rx FIFO */
4867         for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
4868         {
4869           data = SDMMC_ReadFIFO(hmmc->Instance);
4870           *tempbuff = (uint8_t)(data & 0xFFU);
4871           tempbuff++;
4872           byte_count++;
4873           *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
4874           tempbuff++;
4875           byte_count++;
4876           *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
4877           tempbuff++;
4878           byte_count++;
4879           *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
4880           tempbuff++;
4881           byte_count++;
4882           if (byte_count < MMC_RPMB_NONCE_POSITION)
4883           {
4884             tempbuff = zero_pack;
4885           }
4886           else if (byte_count == MMC_RPMB_NONCE_POSITION)
4887           {
4888             tempbuff = echo_nonce;
4889           }
4890           else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
4891           {
4892             tempbuff = tail_pack;
4893           }
4894           else
4895           {
4896             /* Nothing to do */
4897           }
4898         }
4899         dataremaining -= SDMMC_FIFO_SIZE;
4900       }
4901 
4902       if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
4903       {
4904         /* Clear all the static flags */
4905         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4906         hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
4907         hmmc->State = HAL_MMC_STATE_READY;
4908         hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4909         return 0;
4910       }
4911     }
4912     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
4913 
4914     /* Get error state */
4915     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
4916     {
4917       /* Clear all the static flags */
4918       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4919       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
4920       hmmc->State = HAL_MMC_STATE_READY;
4921       hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4922       return 0;
4923     }
4924     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
4925     {
4926       /* Clear all the static flags */
4927       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4928       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
4929       hmmc->State = HAL_MMC_STATE_READY;
4930       hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4931       return 0;
4932     }
4933     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
4934     {
4935       /* Clear all the static flags */
4936       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4937       hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
4938       hmmc->State = HAL_MMC_STATE_READY;
4939       hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4940       return 0;
4941     }
4942     else
4943     {
4944       /* Nothing to do */
4945     }
4946 
4947     /* Clear all the static flags */
4948     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
4949 
4950     hmmc->State = HAL_MMC_STATE_READY;
4951 
4952     for (uint8_t i = 0; i < 16U; i++)
4953     {
4954       if (pNonce[i] != echo_nonce[i])
4955       {
4956         hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4957         return 0;
4958       }
4959     }
4960 
4961     return ((uint32_t)tail_pack[3] | ((uint32_t)tail_pack[2] << 8) | ((uint32_t)tail_pack[1] << 16) | \
4962             ((uint32_t)tail_pack[0] << 24));
4963   }
4964   else
4965   {
4966     hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
4967     hmmc->RPMBErrorCode |= HAL_MMC_ERROR_RPMB_COUNTER_FAILURE;
4968     return 0;
4969   }
4970 }
4971 
4972 /**
4973   * @brief  Allows to write block(s) to a specified address in the RPMB partition. The Data
4974   *         transfer is managed by polling mode.
4975   * @param  hmmc: Pointer to MMC handle
4976   * @param  pData: Pointer to the buffer that will contain the data to transmit
4977   * @param  BlockAdd: Block Address where data will be written
4978   * @param  NumberOfBlocks: Number of blocks to write
4979   * @param  pMAC: Pointer to the authentication MAC buffer
4980   * @param  Timeout: Specify timeout value
4981   * @retval HAL status
4982   */
HAL_MMC_RPMB_WriteBlocks(MMC_HandleTypeDef * hmmc,const uint8_t * pData,uint16_t BlockAdd,uint16_t NumberOfBlocks,const uint8_t * pMAC,uint32_t Timeout)4983 HAL_StatusTypeDef HAL_MMC_RPMB_WriteBlocks(MMC_HandleTypeDef *hmmc, const uint8_t *pData, uint16_t BlockAdd,
4984                                            uint16_t NumberOfBlocks, const uint8_t *pMAC, uint32_t Timeout)
4985 {
4986 
4987   SDMMC_DataInitTypeDef config;
4988   uint32_t errorstate;
4989   uint32_t tickstart = HAL_GetTick();
4990   uint32_t count;
4991   uint32_t byte_count = 0;
4992   uint32_t data;
4993   uint32_t dataremaining;
4994   uint8_t tail_pack[12] = {0};
4995   uint8_t zero_pack[4] = {0};
4996   uint8_t echo_nonce[16] = {0};
4997   const uint8_t local_nonce[16] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x00, 0x01, 0x02,
4998                                    0x03, 0x04, 0x00, 0x01, 0x02, 0x03, 0x04, 0x08
4999                                   };
5000   const uint8_t *rtempbuff;
5001   uint8_t  *tempbuff;
5002   uint32_t arg = 0x80000000U;
5003   uint32_t offset = 0;
5004 
5005   if ((NumberOfBlocks != 0x1U) && (NumberOfBlocks != 0x2U) && (NumberOfBlocks != 0x20U))
5006   {
5007     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
5008     return HAL_ERROR;
5009   }
5010 
5011   if ((NULL == pData) || (NULL == pMAC))
5012   {
5013     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
5014     return HAL_ERROR;
5015   }
5016 
5017   tail_pack[11] = 0x02;
5018 
5019   if (hmmc->State == HAL_MMC_STATE_READY)
5020   {
5021     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
5022     hmmc->State = HAL_MMC_STATE_BUSY;
5023 
5024     /* Initialize data control register */
5025     hmmc->Instance->DCTRL = 0U;
5026 
5027     errorstate = SDMMC_CmdBlockCount(hmmc->Instance,  0x00000001U);
5028     if (errorstate != HAL_MMC_ERROR_NONE)
5029     {
5030       /* Clear all the static flags */
5031       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5032       hmmc->ErrorCode |= errorstate;
5033       hmmc->State = HAL_MMC_STATE_READY;
5034       return HAL_ERROR;
5035     }
5036 
5037     /* Send Request Packet */
5038 
5039     /* Configure the MMC DPSM (Data Path State Machine) */
5040     config.DataTimeOut   = SDMMC_DATATIMEOUT;
5041     config.DataLength    = MMC_BLOCKSIZE;
5042     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
5043     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
5044     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
5045     config.DPSM          = SDMMC_DPSM_DISABLE;
5046     (void)SDMMC_ConfigData(hmmc->Instance, &config);
5047     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
5048 
5049     /* Write Blocks in Polling mode */
5050     hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
5051 
5052     /* Write Multi Block command */
5053     errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, 0);
5054 
5055     if (errorstate != HAL_MMC_ERROR_NONE)
5056     {
5057       /* Clear all the static flags */
5058       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5059       hmmc->ErrorCode |= errorstate;
5060       hmmc->State = HAL_MMC_STATE_READY;
5061       return HAL_ERROR;
5062     }
5063 
5064     /* Write block(s) in polling mode */
5065     rtempbuff = zero_pack;
5066     dataremaining = config.DataLength;
5067     while (!__HAL_MMC_GET_FLAG(hmmc,
5068                                SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
5069     {
5070       if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= SDMMC_FIFO_SIZE))
5071       {
5072 
5073         /* Write data to SDMMC Tx FIFO */
5074         for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
5075         {
5076           data = (uint32_t)(*rtempbuff);
5077           rtempbuff++;
5078           byte_count++;
5079           data |= ((uint32_t)(*rtempbuff) << 8U);
5080           rtempbuff++;
5081           byte_count++;
5082           data |= ((uint32_t)(*rtempbuff) << 16U);
5083           rtempbuff++;
5084           byte_count++;
5085           data |= ((uint32_t)(*rtempbuff) << 24U);
5086           rtempbuff++;
5087           byte_count++;
5088           (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
5089           if (byte_count < MMC_RPMB_NONCE_POSITION)
5090           {
5091             rtempbuff = zero_pack;
5092           }
5093           else if (byte_count == MMC_RPMB_NONCE_POSITION)
5094           {
5095             rtempbuff = local_nonce;
5096           }
5097           else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
5098           {
5099             rtempbuff = tail_pack;
5100           }
5101           else
5102           {
5103             /* Nothing to do */
5104           }
5105         }
5106         dataremaining -= SDMMC_FIFO_SIZE;
5107       }
5108 
5109       if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
5110       {
5111         /* Clear all the static flags */
5112         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5113         hmmc->ErrorCode |= errorstate;
5114         hmmc->State = HAL_MMC_STATE_READY;
5115         return HAL_TIMEOUT;
5116       }
5117     }
5118     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
5119 
5120     /* Read Response Packt */
5121     errorstate = SDMMC_CmdBlockCount(hmmc->Instance,  0x00000001);
5122     if (errorstate != HAL_MMC_ERROR_NONE)
5123     {
5124       /* Clear all the static flags */
5125       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5126       hmmc->ErrorCode |= errorstate;
5127       hmmc->State = HAL_MMC_STATE_READY;
5128       return HAL_ERROR;
5129     }
5130 
5131     /* Configure the MMC DPSM (Data Path State Machine) */
5132     config.DataTimeOut   = SDMMC_DATATIMEOUT;
5133     config.DataLength    = MMC_BLOCKSIZE;
5134     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
5135     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
5136     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
5137     config.DPSM          = SDMMC_DPSM_DISABLE;
5138     (void)SDMMC_ConfigData(hmmc->Instance, &config);
5139     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
5140 
5141     /* Write Blocks in Polling mode */
5142     hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
5143 
5144     /* Write Multi Block command */
5145     errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, 0);
5146 
5147     if (errorstate != HAL_MMC_ERROR_NONE)
5148     {
5149       /* Clear all the static flags */
5150       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5151       hmmc->ErrorCode |= errorstate;
5152       hmmc->State = HAL_MMC_STATE_READY;
5153       return HAL_ERROR;
5154     }
5155 
5156     /* Clear all the static flags */
5157     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
5158     /* Poll on SDMMC flags */
5159     tempbuff = zero_pack;
5160 
5161     byte_count = 0;
5162     dataremaining = config.DataLength;
5163     while (!__HAL_MMC_GET_FLAG(hmmc,
5164                                SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
5165     {
5166       if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= SDMMC_FIFO_SIZE))
5167       {
5168         /* Read data from SDMMC Rx FIFO */
5169         for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
5170         {
5171           data = SDMMC_ReadFIFO(hmmc->Instance);
5172           *tempbuff = (uint8_t)(data & 0xFFU);
5173           tempbuff++;
5174           byte_count++;
5175           *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
5176           tempbuff++;
5177           byte_count++;
5178           *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
5179           tempbuff++;
5180           byte_count++;
5181           *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
5182           tempbuff++;
5183           byte_count++;
5184           if (byte_count < MMC_RPMB_NONCE_POSITION)
5185           {
5186             tempbuff = zero_pack;
5187           }
5188           else if (byte_count == MMC_RPMB_NONCE_POSITION)
5189           {
5190             tempbuff = echo_nonce;
5191           }
5192           else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
5193           {
5194             tempbuff = tail_pack;
5195           }
5196           else
5197           {
5198             /* Nothing to do */
5199           }
5200         }
5201         dataremaining -= SDMMC_FIFO_SIZE;
5202       }
5203 
5204       if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
5205       {
5206         /* Clear all the static flags */
5207         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5208         hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
5209         hmmc->State = HAL_MMC_STATE_READY;
5210         return HAL_TIMEOUT;
5211       }
5212     }
5213     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
5214 
5215     /* Get error state */
5216     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
5217     {
5218       /* Clear all the static flags */
5219       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5220       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
5221       hmmc->State = HAL_MMC_STATE_READY;
5222       return HAL_ERROR;
5223     }
5224     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
5225     {
5226       /* Clear all the static flags */
5227       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5228       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
5229       hmmc->State = HAL_MMC_STATE_READY;
5230       return HAL_ERROR;
5231     }
5232     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
5233     {
5234       /* Clear all the static flags */
5235       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5236       hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
5237       hmmc->State = HAL_MMC_STATE_READY;
5238       return HAL_ERROR;
5239     }
5240     else
5241     {
5242       /* Nothing to do */
5243     }
5244 
5245     /* Clear all the static flags */
5246     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
5247 
5248     hmmc->State = HAL_MMC_STATE_READY;
5249 
5250     for (uint8_t i = 0; i < 16U; i++)
5251     {
5252       if (local_nonce[i] != echo_nonce[i])
5253       {
5254         return HAL_ERROR;
5255       }
5256     }
5257   }
5258   else
5259   {
5260     hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
5261     return HAL_ERROR;
5262   }
5263   tail_pack[11]  = 0x03;
5264   tail_pack[10]  = 0x00;
5265   tail_pack[7]   = (uint8_t)(NumberOfBlocks) & 0xFFU;
5266   tail_pack[6]   = (uint8_t)(NumberOfBlocks >> 8) & 0xFFU;
5267   tail_pack[5]   = (uint8_t)(BlockAdd) & 0xFFU;
5268   tail_pack[4]   = (uint8_t)(BlockAdd >> 8) & 0xFFU;
5269 
5270   rtempbuff = zero_pack;
5271   byte_count = 0;
5272   arg |= NumberOfBlocks;
5273 
5274   if (hmmc->State == HAL_MMC_STATE_READY)
5275   {
5276     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
5277 
5278 
5279     hmmc->State = HAL_MMC_STATE_BUSY;
5280 
5281     /* Initialize data control register */
5282     hmmc->Instance->DCTRL = 0U;
5283 
5284     errorstate = SDMMC_CmdBlockCount(hmmc->Instance, arg);
5285     if (errorstate != HAL_MMC_ERROR_NONE)
5286     {
5287       /* Clear all the static flags */
5288       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5289       hmmc->ErrorCode |= errorstate;
5290       hmmc->State = HAL_MMC_STATE_READY;
5291       return HAL_ERROR;
5292     }
5293 
5294     /* Send Request Packet */
5295     /* Configure the MMC DPSM (Data Path State Machine) */
5296     config.DataTimeOut   = SDMMC_DATATIMEOUT;
5297     config.DataLength    = NumberOfBlocks * MMC_BLOCKSIZE;
5298     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
5299     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
5300     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
5301     config.DPSM          = SDMMC_DPSM_DISABLE;
5302     (void)SDMMC_ConfigData(hmmc->Instance, &config);
5303     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
5304 
5305     /* Write Blocks in Polling mode */
5306 
5307     {
5308       hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
5309 
5310       /* Write Multi Block command */
5311       errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, 0);
5312     }
5313 
5314     if (errorstate != HAL_MMC_ERROR_NONE)
5315     {
5316       /* Clear all the static flags */
5317       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5318       hmmc->ErrorCode |= errorstate;
5319       hmmc->State = HAL_MMC_STATE_READY;
5320       return HAL_ERROR;
5321     }
5322 
5323 
5324     /* Write block(s) in polling mode */
5325     dataremaining = config.DataLength;
5326     while (!__HAL_MMC_GET_FLAG(hmmc,
5327                                SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
5328     {
5329       if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= SDMMC_FIFO_SIZE))
5330       {
5331 
5332         /* Write data to SDMMC Tx FIFO */
5333         for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
5334         {
5335           data = (uint32_t)(*rtempbuff);
5336           rtempbuff++;
5337           byte_count++;
5338           data |= ((uint32_t)(*rtempbuff) << 8U);
5339           rtempbuff++;
5340           byte_count++;
5341           data |= ((uint32_t)(*rtempbuff) << 16U);
5342           rtempbuff++;
5343           byte_count++;
5344           data |= ((uint32_t)(*rtempbuff) << 24U);
5345           rtempbuff++;
5346           byte_count++;
5347           (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
5348           if (byte_count == MMC_RPMB_KEYMAC_POSITION)
5349           {
5350             rtempbuff = pMAC;
5351           }
5352           if (byte_count == MMC_RPMB_DATA_POSITION)
5353           {
5354             rtempbuff = &pData[offset];
5355           }
5356           if ((byte_count >= MMC_RPMB_NONCE_POSITION) && \
5357               (byte_count < MMC_RPMB_WRITE_COUNTER_POSITION))
5358           {
5359             rtempbuff = zero_pack;
5360           }
5361           if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
5362           {
5363             rtempbuff = tail_pack;
5364           }
5365           else if (byte_count == MMC_BLOCKSIZE)
5366           {
5367             offset += (uint32_t)256U;
5368             byte_count = 0;
5369           }
5370           else
5371           {
5372             /* Nothing to do */
5373           }
5374         }
5375         dataremaining -= SDMMC_FIFO_SIZE;
5376       }
5377 
5378       if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
5379       {
5380         /* Clear all the static flags */
5381         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5382         hmmc->ErrorCode |= errorstate;
5383         hmmc->State = HAL_MMC_STATE_READY;
5384         return HAL_TIMEOUT;
5385       }
5386     }
5387     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
5388 
5389     /* Response Packet */
5390 
5391     errorstate = SDMMC_CmdBlockCount(hmmc->Instance, arg);
5392     if (errorstate != HAL_MMC_ERROR_NONE)
5393     {
5394       /* Clear all the static flags */
5395       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5396       hmmc->ErrorCode |= errorstate;
5397       hmmc->State = HAL_MMC_STATE_READY;
5398       return HAL_ERROR;
5399     }
5400 
5401     /* Configure the MMC DPSM (Data Path State Machine) */
5402     config.DataTimeOut   = SDMMC_DATATIMEOUT;
5403     config.DataLength    = MMC_BLOCKSIZE;
5404     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
5405     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
5406     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
5407     config.DPSM          = SDMMC_DPSM_DISABLE;
5408     (void)SDMMC_ConfigData(hmmc->Instance, &config);
5409     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
5410 
5411     /* Write Blocks in Polling mode */
5412 
5413     {
5414       hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
5415 
5416       /* Write Multi Block command */
5417       errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, 0);
5418     }
5419 
5420     if (errorstate != HAL_MMC_ERROR_NONE)
5421     {
5422       /* Clear all the static flags */
5423       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5424       hmmc->ErrorCode |= errorstate;
5425       hmmc->State = HAL_MMC_STATE_READY;
5426       return HAL_ERROR;
5427     }
5428 
5429 
5430     /* Clear all the static flags */
5431     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
5432     /* Poll on SDMMC flags */
5433     tempbuff = zero_pack;
5434     byte_count = 0;
5435     dataremaining = config.DataLength;
5436     while (!__HAL_MMC_GET_FLAG(hmmc,
5437                                SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
5438     {
5439       if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= SDMMC_FIFO_SIZE))
5440       {
5441         /* Read data from SDMMC Rx FIFO */
5442         for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
5443         {
5444           data = SDMMC_ReadFIFO(hmmc->Instance);
5445           *tempbuff = (uint8_t)(data & 0xFFU);
5446           tempbuff++;
5447           byte_count++;
5448           *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
5449           tempbuff++;
5450           byte_count++;
5451           *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
5452           tempbuff++;
5453           byte_count++;
5454           *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
5455           tempbuff++;
5456           byte_count++;
5457           if (byte_count < MMC_RPMB_WRITE_COUNTER_POSITION)
5458           {
5459             tempbuff = zero_pack;
5460           }
5461           else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
5462           {
5463             tempbuff = tail_pack;
5464           }
5465           else
5466           {
5467             /* Nothing to do */
5468           }
5469         }
5470         dataremaining -= SDMMC_FIFO_SIZE;
5471       }
5472 
5473       if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
5474       {
5475         /* Clear all the static flags */
5476         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5477         hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
5478         hmmc->State = HAL_MMC_STATE_READY;
5479         return HAL_TIMEOUT;
5480       }
5481     }
5482     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
5483 
5484     /* Get error state */
5485     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
5486     {
5487       /* Clear all the static flags */
5488       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5489       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
5490       hmmc->State = HAL_MMC_STATE_READY;
5491       return HAL_ERROR;
5492     }
5493     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
5494     {
5495       /* Clear all the static flags */
5496       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5497       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
5498       hmmc->State = HAL_MMC_STATE_READY;
5499       return HAL_ERROR;
5500     }
5501     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
5502     {
5503       /* Clear all the static flags */
5504       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5505       hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
5506       hmmc->State = HAL_MMC_STATE_READY;
5507       return HAL_ERROR;
5508     }
5509     else
5510     {
5511       /* Nothing to do */
5512     }
5513 
5514     /* Clear all the static flags */
5515     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
5516 
5517     hmmc->State = HAL_MMC_STATE_READY;
5518 
5519     /* Check result of operation */
5520     if (((tail_pack[9] & (uint8_t)0xFEU) != 0x00U) || (tail_pack[10] != 0x03U))
5521     {
5522       hmmc->RPMBErrorCode |= tail_pack[9];
5523       return HAL_ERROR;
5524     }
5525 
5526     return HAL_OK;
5527   }
5528   else
5529   {
5530     hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
5531     return HAL_ERROR;
5532   }
5533 }
5534 
5535 /**
5536   * @brief  Allows to read block(s) to a specified address in the RPMB partition. The Data
5537   *         transfer is managed by polling mode.
5538   * @param  hmmc: Pointer to MMC handle
5539   * @param  pData: Pointer to the buffer that will contain the data to transmit
5540   * @param  BlockAdd: Block Address where data will be written
5541   * @param  NumberOfBlocks: Number of blocks to write
5542   * @param  pNonce: Pointer to the buffer that will contain the nonce to transmit
5543   * @param  pMAC: Pointer to the authentication MAC buffer
5544   * @param  Timeout: Specify timeout value
5545   * @retval HAL status
5546   */
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)5547 HAL_StatusTypeDef HAL_MMC_RPMB_ReadBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint16_t BlockAdd,
5548                                           uint16_t NumberOfBlocks, const uint8_t *pNonce, uint8_t *pMAC,
5549                                           uint32_t Timeout)
5550 {
5551   SDMMC_DataInitTypeDef config;
5552   uint32_t errorstate;
5553   uint32_t tickstart = HAL_GetTick();
5554   uint32_t count;
5555   uint32_t byte_count = 0;
5556   uint32_t data;
5557   uint8_t tail_pack[12] = {0};
5558   uint8_t zero_pack[4] = {0};
5559   uint8_t echo_nonce[16] = {0};
5560   uint32_t dataremaining;
5561   const uint8_t *rtempbuff;
5562   uint8_t  *tempbuff;
5563   uint32_t arg = 0;
5564   uint32_t offset = 0;
5565 
5566   arg |= NumberOfBlocks;
5567 
5568   tail_pack[11] = 0x04;
5569   tail_pack[10] = 0x00;
5570   tail_pack[7]  = 0x00;
5571   tail_pack[6]  = 0x00;
5572   tail_pack[5]  = (uint8_t)(BlockAdd) & 0xFFU;
5573   tail_pack[4]  = (uint8_t)(BlockAdd >> 8) & 0xFFU;
5574   tail_pack[3]  = 0x00;
5575   tail_pack[2]  = 0x00;
5576   tail_pack[1]  = 0x00;
5577   tail_pack[0]  = 0x00;
5578 
5579   if (hmmc->State == HAL_MMC_STATE_READY)
5580   {
5581     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
5582     hmmc->State = HAL_MMC_STATE_BUSY;
5583 
5584     /* Initialize data control register */
5585     hmmc->Instance->DCTRL = 0U;
5586 
5587     errorstate = SDMMC_CmdBlockCount(hmmc->Instance, 1);
5588     if (errorstate != HAL_MMC_ERROR_NONE)
5589     {
5590       /* Clear all the static flags */
5591       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5592       hmmc->ErrorCode |= errorstate;
5593       hmmc->State = HAL_MMC_STATE_READY;
5594       return HAL_ERROR;
5595     }
5596 
5597     /* Send Request Packet */
5598 
5599     /* Configure the MMC DPSM (Data Path State Machine) */
5600     config.DataTimeOut   = SDMMC_DATATIMEOUT;
5601     config.DataLength    = MMC_BLOCKSIZE;
5602     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
5603     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
5604     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
5605     config.DPSM          = SDMMC_DPSM_DISABLE;
5606     (void)SDMMC_ConfigData(hmmc->Instance, &config);
5607     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
5608 
5609     /* Write Blocks in Polling mode */
5610     hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
5611 
5612     /* Write Multi Block command */
5613     errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, 0);
5614 
5615     if (errorstate != HAL_MMC_ERROR_NONE)
5616     {
5617       /* Clear all the static flags */
5618       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5619       hmmc->ErrorCode |= errorstate;
5620       hmmc->State = HAL_MMC_STATE_READY;
5621       return HAL_ERROR;
5622     }
5623 
5624     /* Write block(s) in polling mode */
5625     rtempbuff = zero_pack;
5626     dataremaining = config.DataLength;
5627     while (!__HAL_MMC_GET_FLAG(hmmc,
5628                                SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
5629     {
5630       if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= SDMMC_FIFO_SIZE))
5631       {
5632 
5633         /* Write data to SDMMC Tx FIFO */
5634         for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
5635         {
5636           data = (uint32_t)(*rtempbuff);
5637           rtempbuff++;
5638           byte_count++;
5639           data |= ((uint32_t)(*rtempbuff) << 8U);
5640           rtempbuff++;
5641           byte_count++;
5642           data |= ((uint32_t)(*rtempbuff) << 16U);
5643           rtempbuff++;
5644           byte_count++;
5645           data |= ((uint32_t)(*rtempbuff) << 24U);
5646           rtempbuff++;
5647           byte_count++;
5648           (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
5649           if (byte_count < MMC_RPMB_NONCE_POSITION)
5650           {
5651             rtempbuff = zero_pack;
5652           }
5653           else if (byte_count == MMC_RPMB_NONCE_POSITION)
5654           {
5655             rtempbuff = pNonce;
5656           }
5657           else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
5658           {
5659             rtempbuff = tail_pack;
5660           }
5661           else
5662           {
5663             /* Nothing to do */
5664           }
5665         }
5666         dataremaining -= SDMMC_FIFO_SIZE;
5667       }
5668 
5669       if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
5670       {
5671         /* Clear all the static flags */
5672         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5673         hmmc->ErrorCode |= errorstate;
5674         hmmc->State = HAL_MMC_STATE_READY;
5675         return HAL_TIMEOUT;
5676       }
5677     }
5678     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
5679 
5680     /* Read Response Packet */
5681     errorstate = SDMMC_CmdBlockCount(hmmc->Instance, arg);
5682     if (errorstate != HAL_MMC_ERROR_NONE)
5683     {
5684       /* Clear all the static flags */
5685       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5686       hmmc->ErrorCode |= errorstate;
5687       hmmc->State = HAL_MMC_STATE_READY;
5688       return HAL_ERROR;
5689     }
5690 
5691     /* Configure the MMC DPSM (Data Path State Machine) */
5692     config.DataTimeOut   = SDMMC_DATATIMEOUT;
5693     config.DataLength    = NumberOfBlocks * MMC_BLOCKSIZE;
5694     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
5695     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
5696     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
5697     config.DPSM          = SDMMC_DPSM_DISABLE;
5698     (void)SDMMC_ConfigData(hmmc->Instance, &config);
5699     __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
5700 
5701     /* Write Blocks in Polling mode */
5702     hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
5703 
5704     /* Write Multi Block command */
5705     errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, 0);
5706 
5707     if (errorstate != HAL_MMC_ERROR_NONE)
5708     {
5709       /* Clear all the static flags */
5710       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5711       hmmc->ErrorCode |= errorstate;
5712       hmmc->State = HAL_MMC_STATE_READY;
5713       return HAL_ERROR;
5714     }
5715 
5716     /* Clear all the static flags */
5717     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
5718     /* Poll on SDMMC flags */
5719     tempbuff = zero_pack;
5720     byte_count = 0;
5721 
5722     dataremaining = config.DataLength;
5723     while (!__HAL_MMC_GET_FLAG(hmmc,
5724                                SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
5725     {
5726       if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= SDMMC_FIFO_SIZE))
5727       {
5728         /* Read data from SDMMC Rx FIFO */
5729         for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
5730         {
5731           data = SDMMC_ReadFIFO(hmmc->Instance);
5732           *tempbuff = (uint8_t)(data & 0xFFU);
5733           tempbuff++;
5734           byte_count++;
5735           *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
5736           tempbuff++;
5737           byte_count++;
5738           *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
5739           tempbuff++;
5740           byte_count++;
5741           *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
5742           tempbuff++;
5743           byte_count++;
5744           if (byte_count < MMC_RPMB_KEYMAC_POSITION)
5745           {
5746             tempbuff = zero_pack;
5747           }
5748           else if (byte_count == MMC_RPMB_KEYMAC_POSITION)
5749           {
5750             tempbuff = (uint8_t *)pMAC;
5751           }
5752           else if (byte_count == MMC_RPMB_DATA_POSITION)
5753           {
5754             tempbuff = &pData[offset];
5755           }
5756           else if (byte_count == MMC_RPMB_NONCE_POSITION)
5757           {
5758             tempbuff = echo_nonce;
5759           }
5760           else if (byte_count == MMC_RPMB_WRITE_COUNTER_POSITION)
5761           {
5762             tempbuff = tail_pack;
5763           }
5764           else if (byte_count == MMC_BLOCKSIZE)
5765           {
5766             byte_count = 0;
5767             offset += (uint32_t)256U;
5768           }
5769           else
5770           {
5771             /* Nothing to do */
5772           }
5773         }
5774         dataremaining -= SDMMC_FIFO_SIZE;
5775       }
5776 
5777       if (((HAL_GetTick() - tickstart) >=  Timeout) || (Timeout == 0U))
5778       {
5779         /* Clear all the static flags */
5780         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5781         hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
5782         hmmc->State = HAL_MMC_STATE_READY;
5783         return HAL_TIMEOUT;
5784       }
5785     }
5786     __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
5787 
5788     /* Get error state */
5789     if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
5790     {
5791       /* Clear all the static flags */
5792       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5793       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
5794       hmmc->State = HAL_MMC_STATE_READY;
5795       return HAL_ERROR;
5796     }
5797     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
5798     {
5799       /* Clear all the static flags */
5800       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5801       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
5802       hmmc->State = HAL_MMC_STATE_READY;
5803       return HAL_ERROR;
5804     }
5805     else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
5806     {
5807       /* Clear all the static flags */
5808       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
5809       hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
5810       hmmc->State = HAL_MMC_STATE_READY;
5811       return HAL_ERROR;
5812     }
5813     else
5814     {
5815       /* Nothing to do */
5816     }
5817 
5818     /* Clear all the static flags */
5819     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
5820 
5821     hmmc->State = HAL_MMC_STATE_READY;
5822 
5823     for (uint8_t i = 0; i < 16U; i++)
5824     {
5825       if (pNonce[i] != echo_nonce[i])
5826       {
5827         return HAL_ERROR;
5828       }
5829     }
5830 
5831     /* Check result of operation */
5832     if ((tail_pack[9] != 0x00U) || (tail_pack[10] != 0x04U))
5833     {
5834       hmmc->RPMBErrorCode |= tail_pack[9];
5835       return HAL_ERROR;
5836     }
5837 
5838     return HAL_OK;
5839   }
5840   else
5841   {
5842     hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
5843     return HAL_ERROR;
5844   }
5845 }
5846 
5847 
5848 /**
5849   * @brief Read DMA Linked list node Transfer completed callbacks
5850   * @param hmmc: MMC handle
5851   * @retval None
5852   */
HAL_MMCEx_Read_DMALnkLstBufCpltCallback(MMC_HandleTypeDef * hmmc)5853 __weak void HAL_MMCEx_Read_DMALnkLstBufCpltCallback(MMC_HandleTypeDef *hmmc)
5854 {
5855   /* Prevent unused argument(s) compilation warning */
5856   UNUSED(hmmc);
5857 
5858   /* NOTE : This function should not be modified, when the callback is needed,
5859             the HAL_MMCEx_Read_DMALnkLstBufCpltCallback can be implemented in the user file
5860    */
5861 }
5862 /**
5863   * @brief Read DMA Linked list node Transfer completed callbacks
5864   * @param hmmc: MMC handle
5865   * @retval None
5866   */
HAL_MMCEx_Write_DMALnkLstBufCpltCallback(MMC_HandleTypeDef * hmmc)5867 __weak void HAL_MMCEx_Write_DMALnkLstBufCpltCallback(MMC_HandleTypeDef *hmmc)
5868 {
5869   /* Prevent unused argument(s) compilation warning */
5870   UNUSED(hmmc);
5871 
5872   /* NOTE : This function should not be modified, when the callback is needed,
5873             the HAL_MMCEx_Write_DMALnkLstBufCpltCallback can be implemented in the user file
5874    */
5875 }
5876 
5877 /**
5878   * @}
5879   */
5880 
5881 #endif /* HAL_MMC_MODULE_ENABLED */
5882 #endif /* SDMMC1 || SDMMC2 */
5883 
5884 /**
5885   * @}
5886   */
5887 
5888 /**
5889   * @}
5890   */
5891