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