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