1 /**
2 ******************************************************************************
3 * @file stm32u5xx_hal_mmc.c
4 * @author MCD Application Team
5 * @brief MMC card HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the Secure Digital (MMC) peripheral:
8 * + Initialization and de-initialization functions
9 * + IO operation functions
10 * + Peripheral Control functions
11 * + MMC card Control functions
12 *
13 ******************************************************************************
14 * @attention
15 *
16 * Copyright (c) 2021 STMicroelectronics.
17 * All rights reserved.
18 *
19 * This software is licensed under terms that can be found in the LICENSE file
20 * in the root directory of this software component.
21 * If no LICENSE file comes with this software, it is provided AS-IS.
22 *
23 ******************************************************************************
24 @verbatim
25 ==============================================================================
26 ##### How to use this driver #####
27 ==============================================================================
28 [..]
29 This driver implements a high level communication layer for read and write from/to
30 this memory. The needed STM32 hardware resources (SDMMC and GPIO) are performed by
31 the user in HAL_MMC_MspInit() function (MSP layer).
32 Basically, the MSP layer configuration should be the same as we provide in the
33 examples.
34 You can easily tailor this configuration according to hardware resources.
35
36 [..]
37 This driver is a generic layered driver for SDMMC memories which uses the HAL
38 SDMMC driver functions to interface with MMC and eMMC cards devices.
39 It is used as follows:
40
41 (#)Initialize the SDMMC low level resources by implement the HAL_MMC_MspInit() API:
42 (##) Enable the SDMMC interface clock using __HAL_RCC_SDMMC_CLK_ENABLE();
43 (##) SDMMC pins configuration for MMC card
44 (+++) Enable the clock for the SDMMC GPIOs using the functions __HAL_RCC_GPIOx_CLK_ENABLE();
45 (+++) Configure these SDMMC pins as alternate function pull-up using HAL_GPIO_Init()
46 and according to your pin assignment;
47 (##) NVIC configuration if you need to use interrupt process (HAL_MMC_ReadBlocks_IT()
48 and HAL_MMC_WriteBlocks_IT() APIs).
49 (+++) Configure the SDMMC interrupt priorities using function HAL_NVIC_SetPriority();
50 (+++) Enable the NVIC SDMMC IRQs using function HAL_NVIC_EnableIRQ()
51 (+++) SDMMC interrupts are managed using the macros __HAL_MMC_ENABLE_IT()
52 and __HAL_MMC_DISABLE_IT() inside the communication process.
53 (+++) SDMMC interrupts pending bits are managed using the macros __HAL_MMC_GET_IT()
54 and __HAL_MMC_CLEAR_IT()
55 (##) No general propose DMA Configuration is needed, an Internal DMA for SDMMC Peripheral are used.
56
57 (#) At this stage, you can perform MMC read/write/erase operations after MMC card initialization
58
59
60 *** MMC Card Initialization and configuration ***
61 ================================================
62 [..]
63 To initialize the MMC Card, use the HAL_MMC_Init() function. It Initializes
64 SDMMC Peripheral (STM32 side) and the MMC Card, and put it into StandBy State (Ready for data transfer).
65 This function provide the following operations:
66
67 (#) Initialize the SDMMC peripheral interface with default configuration.
68 The initialization process is done at 400KHz. You can change or adapt
69 this frequency by adjusting the "ClockDiv" field.
70 The MMC Card frequency (SDMMC_CK) is computed as follows:
71
72 SDMMC_CK = SDMMCCLK / (2 * ClockDiv)
73
74 In initialization mode and according to the MMC Card standard,
75 make sure that the SDMMC_CK frequency doesn't exceed 400KHz.
76
77 This phase of initialization is done through SDMMC_Init() and
78 SDMMC_PowerState_ON() SDMMC low level APIs.
79
80 (#) Initialize the MMC card. The API used is HAL_MMC_InitCard().
81 This phase allows the card initialization and identification
82 and check the MMC Card type (Standard Capacity or High Capacity)
83 The initialization flow is compatible with MMC standard.
84
85 This API (HAL_MMC_InitCard()) could be used also to reinitialize the card in case
86 of plug-off plug-in.
87
88 (#) Configure the MMC Card Data transfer frequency. By Default, the card transfer
89 frequency by adjusting the "ClockDiv" field.
90 In transfer mode and according to the MMC Card standard, make sure that the
91 SDMMC_CK frequency doesn't exceed 25MHz and 100MHz in High-speed mode switch.
92
93 (#) Select the corresponding MMC Card according to the address read with the step 2.
94
95 (#) Configure the MMC Card in wide bus mode: 4-bits data.
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 HAL driver macros list ***
173 ==================================
174 [..]
175 Below the list of most used macros in MMC HAL driver.
176
177 (+) __HAL_MMC_ENABLE_IT: Enable the MMC device interrupt
178 (+) __HAL_MMC_DISABLE_IT: Disable the MMC device interrupt
179 (+) __HAL_MMC_GET_FLAG:Check whether the specified MMC flag is set or not
180 (+) __HAL_MMC_CLEAR_FLAG: Clear the MMC's pending flags
181
182 [..]
183 (@) You can refer to the MMC HAL driver header file for more useful macros
184
185 *** Callback registration ***
186 =============================================
187 [..]
188 The compilation define USE_HAL_MMC_REGISTER_CALLBACKS when set to 1
189 allows the user to configure dynamically the driver callbacks.
190
191 Use Functions HAL_MMC_RegisterCallback() to register a user callback,
192 it allows to register following callbacks:
193 (+) TxCpltCallback : callback when a transmission transfer is completed.
194 (+) RxCpltCallback : callback when a reception transfer is completed.
195 (+) ErrorCallback : callback when error occurs.
196 (+) AbortCpltCallback : callback when abort is completed.
197 (+) Read_DMALnkLstBufCpltCallback : callback when the DMA reception of linked list node buffer is completed.
198 (+) Write_DMALnkLstBufCpltCallback : callback when the DMA transmission of linked list node buffer is completed.
199 (+) MspInitCallback : MMC MspInit.
200 (+) MspDeInitCallback : MMC MspDeInit.
201 This function takes as parameters the HAL peripheral handle, the Callback ID
202 and a pointer to the user callback function.
203
204 Use function HAL_MMC_UnRegisterCallback() to reset a callback to the default
205 weak (overridden) function. It allows to reset following callbacks:
206 (+) TxCpltCallback : callback when a transmission transfer is completed.
207 (+) RxCpltCallback : callback when a reception transfer is completed.
208 (+) ErrorCallback : callback when error occurs.
209 (+) AbortCpltCallback : callback when abort is completed.
210 (+) Read_DMADblBuf0CpltCallback : callback when the DMA reception of first buffer is completed.
211 (+) Read_DMADblBuf1CpltCallback : callback when the DMA reception of second buffer is completed.
212 (+) Write_DMADblBuf0CpltCallback : callback when the DMA transmission of first buffer is completed.
213 (+) Write_DMADblBuf1CpltCallback : callback when the DMA transmission of second buffer is completed.
214 (+) MspInitCallback : MMC MspInit.
215 (+) MspDeInitCallback : MMC MspDeInit.
216 This function) takes as parameters the HAL peripheral handle and the Callback ID.
217
218 By default, after the HAL_MMC_Init and if the state is HAL_MMC_STATE_RESET
219 all callbacks are reset to the corresponding legacy weak (overridden) functions.
220 Exception done for MspInit and MspDeInit callbacks that are respectively
221 reset to the legacy weak (overridden) functions in the HAL_MMC_Init
222 and HAL_MMC_DeInit only when these callbacks are null (not registered beforehand).
223 If not, MspInit or MspDeInit are not null, the HAL_MMC_Init and HAL_MMC_DeInit
224 keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
225
226 Callbacks can be registered/unregistered in READY state only.
227 Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
228 in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
229 during the Init/DeInit.
230 In that case first register the MspInit/MspDeInit user callbacks
231 using HAL_MMC_RegisterCallback before calling HAL_MMC_DeInit
232 or HAL_MMC_Init function.
233
234 When The compilation define USE_HAL_MMC_REGISTER_CALLBACKS is set to 0 or
235 not defined, the callback registering feature is not available
236 and weak (overridden) callbacks are used.
237
238 @endverbatim
239 ******************************************************************************
240 */
241
242 /* Includes ------------------------------------------------------------------*/
243 #include "stm32u5xx_hal.h"
244
245 /** @addtogroup STM32U5xx_HAL_Driver
246 * @{
247 */
248
249 /** @defgroup MMC MMC
250 * @brief MMC HAL module driver
251 * @{
252 */
253
254 #if defined (SDMMC1) || defined (SDMMC2)
255 #ifdef HAL_MMC_MODULE_ENABLED
256
257 /* Private typedef -----------------------------------------------------------*/
258 /* Private define ------------------------------------------------------------*/
259 /** @addtogroup MMC_Private_Defines
260 * @{
261 */
262 #if defined (VDD_VALUE) && (VDD_VALUE <= 1950U)
263 #define MMC_VOLTAGE_RANGE EMMC_LOW_VOLTAGE_RANGE
264
265 #define MMC_EXT_CSD_PWR_CL_26_INDEX 201
266 #define MMC_EXT_CSD_PWR_CL_52_INDEX 200
267 #define MMC_EXT_CSD_PWR_CL_DDR_52_INDEX 238
268
269 #define MMC_EXT_CSD_PWR_CL_26_POS 8
270 #define MMC_EXT_CSD_PWR_CL_52_POS 0
271 #define MMC_EXT_CSD_PWR_CL_DDR_52_POS 16
272 #else
273 #define MMC_VOLTAGE_RANGE EMMC_HIGH_VOLTAGE_RANGE
274
275 #define MMC_EXT_CSD_PWR_CL_26_INDEX 203
276 #define MMC_EXT_CSD_PWR_CL_52_INDEX 202
277 #define MMC_EXT_CSD_PWR_CL_DDR_52_INDEX 239
278
279 #define MMC_EXT_CSD_PWR_CL_26_POS 24
280 #define MMC_EXT_CSD_PWR_CL_52_POS 16
281 #define MMC_EXT_CSD_PWR_CL_DDR_52_POS 24
282 #endif /* (VDD_VALUE) && (VDD_VALUE <= 1950U)*/
283
284 #define MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_INDEX 216
285 #define MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_POS 0
286 #define MMC_EXT_CSD_S_A_TIMEOUT_INDEX 217
287 #define MMC_EXT_CSD_S_A_TIMEOUT_POS 8
288
289 /* Frequencies used in the driver for clock divider calculation */
290 #define MMC_INIT_FREQ 400000U /* Initialization phase : 400 kHz max */
291 #define MMC_HIGH_SPEED_FREQ 52000000U /* High speed phase : 52 MHz max */
292
293 /**
294 * @}
295 */
296
297 /* Private macro -------------------------------------------------------------*/
298 /* Private variables ---------------------------------------------------------*/
299 /* Private function prototypes -----------------------------------------------*/
300 /* Private functions ---------------------------------------------------------*/
301 /** @defgroup MMC_Private_Functions MMC Private Functions
302 * @{
303 */
304 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc);
305 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc);
306 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus);
307 static void MMC_PowerOFF(MMC_HandleTypeDef *hmmc);
308 static void MMC_Write_IT(MMC_HandleTypeDef *hmmc);
309 static void MMC_Read_IT(MMC_HandleTypeDef *hmmc);
310 static uint32_t MMC_HighSpeed(MMC_HandleTypeDef *hmmc, FunctionalState state);
311 static uint32_t MMC_DDR_Mode(MMC_HandleTypeDef *hmmc, FunctionalState state);
312 static HAL_StatusTypeDef MMC_ReadExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pFieldData, uint16_t FieldIndex,
313 uint32_t Timeout);
314 static uint32_t MMC_PwrClassUpdate(MMC_HandleTypeDef *hmmc, uint32_t Wide, uint32_t Speed);
315
316 /**
317 * @}
318 */
319 /* Exported functions --------------------------------------------------------*/
320 /** @addtogroup MMC_Exported_Functions
321 * @{
322 */
323
324 /** @addtogroup MMC_Exported_Functions_Group1
325 * @brief Initialization and de-initialization functions
326 *
327 @verbatim
328 ==============================================================================
329 ##### Initialization and de-initialization functions #####
330 ==============================================================================
331 [..]
332 This section provides functions allowing to initialize/de-initialize the MMC
333 card device to be ready for use.
334
335 @endverbatim
336 * @{
337 */
338
339 /**
340 * @brief Initializes the MMC according to the specified parameters in the
341 MMC_HandleTypeDef and create the associated handle.
342 * @param hmmc: Pointer to the MMC handle
343 * @retval HAL status
344 */
HAL_MMC_Init(MMC_HandleTypeDef * hmmc)345 HAL_StatusTypeDef HAL_MMC_Init(MMC_HandleTypeDef *hmmc)
346 {
347 /* Check the MMC handle allocation */
348 if (hmmc == NULL)
349 {
350 return HAL_ERROR;
351 }
352
353 /* Check the parameters */
354 assert_param(IS_SDMMC_ALL_INSTANCE(hmmc->Instance));
355 assert_param(IS_SDMMC_CLOCK_EDGE(hmmc->Init.ClockEdge));
356 assert_param(IS_SDMMC_CLOCK_POWER_SAVE(hmmc->Init.ClockPowerSave));
357 assert_param(IS_SDMMC_BUS_WIDE(hmmc->Init.BusWide));
358 assert_param(IS_SDMMC_HARDWARE_FLOW_CONTROL(hmmc->Init.HardwareFlowControl));
359 assert_param(IS_SDMMC_CLKDIV(hmmc->Init.ClockDiv));
360
361 if (hmmc->State == HAL_MMC_STATE_RESET)
362 {
363 /* Allocate lock resource and initialize it */
364 hmmc->Lock = HAL_UNLOCKED;
365 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
366 /* Reset Callback pointers in HAL_MMC_STATE_RESET only */
367 hmmc->TxCpltCallback = HAL_MMC_TxCpltCallback;
368 hmmc->RxCpltCallback = HAL_MMC_RxCpltCallback;
369 hmmc->ErrorCallback = HAL_MMC_ErrorCallback;
370 hmmc->AbortCpltCallback = HAL_MMC_AbortCallback;
371 hmmc->Read_DMALnkLstBufCpltCallback = HAL_MMCEx_Read_DMALnkLstBufCpltCallback;
372 hmmc->Write_DMALnkLstBufCpltCallback = HAL_MMCEx_Write_DMALnkLstBufCpltCallback;
373
374 if (hmmc->MspInitCallback == NULL)
375 {
376 hmmc->MspInitCallback = HAL_MMC_MspInit;
377 }
378
379 /* Init the low level hardware */
380 hmmc->MspInitCallback(hmmc);
381 #else
382 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
383 HAL_MMC_MspInit(hmmc);
384 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
385 }
386
387 hmmc->State = HAL_MMC_STATE_BUSY;
388
389 /* Initialize the Card parameters */
390 if (HAL_MMC_InitCard(hmmc) == HAL_ERROR)
391 {
392 return HAL_ERROR;
393 }
394
395 /* Initialize the error code */
396 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
397
398 /* Initialize the MMC operation */
399 hmmc->Context = MMC_CONTEXT_NONE;
400
401 /* Initialize the MMC state */
402 hmmc->State = HAL_MMC_STATE_READY;
403
404 /* Configure bus width */
405 if (hmmc->Init.BusWide != SDMMC_BUS_WIDE_1B)
406 {
407 if (HAL_MMC_ConfigWideBusOperation(hmmc, hmmc->Init.BusWide) != HAL_OK)
408 {
409 return HAL_ERROR;
410 }
411 }
412
413 return HAL_OK;
414 }
415
416 /**
417 * @brief Initializes the MMC Card.
418 * @param hmmc: Pointer to MMC handle
419 * @note This function initializes the MMC card. It could be used when a card
420 re-initialization is needed.
421 * @retval HAL status
422 */
HAL_MMC_InitCard(MMC_HandleTypeDef * hmmc)423 HAL_StatusTypeDef HAL_MMC_InitCard(MMC_HandleTypeDef *hmmc)
424 {
425 uint32_t errorstate;
426 MMC_InitTypeDef Init;
427 uint32_t sdmmc_clk;
428
429 /* Default SDMMC peripheral configuration for MMC card initialization */
430 Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
431 Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
432 Init.BusWide = SDMMC_BUS_WIDE_1B;
433 Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
434
435 /* Init Clock should be less or equal to 400Khz*/
436 sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC);
437 if (sdmmc_clk == 0U)
438 {
439 hmmc->State = HAL_MMC_STATE_READY;
440 hmmc->ErrorCode = SDMMC_ERROR_INVALID_PARAMETER;
441 return HAL_ERROR;
442 }
443 Init.ClockDiv = sdmmc_clk / (2U * MMC_INIT_FREQ);
444
445 #if (USE_SD_TRANSCEIVER != 0U)
446 Init.TranceiverPresent = SDMMC_TRANSCEIVER_NOT_PRESENT;
447 #endif /* USE_SD_TRANSCEIVER */
448
449 /* Initialize SDMMC peripheral interface with default configuration */
450 (void)SDMMC_Init(hmmc->Instance, Init);
451
452 /* Set Power State to ON */
453 (void)SDMMC_PowerState_ON(hmmc->Instance);
454
455 /* wait 74 Cycles: required power up waiting time before starting
456 the MMC initialization sequence */
457 if (Init.ClockDiv != 0U)
458 {
459 sdmmc_clk = sdmmc_clk / (2U * Init.ClockDiv);
460 }
461
462 if (sdmmc_clk != 0U)
463 {
464 HAL_Delay(1U + (74U * 1000U / (sdmmc_clk)));
465 }
466
467 /* Identify card operating voltage */
468 errorstate = MMC_PowerON(hmmc);
469 if (errorstate != HAL_MMC_ERROR_NONE)
470 {
471 hmmc->State = HAL_MMC_STATE_READY;
472 hmmc->ErrorCode |= errorstate;
473 return HAL_ERROR;
474 }
475
476 /* Card initialization */
477 errorstate = MMC_InitCard(hmmc);
478 if (errorstate != HAL_MMC_ERROR_NONE)
479 {
480 hmmc->State = HAL_MMC_STATE_READY;
481 hmmc->ErrorCode |= errorstate;
482 return HAL_ERROR;
483 }
484
485 /* Set Block Size for Card */
486 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, MMC_BLOCKSIZE);
487 if (errorstate != HAL_MMC_ERROR_NONE)
488 {
489 /* Clear all the static flags */
490 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
491 hmmc->ErrorCode |= errorstate;
492 hmmc->State = HAL_MMC_STATE_READY;
493 return HAL_ERROR;
494 }
495
496 return HAL_OK;
497 }
498
499 /**
500 * @brief De-Initializes the MMC card.
501 * @param hmmc: Pointer to MMC handle
502 * @retval HAL status
503 */
HAL_MMC_DeInit(MMC_HandleTypeDef * hmmc)504 HAL_StatusTypeDef HAL_MMC_DeInit(MMC_HandleTypeDef *hmmc)
505 {
506 /* Check the MMC handle allocation */
507 if (hmmc == NULL)
508 {
509 return HAL_ERROR;
510 }
511
512 /* Check the parameters */
513 assert_param(IS_SDMMC_ALL_INSTANCE(hmmc->Instance));
514
515 hmmc->State = HAL_MMC_STATE_BUSY;
516
517 /* Set MMC power state to off */
518 MMC_PowerOFF(hmmc);
519
520 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
521 if (hmmc->MspDeInitCallback == NULL)
522 {
523 hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
524 }
525
526 /* DeInit the low level hardware */
527 hmmc->MspDeInitCallback(hmmc);
528 #else
529 /* De-Initialize the MSP layer */
530 HAL_MMC_MspDeInit(hmmc);
531 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
532
533 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
534 hmmc->State = HAL_MMC_STATE_RESET;
535
536 return HAL_OK;
537 }
538
539
540 /**
541 * @brief Initializes the MMC MSP.
542 * @param hmmc: Pointer to MMC handle
543 * @retval None
544 */
HAL_MMC_MspInit(MMC_HandleTypeDef * hmmc)545 __weak void HAL_MMC_MspInit(MMC_HandleTypeDef *hmmc)
546 {
547 /* Prevent unused argument(s) compilation warning */
548 UNUSED(hmmc);
549
550 /* NOTE : This function Should not be modified, when the callback is needed,
551 the HAL_MMC_MspInit could be implemented in the user file
552 */
553 }
554
555 /**
556 * @brief De-Initialize MMC MSP.
557 * @param hmmc: Pointer to MMC handle
558 * @retval None
559 */
HAL_MMC_MspDeInit(MMC_HandleTypeDef * hmmc)560 __weak void HAL_MMC_MspDeInit(MMC_HandleTypeDef *hmmc)
561 {
562 /* Prevent unused argument(s) compilation warning */
563 UNUSED(hmmc);
564
565 /* NOTE : This function Should not be modified, when the callback is needed,
566 the HAL_MMC_MspDeInit could be implemented in the user file
567 */
568 }
569
570 /**
571 * @}
572 */
573
574 /** @addtogroup MMC_Exported_Functions_Group2
575 * @brief Data transfer functions
576 *
577 @verbatim
578 ==============================================================================
579 ##### IO operation functions #####
580 ==============================================================================
581 [..]
582 This subsection provides a set of functions allowing to manage the data
583 transfer from/to MMC card.
584
585 @endverbatim
586 * @{
587 */
588
589 /**
590 * @brief Reads block(s) from a specified address in a card. The Data transfer
591 * is managed by polling mode.
592 * @note This API should be followed by a check on the card state through
593 * HAL_MMC_GetCardState().
594 * @param hmmc: Pointer to MMC handle
595 * @param pData: pointer to the buffer that will contain the received data
596 * @param BlockAdd: Block Address from where data is to be read
597 * @param NumberOfBlocks: Number of MMC blocks to read
598 * @param Timeout: Specify timeout value
599 * @retval HAL status
600 */
HAL_MMC_ReadBlocks(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks,uint32_t Timeout)601 HAL_StatusTypeDef HAL_MMC_ReadBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd,
602 uint32_t NumberOfBlocks,
603 uint32_t Timeout)
604 {
605 SDMMC_DataInitTypeDef config;
606 uint32_t errorstate;
607 uint32_t tickstart = HAL_GetTick();
608 uint32_t count;
609 uint32_t data;
610 uint32_t dataremaining;
611 uint32_t add = BlockAdd;
612 uint8_t *tempbuff = pData;
613
614 if (NULL == pData)
615 {
616 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
617 return HAL_ERROR;
618 }
619
620 if (hmmc->State == HAL_MMC_STATE_READY)
621 {
622 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
623
624 if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
625 {
626 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
627 return HAL_ERROR;
628 }
629
630 /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
631 if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS)
632 & 0x000000FFU) != 0x0U)
633 {
634 if ((NumberOfBlocks % 8U) != 0U)
635 {
636 /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */
637 hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR;
638 return HAL_ERROR;
639 }
640
641 if ((BlockAdd % 8U) != 0U)
642 {
643 /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
644 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
645 return HAL_ERROR;
646 }
647 }
648
649 hmmc->State = HAL_MMC_STATE_BUSY;
650
651 /* Initialize data control register */
652 hmmc->Instance->DCTRL = 0U;
653
654 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
655 {
656 add *= MMC_BLOCKSIZE;
657 }
658
659 /* Configure the MMC DPSM (Data Path State Machine) */
660 config.DataTimeOut = SDMMC_DATATIMEOUT;
661 config.DataLength = NumberOfBlocks * MMC_BLOCKSIZE;
662 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
663 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
664 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
665 config.DPSM = SDMMC_DPSM_DISABLE;
666 (void)SDMMC_ConfigData(hmmc->Instance, &config);
667 __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
668
669 /* Read block(s) in polling mode */
670 if (NumberOfBlocks > 1U)
671 {
672 hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
673
674 /* Read Multi Block command */
675 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
676 }
677 else
678 {
679 hmmc->Context = MMC_CONTEXT_READ_SINGLE_BLOCK;
680
681 /* Read Single Block command */
682 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
683 }
684 if (errorstate != HAL_MMC_ERROR_NONE)
685 {
686 /* Clear all the static flags */
687 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
688 hmmc->ErrorCode |= errorstate;
689 hmmc->State = HAL_MMC_STATE_READY;
690 return HAL_ERROR;
691 }
692
693 /* Poll on SDMMC flags */
694 dataremaining = config.DataLength;
695 while (!__HAL_MMC_GET_FLAG(hmmc,
696 SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
697 {
698 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= SDMMC_FIFO_SIZE))
699 {
700 /* Read data from SDMMC Rx FIFO */
701 for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
702 {
703 data = SDMMC_ReadFIFO(hmmc->Instance);
704 *tempbuff = (uint8_t)(data & 0xFFU);
705 tempbuff++;
706 *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
707 tempbuff++;
708 *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
709 tempbuff++;
710 *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
711 tempbuff++;
712 }
713 dataremaining -= SDMMC_FIFO_SIZE;
714 }
715
716 if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
717 {
718 /* Clear all the static flags */
719 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
720 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
721 hmmc->State = HAL_MMC_STATE_READY;
722 return HAL_TIMEOUT;
723 }
724 }
725 __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
726
727 /* Send stop transmission command in case of multiblock read */
728 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U))
729 {
730 /* Send stop transmission command */
731 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
732 if (errorstate != HAL_MMC_ERROR_NONE)
733 {
734 /* Clear all the static flags */
735 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
736 hmmc->ErrorCode |= errorstate;
737 hmmc->State = HAL_MMC_STATE_READY;
738 return HAL_ERROR;
739 }
740 }
741
742 /* Get error state */
743 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
744 {
745 /* Clear all the static flags */
746 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
747 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
748 hmmc->State = HAL_MMC_STATE_READY;
749 return HAL_ERROR;
750 }
751 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
752 {
753 /* Clear all the static flags */
754 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
755 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
756 hmmc->State = HAL_MMC_STATE_READY;
757 return HAL_ERROR;
758 }
759 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR))
760 {
761 /* Clear all the static flags */
762 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
763 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
764 hmmc->State = HAL_MMC_STATE_READY;
765 return HAL_ERROR;
766 }
767 else
768 {
769 /* Nothing to do */
770 }
771
772 /* Clear all the static flags */
773 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
774
775 hmmc->State = HAL_MMC_STATE_READY;
776
777 return HAL_OK;
778 }
779 else
780 {
781 hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
782 return HAL_ERROR;
783 }
784 }
785
786 /**
787 * @brief Allows to write block(s) to a specified address in a card. The Data
788 * transfer is managed by polling mode.
789 * @note This API should be followed by a check on the card state through
790 * HAL_MMC_GetCardState().
791 * @param hmmc: Pointer to MMC handle
792 * @param pData: pointer to the buffer that will contain the data to transmit
793 * @param BlockAdd: Block Address where data will be written
794 * @param NumberOfBlocks: Number of MMC blocks to write
795 * @param Timeout: Specify timeout value
796 * @retval HAL status
797 */
HAL_MMC_WriteBlocks(MMC_HandleTypeDef * hmmc,const uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks,uint32_t Timeout)798 HAL_StatusTypeDef HAL_MMC_WriteBlocks(MMC_HandleTypeDef *hmmc, const uint8_t *pData, uint32_t BlockAdd,
799 uint32_t NumberOfBlocks, uint32_t Timeout)
800 {
801 SDMMC_DataInitTypeDef config;
802 uint32_t errorstate;
803 uint32_t tickstart = HAL_GetTick();
804 uint32_t count;
805 uint32_t data;
806 uint32_t dataremaining;
807 uint32_t add = BlockAdd;
808 const uint8_t *tempbuff = pData;
809
810 if (NULL == pData)
811 {
812 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
813 return HAL_ERROR;
814 }
815
816 if (hmmc->State == HAL_MMC_STATE_READY)
817 {
818 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
819
820 if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
821 {
822 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
823 return HAL_ERROR;
824 }
825
826 /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
827 if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U)
828 {
829 if ((NumberOfBlocks % 8U) != 0U)
830 {
831 /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */
832 hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR;
833 return HAL_ERROR;
834 }
835
836 if ((BlockAdd % 8U) != 0U)
837 {
838 /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
839 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
840 return HAL_ERROR;
841 }
842 }
843
844 hmmc->State = HAL_MMC_STATE_BUSY;
845
846 /* Initialize data control register */
847 hmmc->Instance->DCTRL = 0U;
848
849 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
850 {
851 add *= MMC_BLOCKSIZE;
852 }
853
854 /* Configure the MMC DPSM (Data Path State Machine) */
855 config.DataTimeOut = SDMMC_DATATIMEOUT;
856 config.DataLength = NumberOfBlocks * MMC_BLOCKSIZE;
857 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
858 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
859 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
860 config.DPSM = SDMMC_DPSM_DISABLE;
861 (void)SDMMC_ConfigData(hmmc->Instance, &config);
862 __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
863
864 /* Write Blocks in Polling mode */
865 if (NumberOfBlocks > 1U)
866 {
867 hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
868
869 /* Write Multi Block command */
870 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
871 }
872 else
873 {
874 hmmc->Context = MMC_CONTEXT_WRITE_SINGLE_BLOCK;
875
876 /* Write Single Block command */
877 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
878 }
879 if (errorstate != HAL_MMC_ERROR_NONE)
880 {
881 /* Clear all the static flags */
882 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
883 hmmc->ErrorCode |= errorstate;
884 hmmc->State = HAL_MMC_STATE_READY;
885 return HAL_ERROR;
886 }
887
888 /* Write block(s) in polling mode */
889 dataremaining = config.DataLength;
890 while (!__HAL_MMC_GET_FLAG(hmmc,
891 SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
892 {
893 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= SDMMC_FIFO_SIZE))
894 {
895 /* Write data to SDMMC Tx FIFO */
896 for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
897 {
898 data = (uint32_t)(*tempbuff);
899 tempbuff++;
900 data |= ((uint32_t)(*tempbuff) << 8U);
901 tempbuff++;
902 data |= ((uint32_t)(*tempbuff) << 16U);
903 tempbuff++;
904 data |= ((uint32_t)(*tempbuff) << 24U);
905 tempbuff++;
906 (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
907 }
908 dataremaining -= SDMMC_FIFO_SIZE;
909 }
910
911 if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
912 {
913 /* Clear all the static flags */
914 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
915 hmmc->ErrorCode |= errorstate;
916 hmmc->State = HAL_MMC_STATE_READY;
917 return HAL_TIMEOUT;
918 }
919 }
920 __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
921
922 /* Send stop transmission command in case of multiblock write */
923 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U))
924 {
925 /* Send stop transmission command */
926 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
927 if (errorstate != HAL_MMC_ERROR_NONE)
928 {
929 /* Clear all the static flags */
930 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
931 hmmc->ErrorCode |= errorstate;
932 hmmc->State = HAL_MMC_STATE_READY;
933 return HAL_ERROR;
934 }
935 }
936
937 /* Get error state */
938 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
939 {
940 /* Clear all the static flags */
941 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
942 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
943 hmmc->State = HAL_MMC_STATE_READY;
944 return HAL_ERROR;
945 }
946 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
947 {
948 /* Clear all the static flags */
949 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
950 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
951 hmmc->State = HAL_MMC_STATE_READY;
952 return HAL_ERROR;
953 }
954 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
955 {
956 /* Clear all the static flags */
957 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
958 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
959 hmmc->State = HAL_MMC_STATE_READY;
960 return HAL_ERROR;
961 }
962 else
963 {
964 /* Nothing to do */
965 }
966
967 /* Clear all the static flags */
968 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
969
970 hmmc->State = HAL_MMC_STATE_READY;
971
972 return HAL_OK;
973 }
974 else
975 {
976 hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
977 return HAL_ERROR;
978 }
979 }
980
981 /**
982 * @brief Reads block(s) from a specified address in a card. The Data transfer
983 * is managed in interrupt mode.
984 * @note This API should be followed by a check on the card state through
985 * HAL_MMC_GetCardState().
986 * @note You could also check the IT transfer process through the MMC Rx
987 * interrupt event.
988 * @param hmmc: Pointer to MMC handle
989 * @param pData: Pointer to the buffer that will contain the received data
990 * @param BlockAdd: Block Address from where data is to be read
991 * @param NumberOfBlocks: Number of blocks to read.
992 * @retval HAL status
993 */
HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)994 HAL_StatusTypeDef HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd,
995 uint32_t NumberOfBlocks)
996 {
997 SDMMC_DataInitTypeDef config;
998 uint32_t errorstate;
999 uint32_t add = BlockAdd;
1000
1001 if (NULL == pData)
1002 {
1003 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1004 return HAL_ERROR;
1005 }
1006
1007 if (hmmc->State == HAL_MMC_STATE_READY)
1008 {
1009 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1010
1011 if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1012 {
1013 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1014 return HAL_ERROR;
1015 }
1016
1017 /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
1018 if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U)
1019 {
1020 if ((NumberOfBlocks % 8U) != 0U)
1021 {
1022 /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */
1023 hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR;
1024 return HAL_ERROR;
1025 }
1026
1027 if ((BlockAdd % 8U) != 0U)
1028 {
1029 /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
1030 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
1031 return HAL_ERROR;
1032 }
1033 }
1034
1035 hmmc->State = HAL_MMC_STATE_BUSY;
1036
1037 /* Initialize data control register */
1038 hmmc->Instance->DCTRL = 0U;
1039
1040 hmmc->pRxBuffPtr = pData;
1041 hmmc->RxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1042
1043 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1044 {
1045 add *= MMC_BLOCKSIZE;
1046 }
1047
1048 /* Configure the MMC DPSM (Data Path State Machine) */
1049 config.DataTimeOut = SDMMC_DATATIMEOUT;
1050 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks;
1051 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1052 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
1053 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
1054 config.DPSM = SDMMC_DPSM_DISABLE;
1055 (void)SDMMC_ConfigData(hmmc->Instance, &config);
1056 __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
1057
1058 /* Read Blocks in IT mode */
1059 if (NumberOfBlocks > 1U)
1060 {
1061 hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_IT);
1062
1063 /* Read Multi Block command */
1064 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
1065 }
1066 else
1067 {
1068 hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_IT);
1069
1070 /* Read Single Block command */
1071 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
1072 }
1073
1074 if (errorstate != HAL_MMC_ERROR_NONE)
1075 {
1076 /* Clear all the static flags */
1077 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1078 hmmc->ErrorCode |= errorstate;
1079 hmmc->State = HAL_MMC_STATE_READY;
1080 return HAL_ERROR;
1081 }
1082
1083 __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND |
1084 SDMMC_FLAG_RXFIFOHF));
1085
1086 return HAL_OK;
1087 }
1088 else
1089 {
1090 return HAL_BUSY;
1091 }
1092 }
1093
1094 /**
1095 * @brief Writes block(s) to a specified address in a card. The Data transfer
1096 * is managed in interrupt mode.
1097 * @note This API should be followed by a check on the card state through
1098 * HAL_MMC_GetCardState().
1099 * @note You could also check the IT transfer process through the MMC Tx
1100 * interrupt event.
1101 * @param hmmc: Pointer to MMC handle
1102 * @param pData: Pointer to the buffer that will contain the data to transmit
1103 * @param BlockAdd: Block Address where data will be written
1104 * @param NumberOfBlocks: Number of blocks to write
1105 * @retval HAL status
1106 */
HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef * hmmc,const uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)1107 HAL_StatusTypeDef HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef *hmmc, const uint8_t *pData,
1108 uint32_t BlockAdd, uint32_t NumberOfBlocks)
1109 {
1110 SDMMC_DataInitTypeDef config;
1111 uint32_t errorstate;
1112 uint32_t add = BlockAdd;
1113
1114 if (NULL == pData)
1115 {
1116 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1117 return HAL_ERROR;
1118 }
1119
1120 if (hmmc->State == HAL_MMC_STATE_READY)
1121 {
1122 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1123
1124 if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1125 {
1126 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1127 return HAL_ERROR;
1128 }
1129
1130 /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
1131 if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U)
1132 {
1133 if ((NumberOfBlocks % 8U) != 0U)
1134 {
1135 /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */
1136 hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR;
1137 return HAL_ERROR;
1138 }
1139
1140 if ((BlockAdd % 8U) != 0U)
1141 {
1142 /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
1143 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
1144 return HAL_ERROR;
1145 }
1146 }
1147
1148 hmmc->State = HAL_MMC_STATE_BUSY;
1149
1150 /* Initialize data control register */
1151 hmmc->Instance->DCTRL = 0U;
1152
1153 hmmc->pTxBuffPtr = pData;
1154 hmmc->TxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1155
1156 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1157 {
1158 add *= MMC_BLOCKSIZE;
1159 }
1160
1161 /* Configure the MMC DPSM (Data Path State Machine) */
1162 config.DataTimeOut = SDMMC_DATATIMEOUT;
1163 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks;
1164 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1165 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
1166 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
1167 config.DPSM = SDMMC_DPSM_DISABLE;
1168 (void)SDMMC_ConfigData(hmmc->Instance, &config);
1169
1170 __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
1171
1172 /* Write Blocks in Polling mode */
1173 if (NumberOfBlocks > 1U)
1174 {
1175 hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_IT);
1176
1177 /* Write Multi Block command */
1178 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
1179 }
1180 else
1181 {
1182 hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_IT);
1183
1184 /* Write Single Block command */
1185 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
1186 }
1187 if (errorstate != HAL_MMC_ERROR_NONE)
1188 {
1189 /* Clear all the static flags */
1190 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1191 hmmc->ErrorCode |= errorstate;
1192 hmmc->State = HAL_MMC_STATE_READY;
1193 return HAL_ERROR;
1194 }
1195
1196 /* Enable transfer interrupts */
1197 __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND |
1198 SDMMC_FLAG_TXFIFOHE));
1199
1200 return HAL_OK;
1201 }
1202 else
1203 {
1204 return HAL_BUSY;
1205 }
1206 }
1207
1208 /**
1209 * @brief Reads block(s) from a specified address in a card. The Data transfer
1210 * is managed by DMA mode.
1211 * @note This API should be followed by a check on the card state through
1212 * HAL_MMC_GetCardState().
1213 * @note You could also check the DMA transfer process through the MMC Rx
1214 * interrupt event.
1215 * @param hmmc: Pointer MMC handle
1216 * @param pData: Pointer to the buffer that will contain the received data
1217 * @param BlockAdd: Block Address from where data is to be read
1218 * @param NumberOfBlocks: Number of blocks to read.
1219 * @retval HAL status
1220 */
HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)1221 HAL_StatusTypeDef HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd,
1222 uint32_t NumberOfBlocks)
1223 {
1224 SDMMC_DataInitTypeDef config;
1225 uint32_t errorstate;
1226 uint32_t add = BlockAdd;
1227
1228 if (NULL == pData)
1229 {
1230 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1231 return HAL_ERROR;
1232 }
1233
1234 if (hmmc->State == HAL_MMC_STATE_READY)
1235 {
1236 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
1237
1238 if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1239 {
1240 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1241 return HAL_ERROR;
1242 }
1243
1244 /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
1245 if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U)
1246 {
1247 if ((NumberOfBlocks % 8U) != 0U)
1248 {
1249 /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */
1250 hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR;
1251 return HAL_ERROR;
1252 }
1253
1254 if ((BlockAdd % 8U) != 0U)
1255 {
1256 /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
1257 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
1258 return HAL_ERROR;
1259 }
1260 }
1261
1262 hmmc->State = HAL_MMC_STATE_BUSY;
1263
1264 /* Initialize data control register */
1265 hmmc->Instance->DCTRL = 0U;
1266
1267 hmmc->pRxBuffPtr = pData;
1268 hmmc->RxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1269
1270 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1271 {
1272 add *= MMC_BLOCKSIZE;
1273 }
1274
1275 /* Configure the MMC DPSM (Data Path State Machine) */
1276 config.DataTimeOut = SDMMC_DATATIMEOUT;
1277 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks;
1278 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1279 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
1280 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
1281 config.DPSM = SDMMC_DPSM_DISABLE;
1282 (void)SDMMC_ConfigData(hmmc->Instance, &config);
1283
1284 __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
1285 hmmc->Instance->IDMABASER = (uint32_t) pData ;
1286 hmmc->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_SINGLE_BUFF;
1287
1288 /* Read Blocks in DMA mode */
1289 if (NumberOfBlocks > 1U)
1290 {
1291 hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
1292
1293 /* Read Multi Block command */
1294 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
1295 }
1296 else
1297 {
1298 hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_DMA);
1299
1300 /* Read Single Block command */
1301 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
1302 }
1303 if (errorstate != HAL_MMC_ERROR_NONE)
1304 {
1305 /* Clear all the static flags */
1306 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1307 hmmc->ErrorCode = errorstate;
1308 hmmc->State = HAL_MMC_STATE_READY;
1309 return HAL_ERROR;
1310 }
1311
1312 /* Enable transfer interrupts */
1313 __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND));
1314
1315 return HAL_OK;
1316 }
1317 else
1318 {
1319 return HAL_BUSY;
1320 }
1321 }
1322
1323 /**
1324 * @brief Writes block(s) to a specified address in a card. The Data transfer
1325 * is managed by DMA mode.
1326 * @note This API should be followed by a check on the card state through
1327 * HAL_MMC_GetCardState().
1328 * @note You could also check the DMA transfer process through the MMC Tx
1329 * interrupt event.
1330 * @param hmmc: Pointer to MMC handle
1331 * @param pData: Pointer to the buffer that will contain the data to transmit
1332 * @param BlockAdd: Block Address where data will be written
1333 * @param NumberOfBlocks: Number of blocks to write
1334 * @retval HAL status
1335 */
HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef * hmmc,const uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)1336 HAL_StatusTypeDef HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef *hmmc, const uint8_t *pData,
1337 uint32_t BlockAdd, uint32_t NumberOfBlocks)
1338 {
1339 SDMMC_DataInitTypeDef config;
1340 uint32_t errorstate;
1341 uint32_t add = BlockAdd;
1342
1343 if (NULL == pData)
1344 {
1345 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1346 return HAL_ERROR;
1347 }
1348
1349 if (hmmc->State == HAL_MMC_STATE_READY)
1350 {
1351 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1352
1353 if ((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1354 {
1355 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1356 return HAL_ERROR;
1357 }
1358
1359 /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
1360 if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U)
1361 {
1362 if ((NumberOfBlocks % 8U) != 0U)
1363 {
1364 /* The number of blocks should be a multiple of 8 sectors of 512 bytes = 4 KBytes */
1365 hmmc->ErrorCode |= HAL_MMC_ERROR_BLOCK_LEN_ERR;
1366 return HAL_ERROR;
1367 }
1368
1369 if ((BlockAdd % 8U) != 0U)
1370 {
1371 /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
1372 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
1373 return HAL_ERROR;
1374 }
1375 }
1376
1377 hmmc->State = HAL_MMC_STATE_BUSY;
1378
1379 /* Initialize data control register */
1380 hmmc->Instance->DCTRL = 0U;
1381
1382 hmmc->pTxBuffPtr = pData;
1383 hmmc->TxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1384
1385 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1386 {
1387 add *= MMC_BLOCKSIZE;
1388 }
1389
1390 /* Configure the MMC DPSM (Data Path State Machine) */
1391 config.DataTimeOut = SDMMC_DATATIMEOUT;
1392 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks;
1393 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1394 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
1395 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
1396 config.DPSM = SDMMC_DPSM_DISABLE;
1397 (void)SDMMC_ConfigData(hmmc->Instance, &config);
1398
1399 __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
1400
1401 hmmc->Instance->IDMABASER = (uint32_t) pData ;
1402 hmmc->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_SINGLE_BUFF;
1403
1404 /* Write Blocks in Polling mode */
1405 if (NumberOfBlocks > 1U)
1406 {
1407 hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
1408
1409 /* Write Multi Block command */
1410 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
1411 }
1412 else
1413 {
1414 hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_DMA);
1415
1416 /* Write Single Block command */
1417 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
1418 }
1419 if (errorstate != HAL_MMC_ERROR_NONE)
1420 {
1421 /* Clear all the static flags */
1422 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1423 hmmc->ErrorCode |= errorstate;
1424 hmmc->State = HAL_MMC_STATE_READY;
1425 return HAL_ERROR;
1426 }
1427
1428 /* Enable transfer interrupts */
1429 __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND));
1430
1431 return HAL_OK;
1432 }
1433 else
1434 {
1435 return HAL_BUSY;
1436 }
1437 }
1438
1439 /**
1440 * @brief Erases the specified memory area of the given MMC card.
1441 * @note This API should be followed by a check on the card state through
1442 * HAL_MMC_GetCardState().
1443 * @param hmmc: Pointer to MMC handle
1444 * @param BlockStartAdd: Start Block address
1445 * @param BlockEndAdd: End Block address
1446 * @retval HAL status
1447 */
HAL_MMC_Erase(MMC_HandleTypeDef * hmmc,uint32_t BlockStartAdd,uint32_t BlockEndAdd)1448 HAL_StatusTypeDef HAL_MMC_Erase(MMC_HandleTypeDef *hmmc, uint32_t BlockStartAdd, uint32_t BlockEndAdd)
1449 {
1450 uint32_t errorstate;
1451 uint32_t start_add = BlockStartAdd;
1452 uint32_t end_add = BlockEndAdd;
1453
1454 if (hmmc->State == HAL_MMC_STATE_READY)
1455 {
1456 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1457
1458 if (end_add < start_add)
1459 {
1460 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1461 return HAL_ERROR;
1462 }
1463
1464 if (end_add > (hmmc->MmcCard.LogBlockNbr))
1465 {
1466 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1467 return HAL_ERROR;
1468 }
1469
1470 /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
1471 if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS)
1472 & 0x000000FFU) != 0x0U)
1473 {
1474 if (((start_add % 8U) != 0U) || ((end_add % 8U) != 0U))
1475 {
1476 /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
1477 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
1478 return HAL_ERROR;
1479 }
1480 }
1481
1482 hmmc->State = HAL_MMC_STATE_BUSY;
1483
1484 /* Check if the card command class supports erase command */
1485 if (((hmmc->MmcCard.Class) & SDMMC_CCCC_ERASE) == 0U)
1486 {
1487 /* Clear all the static flags */
1488 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1489 hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
1490 hmmc->State = HAL_MMC_STATE_READY;
1491 return HAL_ERROR;
1492 }
1493
1494 if ((SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
1495 {
1496 /* Clear all the static flags */
1497 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1498 hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED;
1499 hmmc->State = HAL_MMC_STATE_READY;
1500 return HAL_ERROR;
1501 }
1502
1503 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1504 {
1505 start_add *= MMC_BLOCKSIZE;
1506 end_add *= MMC_BLOCKSIZE;
1507 }
1508
1509 /* Send CMD35 MMC_ERASE_GRP_START with argument as addr */
1510 errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, start_add);
1511 if (errorstate != HAL_MMC_ERROR_NONE)
1512 {
1513 /* Clear all the static flags */
1514 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1515 hmmc->ErrorCode |= errorstate;
1516 hmmc->State = HAL_MMC_STATE_READY;
1517 return HAL_ERROR;
1518 }
1519
1520 /* Send CMD36 MMC_ERASE_GRP_END with argument as addr */
1521 errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, end_add);
1522 if (errorstate != HAL_MMC_ERROR_NONE)
1523 {
1524 /* Clear all the static flags */
1525 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1526 hmmc->ErrorCode |= errorstate;
1527 hmmc->State = HAL_MMC_STATE_READY;
1528 return HAL_ERROR;
1529 }
1530
1531 /* Send CMD38 ERASE */
1532 errorstate = SDMMC_CmdErase(hmmc->Instance, 0UL);
1533 if (errorstate != HAL_MMC_ERROR_NONE)
1534 {
1535 /* Clear all the static flags */
1536 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1537 hmmc->ErrorCode |= errorstate;
1538 hmmc->State = HAL_MMC_STATE_READY;
1539 return HAL_ERROR;
1540 }
1541
1542 hmmc->State = HAL_MMC_STATE_READY;
1543
1544 return HAL_OK;
1545 }
1546 else
1547 {
1548 return HAL_BUSY;
1549 }
1550 }
1551
1552 /**
1553 * @brief This function handles MMC card interrupt request.
1554 * @param hmmc: Pointer to MMC handle
1555 * @retval None
1556 */
HAL_MMC_IRQHandler(MMC_HandleTypeDef * hmmc)1557 void HAL_MMC_IRQHandler(MMC_HandleTypeDef *hmmc)
1558 {
1559 uint32_t errorstate;
1560 uint32_t context = hmmc->Context;
1561
1562 /* Check for SDMMC interrupt flags */
1563 if ((__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) != RESET) && ((context & MMC_CONTEXT_IT) != 0U))
1564 {
1565 MMC_Read_IT(hmmc);
1566 }
1567
1568 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) != RESET)
1569 {
1570 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_DATAEND);
1571
1572 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | \
1573 SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR | SDMMC_IT_TXFIFOHE | \
1574 SDMMC_IT_RXFIFOHF);
1575
1576 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_IDMABTC);
1577 __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
1578
1579 if ((context & MMC_CONTEXT_DMA) != 0U)
1580 {
1581 hmmc->Instance->DLEN = 0;
1582 hmmc->Instance->DCTRL = 0;
1583 hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA ;
1584
1585 /* Stop Transfer for Write Multi blocks or Read Multi blocks */
1586 if (((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
1587 {
1588 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
1589 if (errorstate != HAL_MMC_ERROR_NONE)
1590 {
1591 hmmc->ErrorCode |= errorstate;
1592 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1593 hmmc->ErrorCallback(hmmc);
1594 #else
1595 HAL_MMC_ErrorCallback(hmmc);
1596 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1597 }
1598 }
1599
1600 /* Clear all the static flags */
1601 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
1602
1603 hmmc->State = HAL_MMC_STATE_READY;
1604 if (((context & MMC_CONTEXT_WRITE_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
1605 {
1606 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1607 hmmc->TxCpltCallback(hmmc);
1608 #else
1609 HAL_MMC_TxCpltCallback(hmmc);
1610 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1611 }
1612 if (((context & MMC_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
1613 {
1614 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1615 hmmc->RxCpltCallback(hmmc);
1616 #else
1617 HAL_MMC_RxCpltCallback(hmmc);
1618 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1619 }
1620 }
1621 else if ((context & MMC_CONTEXT_IT) != 0U)
1622 {
1623 /* Stop Transfer for Write Multi blocks or Read Multi blocks */
1624 if (((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
1625 {
1626 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
1627 if (errorstate != HAL_MMC_ERROR_NONE)
1628 {
1629 hmmc->ErrorCode |= errorstate;
1630 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1631 hmmc->ErrorCallback(hmmc);
1632 #else
1633 HAL_MMC_ErrorCallback(hmmc);
1634 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1635 }
1636 }
1637
1638 /* Clear all the static flags */
1639 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
1640
1641 hmmc->State = HAL_MMC_STATE_READY;
1642 if (((context & MMC_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
1643 {
1644 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1645 hmmc->RxCpltCallback(hmmc);
1646 #else
1647 HAL_MMC_RxCpltCallback(hmmc);
1648 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1649 }
1650 else
1651 {
1652 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1653 hmmc->TxCpltCallback(hmmc);
1654 #else
1655 HAL_MMC_TxCpltCallback(hmmc);
1656 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1657 }
1658 }
1659 else
1660 {
1661 /* Nothing to do */
1662 }
1663 }
1664
1665 else if ((__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) != RESET) && ((context & MMC_CONTEXT_IT) != 0U))
1666 {
1667 MMC_Write_IT(hmmc);
1668 }
1669
1670 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL |
1671 SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_RXOVERR | SDMMC_FLAG_TXUNDERR) != RESET)
1672 {
1673 /* Set Error code */
1674 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_DCRCFAIL) != RESET)
1675 {
1676 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
1677 }
1678 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_DTIMEOUT) != RESET)
1679 {
1680 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
1681 }
1682 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_RXOVERR) != RESET)
1683 {
1684 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
1685 }
1686 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_TXUNDERR) != RESET)
1687 {
1688 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
1689 }
1690
1691 /* Clear All flags */
1692 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
1693
1694 /* Disable all interrupts */
1695 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | \
1696 SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR);
1697
1698 __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
1699 hmmc->Instance->DCTRL |= SDMMC_DCTRL_FIFORST;
1700 hmmc->Instance->CMD |= SDMMC_CMD_CMDSTOP;
1701 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
1702 hmmc->Instance->CMD &= ~(SDMMC_CMD_CMDSTOP);
1703 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_DABORT);
1704
1705 if ((context & MMC_CONTEXT_IT) != 0U)
1706 {
1707 /* Set the MMC state to ready to be able to start again the process */
1708 hmmc->State = HAL_MMC_STATE_READY;
1709 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1710 hmmc->ErrorCallback(hmmc);
1711 #else
1712 HAL_MMC_ErrorCallback(hmmc);
1713 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1714 }
1715 else if ((context & MMC_CONTEXT_DMA) != 0U)
1716 {
1717 if (hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
1718 {
1719 /* Disable Internal DMA */
1720 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_IDMABTC);
1721 hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA;
1722
1723 /* Set the MMC state to ready to be able to start again the process */
1724 hmmc->State = HAL_MMC_STATE_READY;
1725 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1726 hmmc->ErrorCallback(hmmc);
1727 #else
1728 HAL_MMC_ErrorCallback(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_IDMABTC) != RESET)
1739 {
1740 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_IT_IDMABTC);
1741
1742 if ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)
1743 {
1744 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1745 hmmc->Write_DMALnkLstBufCpltCallback(hmmc);
1746 #else
1747 HAL_MMCEx_Write_DMALnkLstBufCpltCallback(hmmc);
1748 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1749 }
1750 else /* MMC_CONTEXT_READ_MULTIPLE_BLOCK */
1751 {
1752 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1753 hmmc->Read_DMALnkLstBufCpltCallback(hmmc);
1754 #else
1755 HAL_MMCEx_Read_DMALnkLstBufCpltCallback(hmmc);
1756 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1757 }
1758 }
1759
1760 else
1761 {
1762 /* Nothing to do */
1763 }
1764 }
1765
1766 /**
1767 * @brief return the MMC state
1768 * @param hmmc: Pointer to mmc handle
1769 * @retval HAL state
1770 */
HAL_MMC_GetState(const MMC_HandleTypeDef * hmmc)1771 HAL_MMC_StateTypeDef HAL_MMC_GetState(const MMC_HandleTypeDef *hmmc)
1772 {
1773 return hmmc->State;
1774 }
1775
1776 /**
1777 * @brief Return the MMC error code
1778 * @param hmmc : Pointer to a MMC_HandleTypeDef structure that contains
1779 * the configuration information.
1780 * @retval MMC Error Code
1781 */
HAL_MMC_GetError(const MMC_HandleTypeDef * hmmc)1782 uint32_t HAL_MMC_GetError(const MMC_HandleTypeDef *hmmc)
1783 {
1784 return hmmc->ErrorCode;
1785 }
1786
1787 /**
1788 * @brief Tx Transfer completed callbacks
1789 * @param hmmc: Pointer to MMC handle
1790 * @retval None
1791 */
HAL_MMC_TxCpltCallback(MMC_HandleTypeDef * hmmc)1792 __weak void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef *hmmc)
1793 {
1794 /* Prevent unused argument(s) compilation warning */
1795 UNUSED(hmmc);
1796
1797 /* NOTE : This function should not be modified, when the callback is needed,
1798 the HAL_MMC_TxCpltCallback can be implemented in the user file
1799 */
1800 }
1801
1802 /**
1803 * @brief Rx Transfer completed callbacks
1804 * @param hmmc: Pointer MMC handle
1805 * @retval None
1806 */
HAL_MMC_RxCpltCallback(MMC_HandleTypeDef * hmmc)1807 __weak void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef *hmmc)
1808 {
1809 /* Prevent unused argument(s) compilation warning */
1810 UNUSED(hmmc);
1811
1812 /* NOTE : This function should not be modified, when the callback is needed,
1813 the HAL_MMC_RxCpltCallback can be implemented in the user file
1814 */
1815 }
1816
1817 /**
1818 * @brief MMC error callbacks
1819 * @param hmmc: Pointer MMC handle
1820 * @retval None
1821 */
HAL_MMC_ErrorCallback(MMC_HandleTypeDef * hmmc)1822 __weak void HAL_MMC_ErrorCallback(MMC_HandleTypeDef *hmmc)
1823 {
1824 /* Prevent unused argument(s) compilation warning */
1825 UNUSED(hmmc);
1826
1827 /* NOTE : This function should not be modified, when the callback is needed,
1828 the HAL_MMC_ErrorCallback can be implemented in the user file
1829 */
1830 }
1831
1832 /**
1833 * @brief MMC Abort callbacks
1834 * @param hmmc: Pointer MMC handle
1835 * @retval None
1836 */
HAL_MMC_AbortCallback(MMC_HandleTypeDef * hmmc)1837 __weak void HAL_MMC_AbortCallback(MMC_HandleTypeDef *hmmc)
1838 {
1839 /* Prevent unused argument(s) compilation warning */
1840 UNUSED(hmmc);
1841
1842 /* NOTE : This function should not be modified, when the callback is needed,
1843 the HAL_MMC_AbortCallback can be implemented in the user file
1844 */
1845 }
1846
1847 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1848 /**
1849 * @brief Register a User MMC Callback
1850 * To be used instead of the weak (overridden) predefined callback
1851 * @note The HAL_MMC_RegisterCallback() may be called before HAL_MMC_Init() in
1852 * HAL_MMC_STATE_RESET to register callbacks for HAL_MMC_MSP_INIT_CB_ID
1853 * and HAL_MMC_MSP_DEINIT_CB_ID.
1854 * @param hmmc : MMC handle
1855 * @param CallbackId : ID of the callback to be registered
1856 * This parameter can be one of the following values:
1857 * @arg @ref HAL_MMC_TX_CPLT_CB_ID MMC Tx Complete Callback ID
1858 * @arg @ref HAL_MMC_RX_CPLT_CB_ID MMC Rx Complete Callback ID
1859 * @arg @ref HAL_MMC_ERROR_CB_ID MMC Error Callback ID
1860 * @arg @ref HAL_MMC_ABORT_CB_ID MMC Abort Callback ID
1861 * @arg @ref HAL_MMC_READ_DMA_LNKLST_BUF_CPLT_CB_ID MMC DMA Rx Linked List Node buffer Callback ID
1862 * @arg @ref HAL_MMC_WRITE_DMA_LNKLST_BUF_CPLT_CB_ID MMC DMA Tx Linked List Node buffer Callback ID
1863 * @arg @ref HAL_MMC_MSP_INIT_CB_ID MMC MspInit Callback ID
1864 * @arg @ref HAL_MMC_MSP_DEINIT_CB_ID MMC MspDeInit Callback ID
1865 * @param pCallback : pointer to the Callback function
1866 * @retval status
1867 */
HAL_MMC_RegisterCallback(MMC_HandleTypeDef * hmmc,HAL_MMC_CallbackIDTypeDef CallbackId,pMMC_CallbackTypeDef pCallback)1868 HAL_StatusTypeDef HAL_MMC_RegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId,
1869 pMMC_CallbackTypeDef pCallback)
1870 {
1871 HAL_StatusTypeDef status = HAL_OK;
1872
1873 if (pCallback == NULL)
1874 {
1875 /* Update the error code */
1876 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1877 return HAL_ERROR;
1878 }
1879
1880 if (hmmc->State == HAL_MMC_STATE_READY)
1881 {
1882 switch (CallbackId)
1883 {
1884 case HAL_MMC_TX_CPLT_CB_ID :
1885 hmmc->TxCpltCallback = pCallback;
1886 break;
1887 case HAL_MMC_RX_CPLT_CB_ID :
1888 hmmc->RxCpltCallback = pCallback;
1889 break;
1890 case HAL_MMC_ERROR_CB_ID :
1891 hmmc->ErrorCallback = pCallback;
1892 break;
1893 case HAL_MMC_ABORT_CB_ID :
1894 hmmc->AbortCpltCallback = pCallback;
1895 break;
1896 case HAL_MMC_READ_DMA_LNKLST_BUF_CPLT_CB_ID :
1897 hmmc->Read_DMALnkLstBufCpltCallback = pCallback;
1898 break;
1899 case HAL_MMC_WRITE_DMA_LNKLST_BUF_CPLT_CB_ID :
1900 hmmc->Write_DMALnkLstBufCpltCallback = pCallback;
1901 break;
1902 case HAL_MMC_MSP_INIT_CB_ID :
1903 hmmc->MspInitCallback = pCallback;
1904 break;
1905 case HAL_MMC_MSP_DEINIT_CB_ID :
1906 hmmc->MspDeInitCallback = pCallback;
1907 break;
1908 default :
1909 /* Update the error code */
1910 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1911 /* update return status */
1912 status = HAL_ERROR;
1913 break;
1914 }
1915 }
1916 else if (hmmc->State == HAL_MMC_STATE_RESET)
1917 {
1918 switch (CallbackId)
1919 {
1920 case HAL_MMC_MSP_INIT_CB_ID :
1921 hmmc->MspInitCallback = pCallback;
1922 break;
1923 case HAL_MMC_MSP_DEINIT_CB_ID :
1924 hmmc->MspDeInitCallback = pCallback;
1925 break;
1926 default :
1927 /* Update the error code */
1928 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1929 /* update return status */
1930 status = HAL_ERROR;
1931 break;
1932 }
1933 }
1934 else
1935 {
1936 /* Update the error code */
1937 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1938 /* update return status */
1939 status = HAL_ERROR;
1940 }
1941
1942 return status;
1943 }
1944
1945 /**
1946 * @brief Unregister a User MMC Callback
1947 * MMC Callback is redirected to the weak (overridden) predefined callback
1948 * @note The HAL_MMC_UnRegisterCallback() may be called before HAL_MMC_Init() in
1949 * HAL_MMC_STATE_RESET to register callbacks for HAL_MMC_MSP_INIT_CB_ID
1950 * and HAL_MMC_MSP_DEINIT_CB_ID.
1951 * @param hmmc : MMC handle
1952 * @param CallbackId : ID of the callback to be unregistered
1953 * This parameter can be one of the following values:
1954 * @arg @ref HAL_MMC_TX_CPLT_CB_ID MMC Tx Complete Callback ID
1955 * @arg @ref HAL_MMC_RX_CPLT_CB_ID MMC Rx Complete Callback ID
1956 * @arg @ref HAL_MMC_ERROR_CB_ID MMC Error Callback ID
1957 * @arg @ref HAL_MMC_ABORT_CB_ID MMC Abort Callback ID
1958 * @arg @ref HAL_MMC_READ_DMA_LNKLST_BUF_CPLT_CB_ID MMC DMA Rx Linked List Node buffer Callback ID
1959 * @arg @ref HAL_MMC_WRITE_DMA_LNKLST_BUF_CPLT_CB_ID MMC DMA Tx Linked List Node buffer Callback ID
1960 * @arg @ref HAL_MMC_MSP_INIT_CB_ID MMC MspInit Callback ID
1961 * @arg @ref HAL_MMC_MSP_DEINIT_CB_ID MMC MspDeInit Callback ID
1962 * @retval status
1963 */
HAL_MMC_UnRegisterCallback(MMC_HandleTypeDef * hmmc,HAL_MMC_CallbackIDTypeDef CallbackId)1964 HAL_StatusTypeDef HAL_MMC_UnRegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId)
1965 {
1966 HAL_StatusTypeDef status = HAL_OK;
1967
1968 if (hmmc->State == HAL_MMC_STATE_READY)
1969 {
1970 switch (CallbackId)
1971 {
1972 case HAL_MMC_TX_CPLT_CB_ID :
1973 hmmc->TxCpltCallback = HAL_MMC_TxCpltCallback;
1974 break;
1975 case HAL_MMC_RX_CPLT_CB_ID :
1976 hmmc->RxCpltCallback = HAL_MMC_RxCpltCallback;
1977 break;
1978 case HAL_MMC_ERROR_CB_ID :
1979 hmmc->ErrorCallback = HAL_MMC_ErrorCallback;
1980 break;
1981 case HAL_MMC_ABORT_CB_ID :
1982 hmmc->AbortCpltCallback = HAL_MMC_AbortCallback;
1983 break;
1984 case HAL_MMC_READ_DMA_LNKLST_BUF_CPLT_CB_ID :
1985 hmmc->Read_DMALnkLstBufCpltCallback = HAL_MMCEx_Read_DMALnkLstBufCpltCallback;
1986 break;
1987 case HAL_MMC_WRITE_DMA_LNKLST_BUF_CPLT_CB_ID :
1988 hmmc->Write_DMALnkLstBufCpltCallback = HAL_MMCEx_Write_DMALnkLstBufCpltCallback;
1989 break;
1990 case HAL_MMC_MSP_INIT_CB_ID :
1991 hmmc->MspInitCallback = HAL_MMC_MspInit;
1992 break;
1993 case HAL_MMC_MSP_DEINIT_CB_ID :
1994 hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
1995 break;
1996 default :
1997 /* Update the error code */
1998 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1999 /* update return status */
2000 status = HAL_ERROR;
2001 break;
2002 }
2003 }
2004 else if (hmmc->State == HAL_MMC_STATE_RESET)
2005 {
2006 switch (CallbackId)
2007 {
2008 case HAL_MMC_MSP_INIT_CB_ID :
2009 hmmc->MspInitCallback = HAL_MMC_MspInit;
2010 break;
2011 case HAL_MMC_MSP_DEINIT_CB_ID :
2012 hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
2013 break;
2014 default :
2015 /* Update the error code */
2016 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
2017 /* update return status */
2018 status = HAL_ERROR;
2019 break;
2020 }
2021 }
2022 else
2023 {
2024 /* Update the error code */
2025 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
2026 /* update return status */
2027 status = HAL_ERROR;
2028 }
2029
2030 return status;
2031 }
2032 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
2033
2034 /**
2035 * @}
2036 */
2037
2038 /** @addtogroup MMC_Exported_Functions_Group3
2039 * @brief management functions
2040 *
2041 @verbatim
2042 ==============================================================================
2043 ##### Peripheral Control functions #####
2044 ==============================================================================
2045 [..]
2046 This subsection provides a set of functions allowing to control the MMC card
2047 operations and get the related information
2048
2049 @endverbatim
2050 * @{
2051 */
2052
2053 /**
2054 * @brief Returns information the information of the card which are stored on
2055 * the CID register.
2056 * @param hmmc: Pointer to MMC handle
2057 * @param pCID: Pointer to a HAL_MMC_CIDTypedef structure that
2058 * contains all CID register parameters
2059 * @retval HAL status
2060 */
HAL_MMC_GetCardCID(MMC_HandleTypeDef * hmmc,HAL_MMC_CardCIDTypeDef * pCID)2061 HAL_StatusTypeDef HAL_MMC_GetCardCID(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCIDTypeDef *pCID)
2062 {
2063 pCID->ManufacturerID = (uint8_t)((hmmc->CID[0] & 0xFF000000U) >> 24U);
2064
2065 pCID->OEM_AppliID = (uint16_t)((hmmc->CID[0] & 0x00FFFF00U) >> 8U);
2066
2067 pCID->ProdName1 = (((hmmc->CID[0] & 0x000000FFU) << 24U) | ((hmmc->CID[1] & 0xFFFFFF00U) >> 8U));
2068
2069 pCID->ProdName2 = (uint8_t)(hmmc->CID[1] & 0x000000FFU);
2070
2071 pCID->ProdRev = (uint8_t)((hmmc->CID[2] & 0xFF000000U) >> 24U);
2072
2073 pCID->ProdSN = (((hmmc->CID[2] & 0x00FFFFFFU) << 8U) | ((hmmc->CID[3] & 0xFF000000U) >> 24U));
2074
2075 pCID->Reserved1 = (uint8_t)((hmmc->CID[3] & 0x00F00000U) >> 20U);
2076
2077 pCID->ManufactDate = (uint16_t)((hmmc->CID[3] & 0x000FFF00U) >> 8U);
2078
2079 pCID->CID_CRC = (uint8_t)((hmmc->CID[3] & 0x000000FEU) >> 1U);
2080
2081 pCID->Reserved2 = 1U;
2082
2083 return HAL_OK;
2084 }
2085
2086 /**
2087 * @brief Returns information the information of the card which are stored on
2088 * the CSD register.
2089 * @param hmmc: Pointer to MMC handle
2090 * @param pCSD: Pointer to a HAL_MMC_CardCSDTypeDef structure that
2091 * contains all CSD register parameters
2092 * @retval HAL status
2093 */
HAL_MMC_GetCardCSD(MMC_HandleTypeDef * hmmc,HAL_MMC_CardCSDTypeDef * pCSD)2094 HAL_StatusTypeDef HAL_MMC_GetCardCSD(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCSDTypeDef *pCSD)
2095 {
2096 uint32_t block_nbr = 0;
2097
2098 pCSD->CSDStruct = (uint8_t)((hmmc->CSD[0] & 0xC0000000U) >> 30U);
2099
2100 pCSD->SysSpecVersion = (uint8_t)((hmmc->CSD[0] & 0x3C000000U) >> 26U);
2101
2102 pCSD->Reserved1 = (uint8_t)((hmmc->CSD[0] & 0x03000000U) >> 24U);
2103
2104 pCSD->TAAC = (uint8_t)((hmmc->CSD[0] & 0x00FF0000U) >> 16U);
2105
2106 pCSD->NSAC = (uint8_t)((hmmc->CSD[0] & 0x0000FF00U) >> 8U);
2107
2108 pCSD->MaxBusClkFrec = (uint8_t)(hmmc->CSD[0] & 0x000000FFU);
2109
2110 pCSD->CardComdClasses = (uint16_t)((hmmc->CSD[1] & 0xFFF00000U) >> 20U);
2111
2112 pCSD->RdBlockLen = (uint8_t)((hmmc->CSD[1] & 0x000F0000U) >> 16U);
2113
2114 pCSD->PartBlockRead = (uint8_t)((hmmc->CSD[1] & 0x00008000U) >> 15U);
2115
2116 pCSD->WrBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00004000U) >> 14U);
2117
2118 pCSD->RdBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00002000U) >> 13U);
2119
2120 pCSD->DSRImpl = (uint8_t)((hmmc->CSD[1] & 0x00001000U) >> 12U);
2121
2122 pCSD->Reserved2 = 0U; /*!< Reserved */
2123
2124 if (MMC_ReadExtCSD(hmmc, &block_nbr, 212, 0x0FFFFFFFU) != HAL_OK) /* Field SEC_COUNT [215:212] */
2125 {
2126 return HAL_ERROR;
2127 }
2128
2129 if (hmmc->MmcCard.CardType == MMC_LOW_CAPACITY_CARD)
2130 {
2131 pCSD->DeviceSize = (((hmmc->CSD[1] & 0x000003FFU) << 2U) | ((hmmc->CSD[2] & 0xC0000000U) >> 30U));
2132
2133 pCSD->MaxRdCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x38000000U) >> 27U);
2134
2135 pCSD->MaxRdCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x07000000U) >> 24U);
2136
2137 pCSD->MaxWrCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x00E00000U) >> 21U);
2138
2139 pCSD->MaxWrCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x001C0000U) >> 18U);
2140
2141 pCSD->DeviceSizeMul = (uint8_t)((hmmc->CSD[2] & 0x00038000U) >> 15U);
2142
2143 hmmc->MmcCard.BlockNbr = (pCSD->DeviceSize + 1U) ;
2144 hmmc->MmcCard.BlockNbr *= (1UL << ((pCSD->DeviceSizeMul & 0x07U) + 2U));
2145 hmmc->MmcCard.BlockSize = (1UL << (pCSD->RdBlockLen & 0x0FU));
2146
2147 hmmc->MmcCard.LogBlockNbr = (hmmc->MmcCard.BlockNbr) * ((hmmc->MmcCard.BlockSize) / MMC_BLOCKSIZE);
2148 hmmc->MmcCard.LogBlockSize = MMC_BLOCKSIZE;
2149 }
2150 else if (hmmc->MmcCard.CardType == MMC_HIGH_CAPACITY_CARD)
2151 {
2152 hmmc->MmcCard.BlockNbr = block_nbr;
2153 hmmc->MmcCard.LogBlockNbr = hmmc->MmcCard.BlockNbr;
2154 hmmc->MmcCard.BlockSize = MMC_BLOCKSIZE;
2155 hmmc->MmcCard.LogBlockSize = hmmc->MmcCard.BlockSize;
2156 }
2157 else
2158 {
2159 /* Clear all the static flags */
2160 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2161 hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2162 hmmc->State = HAL_MMC_STATE_READY;
2163 return HAL_ERROR;
2164 }
2165
2166 pCSD->EraseGrSize = (uint8_t)((hmmc->CSD[2] & 0x00004000U) >> 14U);
2167
2168 pCSD->EraseGrMul = (uint8_t)((hmmc->CSD[2] & 0x00003F80U) >> 7U);
2169
2170 pCSD->WrProtectGrSize = (uint8_t)(hmmc->CSD[2] & 0x0000007FU);
2171
2172 pCSD->WrProtectGrEnable = (uint8_t)((hmmc->CSD[3] & 0x80000000U) >> 31U);
2173
2174 pCSD->ManDeflECC = (uint8_t)((hmmc->CSD[3] & 0x60000000U) >> 29U);
2175
2176 pCSD->WrSpeedFact = (uint8_t)((hmmc->CSD[3] & 0x1C000000U) >> 26U);
2177
2178 pCSD->MaxWrBlockLen = (uint8_t)((hmmc->CSD[3] & 0x03C00000U) >> 22U);
2179
2180 pCSD->WriteBlockPaPartial = (uint8_t)((hmmc->CSD[3] & 0x00200000U) >> 21U);
2181
2182 pCSD->Reserved3 = 0;
2183
2184 pCSD->ContentProtectAppli = (uint8_t)((hmmc->CSD[3] & 0x00010000U) >> 16U);
2185
2186 pCSD->FileFormatGroup = (uint8_t)((hmmc->CSD[3] & 0x00008000U) >> 15U);
2187
2188 pCSD->CopyFlag = (uint8_t)((hmmc->CSD[3] & 0x00004000U) >> 14U);
2189
2190 pCSD->PermWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00002000U) >> 13U);
2191
2192 pCSD->TempWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00001000U) >> 12U);
2193
2194 pCSD->FileFormat = (uint8_t)((hmmc->CSD[3] & 0x00000C00U) >> 10U);
2195
2196 pCSD->ECC = (uint8_t)((hmmc->CSD[3] & 0x00000300U) >> 8U);
2197
2198 pCSD->CSD_CRC = (uint8_t)((hmmc->CSD[3] & 0x000000FEU) >> 1U);
2199
2200 pCSD->Reserved4 = 1;
2201
2202 return HAL_OK;
2203 }
2204
2205 /**
2206 * @brief Gets the MMC card info.
2207 * @param hmmc: Pointer to MMC handle
2208 * @param pCardInfo: Pointer to the HAL_MMC_CardInfoTypeDef structure that
2209 * will contain the MMC card status information
2210 * @retval HAL status
2211 */
HAL_MMC_GetCardInfo(MMC_HandleTypeDef * hmmc,HAL_MMC_CardInfoTypeDef * pCardInfo)2212 HAL_StatusTypeDef HAL_MMC_GetCardInfo(MMC_HandleTypeDef *hmmc, HAL_MMC_CardInfoTypeDef *pCardInfo)
2213 {
2214 pCardInfo->CardType = (uint32_t)(hmmc->MmcCard.CardType);
2215 pCardInfo->Class = (uint32_t)(hmmc->MmcCard.Class);
2216 pCardInfo->RelCardAdd = (uint32_t)(hmmc->MmcCard.RelCardAdd);
2217 pCardInfo->BlockNbr = (uint32_t)(hmmc->MmcCard.BlockNbr);
2218 pCardInfo->BlockSize = (uint32_t)(hmmc->MmcCard.BlockSize);
2219 pCardInfo->LogBlockNbr = (uint32_t)(hmmc->MmcCard.LogBlockNbr);
2220 pCardInfo->LogBlockSize = (uint32_t)(hmmc->MmcCard.LogBlockSize);
2221
2222 return HAL_OK;
2223 }
2224
2225 /**
2226 * @brief Returns information the information of the card which are stored on
2227 * the Extended CSD register.
2228 * @param hmmc Pointer to MMC handle
2229 * @param pExtCSD Pointer to a memory area (512 bytes) that contains all
2230 * Extended CSD register parameters
2231 * @param Timeout Specify timeout value
2232 * @retval HAL status
2233 */
HAL_MMC_GetCardExtCSD(MMC_HandleTypeDef * hmmc,uint32_t * pExtCSD,uint32_t Timeout)2234 HAL_StatusTypeDef HAL_MMC_GetCardExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pExtCSD, uint32_t Timeout)
2235 {
2236 SDMMC_DataInitTypeDef config;
2237 uint32_t errorstate;
2238 uint32_t tickstart = HAL_GetTick();
2239 uint32_t count;
2240 uint32_t *tmp_buf;
2241
2242 if (NULL == pExtCSD)
2243 {
2244 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
2245 return HAL_ERROR;
2246 }
2247
2248 if (hmmc->State == HAL_MMC_STATE_READY)
2249 {
2250 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
2251
2252 hmmc->State = HAL_MMC_STATE_BUSY;
2253
2254 /* Initialize data control register */
2255 hmmc->Instance->DCTRL = 0;
2256
2257 /* Initiaize the destination pointer */
2258 tmp_buf = pExtCSD;
2259
2260 /* Configure the MMC DPSM (Data Path State Machine) */
2261 config.DataTimeOut = SDMMC_DATATIMEOUT;
2262 config.DataLength = MMC_BLOCKSIZE;
2263 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
2264 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
2265 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
2266 config.DPSM = SDMMC_DPSM_DISABLE;
2267 (void)SDMMC_ConfigData(hmmc->Instance, &config);
2268 __SDMMC_CMDTRANS_ENABLE(hmmc->Instance);
2269
2270 /* Send ExtCSD Read command to Card */
2271 errorstate = SDMMC_CmdSendEXTCSD(hmmc->Instance, 0);
2272 if (errorstate != HAL_MMC_ERROR_NONE)
2273 {
2274 /* Clear all the static flags */
2275 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2276 hmmc->ErrorCode |= errorstate;
2277 hmmc->State = HAL_MMC_STATE_READY;
2278 return HAL_ERROR;
2279 }
2280
2281 /* Poll on SDMMC flags */
2282 while (!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR |
2283 SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
2284 {
2285 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF))
2286 {
2287 /* Read data from SDMMC Rx FIFO */
2288 for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
2289 {
2290 *tmp_buf = SDMMC_ReadFIFO(hmmc->Instance);
2291 tmp_buf++;
2292 }
2293 }
2294
2295 if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
2296 {
2297 /* Clear all the static flags */
2298 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2299 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
2300 hmmc->State = HAL_MMC_STATE_READY;
2301 return HAL_TIMEOUT;
2302 }
2303 }
2304
2305 __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
2306
2307 /* Get error state */
2308 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
2309 {
2310 /* Clear all the static flags */
2311 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2312 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
2313 hmmc->State = HAL_MMC_STATE_READY;
2314 return HAL_ERROR;
2315 }
2316 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
2317 {
2318 /* Clear all the static flags */
2319 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2320 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
2321 hmmc->State = HAL_MMC_STATE_READY;
2322 return HAL_ERROR;
2323 }
2324 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR))
2325 {
2326 /* Clear all the static flags */
2327 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2328 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
2329 hmmc->State = HAL_MMC_STATE_READY;
2330 return HAL_ERROR;
2331 }
2332 else
2333 {
2334 /* Nothing to do */
2335 }
2336
2337 /* Clear all the static flags */
2338 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2339 hmmc->State = HAL_MMC_STATE_READY;
2340 }
2341
2342 return HAL_OK;
2343 }
2344
2345 /**
2346 * @brief Enables wide bus operation for the requested card if supported by
2347 * card.
2348 * @param hmmc: Pointer to MMC handle
2349 * @param WideMode: Specifies the MMC card wide bus mode
2350 * This parameter can be one of the following values:
2351 * @arg SDMMC_BUS_WIDE_8B: 8-bit data transfer
2352 * @arg SDMMC_BUS_WIDE_4B: 4-bit data transfer
2353 * @arg SDMMC_BUS_WIDE_1B: 1-bit data transfer
2354 * @retval HAL status
2355 */
HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef * hmmc,uint32_t WideMode)2356 HAL_StatusTypeDef HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef *hmmc, uint32_t WideMode)
2357 {
2358 uint32_t count;
2359 SDMMC_InitTypeDef Init;
2360 uint32_t errorstate;
2361 uint32_t response = 0U;
2362
2363 /* Check the parameters */
2364 assert_param(IS_SDMMC_BUS_WIDE(WideMode));
2365
2366 /* Change State */
2367 hmmc->State = HAL_MMC_STATE_BUSY;
2368
2369 /* Check and update the power class if needed */
2370 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) != 0U)
2371 {
2372 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) != 0U)
2373 {
2374 errorstate = MMC_PwrClassUpdate(hmmc, WideMode, SDMMC_SPEED_MODE_DDR);
2375 }
2376 else
2377 {
2378 errorstate = MMC_PwrClassUpdate(hmmc, WideMode, SDMMC_SPEED_MODE_HIGH);
2379 }
2380 }
2381 else
2382 {
2383 errorstate = MMC_PwrClassUpdate(hmmc, WideMode, SDMMC_SPEED_MODE_DEFAULT);
2384 }
2385
2386 if (errorstate == HAL_MMC_ERROR_NONE)
2387 {
2388 if (WideMode == SDMMC_BUS_WIDE_8B)
2389 {
2390 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U);
2391 }
2392 else if (WideMode == SDMMC_BUS_WIDE_4B)
2393 {
2394 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U);
2395 }
2396 else if (WideMode == SDMMC_BUS_WIDE_1B)
2397 {
2398 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70000U);
2399 }
2400 else
2401 {
2402 /* WideMode is not a valid argument*/
2403 errorstate = HAL_MMC_ERROR_PARAM;
2404 }
2405
2406 /* Check for switch error and violation of the trial number of sending CMD 13 */
2407 if (errorstate == HAL_MMC_ERROR_NONE)
2408 {
2409 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2410 count = SDMMC_MAX_TRIAL;
2411 do
2412 {
2413 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2414 if (errorstate != HAL_MMC_ERROR_NONE)
2415 {
2416 break;
2417 }
2418
2419 /* Get command response */
2420 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
2421 count--;
2422 } while (((response & 0x100U) == 0U) && (count != 0U));
2423
2424 /* Check the status after the switch command execution */
2425 if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
2426 {
2427 /* Check the bit SWITCH_ERROR of the device status */
2428 if ((response & 0x80U) != 0U)
2429 {
2430 errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
2431 }
2432 else
2433 {
2434 /* Configure the SDMMC peripheral */
2435 Init = hmmc->Init;
2436 Init.BusWide = WideMode;
2437 (void)SDMMC_Init(hmmc->Instance, Init);
2438 }
2439 }
2440 else if (count == 0U)
2441 {
2442 errorstate = SDMMC_ERROR_TIMEOUT;
2443 }
2444 else
2445 {
2446 /* Nothing to do */
2447 }
2448 }
2449 }
2450
2451 /* Change State */
2452 hmmc->State = HAL_MMC_STATE_READY;
2453
2454 if (errorstate != HAL_MMC_ERROR_NONE)
2455 {
2456 /* Clear all the static flags */
2457 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2458 hmmc->ErrorCode |= errorstate;
2459 return HAL_ERROR;
2460 }
2461
2462 return HAL_OK;
2463 }
2464
2465 /**
2466 * @brief Configure the speed bus mode
2467 * @param hmmc: Pointer to the MMC handle
2468 * @param SpeedMode: Specifies the MMC card speed bus mode
2469 * This parameter can be one of the following values:
2470 * @arg SDMMC_SPEED_MODE_AUTO: Max speed mode supported by the card
2471 * @arg SDMMC_SPEED_MODE_DEFAULT: Default Speed (MMC @ 26MHz)
2472 * @arg SDMMC_SPEED_MODE_HIGH: High Speed (MMC @ 52 MHz)
2473 * @arg SDMMC_SPEED_MODE_DDR: High Speed DDR (MMC DDR @ 52 MHz)
2474 * @retval HAL status
2475 */
2476
HAL_MMC_ConfigSpeedBusOperation(MMC_HandleTypeDef * hmmc,uint32_t SpeedMode)2477 HAL_StatusTypeDef HAL_MMC_ConfigSpeedBusOperation(MMC_HandleTypeDef *hmmc, uint32_t SpeedMode)
2478 {
2479 uint32_t tickstart;
2480 HAL_StatusTypeDef status = HAL_OK;
2481 uint32_t device_type;
2482 uint32_t errorstate;
2483
2484 /* Check the parameters */
2485 assert_param(IS_SDMMC_SPEED_MODE(SpeedMode));
2486
2487 /* Change State */
2488 hmmc->State = HAL_MMC_STATE_BUSY;
2489
2490 /* Field DEVICE_TYPE [196 = 49*4] of Extended CSD register */
2491 device_type = (hmmc->Ext_CSD[49] & 0x000000FFU);
2492
2493 switch (SpeedMode)
2494 {
2495 case SDMMC_SPEED_MODE_AUTO:
2496 {
2497 if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS) != 0U) && ((device_type & 0x04U) != 0U))
2498 {
2499 /* High Speed DDR mode allowed */
2500 errorstate = MMC_HighSpeed(hmmc, ENABLE);
2501 if (errorstate != HAL_MMC_ERROR_NONE)
2502 {
2503 hmmc->ErrorCode |= errorstate;
2504 }
2505 else
2506 {
2507 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_CLKDIV) != 0U)
2508 {
2509 /* DDR mode not supported with CLKDIV = 0 */
2510 errorstate = MMC_DDR_Mode(hmmc, ENABLE);
2511 if (errorstate != HAL_MMC_ERROR_NONE)
2512 {
2513 hmmc->ErrorCode |= errorstate;
2514 }
2515 }
2516 }
2517 }
2518 else if ((device_type & 0x02U) != 0U)
2519 {
2520 /* High Speed mode allowed */
2521 errorstate = MMC_HighSpeed(hmmc, ENABLE);
2522 if (errorstate != HAL_MMC_ERROR_NONE)
2523 {
2524 hmmc->ErrorCode |= errorstate;
2525 }
2526 }
2527 else
2528 {
2529 /* Nothing to do : keep current speed */
2530 }
2531 break;
2532 }
2533 case SDMMC_SPEED_MODE_DDR:
2534 {
2535 if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS) != 0U) && ((device_type & 0x04U) != 0U))
2536 {
2537 /* High Speed DDR mode allowed */
2538 errorstate = MMC_HighSpeed(hmmc, ENABLE);
2539 if (errorstate != HAL_MMC_ERROR_NONE)
2540 {
2541 hmmc->ErrorCode |= errorstate;
2542 }
2543 else
2544 {
2545 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_CLKDIV) != 0U)
2546 {
2547 /* DDR mode not supported with CLKDIV = 0 */
2548 errorstate = MMC_DDR_Mode(hmmc, ENABLE);
2549 if (errorstate != HAL_MMC_ERROR_NONE)
2550 {
2551 hmmc->ErrorCode |= errorstate;
2552 }
2553 }
2554 }
2555 }
2556 else
2557 {
2558 /* High Speed DDR mode not allowed */
2559 hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2560 status = HAL_ERROR;
2561 }
2562 break;
2563 }
2564 case SDMMC_SPEED_MODE_HIGH:
2565 {
2566 if ((device_type & 0x02U) != 0U)
2567 {
2568 /* High Speed mode allowed */
2569 errorstate = MMC_HighSpeed(hmmc, ENABLE);
2570 if (errorstate != HAL_MMC_ERROR_NONE)
2571 {
2572 hmmc->ErrorCode |= errorstate;
2573 }
2574 }
2575 else
2576 {
2577 /* High Speed mode not allowed */
2578 hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2579 status = HAL_ERROR;
2580 }
2581 break;
2582 }
2583 case SDMMC_SPEED_MODE_DEFAULT:
2584 {
2585 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) != 0U)
2586 {
2587 /* High Speed DDR mode activated */
2588 errorstate = MMC_DDR_Mode(hmmc, DISABLE);
2589 if (errorstate != HAL_MMC_ERROR_NONE)
2590 {
2591 hmmc->ErrorCode |= errorstate;
2592 }
2593 }
2594 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) != 0U)
2595 {
2596 /* High Speed mode activated */
2597 errorstate = MMC_HighSpeed(hmmc, DISABLE);
2598 if (errorstate != HAL_MMC_ERROR_NONE)
2599 {
2600 hmmc->ErrorCode |= errorstate;
2601 }
2602 }
2603 break;
2604 }
2605 default:
2606 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
2607 status = HAL_ERROR;
2608 break;
2609 }
2610
2611 /* Verify that MMC card is ready to use after Speed mode switch*/
2612 tickstart = HAL_GetTick();
2613 while ((HAL_MMC_GetCardState(hmmc) != HAL_MMC_CARD_TRANSFER))
2614 {
2615 if ((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT)
2616 {
2617 hmmc->ErrorCode = HAL_MMC_ERROR_TIMEOUT;
2618 hmmc->State = HAL_MMC_STATE_READY;
2619 return HAL_TIMEOUT;
2620 }
2621 }
2622
2623 /* Change State */
2624 hmmc->State = HAL_MMC_STATE_READY;
2625 return status;
2626 }
2627
2628 /**
2629 * @brief Gets the current mmc card data state.
2630 * @param hmmc: pointer to MMC handle
2631 * @retval Card state
2632 */
HAL_MMC_GetCardState(MMC_HandleTypeDef * hmmc)2633 HAL_MMC_CardStateTypeDef HAL_MMC_GetCardState(MMC_HandleTypeDef *hmmc)
2634 {
2635 uint32_t cardstate;
2636 uint32_t errorstate;
2637 uint32_t resp1 = 0U;
2638
2639 errorstate = MMC_SendStatus(hmmc, &resp1);
2640 if (errorstate != HAL_MMC_ERROR_NONE)
2641 {
2642 hmmc->ErrorCode |= errorstate;
2643 }
2644
2645 cardstate = ((resp1 >> 9U) & 0x0FU);
2646
2647 return (HAL_MMC_CardStateTypeDef)cardstate;
2648 }
2649
2650 /**
2651 * @brief Abort the current transfer and disable the MMC.
2652 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2653 * the configuration information for MMC module.
2654 * @retval HAL status
2655 */
HAL_MMC_Abort(MMC_HandleTypeDef * hmmc)2656 HAL_StatusTypeDef HAL_MMC_Abort(MMC_HandleTypeDef *hmmc)
2657 {
2658 uint32_t error_code;
2659 uint32_t tickstart;
2660
2661 if (hmmc->State == HAL_MMC_STATE_BUSY)
2662 {
2663 /* DIsable All interrupts */
2664 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | \
2665 SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR);
2666 __SDMMC_CMDTRANS_DISABLE(hmmc->Instance);
2667
2668 /*we will send the CMD12 in all cases in order to stop the data transfers*/
2669 /*In case the data transfer just finished, the external memory will not respond
2670 and will return HAL_MMC_ERROR_CMD_RSP_TIMEOUT*/
2671 /*In case the data transfer aborted , the external memory will respond and will return HAL_MMC_ERROR_NONE*/
2672 /*Other scenario will return HAL_ERROR*/
2673
2674 hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
2675 error_code = hmmc->ErrorCode;
2676 if ((error_code != HAL_MMC_ERROR_NONE) && (error_code != HAL_MMC_ERROR_CMD_RSP_TIMEOUT))
2677 {
2678 return HAL_ERROR;
2679 }
2680
2681 tickstart = HAL_GetTick();
2682 if ((hmmc->Instance->DCTRL & SDMMC_DCTRL_DTDIR) == SDMMC_TRANSFER_DIR_TO_CARD)
2683 {
2684 if (hmmc->ErrorCode == HAL_MMC_ERROR_NONE)
2685 {
2686 while (!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DABORT | SDMMC_FLAG_BUSYD0END))
2687 {
2688 if ((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT)
2689 {
2690 hmmc->ErrorCode = HAL_MMC_ERROR_TIMEOUT;
2691 hmmc->State = HAL_MMC_STATE_READY;
2692 return HAL_TIMEOUT;
2693 }
2694 }
2695 }
2696
2697 if (hmmc->ErrorCode == HAL_MMC_ERROR_CMD_RSP_TIMEOUT)
2698 {
2699 while (!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND))
2700 {
2701 if ((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT)
2702 {
2703 hmmc->ErrorCode = HAL_MMC_ERROR_TIMEOUT;
2704 hmmc->State = HAL_MMC_STATE_READY;
2705 return HAL_TIMEOUT;
2706 }
2707 }
2708 }
2709 }
2710 else if ((hmmc->Instance->DCTRL & SDMMC_DCTRL_DTDIR) == SDMMC_TRANSFER_DIR_TO_SDMMC)
2711 {
2712 while (!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DABORT | SDMMC_FLAG_DATAEND))
2713 {
2714 if ((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT)
2715 {
2716 hmmc->ErrorCode = HAL_MMC_ERROR_TIMEOUT;
2717 hmmc->State = HAL_MMC_STATE_READY;
2718 return HAL_TIMEOUT;
2719 }
2720 }
2721 }
2722 else
2723 {
2724 /* Nothing to do*/
2725 }
2726
2727 /*The reason of all these while conditions previously is that we need to wait the SDMMC and clear
2728 the appropriate flags that will be set depending of the abort/non abort of the memory */
2729 /*Not waiting the SDMMC flags will cause the next SDMMC_DISABLE_IDMA to not get cleared and will result
2730 in next SDMMC read/write operation to fail */
2731
2732 /*SDMMC ready for clear data flags*/
2733 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
2734 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2735 /* If IDMA Context, disable Internal DMA */
2736 hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA;
2737
2738 hmmc->State = HAL_MMC_STATE_READY;
2739
2740 /* Initialize the MMC operation */
2741 hmmc->Context = MMC_CONTEXT_NONE;
2742 }
2743 return HAL_OK;
2744 }
2745 /**
2746 * @brief Abort the current transfer and disable the MMC (IT mode).
2747 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2748 * the configuration information for MMC module.
2749 * @retval HAL status
2750 */
HAL_MMC_Abort_IT(MMC_HandleTypeDef * hmmc)2751 HAL_StatusTypeDef HAL_MMC_Abort_IT(MMC_HandleTypeDef *hmmc)
2752 {
2753 HAL_MMC_CardStateTypeDef CardState;
2754
2755 /* DIsable All interrupts */
2756 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | \
2757 SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR);
2758
2759 /* If IDMA Context, disable Internal DMA */
2760 hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA;
2761
2762 /* Clear All flags */
2763 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2764
2765 CardState = HAL_MMC_GetCardState(hmmc);
2766 hmmc->State = HAL_MMC_STATE_READY;
2767
2768 if ((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2769 {
2770 hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
2771 }
2772 if (hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2773 {
2774 return HAL_ERROR;
2775 }
2776 else
2777 {
2778 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2779 hmmc->AbortCpltCallback(hmmc);
2780 #else
2781 HAL_MMC_AbortCallback(hmmc);
2782 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
2783 }
2784
2785 return HAL_OK;
2786 }
2787
2788 /**
2789 * @brief Perform specific commands sequence for the different type of erase.
2790 * @note This API should be followed by a check on the card state through
2791 * HAL_MMC_GetCardState().
2792 * @param hmmc Pointer to MMC handle
2793 * @param EraseType Specifies the type of erase to be performed
2794 * This parameter can be one of the following values:
2795 * @arg HAL_MMC_TRIM Erase the write blocks identified by CMD35 & 36
2796 * @arg HAL_MMC_ERASE Erase the erase groups identified by CMD35 & 36
2797 * @arg HAL_MMC_DISCARD Discard the write blocks identified by CMD35 & 36
2798 * @arg HAL_MMC_SECURE_ERASE Perform a secure purge according SRT on the erase groups identified
2799 * by CMD35 & 36
2800 * @arg HAL_MMC_SECURE_TRIM_STEP1 Mark the write blocks identified by CMD35 & 36 for secure erase
2801 * @arg HAL_MMC_SECURE_TRIM_STEP2 Perform a secure purge according SRT on the write blocks
2802 * previously identified
2803 * @param BlockStartAdd Start Block address
2804 * @param BlockEndAdd End Block address
2805 * @retval HAL status
2806 */
HAL_MMC_EraseSequence(MMC_HandleTypeDef * hmmc,uint32_t EraseType,uint32_t BlockStartAdd,uint32_t BlockEndAdd)2807 HAL_StatusTypeDef HAL_MMC_EraseSequence(MMC_HandleTypeDef *hmmc, uint32_t EraseType,
2808 uint32_t BlockStartAdd, uint32_t BlockEndAdd)
2809 {
2810 uint32_t errorstate;
2811 uint32_t start_add = BlockStartAdd;
2812 uint32_t end_add = BlockEndAdd;
2813 uint32_t tickstart = HAL_GetTick();
2814
2815 /* Check the erase type value is correct */
2816 assert_param(IS_MMC_ERASE_TYPE(EraseType));
2817
2818 /* Check the coherence between start and end address */
2819 if (end_add < start_add)
2820 {
2821 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
2822 return HAL_ERROR;
2823 }
2824
2825 /* Check that the end address is not out of range of device memory */
2826 if (end_add > (hmmc->MmcCard.LogBlockNbr))
2827 {
2828 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
2829 return HAL_ERROR;
2830 }
2831
2832 /* Check the case of 4kB blocks (field DATA SECTOR SIZE of extended CSD register) */
2833 if (((hmmc->Ext_CSD[(MMC_EXT_CSD_DATA_SEC_SIZE_INDEX / 4)] >> MMC_EXT_CSD_DATA_SEC_SIZE_POS) & 0x000000FFU) != 0x0U)
2834 {
2835 if (((start_add % 8U) != 0U) || ((end_add % 8U) != 0U))
2836 {
2837 /* The address should be aligned to 8 (corresponding to 4 KBytes blocks) */
2838 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_MISALIGNED;
2839 return HAL_ERROR;
2840 }
2841 }
2842
2843 /* Check if the card command class supports erase command */
2844 if (((hmmc->MmcCard.Class) & SDMMC_CCCC_ERASE) == 0U)
2845 {
2846 hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
2847 return HAL_ERROR;
2848 }
2849
2850 /* Check the state of the driver */
2851 if (hmmc->State == HAL_MMC_STATE_READY)
2852 {
2853 /* Change State */
2854 hmmc->State = HAL_MMC_STATE_BUSY;
2855
2856 /* Check that the card is not locked */
2857 if ((SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
2858 {
2859 hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED;
2860 hmmc->State = HAL_MMC_STATE_READY;
2861 return HAL_ERROR;
2862 }
2863
2864 /* In case of low capacity card, the address is not block number but bytes */
2865 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
2866 {
2867 start_add *= MMC_BLOCKSIZE;
2868 end_add *= MMC_BLOCKSIZE;
2869 }
2870
2871 /* Send CMD35 MMC_ERASE_GRP_START with start address as argument */
2872 errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, start_add);
2873 if (errorstate == HAL_MMC_ERROR_NONE)
2874 {
2875 /* Send CMD36 MMC_ERASE_GRP_END with end address as argument */
2876 errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, end_add);
2877 if (errorstate == HAL_MMC_ERROR_NONE)
2878 {
2879 /* Send CMD38 ERASE with erase type as argument */
2880 errorstate = SDMMC_CmdErase(hmmc->Instance, EraseType);
2881 if (errorstate == HAL_MMC_ERROR_NONE)
2882 {
2883 if ((EraseType == HAL_MMC_SECURE_ERASE) || (EraseType == HAL_MMC_SECURE_TRIM_STEP2))
2884 {
2885 /* Wait that the device is ready by checking the D0 line */
2886 while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
2887 {
2888 if ((HAL_GetTick() - tickstart) >= SDMMC_MAXERASETIMEOUT)
2889 {
2890 errorstate = HAL_MMC_ERROR_TIMEOUT;
2891 }
2892 }
2893
2894 /* Clear the flag corresponding to end D0 bus line */
2895 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
2896 }
2897 }
2898 }
2899 }
2900
2901 /* Change State */
2902 hmmc->State = HAL_MMC_STATE_READY;
2903
2904 /* Manage errors */
2905 if (errorstate != HAL_MMC_ERROR_NONE)
2906 {
2907 /* Clear all the static flags */
2908 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2909 hmmc->ErrorCode |= errorstate;
2910
2911 if (errorstate != HAL_MMC_ERROR_TIMEOUT)
2912 {
2913 return HAL_ERROR;
2914 }
2915 else
2916 {
2917 return HAL_TIMEOUT;
2918 }
2919 }
2920 else
2921 {
2922 return HAL_OK;
2923 }
2924 }
2925 else
2926 {
2927 return HAL_BUSY;
2928 }
2929 }
2930
2931 /**
2932 * @brief Perform sanitize operation on the device.
2933 * @note This API should be followed by a check on the card state through
2934 * HAL_MMC_GetCardState().
2935 * @param hmmc Pointer to MMC handle
2936 * @retval HAL status
2937 */
HAL_MMC_Sanitize(MMC_HandleTypeDef * hmmc)2938 HAL_StatusTypeDef HAL_MMC_Sanitize(MMC_HandleTypeDef *hmmc)
2939 {
2940 uint32_t errorstate;
2941 uint32_t response = 0U;
2942 uint32_t count;
2943 uint32_t tickstart = HAL_GetTick();
2944
2945 /* Check the state of the driver */
2946 if (hmmc->State == HAL_MMC_STATE_READY)
2947 {
2948 /* Change State */
2949 hmmc->State = HAL_MMC_STATE_BUSY;
2950
2951 /* Index : 165 - Value : 0x01 */
2952 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03A50100U);
2953 if (errorstate == HAL_MMC_ERROR_NONE)
2954 {
2955 /* Wait that the device is ready by checking the D0 line */
2956 while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
2957 {
2958 if ((HAL_GetTick() - tickstart) >= SDMMC_MAXERASETIMEOUT)
2959 {
2960 errorstate = HAL_MMC_ERROR_TIMEOUT;
2961 }
2962 }
2963
2964 /* Clear the flag corresponding to end D0 bus line */
2965 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
2966
2967 if (errorstate == HAL_MMC_ERROR_NONE)
2968 {
2969 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2970 count = SDMMC_MAX_TRIAL;
2971 do
2972 {
2973 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2974 if (errorstate != HAL_MMC_ERROR_NONE)
2975 {
2976 break;
2977 }
2978
2979 /* Get command response */
2980 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
2981 count--;
2982 } while (((response & 0x100U) == 0U) && (count != 0U));
2983
2984 /* Check the status after the switch command execution */
2985 if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
2986 {
2987 /* Check the bit SWITCH_ERROR of the device status */
2988 if ((response & 0x80U) != 0U)
2989 {
2990 errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
2991 }
2992 }
2993 else if (count == 0U)
2994 {
2995 errorstate = SDMMC_ERROR_TIMEOUT;
2996 }
2997 else
2998 {
2999 /* Nothing to do */
3000 }
3001 }
3002 }
3003
3004 /* Change State */
3005 hmmc->State = HAL_MMC_STATE_READY;
3006
3007 /* Manage errors */
3008 if (errorstate != HAL_MMC_ERROR_NONE)
3009 {
3010 /* Clear all the static flags */
3011 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3012 hmmc->ErrorCode |= errorstate;
3013
3014 if (errorstate != HAL_MMC_ERROR_TIMEOUT)
3015 {
3016 return HAL_ERROR;
3017 }
3018 else
3019 {
3020 return HAL_TIMEOUT;
3021 }
3022 }
3023 else
3024 {
3025 return HAL_OK;
3026 }
3027 }
3028 else
3029 {
3030 return HAL_BUSY;
3031 }
3032 }
3033
3034 /**
3035 * @brief Configure the Secure Removal Type (SRT) in the Extended CSD register.
3036 * @note This API should be followed by a check on the card state through
3037 * HAL_MMC_GetCardState().
3038 * @param hmmc Pointer to MMC handle
3039 * @param SRTMode Specifies the type of erase to be performed
3040 * This parameter can be one of the following values:
3041 * @arg HAL_MMC_SRT_ERASE Information removed by an erase
3042 * @arg HAL_MMC_SRT_WRITE_CHAR_ERASE Information removed by an overwriting with a character
3043 * followed by an erase
3044 * @arg HAL_MMC_SRT_WRITE_CHAR_COMPL_RANDOM Information removed by an overwriting with a character,
3045 * its complement then a random character
3046 * @arg HAL_MMC_SRT_VENDOR_DEFINED Information removed using a vendor defined
3047 * @retval HAL status
3048 */
HAL_MMC_ConfigSecRemovalType(MMC_HandleTypeDef * hmmc,uint32_t SRTMode)3049 HAL_StatusTypeDef HAL_MMC_ConfigSecRemovalType(MMC_HandleTypeDef *hmmc, uint32_t SRTMode)
3050 {
3051 uint32_t srt;
3052 uint32_t errorstate;
3053 uint32_t response = 0U;
3054 uint32_t count;
3055
3056 /* Check the erase type value is correct */
3057 assert_param(IS_MMC_SRT_TYPE(SRTMode));
3058
3059 /* Check the state of the driver */
3060 if (hmmc->State == HAL_MMC_STATE_READY)
3061 {
3062 /* Get the supported values by the device */
3063 if (HAL_MMC_GetSupportedSecRemovalType(hmmc, &srt) == HAL_OK)
3064 {
3065 /* Change State */
3066 hmmc->State = HAL_MMC_STATE_BUSY;
3067
3068 /* Check the value passed as parameter is supported by the device */
3069 if ((SRTMode & srt) != 0U)
3070 {
3071 /* Index : 16 - Value : SRTMode */
3072 srt |= ((POSITION_VAL(SRTMode)) << 4U);
3073 errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03100000U | (srt << 8U)));
3074 if (errorstate == HAL_MMC_ERROR_NONE)
3075 {
3076 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3077 count = SDMMC_MAX_TRIAL;
3078 do
3079 {
3080 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3081 if (errorstate != HAL_MMC_ERROR_NONE)
3082 {
3083 break;
3084 }
3085
3086 /* Get command response */
3087 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3088 count--;
3089 } while (((response & 0x100U) == 0U) && (count != 0U));
3090
3091 /* Check the status after the switch command execution */
3092 if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
3093 {
3094 /* Check the bit SWITCH_ERROR of the device status */
3095 if ((response & 0x80U) != 0U)
3096 {
3097 errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
3098 }
3099 }
3100 else if (count == 0U)
3101 {
3102 errorstate = SDMMC_ERROR_TIMEOUT;
3103 }
3104 else
3105 {
3106 /* Nothing to do */
3107 }
3108 }
3109 }
3110 else
3111 {
3112 errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3113 }
3114
3115 /* Change State */
3116 hmmc->State = HAL_MMC_STATE_READY;
3117 }
3118 else
3119 {
3120 errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
3121 }
3122
3123 /* Manage errors */
3124 if (errorstate != HAL_MMC_ERROR_NONE)
3125 {
3126 /* Clear all the static flags */
3127 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3128 hmmc->ErrorCode |= errorstate;
3129 return HAL_ERROR;
3130 }
3131 else
3132 {
3133 return HAL_OK;
3134 }
3135 }
3136 else
3137 {
3138 return HAL_BUSY;
3139 }
3140 }
3141
3142 /**
3143 * @brief Gets the supported values of the the Secure Removal Type (SRT).
3144 * @param hmmc pointer to MMC handle
3145 * @param SupportedSRT pointer for supported SRT value
3146 * This parameter is a bit field of the following values:
3147 * @arg HAL_MMC_SRT_ERASE Information removed by an erase
3148 * @arg HAL_MMC_SRT_WRITE_CHAR_ERASE Information removed by an overwriting with a character followed
3149 * by an erase
3150 * @arg HAL_MMC_SRT_WRITE_CHAR_COMPL_RANDOM Information removed by an overwriting with a character,
3151 * its complement then a random character
3152 * @arg HAL_MMC_SRT_VENDOR_DEFINED Information removed using a vendor defined
3153 * @retval HAL status
3154 */
HAL_MMC_GetSupportedSecRemovalType(MMC_HandleTypeDef * hmmc,uint32_t * SupportedSRT)3155 HAL_StatusTypeDef HAL_MMC_GetSupportedSecRemovalType(MMC_HandleTypeDef *hmmc, uint32_t *SupportedSRT)
3156 {
3157 /* Check the state of the driver */
3158 if (hmmc->State == HAL_MMC_STATE_READY)
3159 {
3160 /* Change State */
3161 hmmc->State = HAL_MMC_STATE_BUSY;
3162
3163 /* Read field SECURE_REMOVAL_TYPE [16 = 4*4] of the Extended CSD register */
3164 *SupportedSRT = (hmmc->Ext_CSD[4] & 0x0000000FU); /* Bits [3:0] of field 16 */
3165
3166 /* Change State */
3167 hmmc->State = HAL_MMC_STATE_READY;
3168
3169 return HAL_OK;
3170 }
3171 else
3172 {
3173 return HAL_BUSY;
3174 }
3175 }
3176
3177 /**
3178 * @brief Switch the device from Standby State to Sleep State.
3179 * @param hmmc pointer to MMC handle
3180 * @retval HAL status
3181 */
HAL_MMC_SleepDevice(MMC_HandleTypeDef * hmmc)3182 HAL_StatusTypeDef HAL_MMC_SleepDevice(MMC_HandleTypeDef *hmmc)
3183 {
3184 uint32_t errorstate,
3185 sleep_timeout,
3186 timeout,
3187 count,
3188 response = 0U ;
3189 uint32_t tickstart = HAL_GetTick();
3190
3191 /* Check the state of the driver */
3192 if (hmmc->State == HAL_MMC_STATE_READY)
3193 {
3194 /* Change State */
3195 hmmc->State = HAL_MMC_STATE_BUSY;
3196
3197 /* Set the power-off notification to powered-on : Ext_CSD[34] = 1 */
3198 errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03220100U));
3199 if (errorstate == HAL_MMC_ERROR_NONE)
3200 {
3201 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3202 count = SDMMC_MAX_TRIAL;
3203 do
3204 {
3205 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3206 if (errorstate != HAL_MMC_ERROR_NONE)
3207 {
3208 break;
3209 }
3210
3211 /* Get command response */
3212 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3213 count--;
3214 } while (((response & 0x100U) == 0U) && (count != 0U));
3215
3216 /* Check the status after the switch command execution */
3217 if (count == 0U)
3218 {
3219 errorstate = SDMMC_ERROR_TIMEOUT;
3220 }
3221 else if (errorstate == HAL_MMC_ERROR_NONE)
3222 {
3223 /* Check the bit SWITCH_ERROR of the device status */
3224 if ((response & 0x80U) != 0U)
3225 {
3226 errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3227 }
3228 else
3229 {
3230 /* Set the power-off notification to sleep notification : Ext_CSD[34] = 4 */
3231 errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03220400U));
3232 if (errorstate == HAL_MMC_ERROR_NONE)
3233 {
3234 /* Field SLEEP_NOTIFICATION_TIME [216] */
3235 sleep_timeout = ((hmmc->Ext_CSD[(MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_INDEX / 4)] >>
3236 MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_POS) & 0x000000FFU);
3237
3238 /* Sleep/Awake Timeout = 10us * 2^SLEEP_NOTIFICATION_TIME */
3239 /* In HAL, the tick interrupt occurs each ms */
3240 if ((sleep_timeout == 0U) || (sleep_timeout > 0x17U))
3241 {
3242 sleep_timeout = 0x17U; /* Max register value defined is 0x17 */
3243 }
3244 timeout = (((1UL << sleep_timeout) / 100U) + 1U);
3245
3246 /* Wait that the device is ready by checking the D0 line */
3247 while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
3248 {
3249 if ((HAL_GetTick() - tickstart) >= timeout)
3250 {
3251 errorstate = SDMMC_ERROR_TIMEOUT;
3252 }
3253 }
3254
3255 /* Clear the flag corresponding to end D0 bus line */
3256 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
3257
3258 if (errorstate == HAL_MMC_ERROR_NONE)
3259 {
3260 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3261 count = SDMMC_MAX_TRIAL;
3262 do
3263 {
3264 errorstate = SDMMC_CmdSendStatus(hmmc->Instance,
3265 (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3266 if (errorstate != HAL_MMC_ERROR_NONE)
3267 {
3268 break;
3269 }
3270
3271 /* Get command response */
3272 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3273 count--;
3274 } while (((response & 0x100U) == 0U) && (count != 0U));
3275
3276 /* Check the status after the switch command execution */
3277 if (count == 0U)
3278 {
3279 errorstate = SDMMC_ERROR_TIMEOUT;
3280 }
3281 else if (errorstate == HAL_MMC_ERROR_NONE)
3282 {
3283 /* Check the bit SWITCH_ERROR of the device status */
3284 if ((response & 0x80U) != 0U)
3285 {
3286 errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3287 }
3288 else
3289 {
3290 /* Switch the device in stand-by mode */
3291 (void)SDMMC_CmdSelDesel(hmmc->Instance, 0U);
3292
3293 /* Field S_A_TIEMOUT [217] */
3294 sleep_timeout = ((hmmc->Ext_CSD[(MMC_EXT_CSD_S_A_TIMEOUT_INDEX / 4)] >>
3295 MMC_EXT_CSD_S_A_TIMEOUT_POS) & 0x000000FFU);
3296
3297 /* Sleep/Awake Timeout = 100ns * 2^S_A_TIMEOUT */
3298 /* In HAL, the tick interrupt occurs each ms */
3299 if ((sleep_timeout == 0U) || (sleep_timeout > 0x17U))
3300 {
3301 sleep_timeout = 0x17U; /* Max register value defined is 0x17 */
3302 }
3303 timeout = (((1UL << sleep_timeout) / 10000U) + 1U);
3304
3305 if (HAL_MMC_GetCardState(hmmc) == HAL_MMC_CARD_STANDBY)
3306 {
3307 /* Send CMD5 CMD_MMC_SLEEP_AWAKE with RCA and SLEEP as argument */
3308 errorstate = SDMMC_CmdSleepMmc(hmmc->Instance,
3309 ((hmmc->MmcCard.RelCardAdd << 16U) | (0x1U << 15U)));
3310 if (errorstate == HAL_MMC_ERROR_NONE)
3311 {
3312 /* Wait that the device is ready by checking the D0 line */
3313 while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
3314 {
3315 if ((HAL_GetTick() - tickstart) >= timeout)
3316 {
3317 errorstate = SDMMC_ERROR_TIMEOUT;
3318 }
3319 }
3320
3321 /* Clear the flag corresponding to end D0 bus line */
3322 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
3323 }
3324 }
3325 else
3326 {
3327 errorstate = SDMMC_ERROR_REQUEST_NOT_APPLICABLE;
3328 }
3329 }
3330 }
3331 else
3332 {
3333 /* Nothing to do */
3334 }
3335 }
3336 }
3337 }
3338 }
3339 else
3340 {
3341 /* Nothing to do */
3342 }
3343 }
3344
3345 /* Change State */
3346 hmmc->State = HAL_MMC_STATE_READY;
3347
3348 /* Manage errors */
3349 if (errorstate != HAL_MMC_ERROR_NONE)
3350 {
3351 /* Clear all the static flags */
3352 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3353 hmmc->ErrorCode |= errorstate;
3354
3355 if (errorstate != HAL_MMC_ERROR_TIMEOUT)
3356 {
3357 return HAL_ERROR;
3358 }
3359 else
3360 {
3361 return HAL_TIMEOUT;
3362 }
3363 }
3364 else
3365 {
3366 return HAL_OK;
3367 }
3368 }
3369 else
3370 {
3371 return HAL_BUSY;
3372 }
3373 }
3374
3375 /**
3376 * @brief Switch the device from Sleep State to Standby State.
3377 * @param hmmc pointer to MMC handle
3378 * @retval HAL status
3379 */
HAL_MMC_AwakeDevice(MMC_HandleTypeDef * hmmc)3380 HAL_StatusTypeDef HAL_MMC_AwakeDevice(MMC_HandleTypeDef *hmmc)
3381 {
3382 uint32_t errorstate;
3383 uint32_t sleep_timeout;
3384 uint32_t timeout;
3385 uint32_t count;
3386 uint32_t response = 0U;
3387 uint32_t tickstart = HAL_GetTick();
3388
3389 /* Check the state of the driver */
3390 if (hmmc->State == HAL_MMC_STATE_READY)
3391 {
3392 /* Change State */
3393 hmmc->State = HAL_MMC_STATE_BUSY;
3394
3395 /* Field S_A_TIEMOUT [217] */
3396 sleep_timeout = ((hmmc->Ext_CSD[(MMC_EXT_CSD_S_A_TIMEOUT_INDEX / 4)] >> MMC_EXT_CSD_S_A_TIMEOUT_POS) &
3397 0x000000FFU);
3398
3399 /* Sleep/Awake Timeout = 100ns * 2^S_A_TIMEOUT */
3400 /* In HAL, the tick interrupt occurs each ms */
3401 if ((sleep_timeout == 0U) || (sleep_timeout > 0x17U))
3402 {
3403 sleep_timeout = 0x17U; /* Max register value defined is 0x17 */
3404 }
3405 timeout = (((1UL << sleep_timeout) / 10000U) + 1U);
3406
3407 /* Send CMD5 CMD_MMC_SLEEP_AWAKE with RCA and AWAKE as argument */
3408 errorstate = SDMMC_CmdSleepMmc(hmmc->Instance, (hmmc->MmcCard.RelCardAdd << 16U));
3409 if (errorstate == HAL_MMC_ERROR_NONE)
3410 {
3411 /* Wait that the device is ready by checking the D0 line */
3412 while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
3413 {
3414 if ((HAL_GetTick() - tickstart) >= timeout)
3415 {
3416 errorstate = SDMMC_ERROR_TIMEOUT;
3417 }
3418 }
3419
3420 /* Clear the flag corresponding to end D0 bus line */
3421 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
3422
3423 if (errorstate == HAL_MMC_ERROR_NONE)
3424 {
3425 if (HAL_MMC_GetCardState(hmmc) == HAL_MMC_CARD_STANDBY)
3426 {
3427 /* Switch the device in transfer mode */
3428 errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (hmmc->MmcCard.RelCardAdd << 16U));
3429 if (errorstate == HAL_MMC_ERROR_NONE)
3430 {
3431 if (HAL_MMC_GetCardState(hmmc) == HAL_MMC_CARD_TRANSFER)
3432 {
3433 /* Set the power-off notification to powered-on : Ext_CSD[34] = 1 */
3434 errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03220100U));
3435 if (errorstate == HAL_MMC_ERROR_NONE)
3436 {
3437 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3438 count = SDMMC_MAX_TRIAL;
3439 do
3440 {
3441 errorstate = SDMMC_CmdSendStatus(hmmc->Instance,
3442 (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3443 if (errorstate != HAL_MMC_ERROR_NONE)
3444 {
3445 break;
3446 }
3447
3448 /* Get command response */
3449 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3450 count--;
3451 } while (((response & 0x100U) == 0U) && (count != 0U));
3452
3453 /* Check the status after the switch command execution */
3454 if (count == 0U)
3455 {
3456 errorstate = SDMMC_ERROR_TIMEOUT;
3457 }
3458 else if (errorstate == HAL_MMC_ERROR_NONE)
3459 {
3460 /* Check the bit SWITCH_ERROR of the device status */
3461 if ((response & 0x80U) != 0U)
3462 {
3463 errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3464 }
3465 }
3466 else
3467 {
3468 /* NOthing to do */
3469 }
3470 }
3471 }
3472 else
3473 {
3474 errorstate = SDMMC_ERROR_REQUEST_NOT_APPLICABLE;
3475 }
3476 }
3477 }
3478 else
3479 {
3480 errorstate = SDMMC_ERROR_REQUEST_NOT_APPLICABLE;
3481 }
3482 }
3483 }
3484
3485 /* Change State */
3486 hmmc->State = HAL_MMC_STATE_READY;
3487
3488 /* Manage errors */
3489 if (errorstate != HAL_MMC_ERROR_NONE)
3490 {
3491 /* Clear all the static flags */
3492 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3493 hmmc->ErrorCode |= errorstate;
3494
3495 if (errorstate != HAL_MMC_ERROR_TIMEOUT)
3496 {
3497 return HAL_ERROR;
3498 }
3499 else
3500 {
3501 return HAL_TIMEOUT;
3502 }
3503 }
3504 else
3505 {
3506 return HAL_OK;
3507 }
3508 }
3509 else
3510 {
3511 return HAL_BUSY;
3512 }
3513 }
3514 /**
3515 * @}
3516 */
3517
3518 /**
3519 * @}
3520 */
3521
3522 /* Private function ----------------------------------------------------------*/
3523 /** @addtogroup MMC_Private_Functions
3524 * @{
3525 */
3526
3527
3528 /**
3529 * @brief Initializes the mmc card.
3530 * @param hmmc: Pointer to MMC handle
3531 * @retval MMC Card error state
3532 */
MMC_InitCard(MMC_HandleTypeDef * hmmc)3533 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc)
3534 {
3535 HAL_MMC_CardCSDTypeDef CSD;
3536 uint32_t errorstate;
3537 uint16_t mmc_rca = 2U;
3538 MMC_InitTypeDef Init;
3539
3540 /* Check the power State */
3541 if (SDMMC_GetPowerState(hmmc->Instance) == 0U)
3542 {
3543 /* Power off */
3544 return HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
3545 }
3546
3547 /* Send CMD2 ALL_SEND_CID */
3548 errorstate = SDMMC_CmdSendCID(hmmc->Instance);
3549 if (errorstate != HAL_MMC_ERROR_NONE)
3550 {
3551 return errorstate;
3552 }
3553 else
3554 {
3555 /* Get Card identification number data */
3556 hmmc->CID[0U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3557 hmmc->CID[1U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2);
3558 hmmc->CID[2U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP3);
3559 hmmc->CID[3U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP4);
3560 }
3561
3562 /* Send CMD3 SET_REL_ADDR with RCA = 2 (should be greater than 1) */
3563 /* MMC Card publishes its RCA. */
3564 errorstate = SDMMC_CmdSetRelAddMmc(hmmc->Instance, mmc_rca);
3565 if (errorstate != HAL_MMC_ERROR_NONE)
3566 {
3567 return errorstate;
3568 }
3569
3570 /* Get the MMC card RCA */
3571 hmmc->MmcCard.RelCardAdd = mmc_rca;
3572
3573 /* Send CMD9 SEND_CSD with argument as card's RCA */
3574 errorstate = SDMMC_CmdSendCSD(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
3575 if (errorstate != HAL_MMC_ERROR_NONE)
3576 {
3577 return errorstate;
3578 }
3579 else
3580 {
3581 /* Get Card Specific Data */
3582 hmmc->CSD[0U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3583 hmmc->CSD[1U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2);
3584 hmmc->CSD[2U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP3);
3585 hmmc->CSD[3U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP4);
3586 }
3587
3588 /* Get the Card Class */
3589 hmmc->MmcCard.Class = (SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2) >> 20U);
3590
3591 /* Select the Card */
3592 errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3593 if (errorstate != HAL_MMC_ERROR_NONE)
3594 {
3595 return errorstate;
3596 }
3597
3598 /* Get CSD parameters */
3599 if (HAL_MMC_GetCardCSD(hmmc, &CSD) != HAL_OK)
3600 {
3601 return hmmc->ErrorCode;
3602 }
3603
3604 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3605 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3606 if (errorstate != HAL_MMC_ERROR_NONE)
3607 {
3608 hmmc->ErrorCode |= errorstate;
3609 }
3610
3611
3612 /* Get Extended CSD parameters */
3613 if (HAL_MMC_GetCardExtCSD(hmmc, hmmc->Ext_CSD, SDMMC_DATATIMEOUT) != HAL_OK)
3614 {
3615 return hmmc->ErrorCode;
3616 }
3617
3618 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3619 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3620 if (errorstate != HAL_MMC_ERROR_NONE)
3621 {
3622 hmmc->ErrorCode |= errorstate;
3623 }
3624
3625 /* Configure the SDMMC peripheral */
3626 Init = hmmc->Init;
3627 Init.BusWide = SDMMC_BUS_WIDE_1B;
3628 (void)SDMMC_Init(hmmc->Instance, Init);
3629
3630 /* All cards are initialized */
3631 return HAL_MMC_ERROR_NONE;
3632 }
3633
3634 /**
3635 * @brief Enquires cards about their operating voltage and configures clock
3636 * controls and stores MMC information that will be needed in future
3637 * in the MMC handle.
3638 * @param hmmc: Pointer to MMC handle
3639 * @retval error state
3640 */
MMC_PowerON(MMC_HandleTypeDef * hmmc)3641 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc)
3642 {
3643 __IO uint32_t count = 0U;
3644 uint32_t response = 0U;
3645 uint32_t validvoltage = 0U;
3646 uint32_t errorstate;
3647
3648 /* CMD0: GO_IDLE_STATE */
3649 errorstate = SDMMC_CmdGoIdleState(hmmc->Instance);
3650 if (errorstate != HAL_MMC_ERROR_NONE)
3651 {
3652 return errorstate;
3653 }
3654
3655 while (validvoltage == 0U)
3656 {
3657 if (count++ == SDMMC_MAX_VOLT_TRIAL)
3658 {
3659 return HAL_MMC_ERROR_INVALID_VOLTRANGE;
3660 }
3661
3662 /* SEND CMD1 APP_CMD with voltage range as argument */
3663 errorstate = SDMMC_CmdOpCondition(hmmc->Instance, MMC_VOLTAGE_RANGE);
3664 if (errorstate != HAL_MMC_ERROR_NONE)
3665 {
3666 return HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
3667 }
3668
3669 /* Get command response */
3670 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3671
3672 /* Get operating voltage*/
3673 validvoltage = (((response >> 31U) == 1U) ? 1U : 0U);
3674 }
3675
3676 /* When power routine is finished and command returns valid voltage */
3677 if (((response & (0xFF000000U)) >> 24) == 0xC0U)
3678 {
3679 hmmc->MmcCard.CardType = MMC_HIGH_CAPACITY_CARD;
3680 }
3681 else
3682 {
3683 hmmc->MmcCard.CardType = MMC_LOW_CAPACITY_CARD;
3684 }
3685
3686 return HAL_MMC_ERROR_NONE;
3687 }
3688
3689 /**
3690 * @brief Turns the SDMMC output signals off.
3691 * @param hmmc: Pointer to MMC handle
3692 * @retval None
3693 */
MMC_PowerOFF(MMC_HandleTypeDef * hmmc)3694 static void MMC_PowerOFF(MMC_HandleTypeDef *hmmc)
3695 {
3696 /* Set Power State to OFF */
3697 (void)SDMMC_PowerState_OFF(hmmc->Instance);
3698 }
3699
3700 /**
3701 * @brief Returns the current card's status.
3702 * @param hmmc: Pointer to MMC handle
3703 * @param pCardStatus: pointer to the buffer that will contain the MMC card
3704 * status (Card Status register)
3705 * @retval error state
3706 */
MMC_SendStatus(MMC_HandleTypeDef * hmmc,uint32_t * pCardStatus)3707 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus)
3708 {
3709 uint32_t errorstate;
3710
3711 if (pCardStatus == NULL)
3712 {
3713 return HAL_MMC_ERROR_PARAM;
3714 }
3715
3716 /* Send Status command */
3717 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
3718 if (errorstate != HAL_MMC_ERROR_NONE)
3719 {
3720 return errorstate;
3721 }
3722
3723 /* Get MMC card status */
3724 *pCardStatus = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3725
3726 return HAL_MMC_ERROR_NONE;
3727 }
3728
3729 /**
3730 * @brief Reads extended CSD register to get the sectors number of the device
3731 * @param hmmc: Pointer to MMC handle
3732 * @param pFieldData: Pointer to the read buffer
3733 * @param FieldIndex: Index of the field to be read
3734 * @param Timeout: Specify timeout value
3735 * @retval HAL status
3736 */
MMC_ReadExtCSD(MMC_HandleTypeDef * hmmc,uint32_t * pFieldData,uint16_t FieldIndex,uint32_t Timeout)3737 static HAL_StatusTypeDef MMC_ReadExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pFieldData,
3738 uint16_t FieldIndex, uint32_t Timeout)
3739 {
3740 SDMMC_DataInitTypeDef config;
3741 uint32_t errorstate;
3742 uint32_t tickstart = HAL_GetTick();
3743 uint32_t count;
3744 uint32_t i = 0;
3745 uint32_t tmp_data;
3746
3747 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
3748
3749 /* Initialize data control register */
3750 hmmc->Instance->DCTRL = 0;
3751
3752 /* Configure the MMC DPSM (Data Path State Machine) */
3753 config.DataTimeOut = SDMMC_DATATIMEOUT;
3754 config.DataLength = MMC_BLOCKSIZE;
3755 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
3756 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
3757 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
3758 config.DPSM = SDMMC_DPSM_ENABLE;
3759 (void)SDMMC_ConfigData(hmmc->Instance, &config);
3760
3761 /* Set Block Size for Card */
3762 errorstate = SDMMC_CmdSendEXTCSD(hmmc->Instance, 0);
3763 if (errorstate != HAL_MMC_ERROR_NONE)
3764 {
3765 /* Clear all the static flags */
3766 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3767 hmmc->ErrorCode |= errorstate;
3768 hmmc->State = HAL_MMC_STATE_READY;
3769 return HAL_ERROR;
3770 }
3771
3772 /* Poll on SDMMC flags */
3773 while (!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT |
3774 SDMMC_FLAG_DATAEND))
3775 {
3776 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF))
3777 {
3778 /* Read data from SDMMC Rx FIFO */
3779 for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
3780 {
3781 tmp_data = SDMMC_ReadFIFO(hmmc->Instance);
3782 /* eg : SEC_COUNT : FieldIndex = 212 => i+count = 53 */
3783 /* DEVICE_TYPE : FieldIndex = 196 => i+count = 49 */
3784 if ((i + count) == ((uint32_t)FieldIndex / 4U))
3785 {
3786 *pFieldData = tmp_data;
3787 }
3788 }
3789 i += 8U;
3790 }
3791
3792 if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
3793 {
3794 /* Clear all the static flags */
3795 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3796 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
3797 hmmc->State = HAL_MMC_STATE_READY;
3798 return HAL_TIMEOUT;
3799 }
3800 }
3801
3802 /* Get error state */
3803 if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
3804 {
3805 /* Clear all the static flags */
3806 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3807 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
3808 hmmc->State = HAL_MMC_STATE_READY;
3809 return HAL_ERROR;
3810 }
3811 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
3812 {
3813 /* Clear all the static flags */
3814 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3815 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
3816 hmmc->State = HAL_MMC_STATE_READY;
3817 return HAL_ERROR;
3818 }
3819 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR))
3820 {
3821 /* Clear all the static flags */
3822 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3823 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
3824 hmmc->State = HAL_MMC_STATE_READY;
3825 return HAL_ERROR;
3826 }
3827 else
3828 {
3829 /* Nothing to do */
3830 }
3831
3832 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3833 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16));
3834 if (errorstate != HAL_MMC_ERROR_NONE)
3835 {
3836 hmmc->ErrorCode |= errorstate;
3837 }
3838
3839 /* Clear all the static flags */
3840 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
3841
3842 hmmc->State = HAL_MMC_STATE_READY;
3843
3844 return HAL_OK;
3845 }
3846
3847 /**
3848 * @brief Wrap up reading in non-blocking mode.
3849 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
3850 * the configuration information.
3851 * @retval None
3852 */
MMC_Read_IT(MMC_HandleTypeDef * hmmc)3853 static void MMC_Read_IT(MMC_HandleTypeDef *hmmc)
3854 {
3855 uint32_t count;
3856 uint32_t data;
3857 uint8_t *tmp;
3858
3859 tmp = hmmc->pRxBuffPtr;
3860
3861
3862 if (hmmc->RxXferSize >= SDMMC_FIFO_SIZE)
3863 {
3864 /* Read data from SDMMC Rx FIFO */
3865 for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
3866 {
3867 data = SDMMC_ReadFIFO(hmmc->Instance);
3868 *tmp = (uint8_t)(data & 0xFFU);
3869 tmp++;
3870 *tmp = (uint8_t)((data >> 8U) & 0xFFU);
3871 tmp++;
3872 *tmp = (uint8_t)((data >> 16U) & 0xFFU);
3873 tmp++;
3874 *tmp = (uint8_t)((data >> 24U) & 0xFFU);
3875 tmp++;
3876 }
3877
3878 hmmc->pRxBuffPtr = tmp;
3879 hmmc->RxXferSize -= SDMMC_FIFO_SIZE;
3880 }
3881 }
3882
3883 /**
3884 * @brief Wrap up writing in non-blocking mode.
3885 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
3886 * the configuration information.
3887 * @retval None
3888 */
MMC_Write_IT(MMC_HandleTypeDef * hmmc)3889 static void MMC_Write_IT(MMC_HandleTypeDef *hmmc)
3890 {
3891 uint32_t count;
3892 uint32_t data;
3893 const uint8_t *tmp;
3894
3895 tmp = hmmc->pTxBuffPtr;
3896
3897 if (hmmc->TxXferSize >= SDMMC_FIFO_SIZE)
3898 {
3899 /* Write data to SDMMC Tx FIFO */
3900 for (count = 0U; count < (SDMMC_FIFO_SIZE / 4U); count++)
3901 {
3902 data = (uint32_t)(*tmp);
3903 tmp++;
3904 data |= ((uint32_t)(*tmp) << 8U);
3905 tmp++;
3906 data |= ((uint32_t)(*tmp) << 16U);
3907 tmp++;
3908 data |= ((uint32_t)(*tmp) << 24U);
3909 tmp++;
3910 (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
3911 }
3912
3913 hmmc->pTxBuffPtr = tmp;
3914 hmmc->TxXferSize -= SDMMC_FIFO_SIZE;
3915 }
3916 }
3917
3918 /**
3919 * @brief Switches the MMC card to high speed mode.
3920 * @param hmmc: MMC handle
3921 * @param state: State of high speed mode
3922 * @retval MMC Card error state
3923 */
MMC_HighSpeed(MMC_HandleTypeDef * hmmc,FunctionalState state)3924 static uint32_t MMC_HighSpeed(MMC_HandleTypeDef *hmmc, FunctionalState state)
3925 {
3926 uint32_t errorstate = HAL_MMC_ERROR_NONE;
3927 uint32_t response = 0U;
3928 uint32_t count;
3929 uint32_t sdmmc_clk;
3930 SDMMC_InitTypeDef Init;
3931
3932 if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) != 0U) && (state == DISABLE))
3933 {
3934 errorstate = MMC_PwrClassUpdate(hmmc, (hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS), SDMMC_SPEED_MODE_DEFAULT);
3935 if (errorstate == HAL_MMC_ERROR_NONE)
3936 {
3937 /* Index : 185 - Value : 0 */
3938 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B90000U);
3939 }
3940 }
3941
3942 if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) == 0U) && (state != DISABLE))
3943 {
3944 errorstate = MMC_PwrClassUpdate(hmmc, (hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS), SDMMC_SPEED_MODE_HIGH);
3945 if (errorstate == HAL_MMC_ERROR_NONE)
3946 {
3947 /* Index : 185 - Value : 1 */
3948 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B90100U);
3949 }
3950 }
3951
3952 if (errorstate == HAL_MMC_ERROR_NONE)
3953 {
3954 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3955 count = SDMMC_MAX_TRIAL;
3956 do
3957 {
3958 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3959 if (errorstate != HAL_MMC_ERROR_NONE)
3960 {
3961 break;
3962 }
3963
3964 /* Get command response */
3965 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3966 count--;
3967 } while (((response & 0x100U) == 0U) && (count != 0U));
3968
3969 /* Check the status after the switch command execution */
3970 if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
3971 {
3972 /* Check the bit SWITCH_ERROR of the device status */
3973 if ((response & 0x80U) != 0U)
3974 {
3975 errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3976 }
3977 else
3978 {
3979 /* Configure high speed */
3980 Init.ClockEdge = hmmc->Init.ClockEdge;
3981 Init.ClockPowerSave = hmmc->Init.ClockPowerSave;
3982 Init.BusWide = (hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS);
3983 Init.HardwareFlowControl = hmmc->Init.HardwareFlowControl;
3984
3985 if (state == DISABLE)
3986 {
3987 Init.ClockDiv = hmmc->Init.ClockDiv;
3988 (void)SDMMC_Init(hmmc->Instance, Init);
3989
3990 CLEAR_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_BUSSPEED);
3991 }
3992 else
3993 {
3994 /* High Speed Clock should be less or equal to 52MHz*/
3995 sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC);
3996
3997 if (sdmmc_clk == 0U)
3998 {
3999 errorstate = SDMMC_ERROR_INVALID_PARAMETER;
4000 }
4001 else
4002 {
4003 if (sdmmc_clk <= MMC_HIGH_SPEED_FREQ)
4004 {
4005 Init.ClockDiv = 0;
4006 }
4007 else
4008 {
4009 Init.ClockDiv = (sdmmc_clk / (2U * MMC_HIGH_SPEED_FREQ)) + 1U;
4010 }
4011 (void)SDMMC_Init(hmmc->Instance, Init);
4012
4013 SET_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_BUSSPEED);
4014 }
4015 }
4016 }
4017 }
4018 else if (count == 0U)
4019 {
4020 errorstate = SDMMC_ERROR_TIMEOUT;
4021 }
4022 else
4023 {
4024 /* Nothing to do */
4025 }
4026 }
4027
4028 return errorstate;
4029 }
4030
4031 /**
4032 * @brief Switches the MMC card to Double Data Rate (DDR) mode.
4033 * @param hmmc: MMC handle
4034 * @param state: State of DDR mode
4035 * @retval MMC Card error state
4036 */
MMC_DDR_Mode(MMC_HandleTypeDef * hmmc,FunctionalState state)4037 static uint32_t MMC_DDR_Mode(MMC_HandleTypeDef *hmmc, FunctionalState state)
4038 {
4039 uint32_t errorstate = HAL_MMC_ERROR_NONE;
4040 uint32_t response = 0U;
4041 uint32_t count;
4042
4043 if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) != 0U) && (state == DISABLE))
4044 {
4045 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS_0) != 0U)
4046 {
4047 errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_4B, SDMMC_SPEED_MODE_HIGH);
4048 if (errorstate == HAL_MMC_ERROR_NONE)
4049 {
4050 /* Index : 183 - Value : 1 */
4051 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U);
4052 }
4053 }
4054 else
4055 {
4056 errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_8B, SDMMC_SPEED_MODE_HIGH);
4057 if (errorstate == HAL_MMC_ERROR_NONE)
4058 {
4059 /* Index : 183 - Value : 2 */
4060 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U);
4061 }
4062 }
4063 }
4064
4065 if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) == 0U) && (state != DISABLE))
4066 {
4067 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS_0) != 0U)
4068 {
4069 errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_4B, SDMMC_SPEED_MODE_DDR);
4070 if (errorstate == HAL_MMC_ERROR_NONE)
4071 {
4072 /* Index : 183 - Value : 5 */
4073 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70500U);
4074 }
4075 }
4076 else
4077 {
4078 errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_8B, SDMMC_SPEED_MODE_DDR);
4079 if (errorstate == HAL_MMC_ERROR_NONE)
4080 {
4081 /* Index : 183 - Value : 6 */
4082 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70600U);
4083 }
4084 }
4085 }
4086
4087 if (errorstate == HAL_MMC_ERROR_NONE)
4088 {
4089 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
4090 count = SDMMC_MAX_TRIAL;
4091 do
4092 {
4093 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
4094 if (errorstate != HAL_MMC_ERROR_NONE)
4095 {
4096 break;
4097 }
4098
4099 /* Get command response */
4100 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
4101 count--;
4102 } while (((response & 0x100U) == 0U) && (count != 0U));
4103
4104 /* Check the status after the switch command execution */
4105 if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
4106 {
4107 /* Check the bit SWITCH_ERROR of the device status */
4108 if ((response & 0x80U) != 0U)
4109 {
4110 errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
4111 }
4112 else
4113 {
4114 /* Configure DDR mode */
4115 if (state == DISABLE)
4116 {
4117 CLEAR_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_DDR);
4118 }
4119 else
4120 {
4121 SET_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_DDR);
4122 }
4123 }
4124 }
4125 else if (count == 0U)
4126 {
4127 errorstate = SDMMC_ERROR_TIMEOUT;
4128 }
4129 else
4130 {
4131 /* Nothing to do */
4132 }
4133 }
4134
4135 return errorstate;
4136 }
4137
4138 /**
4139 * @brief Update the power class of the device.
4140 * @param hmmc MMC handle
4141 * @param Wide Wide of MMC bus
4142 * @param Speed Speed of the MMC bus
4143 * @retval MMC Card error state
4144 */
MMC_PwrClassUpdate(MMC_HandleTypeDef * hmmc,uint32_t Wide,uint32_t Speed)4145 static uint32_t MMC_PwrClassUpdate(MMC_HandleTypeDef *hmmc, uint32_t Wide, uint32_t Speed)
4146 {
4147 uint32_t count;
4148 uint32_t response = 0U;
4149 uint32_t errorstate = HAL_MMC_ERROR_NONE;
4150 uint32_t power_class;
4151 uint32_t supported_pwr_class;
4152
4153 if ((Wide == SDMMC_BUS_WIDE_8B) || (Wide == SDMMC_BUS_WIDE_4B))
4154 {
4155 power_class = 0U; /* Default value after power-on or software reset */
4156
4157 /* Read the PowerClass field of the Extended CSD register */
4158 if (MMC_ReadExtCSD(hmmc, &power_class, 187, SDMMC_DATATIMEOUT) != HAL_OK) /* Field POWER_CLASS [187] */
4159 {
4160 errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
4161 }
4162 else
4163 {
4164 power_class = ((power_class >> 24U) & 0x000000FFU);
4165 }
4166
4167 /* Get the supported PowerClass field of the Extended CSD register */
4168 if (Speed == SDMMC_SPEED_MODE_DDR)
4169 {
4170 /* Field PWR_CL_DDR_52_xxx [238 or 239] */
4171 supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_DDR_52_INDEX / 4)] >> MMC_EXT_CSD_PWR_CL_DDR_52_POS) &
4172 0x000000FFU);
4173 }
4174 else if (Speed == SDMMC_SPEED_MODE_HIGH)
4175 {
4176 /* Field PWR_CL_52_xxx [200 or 202] */
4177 supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_52_INDEX / 4)] >> MMC_EXT_CSD_PWR_CL_52_POS) &
4178 0x000000FFU);
4179 }
4180 else
4181 {
4182 /* Field PWR_CL_26_xxx [201 or 203] */
4183 supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_26_INDEX / 4)] >> MMC_EXT_CSD_PWR_CL_26_POS) &
4184 0x000000FFU);
4185 }
4186
4187 if (errorstate == HAL_MMC_ERROR_NONE)
4188 {
4189 if (Wide == SDMMC_BUS_WIDE_8B)
4190 {
4191 /* Bit [7:4]: power class for 8-bits bus configuration - Bit [3:0]: power class for 4-bits bus configuration */
4192 supported_pwr_class = (supported_pwr_class >> 4U);
4193 }
4194
4195 if ((power_class & 0x0FU) != (supported_pwr_class & 0x0FU))
4196 {
4197 /* Need to change current power class */
4198 errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03BB0000U | ((supported_pwr_class & 0x0FU) << 8U)));
4199
4200 if (errorstate == HAL_MMC_ERROR_NONE)
4201 {
4202 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
4203 count = SDMMC_MAX_TRIAL;
4204 do
4205 {
4206 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
4207 if (errorstate != HAL_MMC_ERROR_NONE)
4208 {
4209 break;
4210 }
4211
4212 /* Get command response */
4213 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
4214 count--;
4215 } while (((response & 0x100U) == 0U) && (count != 0U));
4216
4217 /* Check the status after the switch command execution */
4218 if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
4219 {
4220 /* Check the bit SWITCH_ERROR of the device status */
4221 if ((response & 0x80U) != 0U)
4222 {
4223 errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
4224 }
4225 }
4226 else if (count == 0U)
4227 {
4228 errorstate = SDMMC_ERROR_TIMEOUT;
4229 }
4230 else
4231 {
4232 /* Nothing to do */
4233 }
4234 }
4235 }
4236 }
4237 }
4238
4239 return errorstate;
4240 }
4241
4242 /**
4243 * @brief Read DMA Linked list node Transfer completed callbacks
4244 * @param hmmc: MMC handle
4245 * @retval None
4246 */
HAL_MMCEx_Read_DMALnkLstBufCpltCallback(MMC_HandleTypeDef * hmmc)4247 __weak void HAL_MMCEx_Read_DMALnkLstBufCpltCallback(MMC_HandleTypeDef *hmmc)
4248 {
4249 /* Prevent unused argument(s) compilation warning */
4250 UNUSED(hmmc);
4251
4252 /* NOTE : This function should not be modified, when the callback is needed,
4253 the HAL_MMCEx_Read_DMALnkLstBufCpltCallback can be implemented in the user file
4254 */
4255 }
4256 /**
4257 * @brief Read DMA Linked list node Transfer completed callbacks
4258 * @param hmmc: MMC handle
4259 * @retval None
4260 */
HAL_MMCEx_Write_DMALnkLstBufCpltCallback(MMC_HandleTypeDef * hmmc)4261 __weak void HAL_MMCEx_Write_DMALnkLstBufCpltCallback(MMC_HandleTypeDef *hmmc)
4262 {
4263 /* Prevent unused argument(s) compilation warning */
4264 UNUSED(hmmc);
4265
4266 /* NOTE : This function should not be modified, when the callback is needed,
4267 the HAL_MMCEx_Write_DMALnkLstBufCpltCallback can be implemented in the user file
4268 */
4269 }
4270
4271 /**
4272 * @}
4273 */
4274
4275 #endif /* HAL_MMC_MODULE_ENABLED */
4276 #endif /* SDMMC1 || SDMMC2 */
4277
4278 /**
4279 * @}
4280 */
4281
4282 /**
4283 * @}
4284 */
4285