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