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