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