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