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