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