1 /**
2 ******************************************************************************
3 * @file stm32f4xx_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) 2016 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 (##) DMA Configuration if you need to use DMA process (HAL_MMC_ReadBlocks_DMA()
48 and HAL_MMC_WriteBlocks_DMA() APIs).
49 (+++) Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE();
50 (+++) Configure the DMA using the function HAL_DMA_Init() with predeclared and filled.
51 (##) NVIC configuration if you need to use interrupt process when using DMA transfer.
52 (+++) Configure the SDMMC and DMA interrupt priorities using function HAL_NVIC_SetPriority();
53 DMA priority is superior to SDMMC's priority
54 (+++) Enable the NVIC DMA and SDMMC IRQs using function HAL_NVIC_EnableIRQ()
55 (+++) SDMMC interrupts are managed using the macros __HAL_MMC_ENABLE_IT()
56 and __HAL_MMC_DISABLE_IT() inside the communication process.
57 (+++) SDMMC interrupts pending bits are managed using the macros __HAL_MMC_GET_IT()
58 and __HAL_MMC_CLEAR_IT()
59 (##) NVIC configuration if you need to use interrupt process (HAL_MMC_ReadBlocks_IT()
60 and HAL_MMC_WriteBlocks_IT() APIs).
61 (+++) Configure the SDMMC interrupt priorities using function HAL_NVIC_SetPriority();
62 (+++) Enable the NVIC SDMMC IRQs using function HAL_NVIC_EnableIRQ()
63 (+++) SDMMC interrupts are managed using the macros __HAL_MMC_ENABLE_IT()
64 and __HAL_MMC_DISABLE_IT() inside the communication process.
65 (+++) SDMMC interrupts pending bits are managed using the macros __HAL_MMC_GET_IT()
66 and __HAL_MMC_CLEAR_IT()
67 (#) At this stage, you can perform MMC read/write/erase operations after MMC card initialization
68
69
70 *** MMC Card Initialization and configuration ***
71 ================================================
72 [..]
73 To initialize the MMC Card, use the HAL_MMC_Init() function. It Initializes
74 SDMMC Peripheral (STM32 side) and the MMC Card, and put it into StandBy State (Ready for data transfer).
75 This function provide the following operations:
76
77 (#) Initialize the SDMMC peripheral interface with default configuration.
78 The initialization process is done at 400KHz. You can change or adapt
79 this frequency by adjusting the "ClockDiv" field.
80 The MMC Card frequency (SDMMC_CK) is computed as follows:
81
82 SDMMC_CK = SDMMCCLK / (ClockDiv + 2)
83
84 In initialization mode and according to the MMC Card standard,
85 make sure that the SDMMC_CK frequency doesn't exceed 400KHz.
86
87 This phase of initialization is done through SDMMC_Init() and
88 SDMMC_PowerState_ON() SDMMC low level APIs.
89
90 (#) Initialize the MMC card. The API used is HAL_MMC_InitCard().
91 This phase allows the card initialization and identification
92 and check the MMC Card type (Standard Capacity or High Capacity)
93 The initialization flow is compatible with MMC standard.
94
95 This API (HAL_MMC_InitCard()) could be used also to reinitialize the card in case
96 of plug-off plug-in.
97
98 (#) Configure the MMC Card Data transfer frequency. By Default, the card transfer
99 frequency is set to 24MHz. You can change or adapt this frequency by adjusting
100 the "ClockDiv" field.
101 In transfer mode and according to the MMC Card standard, make sure that the
102 SDMMC_CK frequency doesn't exceed 25MHz and 50MHz in High-speed mode switch.
103 To be able to use a frequency higher than 24MHz, you should use the SDMMC
104 peripheral in bypass mode. Refer to the corresponding reference manual
105 for more details.
106
107 (#) Select the corresponding MMC Card according to the address read with the step 2.
108
109 (#) Configure the MMC Card in wide bus mode: 4-bits data.
110
111 *** MMC Card Read operation ***
112 ==============================
113 [..]
114 (+) You can read from MMC card in polling mode by using function HAL_MMC_ReadBlocks().
115 This function support only 512-bytes block length (the block size should be
116 chosen as 512 bytes).
117 You can choose either one block read operation or multiple block read operation
118 by adjusting the "NumberOfBlocks" parameter.
119 After this, you have to ensure that the transfer is done correctly. The check is done
120 through HAL_MMC_GetCardState() function for MMC card state.
121
122 (+) You can read from MMC card in DMA mode by using function HAL_MMC_ReadBlocks_DMA().
123 This function support only 512-bytes block length (the block size should be
124 chosen as 512 bytes).
125 You can choose either one block read operation or multiple block read operation
126 by adjusting the "NumberOfBlocks" parameter.
127 After this, you have to ensure that the transfer is done correctly. The check is done
128 through HAL_MMC_GetCardState() function for MMC card state.
129 You could also check the DMA transfer process through the MMC Rx interrupt event.
130
131 (+) You can read from MMC card in Interrupt mode by using function HAL_MMC_ReadBlocks_IT().
132 This function allows the read of 512 bytes blocks.
133 You can choose either one block read operation or multiple block read operation
134 by adjusting the "NumberOfBlocks" parameter.
135 After this, you have to ensure that the transfer is done correctly. The check is done
136 through HAL_MMC_GetCardState() function for MMC card state.
137 You could also check the IT transfer process through the MMC Rx interrupt event.
138
139 *** MMC Card Write operation ***
140 ===============================
141 [..]
142 (+) You can write to MMC card in polling mode by using function HAL_MMC_WriteBlocks().
143 This function support only 512-bytes block length (the block size should be
144 chosen as 512 bytes).
145 You can choose either one block read operation or multiple block read operation
146 by adjusting the "NumberOfBlocks" parameter.
147 After this, you have to ensure that the transfer is done correctly. The check is done
148 through HAL_MMC_GetCardState() function for MMC card state.
149
150 (+) You can write to MMC card in DMA mode by using function HAL_MMC_WriteBlocks_DMA().
151 This function support only 512-bytes block length (the block size should be
152 chosen as 512 byte).
153 You can choose either one block read operation or multiple block read operation
154 by adjusting the "NumberOfBlocks" parameter.
155 After this, you have to ensure that the transfer is done correctly. The check is done
156 through HAL_MMC_GetCardState() function for MMC card state.
157 You could also check the DMA transfer process through the MMC Tx interrupt event.
158
159 (+) You can write to MMC card in Interrupt mode by using function HAL_MMC_WriteBlocks_IT().
160 This function allows the read of 512 bytes blocks.
161 You can choose either one block read operation or multiple block read operation
162 by adjusting the "NumberOfBlocks" parameter.
163 After this, you have to ensure that the transfer is done correctly. The check is done
164 through HAL_MMC_GetCardState() function for MMC card state.
165 You could also check the IT transfer process through the MMC Tx interrupt event.
166
167 *** MMC card information ***
168 ===========================
169 [..]
170 (+) To get MMC card information, you can use the function HAL_MMC_GetCardInfo().
171 It returns useful information about the MMC card such as block size, card type,
172 block number ...
173
174 *** MMC card CSD register ***
175 ============================
176 [..]
177 (+) The HAL_MMC_GetCardCSD() API allows to get the parameters of the CSD register.
178 Some of the CSD parameters are useful for card initialization and identification.
179
180 *** MMC card CID register ***
181 ============================
182 [..]
183 (+) The HAL_MMC_GetCardCID() API allows to get the parameters of the CID register.
184 Some of the CID parameters are useful for card initialization and identification.
185
186 *** MMC HAL driver macros list ***
187 ==================================
188 [..]
189 Below the list of most used macros in MMC HAL driver.
190
191 (+) __HAL_MMC_ENABLE : Enable the MMC device
192 (+) __HAL_MMC_DISABLE : Disable the MMC device
193 (+) __HAL_MMC_DMA_ENABLE: Enable the SDMMC DMA transfer
194 (+) __HAL_MMC_DMA_DISABLE: Disable the SDMMC DMA transfer
195 (+) __HAL_MMC_ENABLE_IT: Enable the MMC device interrupt
196 (+) __HAL_MMC_DISABLE_IT: Disable the MMC device interrupt
197 (+) __HAL_MMC_GET_FLAG:Check whether the specified MMC flag is set or not
198 (+) __HAL_MMC_CLEAR_FLAG: Clear the MMC's pending flags
199
200 [..]
201 (@) You can refer to the MMC HAL driver header file for more useful macros
202
203 *** Callback registration ***
204 =============================================
205 [..]
206 The compilation define USE_HAL_MMC_REGISTER_CALLBACKS when set to 1
207 allows the user to configure dynamically the driver callbacks.
208
209 Use Functions HAL_MMC_RegisterCallback() to register a user callback,
210 it allows to register following callbacks:
211 (+) TxCpltCallback : callback when a transmission transfer is completed.
212 (+) RxCpltCallback : callback when a reception transfer is completed.
213 (+) ErrorCallback : callback when error occurs.
214 (+) AbortCpltCallback : callback when abort is completed.
215 (+) MspInitCallback : MMC MspInit.
216 (+) MspDeInitCallback : MMC MspDeInit.
217 This function takes as parameters the HAL peripheral handle, the Callback ID
218 and a pointer to the user callback function.
219
220 Use function HAL_MMC_UnRegisterCallback() to reset a callback to the default
221 weak (surcharged) function. It allows to reset following callbacks:
222 (+) TxCpltCallback : callback when a transmission transfer is completed.
223 (+) RxCpltCallback : callback when a reception transfer is completed.
224 (+) ErrorCallback : callback when error occurs.
225 (+) AbortCpltCallback : callback when abort is completed.
226 (+) MspInitCallback : MMC MspInit.
227 (+) MspDeInitCallback : MMC MspDeInit.
228 This function) takes as parameters the HAL peripheral handle and the Callback ID.
229
230 By default, after the HAL_MMC_Init and if the state is HAL_MMC_STATE_RESET
231 all callbacks are reset to the corresponding legacy weak (surcharged) functions.
232 Exception done for MspInit and MspDeInit callbacks that are respectively
233 reset to the legacy weak (surcharged) functions in the HAL_MMC_Init
234 and HAL_MMC_DeInit only when these callbacks are null (not registered beforehand).
235 If not, MspInit or MspDeInit are not null, the HAL_MMC_Init and HAL_MMC_DeInit
236 keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
237
238 Callbacks can be registered/unregistered in READY state only.
239 Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
240 in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
241 during the Init/DeInit.
242 In that case first register the MspInit/MspDeInit user callbacks
243 using HAL_MMC_RegisterCallback before calling HAL_MMC_DeInit
244 or HAL_MMC_Init function.
245
246 When The compilation define USE_HAL_MMC_REGISTER_CALLBACKS is set to 0 or
247 not defined, the callback registering feature is not available
248 and weak (surcharged) callbacks are used.
249
250 @endverbatim
251 ******************************************************************************
252 */
253
254 /* Includes ------------------------------------------------------------------*/
255 #include "stm32f4xx_hal.h"
256
257 /** @addtogroup STM32F4xx_HAL_Driver
258 * @{
259 */
260
261 /** @defgroup MMC MMC
262 * @brief MMC HAL module driver
263 * @{
264 */
265
266 #ifdef HAL_MMC_MODULE_ENABLED
267
268 #if defined(SDIO)
269
270 /* Private typedef -----------------------------------------------------------*/
271 /* Private define ------------------------------------------------------------*/
272 /** @addtogroup MMC_Private_Defines
273 * @{
274 */
275 #if defined (VDD_VALUE) && (VDD_VALUE <= 1950U)
276 #define MMC_VOLTAGE_RANGE EMMC_LOW_VOLTAGE_RANGE
277
278 #define MMC_EXT_CSD_PWR_CL_26_INDEX 201
279 #define MMC_EXT_CSD_PWR_CL_52_INDEX 200
280 #define MMC_EXT_CSD_PWR_CL_DDR_52_INDEX 238
281
282 #define MMC_EXT_CSD_PWR_CL_26_POS 8
283 #define MMC_EXT_CSD_PWR_CL_52_POS 0
284 #define MMC_EXT_CSD_PWR_CL_DDR_52_POS 16
285 #else
286 #define MMC_VOLTAGE_RANGE EMMC_HIGH_VOLTAGE_RANGE
287
288 #define MMC_EXT_CSD_PWR_CL_26_INDEX 203
289 #define MMC_EXT_CSD_PWR_CL_52_INDEX 202
290 #define MMC_EXT_CSD_PWR_CL_DDR_52_INDEX 239
291
292 #define MMC_EXT_CSD_PWR_CL_26_POS 24
293 #define MMC_EXT_CSD_PWR_CL_52_POS 16
294 #define MMC_EXT_CSD_PWR_CL_DDR_52_POS 24
295 #endif
296
297 /* Frequencies used in the driver for clock divider calculation */
298 #define MMC_INIT_FREQ 400000U /* Initialization phase : 400 kHz max */
299 /**
300 * @}
301 */
302
303 /* Private macro -------------------------------------------------------------*/
304 /* Private variables ---------------------------------------------------------*/
305 /* Private function prototypes -----------------------------------------------*/
306 /* Private functions ---------------------------------------------------------*/
307 /** @defgroup MMC_Private_Functions MMC Private Functions
308 * @{
309 */
310 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc);
311 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc);
312 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus);
313 static uint32_t MMC_ReadExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pFieldData, uint16_t FieldIndex, uint32_t Timeout);
314 static void MMC_PowerOFF(MMC_HandleTypeDef *hmmc);
315 static void MMC_Write_IT(MMC_HandleTypeDef *hmmc);
316 static void MMC_Read_IT(MMC_HandleTypeDef *hmmc);
317 static void MMC_DMATransmitCplt(DMA_HandleTypeDef *hdma);
318 static void MMC_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
319 static void MMC_DMAError(DMA_HandleTypeDef *hdma);
320 static void MMC_DMATxAbort(DMA_HandleTypeDef *hdma);
321 static void MMC_DMARxAbort(DMA_HandleTypeDef *hdma);
322 static uint32_t MMC_PwrClassUpdate(MMC_HandleTypeDef *hmmc, uint32_t Wide);
323 /**
324 * @}
325 */
326 /* Exported functions --------------------------------------------------------*/
327 /** @addtogroup MMC_Exported_Functions
328 * @{
329 */
330
331 /** @addtogroup MMC_Exported_Functions_Group1
332 * @brief Initialization and de-initialization functions
333 *
334 @verbatim
335 ==============================================================================
336 ##### Initialization and de-initialization functions #####
337 ==============================================================================
338 [..]
339 This section provides functions allowing to initialize/de-initialize the MMC
340 card device to be ready for use.
341
342 @endverbatim
343 * @{
344 */
345
346 /**
347 * @brief Initializes the MMC according to the specified parameters in the
348 MMC_HandleTypeDef and create the associated handle.
349 * @param hmmc: Pointer to the MMC handle
350 * @retval HAL status
351 */
HAL_MMC_Init(MMC_HandleTypeDef * hmmc)352 HAL_StatusTypeDef HAL_MMC_Init(MMC_HandleTypeDef *hmmc)
353 {
354 /* Check the MMC handle allocation */
355 if(hmmc == NULL)
356 {
357 return HAL_ERROR;
358 }
359
360 /* Check the parameters */
361 assert_param(IS_SDIO_ALL_INSTANCE(hmmc->Instance));
362 assert_param(IS_SDIO_CLOCK_EDGE(hmmc->Init.ClockEdge));
363 assert_param(IS_SDIO_CLOCK_BYPASS(hmmc->Init.ClockBypass));
364 assert_param(IS_SDIO_CLOCK_POWER_SAVE(hmmc->Init.ClockPowerSave));
365 assert_param(IS_SDIO_BUS_WIDE(hmmc->Init.BusWide));
366 assert_param(IS_SDIO_HARDWARE_FLOW_CONTROL(hmmc->Init.HardwareFlowControl));
367 assert_param(IS_SDIO_CLKDIV(hmmc->Init.ClockDiv));
368
369 if(hmmc->State == HAL_MMC_STATE_RESET)
370 {
371 /* Allocate lock resource and initialize it */
372 hmmc->Lock = HAL_UNLOCKED;
373 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
374 /* Reset Callback pointers in HAL_MMC_STATE_RESET only */
375 hmmc->TxCpltCallback = HAL_MMC_TxCpltCallback;
376 hmmc->RxCpltCallback = HAL_MMC_RxCpltCallback;
377 hmmc->ErrorCallback = HAL_MMC_ErrorCallback;
378 hmmc->AbortCpltCallback = HAL_MMC_AbortCallback;
379
380 if(hmmc->MspInitCallback == NULL)
381 {
382 hmmc->MspInitCallback = HAL_MMC_MspInit;
383 }
384
385 /* Init the low level hardware */
386 hmmc->MspInitCallback(hmmc);
387 #else
388 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
389 HAL_MMC_MspInit(hmmc);
390 #endif
391 }
392
393 hmmc->State = HAL_MMC_STATE_BUSY;
394
395 /* Initialize the Card parameters */
396 if(HAL_MMC_InitCard(hmmc) == HAL_ERROR)
397 {
398 return HAL_ERROR;
399 }
400
401 /* Initialize the error code */
402 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
403
404 /* Initialize the MMC operation */
405 hmmc->Context = MMC_CONTEXT_NONE;
406
407 /* Initialize the MMC state */
408 hmmc->State = HAL_MMC_STATE_READY;
409
410 /* Configure bus width */
411 if (hmmc->Init.BusWide != SDIO_BUS_WIDE_1B)
412 {
413 if (HAL_MMC_ConfigWideBusOperation(hmmc, hmmc->Init.BusWide) != HAL_OK)
414 {
415 return HAL_ERROR;
416 }
417 }
418
419 return HAL_OK;
420 }
421
422 /**
423 * @brief Initializes the MMC Card.
424 * @param hmmc: Pointer to MMC handle
425 * @note This function initializes the MMC card. It could be used when a card
426 re-initialization is needed.
427 * @retval HAL status
428 */
HAL_MMC_InitCard(MMC_HandleTypeDef * hmmc)429 HAL_StatusTypeDef HAL_MMC_InitCard(MMC_HandleTypeDef *hmmc)
430 {
431 uint32_t errorstate;
432 MMC_InitTypeDef Init;
433 HAL_StatusTypeDef status;
434
435 /* Default SDIO peripheral configuration for MMC card initialization */
436 Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
437 Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
438 Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
439 Init.BusWide = SDIO_BUS_WIDE_1B;
440 Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
441 Init.ClockDiv = SDIO_INIT_CLK_DIV;
442
443 /* Initialize SDIO peripheral interface with default configuration */
444 status = SDIO_Init(hmmc->Instance, Init);
445 if(status == HAL_ERROR)
446 {
447 return HAL_ERROR;
448 }
449
450 /* Disable SDIO Clock */
451 __HAL_MMC_DISABLE(hmmc);
452
453 /* Set Power State to ON */
454 status = SDIO_PowerState_ON(hmmc->Instance);
455 if(status == HAL_ERROR)
456 {
457 return HAL_ERROR;
458 }
459
460 /* Enable MMC Clock */
461 __HAL_MMC_ENABLE(hmmc);
462
463 /* Required power up waiting time before starting the MMC initialization sequence */
464 HAL_Delay(2);
465
466 /* Identify card operating voltage */
467 errorstate = MMC_PowerON(hmmc);
468 if(errorstate != HAL_MMC_ERROR_NONE)
469 {
470 hmmc->State = HAL_MMC_STATE_READY;
471 hmmc->ErrorCode |= errorstate;
472 return HAL_ERROR;
473 }
474
475 /* Card initialization */
476 errorstate = MMC_InitCard(hmmc);
477 if(errorstate != HAL_MMC_ERROR_NONE)
478 {
479 hmmc->State = HAL_MMC_STATE_READY;
480 hmmc->ErrorCode |= errorstate;
481 return HAL_ERROR;
482 }
483
484 /* Set Block Size for Card */
485 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, MMC_BLOCKSIZE);
486 if(errorstate != HAL_MMC_ERROR_NONE)
487 {
488 /* Clear all the static flags */
489 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
490 hmmc->ErrorCode |= errorstate;
491 hmmc->State = HAL_MMC_STATE_READY;
492 return HAL_ERROR;
493 }
494
495 return HAL_OK;
496 }
497
498 /**
499 * @brief De-Initializes the MMC card.
500 * @param hmmc: Pointer to MMC handle
501 * @retval HAL status
502 */
HAL_MMC_DeInit(MMC_HandleTypeDef * hmmc)503 HAL_StatusTypeDef HAL_MMC_DeInit(MMC_HandleTypeDef *hmmc)
504 {
505 /* Check the MMC handle allocation */
506 if(hmmc == NULL)
507 {
508 return HAL_ERROR;
509 }
510
511 /* Check the parameters */
512 assert_param(IS_SDIO_ALL_INSTANCE(hmmc->Instance));
513
514 hmmc->State = HAL_MMC_STATE_BUSY;
515
516 /* Set MMC power state to off */
517 MMC_PowerOFF(hmmc);
518
519 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
520 if(hmmc->MspDeInitCallback == NULL)
521 {
522 hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
523 }
524
525 /* DeInit the low level hardware */
526 hmmc->MspDeInitCallback(hmmc);
527 #else
528 /* De-Initialize the MSP layer */
529 HAL_MMC_MspDeInit(hmmc);
530 #endif
531
532 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
533 hmmc->State = HAL_MMC_STATE_RESET;
534
535 return HAL_OK;
536 }
537
538
539 /**
540 * @brief Initializes the MMC MSP.
541 * @param hmmc: Pointer to MMC handle
542 * @retval None
543 */
HAL_MMC_MspInit(MMC_HandleTypeDef * hmmc)544 __weak void HAL_MMC_MspInit(MMC_HandleTypeDef *hmmc)
545 {
546 /* Prevent unused argument(s) compilation warning */
547 UNUSED(hmmc);
548
549 /* NOTE : This function Should not be modified, when the callback is needed,
550 the HAL_MMC_MspInit could be implemented in the user file
551 */
552 }
553
554 /**
555 * @brief De-Initialize MMC MSP.
556 * @param hmmc: Pointer to MMC handle
557 * @retval None
558 */
HAL_MMC_MspDeInit(MMC_HandleTypeDef * hmmc)559 __weak void HAL_MMC_MspDeInit(MMC_HandleTypeDef *hmmc)
560 {
561 /* Prevent unused argument(s) compilation warning */
562 UNUSED(hmmc);
563
564 /* NOTE : This function Should not be modified, when the callback is needed,
565 the HAL_MMC_MspDeInit could be implemented in the user file
566 */
567 }
568
569 /**
570 * @}
571 */
572
573 /** @addtogroup MMC_Exported_Functions_Group2
574 * @brief Data transfer functions
575 *
576 @verbatim
577 ==============================================================================
578 ##### IO operation functions #####
579 ==============================================================================
580 [..]
581 This subsection provides a set of functions allowing to manage the data
582 transfer from/to MMC card.
583
584 @endverbatim
585 * @{
586 */
587
588 /**
589 * @brief Reads block(s) from a specified address in a card. The Data transfer
590 * is managed by polling mode.
591 * @note This API should be followed by a check on the card state through
592 * HAL_MMC_GetCardState().
593 * @param hmmc: Pointer to MMC handle
594 * @param pData: pointer to the buffer that will contain the received data
595 * @param BlockAdd: Block Address from where data is to be read
596 * @param NumberOfBlocks: Number of MMC blocks to read
597 * @param Timeout: Specify timeout value
598 * @retval HAL status
599 */
HAL_MMC_ReadBlocks(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks,uint32_t Timeout)600 HAL_StatusTypeDef HAL_MMC_ReadBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
601 {
602 SDIO_DataInitTypeDef config;
603 uint32_t errorstate;
604 uint32_t tickstart = HAL_GetTick();
605 uint32_t count, data, dataremaining;
606 uint32_t add = BlockAdd;
607 uint8_t *tempbuff = pData;
608
609 if(NULL == pData)
610 {
611 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
612 return HAL_ERROR;
613 }
614
615 if(hmmc->State == HAL_MMC_STATE_READY)
616 {
617 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
618
619 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
620 {
621 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
622 return HAL_ERROR;
623 }
624
625 hmmc->State = HAL_MMC_STATE_BUSY;
626
627 /* Initialize data control register */
628 hmmc->Instance->DCTRL = 0U;
629
630 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
631 {
632 add *= 512U;
633 }
634
635 /* Configure the MMC DPSM (Data Path State Machine) */
636 config.DataTimeOut = SDMMC_DATATIMEOUT;
637 config.DataLength = NumberOfBlocks * MMC_BLOCKSIZE;
638 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
639 config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
640 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
641 config.DPSM = SDIO_DPSM_ENABLE;
642 (void)SDIO_ConfigData(hmmc->Instance, &config);
643
644 /* Read block(s) in polling mode */
645 if(NumberOfBlocks > 1U)
646 {
647 hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
648
649 /* Read Multi Block command */
650 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
651 }
652 else
653 {
654 hmmc->Context = MMC_CONTEXT_READ_SINGLE_BLOCK;
655
656 /* Read Single Block command */
657 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
658 }
659 if(errorstate != HAL_MMC_ERROR_NONE)
660 {
661 /* Clear all the static flags */
662 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
663 hmmc->ErrorCode |= errorstate;
664 hmmc->State = HAL_MMC_STATE_READY;
665 return HAL_ERROR;
666 }
667
668 /* Poll on SDIO flags */
669 dataremaining = config.DataLength;
670 #if defined(SDIO_STA_STBITERR)
671 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_FLAG_STBITERR))
672 #else /* SDIO_STA_STBITERR not defined */
673 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND))
674 #endif /* SDIO_STA_STBITERR */
675 {
676 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXFIFOHF) && (dataremaining > 0U))
677 {
678 /* Read data from SDIO Rx FIFO */
679 for(count = 0U; count < 8U; count++)
680 {
681 data = SDIO_ReadFIFO(hmmc->Instance);
682 *tempbuff = (uint8_t)(data & 0xFFU);
683 tempbuff++;
684 dataremaining--;
685 *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
686 tempbuff++;
687 dataremaining--;
688 *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
689 tempbuff++;
690 dataremaining--;
691 *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
692 tempbuff++;
693 dataremaining--;
694 }
695 }
696
697 if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U))
698 {
699 /* Clear all the static flags */
700 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
701 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
702 hmmc->State= HAL_MMC_STATE_READY;
703 return HAL_TIMEOUT;
704 }
705 }
706
707 /* Send stop transmission command in case of multiblock read */
708 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1U))
709 {
710 /* Send stop transmission command */
711 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
712 if(errorstate != HAL_MMC_ERROR_NONE)
713 {
714 /* Clear all the static flags */
715 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
716 hmmc->ErrorCode |= errorstate;
717 hmmc->State = HAL_MMC_STATE_READY;
718 return HAL_ERROR;
719 }
720 }
721
722 /* Get error state */
723 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DTIMEOUT))
724 {
725 /* Clear all the static flags */
726 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
727 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
728 hmmc->State = HAL_MMC_STATE_READY;
729 return HAL_ERROR;
730 }
731 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL))
732 {
733 /* Clear all the static flags */
734 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
735 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
736 hmmc->State = HAL_MMC_STATE_READY;
737 return HAL_ERROR;
738 }
739 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR))
740 {
741 /* Clear all the static flags */
742 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
743 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
744 hmmc->State = HAL_MMC_STATE_READY;
745 return HAL_ERROR;
746 }
747 else
748 {
749 /* Nothing to do */
750 }
751
752 /* Empty FIFO if there is still any data */
753 while ((__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXDAVL)) && (dataremaining > 0U))
754 {
755 data = SDIO_ReadFIFO(hmmc->Instance);
756 *tempbuff = (uint8_t)(data & 0xFFU);
757 tempbuff++;
758 dataremaining--;
759 *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
760 tempbuff++;
761 dataremaining--;
762 *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
763 tempbuff++;
764 dataremaining--;
765 *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
766 tempbuff++;
767 dataremaining--;
768
769 if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U))
770 {
771 /* Clear all the static flags */
772 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
773 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
774 hmmc->State= HAL_MMC_STATE_READY;
775 return HAL_ERROR;
776 }
777 }
778
779 /* Clear all the static flags */
780 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
781
782 hmmc->State = HAL_MMC_STATE_READY;
783
784 return HAL_OK;
785 }
786 else
787 {
788 hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
789 return HAL_ERROR;
790 }
791 }
792
793 /**
794 * @brief Allows to write block(s) to a specified address in a card. The Data
795 * transfer is managed by polling mode.
796 * @note This API should be followed by a check on the card state through
797 * HAL_MMC_GetCardState().
798 * @param hmmc: Pointer to MMC handle
799 * @param pData: pointer to the buffer that will contain the data to transmit
800 * @param BlockAdd: Block Address where data will be written
801 * @param NumberOfBlocks: Number of MMC blocks to write
802 * @param Timeout: Specify timeout value
803 * @retval HAL status
804 */
HAL_MMC_WriteBlocks(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks,uint32_t Timeout)805 HAL_StatusTypeDef HAL_MMC_WriteBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
806 {
807 SDIO_DataInitTypeDef config;
808 uint32_t errorstate;
809 uint32_t tickstart = HAL_GetTick();
810 uint32_t count, data, dataremaining;
811 uint32_t add = BlockAdd;
812 uint8_t *tempbuff = pData;
813
814 if(NULL == pData)
815 {
816 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
817 return HAL_ERROR;
818 }
819
820 if(hmmc->State == HAL_MMC_STATE_READY)
821 {
822 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
823
824 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
825 {
826 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
827 return HAL_ERROR;
828 }
829
830 hmmc->State = HAL_MMC_STATE_BUSY;
831
832 /* Initialize data control register */
833 hmmc->Instance->DCTRL = 0U;
834
835 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
836 {
837 add *= 512U;
838 }
839
840 /* Write Blocks in Polling mode */
841 if(NumberOfBlocks > 1U)
842 {
843 hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
844
845 /* Write Multi Block command */
846 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
847 }
848 else
849 {
850 hmmc->Context = MMC_CONTEXT_WRITE_SINGLE_BLOCK;
851
852 /* Write Single Block command */
853 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
854 }
855 if(errorstate != HAL_MMC_ERROR_NONE)
856 {
857 /* Clear all the static flags */
858 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
859 hmmc->ErrorCode |= errorstate;
860 hmmc->State = HAL_MMC_STATE_READY;
861 return HAL_ERROR;
862 }
863
864 /* Configure the MMC DPSM (Data Path State Machine) */
865 config.DataTimeOut = SDMMC_DATATIMEOUT;
866 config.DataLength = NumberOfBlocks * MMC_BLOCKSIZE;
867 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
868 config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
869 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
870 config.DPSM = SDIO_DPSM_ENABLE;
871 (void)SDIO_ConfigData(hmmc->Instance, &config);
872
873 /* Write block(s) in polling mode */
874 dataremaining = config.DataLength;
875 #if defined(SDIO_STA_STBITERR)
876 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_FLAG_STBITERR))
877 #else /* SDIO_STA_STBITERR not defined */
878 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND))
879 #endif /* SDIO_STA_STBITERR */
880 {
881 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXFIFOHE) && (dataremaining > 0U))
882 {
883 /* Write data to SDIO Tx FIFO */
884 for(count = 0U; count < 8U; count++)
885 {
886 data = (uint32_t)(*tempbuff);
887 tempbuff++;
888 dataremaining--;
889 data |= ((uint32_t)(*tempbuff) << 8U);
890 tempbuff++;
891 dataremaining--;
892 data |= ((uint32_t)(*tempbuff) << 16U);
893 tempbuff++;
894 dataremaining--;
895 data |= ((uint32_t)(*tempbuff) << 24U);
896 tempbuff++;
897 dataremaining--;
898 (void)SDIO_WriteFIFO(hmmc->Instance, &data);
899 }
900 }
901
902 if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U))
903 {
904 /* Clear all the static flags */
905 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
906 hmmc->ErrorCode |= errorstate;
907 hmmc->State = HAL_MMC_STATE_READY;
908 return HAL_TIMEOUT;
909 }
910 }
911
912 /* Send stop transmission command in case of multiblock write */
913 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1U))
914 {
915 /* Send stop transmission command */
916 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
917 if(errorstate != HAL_MMC_ERROR_NONE)
918 {
919 /* Clear all the static flags */
920 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
921 hmmc->ErrorCode |= errorstate;
922 hmmc->State = HAL_MMC_STATE_READY;
923 return HAL_ERROR;
924 }
925 }
926
927 /* Get error state */
928 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DTIMEOUT))
929 {
930 /* Clear all the static flags */
931 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
932 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
933 hmmc->State = HAL_MMC_STATE_READY;
934 return HAL_ERROR;
935 }
936 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL))
937 {
938 /* Clear all the static flags */
939 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
940 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
941 hmmc->State = HAL_MMC_STATE_READY;
942 return HAL_ERROR;
943 }
944 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR))
945 {
946 /* Clear all the static flags */
947 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
948 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
949 hmmc->State = HAL_MMC_STATE_READY;
950 return HAL_ERROR;
951 }
952 else
953 {
954 /* Nothing to do */
955 }
956
957 /* Clear all the static flags */
958 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
959
960 hmmc->State = HAL_MMC_STATE_READY;
961
962 return HAL_OK;
963 }
964 else
965 {
966 hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
967 return HAL_ERROR;
968 }
969 }
970
971 /**
972 * @brief Reads block(s) from a specified address in a card. The Data transfer
973 * is managed in interrupt mode.
974 * @note This API should be followed by a check on the card state through
975 * HAL_MMC_GetCardState().
976 * @note You could also check the IT transfer process through the MMC Rx
977 * interrupt event.
978 * @param hmmc: Pointer to MMC handle
979 * @param pData: Pointer to the buffer that will contain the received data
980 * @param BlockAdd: Block Address from where data is to be read
981 * @param NumberOfBlocks: Number of blocks to read.
982 * @retval HAL status
983 */
HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)984 HAL_StatusTypeDef HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
985 {
986 SDIO_DataInitTypeDef config;
987 uint32_t errorstate;
988 uint32_t add = BlockAdd;
989
990 if(NULL == pData)
991 {
992 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
993 return HAL_ERROR;
994 }
995
996 if(hmmc->State == HAL_MMC_STATE_READY)
997 {
998 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
999
1000 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1001 {
1002 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1003 return HAL_ERROR;
1004 }
1005
1006 hmmc->State = HAL_MMC_STATE_BUSY;
1007
1008 /* Initialize data control register */
1009 hmmc->Instance->DCTRL = 0U;
1010
1011 hmmc->pRxBuffPtr = pData;
1012 hmmc->RxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1013
1014 #if defined(SDIO_STA_STBITERR)
1015 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_FLAG_RXFIFOHF | SDIO_IT_STBITERR));
1016 #else /* SDIO_STA_STBITERR not defined */
1017 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_FLAG_RXFIFOHF));
1018 #endif /* SDIO_STA_STBITERR */
1019
1020 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1021 {
1022 add *= 512U;
1023 }
1024
1025 /* Configure the MMC DPSM (Data Path State Machine) */
1026 config.DataTimeOut = SDMMC_DATATIMEOUT;
1027 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks;
1028 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
1029 config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
1030 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
1031 config.DPSM = SDIO_DPSM_ENABLE;
1032 (void)SDIO_ConfigData(hmmc->Instance, &config);
1033
1034 /* Read Blocks in IT mode */
1035 if(NumberOfBlocks > 1U)
1036 {
1037 hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_IT);
1038
1039 /* Read Multi Block command */
1040 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
1041 }
1042 else
1043 {
1044 hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_IT);
1045
1046 /* Read Single Block command */
1047 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
1048 }
1049
1050 if(errorstate != HAL_MMC_ERROR_NONE)
1051 {
1052 /* Clear all the static flags */
1053 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1054 hmmc->ErrorCode |= errorstate;
1055 hmmc->State = HAL_MMC_STATE_READY;
1056 return HAL_ERROR;
1057 }
1058
1059 return HAL_OK;
1060 }
1061 else
1062 {
1063 return HAL_BUSY;
1064 }
1065 }
1066
1067 /**
1068 * @brief Writes block(s) to a specified address in a card. The Data transfer
1069 * is managed in interrupt mode.
1070 * @note This API should be followed by a check on the card state through
1071 * HAL_MMC_GetCardState().
1072 * @note You could also check the IT transfer process through the MMC Tx
1073 * interrupt event.
1074 * @param hmmc: Pointer to MMC handle
1075 * @param pData: Pointer to the buffer that will contain the data to transmit
1076 * @param BlockAdd: Block Address where data will be written
1077 * @param NumberOfBlocks: Number of blocks to write
1078 * @retval HAL status
1079 */
HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)1080 HAL_StatusTypeDef HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
1081 {
1082 SDIO_DataInitTypeDef config;
1083 uint32_t errorstate;
1084 uint32_t add = BlockAdd;
1085
1086 if(NULL == pData)
1087 {
1088 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1089 return HAL_ERROR;
1090 }
1091
1092 if(hmmc->State == HAL_MMC_STATE_READY)
1093 {
1094 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1095
1096 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1097 {
1098 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1099 return HAL_ERROR;
1100 }
1101
1102 hmmc->State = HAL_MMC_STATE_BUSY;
1103
1104 /* Initialize data control register */
1105 hmmc->Instance->DCTRL = 0U;
1106
1107 hmmc->pTxBuffPtr = pData;
1108 hmmc->TxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1109
1110 /* Enable transfer interrupts */
1111 #if defined(SDIO_STA_STBITERR)
1112 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_DATAEND | SDIO_FLAG_TXFIFOHE | SDIO_IT_STBITERR));
1113 #else /* SDIO_STA_STBITERR not defined */
1114 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_DATAEND | SDIO_FLAG_TXFIFOHE));
1115 #endif /* SDIO_STA_STBITERR */
1116
1117 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1118 {
1119 add *= 512U;
1120 }
1121
1122 /* Write Blocks in Polling mode */
1123 if(NumberOfBlocks > 1U)
1124 {
1125 hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK| MMC_CONTEXT_IT);
1126
1127 /* Write Multi Block command */
1128 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
1129 }
1130 else
1131 {
1132 hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_IT);
1133
1134 /* Write Single Block command */
1135 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
1136 }
1137 if(errorstate != HAL_MMC_ERROR_NONE)
1138 {
1139 /* Clear all the static flags */
1140 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1141 hmmc->ErrorCode |= errorstate;
1142 hmmc->State = HAL_MMC_STATE_READY;
1143 return HAL_ERROR;
1144 }
1145
1146 /* Configure the MMC DPSM (Data Path State Machine) */
1147 config.DataTimeOut = SDMMC_DATATIMEOUT;
1148 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks;
1149 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
1150 config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
1151 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
1152 config.DPSM = SDIO_DPSM_ENABLE;
1153 (void)SDIO_ConfigData(hmmc->Instance, &config);
1154
1155 return HAL_OK;
1156 }
1157 else
1158 {
1159 return HAL_BUSY;
1160 }
1161 }
1162
1163 /**
1164 * @brief Reads block(s) from a specified address in a card. The Data transfer
1165 * is managed by DMA mode.
1166 * @note This API should be followed by a check on the card state through
1167 * HAL_MMC_GetCardState().
1168 * @note You could also check the DMA transfer process through the MMC Rx
1169 * interrupt event.
1170 * @param hmmc: Pointer MMC handle
1171 * @param pData: Pointer to the buffer that will contain the received data
1172 * @param BlockAdd: Block Address from where data is to be read
1173 * @param NumberOfBlocks: Number of blocks to read.
1174 * @retval HAL status
1175 */
HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)1176 HAL_StatusTypeDef HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
1177 {
1178 SDIO_DataInitTypeDef config;
1179 uint32_t errorstate;
1180 uint32_t add = BlockAdd;
1181
1182 if(NULL == pData)
1183 {
1184 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1185 return HAL_ERROR;
1186 }
1187
1188 if(hmmc->State == HAL_MMC_STATE_READY)
1189 {
1190 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1191
1192 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1193 {
1194 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1195 return HAL_ERROR;
1196 }
1197
1198 hmmc->State = HAL_MMC_STATE_BUSY;
1199
1200 /* Initialize data control register */
1201 hmmc->Instance->DCTRL = 0U;
1202
1203 #if defined(SDIO_STA_STBITERR)
1204 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_IT_STBITERR));
1205 #else /* SDIO_STA_STBITERR not defined */
1206 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND));
1207 #endif /* SDIO_STA_STBITERR */
1208
1209 /* Set the DMA transfer complete callback */
1210 hmmc->hdmarx->XferCpltCallback = MMC_DMAReceiveCplt;
1211
1212 /* Set the DMA error callback */
1213 hmmc->hdmarx->XferErrorCallback = MMC_DMAError;
1214
1215 /* Set the DMA Abort callback */
1216 hmmc->hdmarx->XferAbortCallback = NULL;
1217
1218 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1219 {
1220 add *= 512U;
1221 }
1222
1223 /* Force DMA Direction */
1224 hmmc->hdmarx->Init.Direction = DMA_PERIPH_TO_MEMORY;
1225 MODIFY_REG(hmmc->hdmarx->Instance->CR, DMA_SxCR_DIR, hmmc->hdmarx->Init.Direction);
1226
1227 /* Enable the DMA Channel */
1228 if(HAL_DMA_Start_IT(hmmc->hdmarx, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)pData, (uint32_t)(MMC_BLOCKSIZE * NumberOfBlocks)/4) != HAL_OK)
1229 {
1230 __HAL_MMC_DISABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND));
1231 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1232 hmmc->ErrorCode = HAL_MMC_ERROR_DMA;
1233 hmmc->State = HAL_MMC_STATE_READY;
1234 return HAL_ERROR;
1235 }
1236 else
1237 {
1238 /* Enable MMC DMA transfer */
1239 __HAL_MMC_DMA_ENABLE(hmmc);
1240
1241 /* Configure the MMC DPSM (Data Path State Machine) */
1242 config.DataTimeOut = SDMMC_DATATIMEOUT;
1243 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks;
1244 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
1245 config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
1246 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
1247 config.DPSM = SDIO_DPSM_ENABLE;
1248 (void)SDIO_ConfigData(hmmc->Instance, &config);
1249
1250 /* Read Blocks in DMA mode */
1251 if(NumberOfBlocks > 1U)
1252 {
1253 hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
1254
1255 /* Read Multi Block command */
1256 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
1257 }
1258 else
1259 {
1260 hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_DMA);
1261
1262 /* Read Single Block command */
1263 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
1264 }
1265 if(errorstate != HAL_MMC_ERROR_NONE)
1266 {
1267 /* Clear all the static flags */
1268 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1269 __HAL_MMC_DISABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND));
1270 hmmc->ErrorCode = errorstate;
1271 hmmc->State = HAL_MMC_STATE_READY;
1272 return HAL_ERROR;
1273 }
1274
1275 return HAL_OK;
1276 }
1277 }
1278 else
1279 {
1280 return HAL_BUSY;
1281 }
1282 }
1283
1284 /**
1285 * @brief Writes block(s) to a specified address in a card. The Data transfer
1286 * is managed by DMA mode.
1287 * @note This API should be followed by a check on the card state through
1288 * HAL_MMC_GetCardState().
1289 * @note You could also check the DMA transfer process through the MMC Tx
1290 * interrupt event.
1291 * @param hmmc: Pointer to MMC handle
1292 * @param pData: Pointer to the buffer that will contain the data to transmit
1293 * @param BlockAdd: Block Address where data will be written
1294 * @param NumberOfBlocks: Number of blocks to write
1295 * @retval HAL status
1296 */
HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)1297 HAL_StatusTypeDef HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
1298 {
1299 SDIO_DataInitTypeDef config;
1300 uint32_t errorstate;
1301 uint32_t add = BlockAdd;
1302
1303 if(NULL == pData)
1304 {
1305 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1306 return HAL_ERROR;
1307 }
1308
1309 if(hmmc->State == HAL_MMC_STATE_READY)
1310 {
1311 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1312
1313 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1314 {
1315 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1316 return HAL_ERROR;
1317 }
1318
1319 hmmc->State = HAL_MMC_STATE_BUSY;
1320
1321 /* Initialize data control register */
1322 hmmc->Instance->DCTRL = 0U;
1323
1324 /* Enable MMC Error interrupts */
1325 #if defined(SDIO_STA_STBITERR)
1326 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR));
1327 #else /* SDIO_STA_STBITERR not defined */
1328 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR));
1329 #endif /* SDIO_STA_STBITERR */
1330
1331 /* Set the DMA transfer complete callback */
1332 hmmc->hdmatx->XferCpltCallback = MMC_DMATransmitCplt;
1333
1334 /* Set the DMA error callback */
1335 hmmc->hdmatx->XferErrorCallback = MMC_DMAError;
1336
1337 /* Set the DMA Abort callback */
1338 hmmc->hdmatx->XferAbortCallback = NULL;
1339
1340 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1341 {
1342 add *= 512U;
1343 }
1344
1345
1346 /* Write Blocks in Polling mode */
1347 if(NumberOfBlocks > 1U)
1348 {
1349 hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
1350
1351 /* Write Multi Block command */
1352 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
1353 }
1354 else
1355 {
1356 hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_DMA);
1357
1358 /* Write Single Block command */
1359 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
1360 }
1361 if(errorstate != HAL_MMC_ERROR_NONE)
1362 {
1363 /* Clear all the static flags */
1364 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1365 __HAL_MMC_DISABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_DATAEND));
1366 hmmc->ErrorCode |= errorstate;
1367 hmmc->State = HAL_MMC_STATE_READY;
1368 return HAL_ERROR;
1369 }
1370
1371 /* Enable SDIO DMA transfer */
1372 __HAL_MMC_DMA_ENABLE(hmmc);
1373
1374 /* Force DMA Direction */
1375 hmmc->hdmatx->Init.Direction = DMA_MEMORY_TO_PERIPH;
1376 MODIFY_REG(hmmc->hdmatx->Instance->CR, DMA_SxCR_DIR, hmmc->hdmatx->Init.Direction);
1377
1378 /* Enable the DMA Channel */
1379 if(HAL_DMA_Start_IT(hmmc->hdmatx, (uint32_t)pData, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)(MMC_BLOCKSIZE * NumberOfBlocks)/4) != HAL_OK)
1380 {
1381 __HAL_MMC_DISABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_DATAEND));
1382 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1383 hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
1384 hmmc->State = HAL_MMC_STATE_READY;
1385 return HAL_ERROR;
1386 }
1387 else
1388 {
1389 /* Configure the MMC DPSM (Data Path State Machine) */
1390 config.DataTimeOut = SDMMC_DATATIMEOUT;
1391 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks;
1392 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
1393 config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
1394 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
1395 config.DPSM = SDIO_DPSM_ENABLE;
1396 (void)SDIO_ConfigData(hmmc->Instance, &config);
1397
1398 return HAL_OK;
1399 }
1400 }
1401 else
1402 {
1403 return HAL_BUSY;
1404 }
1405 }
1406
1407 /**
1408 * @brief Erases the specified memory area of the given MMC card.
1409 * @note This API should be followed by a check on the card state through
1410 * HAL_MMC_GetCardState().
1411 * @param hmmc: Pointer to MMC handle
1412 * @param BlockStartAdd: Start Block address
1413 * @param BlockEndAdd: End Block address
1414 * @retval HAL status
1415 */
HAL_MMC_Erase(MMC_HandleTypeDef * hmmc,uint32_t BlockStartAdd,uint32_t BlockEndAdd)1416 HAL_StatusTypeDef HAL_MMC_Erase(MMC_HandleTypeDef *hmmc, uint32_t BlockStartAdd, uint32_t BlockEndAdd)
1417 {
1418 uint32_t errorstate;
1419 uint32_t start_add = BlockStartAdd;
1420 uint32_t end_add = BlockEndAdd;
1421
1422 if(hmmc->State == HAL_MMC_STATE_READY)
1423 {
1424 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1425
1426 if(end_add < start_add)
1427 {
1428 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1429 return HAL_ERROR;
1430 }
1431
1432 if(end_add > (hmmc->MmcCard.LogBlockNbr))
1433 {
1434 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1435 return HAL_ERROR;
1436 }
1437
1438 hmmc->State = HAL_MMC_STATE_BUSY;
1439
1440 /* Check if the card command class supports erase command */
1441 if(((hmmc->MmcCard.Class) & SDIO_CCCC_ERASE) == 0U)
1442 {
1443 /* Clear all the static flags */
1444 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1445 hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
1446 hmmc->State = HAL_MMC_STATE_READY;
1447 return HAL_ERROR;
1448 }
1449
1450 if((SDIO_GetResponse(hmmc->Instance, SDIO_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
1451 {
1452 /* Clear all the static flags */
1453 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1454 hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED;
1455 hmmc->State = HAL_MMC_STATE_READY;
1456 return HAL_ERROR;
1457 }
1458
1459 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1460 {
1461 start_add *= 512U;
1462 end_add *= 512U;
1463 }
1464
1465 /* Send CMD35 MMC_ERASE_GRP_START with argument as addr */
1466 errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, start_add);
1467 if(errorstate != HAL_MMC_ERROR_NONE)
1468 {
1469 /* Clear all the static flags */
1470 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1471 hmmc->ErrorCode |= errorstate;
1472 hmmc->State = HAL_MMC_STATE_READY;
1473 return HAL_ERROR;
1474 }
1475
1476 /* Send CMD36 MMC_ERASE_GRP_END with argument as addr */
1477 errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, end_add);
1478 if(errorstate != HAL_MMC_ERROR_NONE)
1479 {
1480 /* Clear all the static flags */
1481 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1482 hmmc->ErrorCode |= errorstate;
1483 hmmc->State = HAL_MMC_STATE_READY;
1484 return HAL_ERROR;
1485 }
1486
1487 /* Send CMD38 ERASE */
1488 errorstate = SDMMC_CmdErase(hmmc->Instance);
1489 if(errorstate != HAL_MMC_ERROR_NONE)
1490 {
1491 /* Clear all the static flags */
1492 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1493 hmmc->ErrorCode |= errorstate;
1494 hmmc->State = HAL_MMC_STATE_READY;
1495 return HAL_ERROR;
1496 }
1497
1498 hmmc->State = HAL_MMC_STATE_READY;
1499
1500 return HAL_OK;
1501 }
1502 else
1503 {
1504 return HAL_BUSY;
1505 }
1506 }
1507
1508 /**
1509 * @brief This function handles MMC card interrupt request.
1510 * @param hmmc: Pointer to MMC handle
1511 * @retval None
1512 */
HAL_MMC_IRQHandler(MMC_HandleTypeDef * hmmc)1513 void HAL_MMC_IRQHandler(MMC_HandleTypeDef *hmmc)
1514 {
1515 uint32_t errorstate;
1516 uint32_t context = hmmc->Context;
1517
1518 /* Check for SDIO interrupt flags */
1519 if((__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXFIFOHF) != RESET) && ((context & MMC_CONTEXT_IT) != 0U))
1520 {
1521 MMC_Read_IT(hmmc);
1522 }
1523
1524 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DATAEND) != RESET)
1525 {
1526 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_FLAG_DATAEND);
1527
1528 #if defined(SDIO_STA_STBITERR)
1529 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
1530 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR | SDIO_IT_STBITERR);
1531 #else /* SDIO_STA_STBITERR not defined */
1532 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT |\
1533 SDIO_IT_TXUNDERR | SDIO_IT_RXOVERR | SDIO_IT_TXFIFOHE |\
1534 SDIO_IT_RXFIFOHF);
1535 #endif /* SDIO_STA_STBITERR */
1536
1537 hmmc->Instance->DCTRL &= ~(SDIO_DCTRL_DTEN);
1538
1539 if((context & MMC_CONTEXT_DMA) != 0U)
1540 {
1541 if((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)
1542 {
1543 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
1544 if(errorstate != HAL_MMC_ERROR_NONE)
1545 {
1546 hmmc->ErrorCode |= errorstate;
1547 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1548 hmmc->ErrorCallback(hmmc);
1549 #else
1550 HAL_MMC_ErrorCallback(hmmc);
1551 #endif
1552 }
1553 }
1554 if(((context & MMC_CONTEXT_READ_SINGLE_BLOCK) == 0U) && ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) == 0U))
1555 {
1556 /* Disable the DMA transfer for transmit request by setting the DMAEN bit
1557 in the MMC DCTRL register */
1558 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
1559
1560 hmmc->State = HAL_MMC_STATE_READY;
1561
1562 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1563 hmmc->TxCpltCallback(hmmc);
1564 #else
1565 HAL_MMC_TxCpltCallback(hmmc);
1566 #endif
1567 }
1568 }
1569 else if((context & MMC_CONTEXT_IT) != 0U)
1570 {
1571 /* Stop Transfer for Write Multi blocks or Read Multi blocks */
1572 if(((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
1573 {
1574 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
1575 if(errorstate != HAL_MMC_ERROR_NONE)
1576 {
1577 hmmc->ErrorCode |= errorstate;
1578 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1579 hmmc->ErrorCallback(hmmc);
1580 #else
1581 HAL_MMC_ErrorCallback(hmmc);
1582 #endif
1583 }
1584 }
1585
1586 /* Clear all the static flags */
1587 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
1588
1589 hmmc->State = HAL_MMC_STATE_READY;
1590 if(((context & MMC_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
1591 {
1592 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1593 hmmc->RxCpltCallback(hmmc);
1594 #else
1595 HAL_MMC_RxCpltCallback(hmmc);
1596 #endif
1597 }
1598 else
1599 {
1600 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1601 hmmc->TxCpltCallback(hmmc);
1602 #else
1603 HAL_MMC_TxCpltCallback(hmmc);
1604 #endif
1605 }
1606 }
1607 else
1608 {
1609 /* Nothing to do */
1610 }
1611 }
1612
1613 else if((__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXFIFOHE) != RESET) && ((context & MMC_CONTEXT_IT) != 0U))
1614 {
1615 MMC_Write_IT(hmmc);
1616 }
1617
1618 #if defined(SDIO_STA_STBITERR)
1619 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_RXOVERR | SDIO_FLAG_TXUNDERR | SDIO_FLAG_STBITERR) != RESET)
1620 #else /* SDIO_STA_STBITERR not defined */
1621 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_RXOVERR | SDIO_FLAG_TXUNDERR) != RESET)
1622 #endif /* SDIO_STA_STBITERR */
1623 {
1624 /* Set Error code */
1625 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL) != RESET)
1626 {
1627 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
1628 }
1629 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DTIMEOUT) != RESET)
1630 {
1631 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
1632 }
1633 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR) != RESET)
1634 {
1635 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
1636 }
1637 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR) != RESET)
1638 {
1639 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
1640 }
1641 #if defined(SDIO_STA_STBITERR)
1642 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_STBITERR) != RESET)
1643 {
1644 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
1645 }
1646 #endif /* SDIO_STA_STBITERR */
1647
1648 #if defined(SDIO_STA_STBITERR)
1649 /* Clear All flags */
1650 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS | SDIO_FLAG_STBITERR);
1651
1652 /* Disable all interrupts */
1653 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
1654 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR | SDIO_IT_STBITERR);
1655 #else /* SDIO_STA_STBITERR */
1656 /* Clear All flags */
1657 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
1658
1659 /* Disable all interrupts */
1660 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
1661 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
1662 #endif /* SDIO_STA_STBITERR */
1663
1664 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
1665
1666 if((context & MMC_CONTEXT_IT) != 0U)
1667 {
1668 /* Set the MMC state to ready to be able to start again the process */
1669 hmmc->State = HAL_MMC_STATE_READY;
1670 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1671 hmmc->ErrorCallback(hmmc);
1672 #else
1673 HAL_MMC_ErrorCallback(hmmc);
1674 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1675 }
1676 else if((context & MMC_CONTEXT_DMA) != 0U)
1677 {
1678 /* Abort the MMC DMA Streams */
1679 if(hmmc->hdmatx != NULL)
1680 {
1681 /* Set the DMA Tx abort callback */
1682 hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort;
1683 /* Abort DMA in IT mode */
1684 if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
1685 {
1686 MMC_DMATxAbort(hmmc->hdmatx);
1687 }
1688 }
1689 else if(hmmc->hdmarx != NULL)
1690 {
1691 /* Set the DMA Rx abort callback */
1692 hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort;
1693 /* Abort DMA in IT mode */
1694 if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
1695 {
1696 MMC_DMARxAbort(hmmc->hdmarx);
1697 }
1698 }
1699 else
1700 {
1701 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1702 hmmc->State = HAL_MMC_STATE_READY;
1703 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1704 hmmc->AbortCpltCallback(hmmc);
1705 #else
1706 HAL_MMC_AbortCallback(hmmc);
1707 #endif
1708 }
1709 }
1710 else
1711 {
1712 /* Nothing to do */
1713 }
1714 }
1715
1716 else
1717 {
1718 /* Nothing to do */
1719 }
1720 }
1721
1722 /**
1723 * @brief return the MMC state
1724 * @param hmmc: Pointer to mmc handle
1725 * @retval HAL state
1726 */
HAL_MMC_GetState(MMC_HandleTypeDef * hmmc)1727 HAL_MMC_StateTypeDef HAL_MMC_GetState(MMC_HandleTypeDef *hmmc)
1728 {
1729 return hmmc->State;
1730 }
1731
1732 /**
1733 * @brief Return the MMC error code
1734 * @param hmmc : Pointer to a MMC_HandleTypeDef structure that contains
1735 * the configuration information.
1736 * @retval MMC Error Code
1737 */
HAL_MMC_GetError(MMC_HandleTypeDef * hmmc)1738 uint32_t HAL_MMC_GetError(MMC_HandleTypeDef *hmmc)
1739 {
1740 return hmmc->ErrorCode;
1741 }
1742
1743 /**
1744 * @brief Tx Transfer completed callbacks
1745 * @param hmmc: Pointer to MMC handle
1746 * @retval None
1747 */
HAL_MMC_TxCpltCallback(MMC_HandleTypeDef * hmmc)1748 __weak void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef *hmmc)
1749 {
1750 /* Prevent unused argument(s) compilation warning */
1751 UNUSED(hmmc);
1752
1753 /* NOTE : This function should not be modified, when the callback is needed,
1754 the HAL_MMC_TxCpltCallback can be implemented in the user file
1755 */
1756 }
1757
1758 /**
1759 * @brief Rx Transfer completed callbacks
1760 * @param hmmc: Pointer MMC handle
1761 * @retval None
1762 */
HAL_MMC_RxCpltCallback(MMC_HandleTypeDef * hmmc)1763 __weak void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef *hmmc)
1764 {
1765 /* Prevent unused argument(s) compilation warning */
1766 UNUSED(hmmc);
1767
1768 /* NOTE : This function should not be modified, when the callback is needed,
1769 the HAL_MMC_RxCpltCallback can be implemented in the user file
1770 */
1771 }
1772
1773 /**
1774 * @brief MMC error callbacks
1775 * @param hmmc: Pointer MMC handle
1776 * @retval None
1777 */
HAL_MMC_ErrorCallback(MMC_HandleTypeDef * hmmc)1778 __weak void HAL_MMC_ErrorCallback(MMC_HandleTypeDef *hmmc)
1779 {
1780 /* Prevent unused argument(s) compilation warning */
1781 UNUSED(hmmc);
1782
1783 /* NOTE : This function should not be modified, when the callback is needed,
1784 the HAL_MMC_ErrorCallback can be implemented in the user file
1785 */
1786 }
1787
1788 /**
1789 * @brief MMC Abort callbacks
1790 * @param hmmc: Pointer MMC handle
1791 * @retval None
1792 */
HAL_MMC_AbortCallback(MMC_HandleTypeDef * hmmc)1793 __weak void HAL_MMC_AbortCallback(MMC_HandleTypeDef *hmmc)
1794 {
1795 /* Prevent unused argument(s) compilation warning */
1796 UNUSED(hmmc);
1797
1798 /* NOTE : This function should not be modified, when the callback is needed,
1799 the HAL_MMC_AbortCallback can be implemented in the user file
1800 */
1801 }
1802
1803 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1804 /**
1805 * @brief Register a User MMC Callback
1806 * To be used instead of the weak (surcharged) predefined callback
1807 * @param hmmc : MMC handle
1808 * @param CallbackId : ID of the callback to be registered
1809 * This parameter can be one of the following values:
1810 * @arg @ref HAL_MMC_TX_CPLT_CB_ID MMC Tx Complete Callback ID
1811 * @arg @ref HAL_MMC_RX_CPLT_CB_ID MMC Rx Complete Callback ID
1812 * @arg @ref HAL_MMC_ERROR_CB_ID MMC Error Callback ID
1813 * @arg @ref HAL_MMC_ABORT_CB_ID MMC Abort Callback ID
1814 * @arg @ref HAL_MMC_MSP_INIT_CB_ID MMC MspInit Callback ID
1815 * @arg @ref HAL_MMC_MSP_DEINIT_CB_ID MMC MspDeInit Callback ID
1816 * @param pCallback : pointer to the Callback function
1817 * @retval status
1818 */
HAL_MMC_RegisterCallback(MMC_HandleTypeDef * hmmc,HAL_MMC_CallbackIDTypeDef CallbackId,pMMC_CallbackTypeDef pCallback)1819 HAL_StatusTypeDef HAL_MMC_RegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId, pMMC_CallbackTypeDef pCallback)
1820 {
1821 HAL_StatusTypeDef status = HAL_OK;
1822
1823 if(pCallback == NULL)
1824 {
1825 /* Update the error code */
1826 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1827 return HAL_ERROR;
1828 }
1829
1830 /* Process locked */
1831 __HAL_LOCK(hmmc);
1832
1833 if(hmmc->State == HAL_MMC_STATE_READY)
1834 {
1835 switch (CallbackId)
1836 {
1837 case HAL_MMC_TX_CPLT_CB_ID :
1838 hmmc->TxCpltCallback = pCallback;
1839 break;
1840 case HAL_MMC_RX_CPLT_CB_ID :
1841 hmmc->RxCpltCallback = pCallback;
1842 break;
1843 case HAL_MMC_ERROR_CB_ID :
1844 hmmc->ErrorCallback = pCallback;
1845 break;
1846 case HAL_MMC_ABORT_CB_ID :
1847 hmmc->AbortCpltCallback = pCallback;
1848 break;
1849 case HAL_MMC_MSP_INIT_CB_ID :
1850 hmmc->MspInitCallback = pCallback;
1851 break;
1852 case HAL_MMC_MSP_DEINIT_CB_ID :
1853 hmmc->MspDeInitCallback = pCallback;
1854 break;
1855 default :
1856 /* Update the error code */
1857 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1858 /* update return status */
1859 status = HAL_ERROR;
1860 break;
1861 }
1862 }
1863 else if (hmmc->State == HAL_MMC_STATE_RESET)
1864 {
1865 switch (CallbackId)
1866 {
1867 case HAL_MMC_MSP_INIT_CB_ID :
1868 hmmc->MspInitCallback = pCallback;
1869 break;
1870 case HAL_MMC_MSP_DEINIT_CB_ID :
1871 hmmc->MspDeInitCallback = pCallback;
1872 break;
1873 default :
1874 /* Update the error code */
1875 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1876 /* update return status */
1877 status = HAL_ERROR;
1878 break;
1879 }
1880 }
1881 else
1882 {
1883 /* Update the error code */
1884 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1885 /* update return status */
1886 status = HAL_ERROR;
1887 }
1888
1889 /* Release Lock */
1890 __HAL_UNLOCK(hmmc);
1891 return status;
1892 }
1893
1894 /**
1895 * @brief Unregister a User MMC Callback
1896 * MMC Callback is redirected to the weak (surcharged) predefined callback
1897 * @param hmmc : MMC handle
1898 * @param CallbackId : ID of the callback to be unregistered
1899 * This parameter can be one of the following values:
1900 * @arg @ref HAL_MMC_TX_CPLT_CB_ID MMC Tx Complete Callback ID
1901 * @arg @ref HAL_MMC_RX_CPLT_CB_ID MMC Rx Complete Callback ID
1902 * @arg @ref HAL_MMC_ERROR_CB_ID MMC Error Callback ID
1903 * @arg @ref HAL_MMC_ABORT_CB_ID MMC Abort Callback ID
1904 * @arg @ref HAL_MMC_MSP_INIT_CB_ID MMC MspInit Callback ID
1905 * @arg @ref HAL_MMC_MSP_DEINIT_CB_ID MMC MspDeInit Callback ID
1906 * @retval status
1907 */
HAL_MMC_UnRegisterCallback(MMC_HandleTypeDef * hmmc,HAL_MMC_CallbackIDTypeDef CallbackId)1908 HAL_StatusTypeDef HAL_MMC_UnRegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId)
1909 {
1910 HAL_StatusTypeDef status = HAL_OK;
1911
1912 /* Process locked */
1913 __HAL_LOCK(hmmc);
1914
1915 if(hmmc->State == HAL_MMC_STATE_READY)
1916 {
1917 switch (CallbackId)
1918 {
1919 case HAL_MMC_TX_CPLT_CB_ID :
1920 hmmc->TxCpltCallback = HAL_MMC_TxCpltCallback;
1921 break;
1922 case HAL_MMC_RX_CPLT_CB_ID :
1923 hmmc->RxCpltCallback = HAL_MMC_RxCpltCallback;
1924 break;
1925 case HAL_MMC_ERROR_CB_ID :
1926 hmmc->ErrorCallback = HAL_MMC_ErrorCallback;
1927 break;
1928 case HAL_MMC_ABORT_CB_ID :
1929 hmmc->AbortCpltCallback = HAL_MMC_AbortCallback;
1930 break;
1931 case HAL_MMC_MSP_INIT_CB_ID :
1932 hmmc->MspInitCallback = HAL_MMC_MspInit;
1933 break;
1934 case HAL_MMC_MSP_DEINIT_CB_ID :
1935 hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
1936 break;
1937 default :
1938 /* Update the error code */
1939 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1940 /* update return status */
1941 status = HAL_ERROR;
1942 break;
1943 }
1944 }
1945 else if (hmmc->State == HAL_MMC_STATE_RESET)
1946 {
1947 switch (CallbackId)
1948 {
1949 case HAL_MMC_MSP_INIT_CB_ID :
1950 hmmc->MspInitCallback = HAL_MMC_MspInit;
1951 break;
1952 case HAL_MMC_MSP_DEINIT_CB_ID :
1953 hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
1954 break;
1955 default :
1956 /* Update the error code */
1957 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1958 /* update return status */
1959 status = HAL_ERROR;
1960 break;
1961 }
1962 }
1963 else
1964 {
1965 /* Update the error code */
1966 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1967 /* update return status */
1968 status = HAL_ERROR;
1969 }
1970
1971 /* Release Lock */
1972 __HAL_UNLOCK(hmmc);
1973 return status;
1974 }
1975 #endif
1976
1977 /**
1978 * @}
1979 */
1980
1981 /** @addtogroup MMC_Exported_Functions_Group3
1982 * @brief management functions
1983 *
1984 @verbatim
1985 ==============================================================================
1986 ##### Peripheral Control functions #####
1987 ==============================================================================
1988 [..]
1989 This subsection provides a set of functions allowing to control the MMC card
1990 operations and get the related information
1991
1992 @endverbatim
1993 * @{
1994 */
1995
1996 /**
1997 * @brief Returns information the information of the card which are stored on
1998 * the CID register.
1999 * @param hmmc: Pointer to MMC handle
2000 * @param pCID: Pointer to a HAL_MMC_CIDTypedef structure that
2001 * contains all CID register parameters
2002 * @retval HAL status
2003 */
HAL_MMC_GetCardCID(MMC_HandleTypeDef * hmmc,HAL_MMC_CardCIDTypeDef * pCID)2004 HAL_StatusTypeDef HAL_MMC_GetCardCID(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCIDTypeDef *pCID)
2005 {
2006 pCID->ManufacturerID = (uint8_t)((hmmc->CID[0] & 0xFF000000U) >> 24U);
2007
2008 pCID->OEM_AppliID = (uint16_t)((hmmc->CID[0] & 0x00FFFF00U) >> 8U);
2009
2010 pCID->ProdName1 = (((hmmc->CID[0] & 0x000000FFU) << 24U) | ((hmmc->CID[1] & 0xFFFFFF00U) >> 8U));
2011
2012 pCID->ProdName2 = (uint8_t)(hmmc->CID[1] & 0x000000FFU);
2013
2014 pCID->ProdRev = (uint8_t)((hmmc->CID[2] & 0xFF000000U) >> 24U);
2015
2016 pCID->ProdSN = (((hmmc->CID[2] & 0x00FFFFFFU) << 8U) | ((hmmc->CID[3] & 0xFF000000U) >> 24U));
2017
2018 pCID->Reserved1 = (uint8_t)((hmmc->CID[3] & 0x00F00000U) >> 20U);
2019
2020 pCID->ManufactDate = (uint16_t)((hmmc->CID[3] & 0x000FFF00U) >> 8U);
2021
2022 pCID->CID_CRC = (uint8_t)((hmmc->CID[3] & 0x000000FEU) >> 1U);
2023
2024 pCID->Reserved2 = 1U;
2025
2026 return HAL_OK;
2027 }
2028
2029 /**
2030 * @brief Returns information the information of the card which are stored on
2031 * the CSD register.
2032 * @param hmmc: Pointer to MMC handle
2033 * @param pCSD: Pointer to a HAL_MMC_CardCSDTypeDef structure that
2034 * contains all CSD register parameters
2035 * @retval HAL status
2036 */
HAL_MMC_GetCardCSD(MMC_HandleTypeDef * hmmc,HAL_MMC_CardCSDTypeDef * pCSD)2037 HAL_StatusTypeDef HAL_MMC_GetCardCSD(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCSDTypeDef *pCSD)
2038 {
2039 uint32_t block_nbr = 0;
2040
2041 pCSD->CSDStruct = (uint8_t)((hmmc->CSD[0] & 0xC0000000U) >> 30U);
2042
2043 pCSD->SysSpecVersion = (uint8_t)((hmmc->CSD[0] & 0x3C000000U) >> 26U);
2044
2045 pCSD->Reserved1 = (uint8_t)((hmmc->CSD[0] & 0x03000000U) >> 24U);
2046
2047 pCSD->TAAC = (uint8_t)((hmmc->CSD[0] & 0x00FF0000U) >> 16U);
2048
2049 pCSD->NSAC = (uint8_t)((hmmc->CSD[0] & 0x0000FF00U) >> 8U);
2050
2051 pCSD->MaxBusClkFrec = (uint8_t)(hmmc->CSD[0] & 0x000000FFU);
2052
2053 pCSD->CardComdClasses = (uint16_t)((hmmc->CSD[1] & 0xFFF00000U) >> 20U);
2054
2055 pCSD->RdBlockLen = (uint8_t)((hmmc->CSD[1] & 0x000F0000U) >> 16U);
2056
2057 pCSD->PartBlockRead = (uint8_t)((hmmc->CSD[1] & 0x00008000U) >> 15U);
2058
2059 pCSD->WrBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00004000U) >> 14U);
2060
2061 pCSD->RdBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00002000U) >> 13U);
2062
2063 pCSD->DSRImpl = (uint8_t)((hmmc->CSD[1] & 0x00001000U) >> 12U);
2064
2065 pCSD->Reserved2 = 0U; /*!< Reserved */
2066
2067 pCSD->DeviceSize = (((hmmc->CSD[1] & 0x000003FFU) << 2U) | ((hmmc->CSD[2] & 0xC0000000U) >> 30U));
2068
2069 pCSD->MaxRdCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x38000000U) >> 27U);
2070
2071 pCSD->MaxRdCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x07000000U) >> 24U);
2072
2073 pCSD->MaxWrCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x00E00000U) >> 21U);
2074
2075 pCSD->MaxWrCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x001C0000U) >> 18U);
2076
2077 pCSD->DeviceSizeMul = (uint8_t)((hmmc->CSD[2] & 0x00038000U) >> 15U);
2078
2079 if(MMC_ReadExtCSD(hmmc, &block_nbr, 212, 0x0FFFFFFFU) != HAL_OK) /* Field SEC_COUNT [215:212] */
2080 {
2081 return HAL_ERROR;
2082 }
2083
2084 if(hmmc->MmcCard.CardType == MMC_LOW_CAPACITY_CARD)
2085 {
2086 hmmc->MmcCard.BlockNbr = (pCSD->DeviceSize + 1U) ;
2087 hmmc->MmcCard.BlockNbr *= (1UL << ((pCSD->DeviceSizeMul & 0x07U) + 2U));
2088 hmmc->MmcCard.BlockSize = (1UL << (pCSD->RdBlockLen & 0x0FU));
2089 hmmc->MmcCard.LogBlockNbr = (hmmc->MmcCard.BlockNbr) * ((hmmc->MmcCard.BlockSize) / 512U);
2090 hmmc->MmcCard.LogBlockSize = 512U;
2091 }
2092 else if(hmmc->MmcCard.CardType == MMC_HIGH_CAPACITY_CARD)
2093 {
2094 hmmc->MmcCard.BlockNbr = block_nbr;
2095 hmmc->MmcCard.LogBlockNbr = hmmc->MmcCard.BlockNbr;
2096 hmmc->MmcCard.BlockSize = 512U;
2097 hmmc->MmcCard.LogBlockSize = hmmc->MmcCard.BlockSize;
2098 }
2099 else
2100 {
2101 /* Clear all the static flags */
2102 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
2103 hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2104 hmmc->State = HAL_MMC_STATE_READY;
2105 return HAL_ERROR;
2106 }
2107
2108 pCSD->EraseGrSize = (uint8_t)((hmmc->CSD[2] & 0x00004000U) >> 14U);
2109
2110 pCSD->EraseGrMul = (uint8_t)((hmmc->CSD[2] & 0x00003F80U) >> 7U);
2111
2112 pCSD->WrProtectGrSize = (uint8_t)(hmmc->CSD[2] & 0x0000007FU);
2113
2114 pCSD->WrProtectGrEnable = (uint8_t)((hmmc->CSD[3] & 0x80000000U) >> 31U);
2115
2116 pCSD->ManDeflECC = (uint8_t)((hmmc->CSD[3] & 0x60000000U) >> 29U);
2117
2118 pCSD->WrSpeedFact = (uint8_t)((hmmc->CSD[3] & 0x1C000000U) >> 26U);
2119
2120 pCSD->MaxWrBlockLen= (uint8_t)((hmmc->CSD[3] & 0x03C00000U) >> 22U);
2121
2122 pCSD->WriteBlockPaPartial = (uint8_t)((hmmc->CSD[3] & 0x00200000U) >> 21U);
2123
2124 pCSD->Reserved3 = 0;
2125
2126 pCSD->ContentProtectAppli = (uint8_t)((hmmc->CSD[3] & 0x00010000U) >> 16U);
2127
2128 pCSD->FileFormatGroup = (uint8_t)((hmmc->CSD[3] & 0x00008000U) >> 15U);
2129
2130 pCSD->CopyFlag = (uint8_t)((hmmc->CSD[3] & 0x00004000U) >> 14U);
2131
2132 pCSD->PermWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00002000U) >> 13U);
2133
2134 pCSD->TempWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00001000U) >> 12U);
2135
2136 pCSD->FileFormat = (uint8_t)((hmmc->CSD[3] & 0x00000C00U) >> 10U);
2137
2138 pCSD->ECC= (uint8_t)((hmmc->CSD[3] & 0x00000300U) >> 8U);
2139
2140 pCSD->CSD_CRC = (uint8_t)((hmmc->CSD[3] & 0x000000FEU) >> 1U);
2141
2142 pCSD->Reserved4 = 1;
2143
2144 return HAL_OK;
2145 }
2146
2147 /**
2148 * @brief Gets the MMC card info.
2149 * @param hmmc: Pointer to MMC handle
2150 * @param pCardInfo: Pointer to the HAL_MMC_CardInfoTypeDef structure that
2151 * will contain the MMC card status information
2152 * @retval HAL status
2153 */
HAL_MMC_GetCardInfo(MMC_HandleTypeDef * hmmc,HAL_MMC_CardInfoTypeDef * pCardInfo)2154 HAL_StatusTypeDef HAL_MMC_GetCardInfo(MMC_HandleTypeDef *hmmc, HAL_MMC_CardInfoTypeDef *pCardInfo)
2155 {
2156 pCardInfo->CardType = (uint32_t)(hmmc->MmcCard.CardType);
2157 pCardInfo->Class = (uint32_t)(hmmc->MmcCard.Class);
2158 pCardInfo->RelCardAdd = (uint32_t)(hmmc->MmcCard.RelCardAdd);
2159 pCardInfo->BlockNbr = (uint32_t)(hmmc->MmcCard.BlockNbr);
2160 pCardInfo->BlockSize = (uint32_t)(hmmc->MmcCard.BlockSize);
2161 pCardInfo->LogBlockNbr = (uint32_t)(hmmc->MmcCard.LogBlockNbr);
2162 pCardInfo->LogBlockSize = (uint32_t)(hmmc->MmcCard.LogBlockSize);
2163
2164 return HAL_OK;
2165 }
2166
2167 /**
2168 * @brief Returns information the information of the card which are stored on
2169 * the Extended CSD register.
2170 * @param hmmc Pointer to MMC handle
2171 * @param pExtCSD Pointer to a memory area (512 bytes) that contains all
2172 * Extended CSD register parameters
2173 * @param Timeout Specify timeout value
2174 * @retval HAL status
2175 */
HAL_MMC_GetCardExtCSD(MMC_HandleTypeDef * hmmc,uint32_t * pExtCSD,uint32_t Timeout)2176 HAL_StatusTypeDef HAL_MMC_GetCardExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pExtCSD, uint32_t Timeout)
2177 {
2178 SDIO_DataInitTypeDef config;
2179 uint32_t errorstate;
2180 uint32_t tickstart = HAL_GetTick();
2181 uint32_t count;
2182 uint32_t *tmp_buf;
2183
2184 if(NULL == pExtCSD)
2185 {
2186 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
2187 return HAL_ERROR;
2188 }
2189
2190 if(hmmc->State == HAL_MMC_STATE_READY)
2191 {
2192 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
2193
2194 hmmc->State = HAL_MMC_STATE_BUSY;
2195
2196 /* Initialize data control register */
2197 hmmc->Instance->DCTRL = 0;
2198
2199 /* Initiaize the destination pointer */
2200 tmp_buf = pExtCSD;
2201
2202 /* Configure the MMC DPSM (Data Path State Machine) */
2203 config.DataTimeOut = SDMMC_DATATIMEOUT;
2204 config.DataLength = 512;
2205 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
2206 config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
2207 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
2208 config.DPSM = SDIO_DPSM_ENABLE;
2209 (void)SDIO_ConfigData(hmmc->Instance, &config);
2210
2211 /* Send ExtCSD Read command to Card */
2212 errorstate = SDMMC_CmdSendEXTCSD(hmmc->Instance, 0);
2213 if(errorstate != HAL_MMC_ERROR_NONE)
2214 {
2215 /* Clear all the static flags */
2216 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
2217 hmmc->ErrorCode |= errorstate;
2218 hmmc->State = HAL_MMC_STATE_READY;
2219 return HAL_ERROR;
2220 }
2221
2222 /* Poll on SDMMC flags */
2223 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND))
2224 {
2225 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXFIFOHF))
2226 {
2227 /* Read data from SDMMC Rx FIFO */
2228 for(count = 0U; count < 8U; count++)
2229 {
2230 *tmp_buf = SDIO_ReadFIFO(hmmc->Instance);
2231 tmp_buf++;
2232 }
2233 }
2234
2235 if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U))
2236 {
2237 /* Clear all the static flags */
2238 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
2239 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
2240 hmmc->State= HAL_MMC_STATE_READY;
2241 return HAL_TIMEOUT;
2242 }
2243 }
2244
2245 /* Get error state */
2246 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DTIMEOUT))
2247 {
2248 /* Clear all the static flags */
2249 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
2250 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
2251 hmmc->State = HAL_MMC_STATE_READY;
2252 return HAL_ERROR;
2253 }
2254 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL))
2255 {
2256 /* Clear all the static flags */
2257 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
2258 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
2259 hmmc->State = HAL_MMC_STATE_READY;
2260 return HAL_ERROR;
2261 }
2262 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR))
2263 {
2264 /* Clear all the static flags */
2265 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
2266 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
2267 hmmc->State = HAL_MMC_STATE_READY;
2268 return HAL_ERROR;
2269 }
2270 else
2271 {
2272 /* Nothing to do */
2273 }
2274
2275 /* Clear all the static flags */
2276 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
2277 hmmc->State = HAL_MMC_STATE_READY;
2278 }
2279
2280 return HAL_OK;
2281 }
2282
2283 /**
2284 * @brief Enables wide bus operation for the requested card if supported by
2285 * card.
2286 * @param hmmc: Pointer to MMC handle
2287 * @param WideMode: Specifies the MMC card wide bus mode
2288 * This parameter can be one of the following values:
2289 * @arg SDIO_BUS_WIDE_8B: 8-bit data transfer
2290 * @arg SDIO_BUS_WIDE_4B: 4-bit data transfer
2291 * @arg SDIO_BUS_WIDE_1B: 1-bit data transfer
2292 * @retval HAL status
2293 */
HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef * hmmc,uint32_t WideMode)2294 HAL_StatusTypeDef HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef *hmmc, uint32_t WideMode)
2295 {
2296 uint32_t count;
2297 SDIO_InitTypeDef Init;
2298 uint32_t errorstate;
2299 uint32_t response = 0U;
2300
2301 /* Check the parameters */
2302 assert_param(IS_SDIO_BUS_WIDE(WideMode));
2303
2304 /* Change State */
2305 hmmc->State = HAL_MMC_STATE_BUSY;
2306
2307 errorstate = MMC_PwrClassUpdate(hmmc, WideMode);
2308
2309 if(errorstate == HAL_MMC_ERROR_NONE)
2310 {
2311 if(WideMode == SDIO_BUS_WIDE_8B)
2312 {
2313 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U);
2314 }
2315 else if(WideMode == SDIO_BUS_WIDE_4B)
2316 {
2317 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U);
2318 }
2319 else if(WideMode == SDIO_BUS_WIDE_1B)
2320 {
2321 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70000U);
2322 }
2323 else
2324 {
2325 /* WideMode is not a valid argument*/
2326 errorstate = HAL_MMC_ERROR_PARAM;
2327 }
2328
2329 /* Check for switch error and violation of the trial number of sending CMD 13 */
2330 if(errorstate == HAL_MMC_ERROR_NONE)
2331 {
2332 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2333 count = SDMMC_MAX_TRIAL;
2334 do
2335 {
2336 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2337 if(errorstate != HAL_MMC_ERROR_NONE)
2338 {
2339 break;
2340 }
2341
2342 /* Get command response */
2343 response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
2344 count--;
2345 }while(((response & 0x100U) == 0U) && (count != 0U));
2346
2347 /* Check the status after the switch command execution */
2348 if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
2349 {
2350 /* Check the bit SWITCH_ERROR of the device status */
2351 if ((response & 0x80U) != 0U)
2352 {
2353 errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
2354 }
2355 else
2356 {
2357 /* Configure the SDIO peripheral */
2358 Init = hmmc->Init;
2359 Init.BusWide = WideMode;
2360 (void)SDIO_Init(hmmc->Instance, Init);
2361 }
2362 }
2363 else if (count == 0U)
2364 {
2365 errorstate = SDMMC_ERROR_TIMEOUT;
2366 }
2367 else
2368 {
2369 /* Nothing to do */
2370 }
2371 }
2372 }
2373
2374 /* Change State */
2375 hmmc->State = HAL_MMC_STATE_READY;
2376
2377 if(errorstate != HAL_MMC_ERROR_NONE)
2378 {
2379 /* Clear all the static flags */
2380 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2381 hmmc->ErrorCode |= errorstate;
2382 return HAL_ERROR;
2383 }
2384
2385 return HAL_OK;
2386 }
2387
2388 /**
2389 * @brief Gets the current mmc card data state.
2390 * @param hmmc: pointer to MMC handle
2391 * @retval Card state
2392 */
HAL_MMC_GetCardState(MMC_HandleTypeDef * hmmc)2393 HAL_MMC_CardStateTypeDef HAL_MMC_GetCardState(MMC_HandleTypeDef *hmmc)
2394 {
2395 uint32_t cardstate;
2396 uint32_t errorstate;
2397 uint32_t resp1 = 0U;
2398
2399 errorstate = MMC_SendStatus(hmmc, &resp1);
2400 if(errorstate != HAL_MMC_ERROR_NONE)
2401 {
2402 hmmc->ErrorCode |= errorstate;
2403 }
2404
2405 cardstate = ((resp1 >> 9U) & 0x0FU);
2406
2407 return (HAL_MMC_CardStateTypeDef)cardstate;
2408 }
2409
2410 /**
2411 * @brief Abort the current transfer and disable the MMC.
2412 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2413 * the configuration information for MMC module.
2414 * @retval HAL status
2415 */
HAL_MMC_Abort(MMC_HandleTypeDef * hmmc)2416 HAL_StatusTypeDef HAL_MMC_Abort(MMC_HandleTypeDef *hmmc)
2417 {
2418 HAL_MMC_CardStateTypeDef CardState;
2419
2420 /* DIsable All interrupts */
2421 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
2422 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
2423
2424 /* Clear All flags */
2425 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
2426
2427 if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL))
2428 {
2429 /* Disable the MMC DMA request */
2430 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
2431
2432 /* Abort the MMC DMA Tx Stream */
2433 if(hmmc->hdmatx != NULL)
2434 {
2435 if(HAL_DMA_Abort(hmmc->hdmatx) != HAL_OK)
2436 {
2437 hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
2438 }
2439 }
2440 /* Abort the MMC DMA Rx Stream */
2441 if(hmmc->hdmarx != NULL)
2442 {
2443 if(HAL_DMA_Abort(hmmc->hdmarx) != HAL_OK)
2444 {
2445 hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
2446 }
2447 }
2448 }
2449
2450 hmmc->State = HAL_MMC_STATE_READY;
2451
2452 /* Initialize the MMC operation */
2453 hmmc->Context = MMC_CONTEXT_NONE;
2454
2455 CardState = HAL_MMC_GetCardState(hmmc);
2456 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2457 {
2458 hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
2459 }
2460 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2461 {
2462 return HAL_ERROR;
2463 }
2464 return HAL_OK;
2465 }
2466
2467 /**
2468 * @brief Abort the current transfer and disable the MMC (IT mode).
2469 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2470 * the configuration information for MMC module.
2471 * @retval HAL status
2472 */
HAL_MMC_Abort_IT(MMC_HandleTypeDef * hmmc)2473 HAL_StatusTypeDef HAL_MMC_Abort_IT(MMC_HandleTypeDef *hmmc)
2474 {
2475 HAL_MMC_CardStateTypeDef CardState;
2476
2477 /* DIsable All interrupts */
2478 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
2479 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
2480
2481 /* Clear All flags */
2482 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
2483
2484 if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL))
2485 {
2486 /* Disable the MMC DMA request */
2487 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
2488
2489 /* Abort the MMC DMA Tx Stream */
2490 if(hmmc->hdmatx != NULL)
2491 {
2492 hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort;
2493 if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
2494 {
2495 hmmc->hdmatx = NULL;
2496 }
2497 }
2498 /* Abort the MMC DMA Rx Stream */
2499 if(hmmc->hdmarx != NULL)
2500 {
2501 hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort;
2502 if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
2503 {
2504 hmmc->hdmarx = NULL;
2505 }
2506 }
2507 }
2508
2509 /* No transfer ongoing on both DMA channels*/
2510 if((hmmc->hdmatx == NULL) && (hmmc->hdmarx == NULL))
2511 {
2512 CardState = HAL_MMC_GetCardState(hmmc);
2513 hmmc->State = HAL_MMC_STATE_READY;
2514
2515 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2516 {
2517 hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
2518 }
2519 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2520 {
2521 return HAL_ERROR;
2522 }
2523 else
2524 {
2525 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2526 hmmc->AbortCpltCallback(hmmc);
2527 #else
2528 HAL_MMC_AbortCallback(hmmc);
2529 #endif
2530 }
2531 }
2532
2533 return HAL_OK;
2534 }
2535
2536 /**
2537 * @}
2538 */
2539
2540 /**
2541 * @}
2542 */
2543
2544 /* Private function ----------------------------------------------------------*/
2545 /** @addtogroup MMC_Private_Functions
2546 * @{
2547 */
2548
2549 /**
2550 * @brief DMA MMC transmit process complete callback
2551 * @param hdma: DMA handle
2552 * @retval None
2553 */
MMC_DMATransmitCplt(DMA_HandleTypeDef * hdma)2554 static void MMC_DMATransmitCplt(DMA_HandleTypeDef *hdma)
2555 {
2556 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2557
2558 /* Enable DATAEND Interrupt */
2559 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DATAEND));
2560 }
2561
2562 /**
2563 * @brief DMA MMC receive process complete callback
2564 * @param hdma: DMA handle
2565 * @retval None
2566 */
MMC_DMAReceiveCplt(DMA_HandleTypeDef * hdma)2567 static void MMC_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
2568 {
2569 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2570 uint32_t errorstate;
2571
2572 /* Send stop command in multiblock write */
2573 if(hmmc->Context == (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA))
2574 {
2575 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
2576 if(errorstate != HAL_MMC_ERROR_NONE)
2577 {
2578 hmmc->ErrorCode |= errorstate;
2579 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2580 hmmc->ErrorCallback(hmmc);
2581 #else
2582 HAL_MMC_ErrorCallback(hmmc);
2583 #endif
2584 }
2585 }
2586
2587 /* Disable the DMA transfer for transmit request by setting the DMAEN bit
2588 in the MMC DCTRL register */
2589 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
2590
2591 /* Clear all the static flags */
2592 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
2593
2594 hmmc->State = HAL_MMC_STATE_READY;
2595
2596 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2597 hmmc->RxCpltCallback(hmmc);
2598 #else
2599 HAL_MMC_RxCpltCallback(hmmc);
2600 #endif
2601 }
2602
2603 /**
2604 * @brief DMA MMC communication error callback
2605 * @param hdma: DMA handle
2606 * @retval None
2607 */
MMC_DMAError(DMA_HandleTypeDef * hdma)2608 static void MMC_DMAError(DMA_HandleTypeDef *hdma)
2609 {
2610 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2611 HAL_MMC_CardStateTypeDef CardState;
2612 uint32_t RxErrorCode, TxErrorCode;
2613
2614 /* if DMA error is FIFO error ignore it */
2615 if(HAL_DMA_GetError(hdma) != HAL_DMA_ERROR_FE)
2616 {
2617 RxErrorCode = hmmc->hdmarx->ErrorCode;
2618 TxErrorCode = hmmc->hdmatx->ErrorCode;
2619 if((RxErrorCode == HAL_DMA_ERROR_TE) || (TxErrorCode == HAL_DMA_ERROR_TE))
2620 {
2621 /* Clear All flags */
2622 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
2623
2624 /* Disable All interrupts */
2625 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
2626 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
2627
2628 hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
2629 CardState = HAL_MMC_GetCardState(hmmc);
2630 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2631 {
2632 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
2633 }
2634
2635 hmmc->State= HAL_MMC_STATE_READY;
2636 }
2637
2638 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2639 hmmc->ErrorCallback(hmmc);
2640 #else
2641 HAL_MMC_ErrorCallback(hmmc);
2642 #endif
2643 }
2644 }
2645
2646 /**
2647 * @brief DMA MMC Tx Abort callback
2648 * @param hdma: DMA handle
2649 * @retval None
2650 */
MMC_DMATxAbort(DMA_HandleTypeDef * hdma)2651 static void MMC_DMATxAbort(DMA_HandleTypeDef *hdma)
2652 {
2653 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2654 HAL_MMC_CardStateTypeDef CardState;
2655
2656 if(hmmc->hdmatx != NULL)
2657 {
2658 hmmc->hdmatx = NULL;
2659 }
2660
2661 /* All DMA channels are aborted */
2662 if(hmmc->hdmarx == NULL)
2663 {
2664 CardState = HAL_MMC_GetCardState(hmmc);
2665 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
2666 hmmc->State = HAL_MMC_STATE_READY;
2667 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2668 {
2669 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
2670
2671 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2672 {
2673 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2674 hmmc->AbortCpltCallback(hmmc);
2675 #else
2676 HAL_MMC_AbortCallback(hmmc);
2677 #endif
2678 }
2679 else
2680 {
2681 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2682 hmmc->ErrorCallback(hmmc);
2683 #else
2684 HAL_MMC_ErrorCallback(hmmc);
2685 #endif
2686 }
2687 }
2688 }
2689 }
2690
2691 /**
2692 * @brief DMA MMC Rx Abort callback
2693 * @param hdma: DMA handle
2694 * @retval None
2695 */
MMC_DMARxAbort(DMA_HandleTypeDef * hdma)2696 static void MMC_DMARxAbort(DMA_HandleTypeDef *hdma)
2697 {
2698 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2699 HAL_MMC_CardStateTypeDef CardState;
2700
2701 if(hmmc->hdmarx != NULL)
2702 {
2703 hmmc->hdmarx = NULL;
2704 }
2705
2706 /* All DMA channels are aborted */
2707 if(hmmc->hdmatx == NULL)
2708 {
2709 CardState = HAL_MMC_GetCardState(hmmc);
2710 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
2711 hmmc->State = HAL_MMC_STATE_READY;
2712 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2713 {
2714 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
2715
2716 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2717 {
2718 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2719 hmmc->AbortCpltCallback(hmmc);
2720 #else
2721 HAL_MMC_AbortCallback(hmmc);
2722 #endif
2723 }
2724 else
2725 {
2726 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2727 hmmc->ErrorCallback(hmmc);
2728 #else
2729 HAL_MMC_ErrorCallback(hmmc);
2730 #endif
2731 }
2732 }
2733 }
2734 }
2735
2736 /**
2737 * @brief Initializes the mmc card.
2738 * @param hmmc: Pointer to MMC handle
2739 * @retval MMC Card error state
2740 */
MMC_InitCard(MMC_HandleTypeDef * hmmc)2741 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc)
2742 {
2743 HAL_MMC_CardCSDTypeDef CSD;
2744 uint32_t errorstate;
2745 uint16_t mmc_rca = 2U;
2746 MMC_InitTypeDef Init;
2747
2748 /* Check the power State */
2749 if(SDIO_GetPowerState(hmmc->Instance) == 0U)
2750 {
2751 /* Power off */
2752 return HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
2753 }
2754
2755 /* Send CMD2 ALL_SEND_CID */
2756 errorstate = SDMMC_CmdSendCID(hmmc->Instance);
2757 if(errorstate != HAL_MMC_ERROR_NONE)
2758 {
2759 return errorstate;
2760 }
2761 else
2762 {
2763 /* Get Card identification number data */
2764 hmmc->CID[0U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
2765 hmmc->CID[1U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP2);
2766 hmmc->CID[2U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP3);
2767 hmmc->CID[3U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP4);
2768 }
2769
2770 /* Send CMD3 SET_REL_ADDR with RCA = 2 (should be greater than 1) */
2771 /* MMC Card publishes its RCA. */
2772 errorstate = SDMMC_CmdSetRelAddMmc(hmmc->Instance, mmc_rca);
2773 if(errorstate != HAL_MMC_ERROR_NONE)
2774 {
2775 return errorstate;
2776 }
2777
2778 /* Get the MMC card RCA */
2779 hmmc->MmcCard.RelCardAdd = mmc_rca;
2780
2781 /* Send CMD9 SEND_CSD with argument as card's RCA */
2782 errorstate = SDMMC_CmdSendCSD(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
2783 if(errorstate != HAL_MMC_ERROR_NONE)
2784 {
2785 return errorstate;
2786 }
2787 else
2788 {
2789 /* Get Card Specific Data */
2790 hmmc->CSD[0U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
2791 hmmc->CSD[1U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP2);
2792 hmmc->CSD[2U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP3);
2793 hmmc->CSD[3U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP4);
2794 }
2795
2796 /* Get the Card Class */
2797 hmmc->MmcCard.Class = (SDIO_GetResponse(hmmc->Instance, SDIO_RESP2) >> 20U);
2798
2799 /* Select the Card */
2800 errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2801 if(errorstate != HAL_MMC_ERROR_NONE)
2802 {
2803 return errorstate;
2804 }
2805
2806 /* Get CSD parameters */
2807 if (HAL_MMC_GetCardCSD(hmmc, &CSD) != HAL_OK)
2808 {
2809 return hmmc->ErrorCode;
2810 }
2811
2812 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2813 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2814 if(errorstate != HAL_MMC_ERROR_NONE)
2815 {
2816 hmmc->ErrorCode |= errorstate;
2817 }
2818
2819 /* Get Extended CSD parameters */
2820 if (HAL_MMC_GetCardExtCSD(hmmc, hmmc->Ext_CSD, SDMMC_DATATIMEOUT) != HAL_OK)
2821 {
2822 return hmmc->ErrorCode;
2823 }
2824
2825 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2826 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2827 if(errorstate != HAL_MMC_ERROR_NONE)
2828 {
2829 hmmc->ErrorCode |= errorstate;
2830 }
2831
2832 /* Configure the SDIO peripheral */
2833 Init = hmmc->Init;
2834 Init.BusWide = SDIO_BUS_WIDE_1B;
2835 (void)SDIO_Init(hmmc->Instance, Init);
2836
2837 /* All cards are initialized */
2838 return HAL_MMC_ERROR_NONE;
2839 }
2840
2841 /**
2842 * @brief Enquires cards about their operating voltage and configures clock
2843 * controls and stores MMC information that will be needed in future
2844 * in the MMC handle.
2845 * @param hmmc: Pointer to MMC handle
2846 * @retval error state
2847 */
MMC_PowerON(MMC_HandleTypeDef * hmmc)2848 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc)
2849 {
2850 __IO uint32_t count = 0U;
2851 uint32_t response = 0U, validvoltage = 0U;
2852 uint32_t errorstate;
2853
2854 /* CMD0: GO_IDLE_STATE */
2855 errorstate = SDMMC_CmdGoIdleState(hmmc->Instance);
2856 if(errorstate != HAL_MMC_ERROR_NONE)
2857 {
2858 return errorstate;
2859 }
2860
2861 while(validvoltage == 0U)
2862 {
2863 if(count++ == SDMMC_MAX_VOLT_TRIAL)
2864 {
2865 return HAL_MMC_ERROR_INVALID_VOLTRANGE;
2866 }
2867
2868 /* SEND CMD1 APP_CMD with voltage range as argument */
2869 errorstate = SDMMC_CmdOpCondition(hmmc->Instance, MMC_VOLTAGE_RANGE);
2870 if(errorstate != HAL_MMC_ERROR_NONE)
2871 {
2872 return HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2873 }
2874
2875 /* Get command response */
2876 response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
2877
2878 /* Get operating voltage*/
2879 validvoltage = (((response >> 31U) == 1U) ? 1U : 0U);
2880 }
2881
2882 /* When power routine is finished and command returns valid voltage */
2883 if (((response & (0xFF000000U)) >> 24U) == 0xC0U)
2884 {
2885 hmmc->MmcCard.CardType = MMC_HIGH_CAPACITY_CARD;
2886 }
2887 else
2888 {
2889 hmmc->MmcCard.CardType = MMC_LOW_CAPACITY_CARD;
2890 }
2891
2892 return HAL_MMC_ERROR_NONE;
2893 }
2894
2895 /**
2896 * @brief Turns the SDIO output signals off.
2897 * @param hmmc: Pointer to MMC handle
2898 * @retval None
2899 */
MMC_PowerOFF(MMC_HandleTypeDef * hmmc)2900 static void MMC_PowerOFF(MMC_HandleTypeDef *hmmc)
2901 {
2902 /* Set Power State to OFF */
2903 (void)SDIO_PowerState_OFF(hmmc->Instance);
2904 }
2905
2906 /**
2907 * @brief Returns the current card's status.
2908 * @param hmmc: Pointer to MMC handle
2909 * @param pCardStatus: pointer to the buffer that will contain the MMC card
2910 * status (Card Status register)
2911 * @retval error state
2912 */
MMC_SendStatus(MMC_HandleTypeDef * hmmc,uint32_t * pCardStatus)2913 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus)
2914 {
2915 uint32_t errorstate;
2916
2917 if(pCardStatus == NULL)
2918 {
2919 return HAL_MMC_ERROR_PARAM;
2920 }
2921
2922 /* Send Status command */
2923 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
2924 if(errorstate != HAL_MMC_ERROR_NONE)
2925 {
2926 return errorstate;
2927 }
2928
2929 /* Get MMC card status */
2930 *pCardStatus = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
2931
2932 return HAL_MMC_ERROR_NONE;
2933 }
2934
2935 /**
2936 * @brief Reads extended CSD register to get the sectors number of the device
2937 * @param hmmc: Pointer to MMC handle
2938 * @param pFieldData: Pointer to the read buffer
2939 * @param FieldIndex: Index of the field to be read
2940 * @param Timeout: Specify timeout value
2941 * @retval HAL status
2942 */
MMC_ReadExtCSD(MMC_HandleTypeDef * hmmc,uint32_t * pFieldData,uint16_t FieldIndex,uint32_t Timeout)2943 static uint32_t MMC_ReadExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pFieldData, uint16_t FieldIndex, uint32_t Timeout)
2944 {
2945 SDIO_DataInitTypeDef config;
2946 uint32_t errorstate;
2947 uint32_t tickstart = HAL_GetTick();
2948 uint32_t count;
2949 uint32_t i = 0;
2950 uint32_t tmp_data;
2951
2952 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
2953
2954 /* Initialize data control register */
2955 hmmc->Instance->DCTRL = 0;
2956
2957 /* Configure the MMC DPSM (Data Path State Machine) */
2958 config.DataTimeOut = SDMMC_DATATIMEOUT;
2959 config.DataLength = 512;
2960 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
2961 config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
2962 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
2963 config.DPSM = SDIO_DPSM_ENABLE;
2964 (void)SDIO_ConfigData(hmmc->Instance, &config);
2965
2966 /* Set Block Size for Card */
2967 errorstate = SDMMC_CmdSendEXTCSD(hmmc->Instance, 0);
2968 if(errorstate != HAL_MMC_ERROR_NONE)
2969 {
2970 /* Clear all the static flags */
2971 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
2972 hmmc->ErrorCode |= errorstate;
2973 hmmc->State = HAL_MMC_STATE_READY;
2974 return HAL_ERROR;
2975 }
2976
2977 /* Poll on SDMMC flags */
2978 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND))
2979 {
2980 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXFIFOHF))
2981 {
2982 /* Read data from SDMMC Rx FIFO */
2983 for(count = 0U; count < 8U; count++)
2984 {
2985 tmp_data = SDIO_ReadFIFO(hmmc->Instance);
2986 /* eg : SEC_COUNT : FieldIndex = 212 => i+count = 53 */
2987 /* DEVICE_TYPE : FieldIndex = 196 => i+count = 49 */
2988 if ((i + count) == ((uint32_t)FieldIndex/4U))
2989 {
2990 *pFieldData = tmp_data;
2991 }
2992 }
2993 i += 8U;
2994 }
2995
2996 if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U))
2997 {
2998 /* Clear all the static flags */
2999 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
3000 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
3001 hmmc->State= HAL_MMC_STATE_READY;
3002 return HAL_TIMEOUT;
3003 }
3004 }
3005
3006 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3007 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16));
3008 if(errorstate != HAL_MMC_ERROR_NONE)
3009 {
3010 hmmc->ErrorCode |= errorstate;
3011 }
3012
3013 /* Clear all the static flags */
3014 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
3015
3016 hmmc->State = HAL_MMC_STATE_READY;
3017
3018 return HAL_OK;
3019 }
3020
3021
3022 /**
3023 * @brief Wrap up reading in non-blocking mode.
3024 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
3025 * the configuration information.
3026 * @retval None
3027 */
MMC_Read_IT(MMC_HandleTypeDef * hmmc)3028 static void MMC_Read_IT(MMC_HandleTypeDef *hmmc)
3029 {
3030 uint32_t count, data, dataremaining;
3031 uint8_t* tmp;
3032
3033 tmp = hmmc->pRxBuffPtr;
3034 dataremaining = hmmc->RxXferSize;
3035
3036 if (dataremaining > 0U)
3037 {
3038 /* Read data from SDIO Rx FIFO */
3039 for(count = 0U; count < 8U; count++)
3040 {
3041 data = SDIO_ReadFIFO(hmmc->Instance);
3042 *tmp = (uint8_t)(data & 0xFFU);
3043 tmp++;
3044 dataremaining--;
3045 *tmp = (uint8_t)((data >> 8U) & 0xFFU);
3046 tmp++;
3047 dataremaining--;
3048 *tmp = (uint8_t)((data >> 16U) & 0xFFU);
3049 tmp++;
3050 dataremaining--;
3051 *tmp = (uint8_t)((data >> 24U) & 0xFFU);
3052 tmp++;
3053 dataremaining--;
3054 }
3055
3056 hmmc->pRxBuffPtr = tmp;
3057 hmmc->RxXferSize = dataremaining;
3058 }
3059 }
3060
3061 /**
3062 * @brief Wrap up writing in non-blocking mode.
3063 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
3064 * the configuration information.
3065 * @retval None
3066 */
MMC_Write_IT(MMC_HandleTypeDef * hmmc)3067 static void MMC_Write_IT(MMC_HandleTypeDef *hmmc)
3068 {
3069 uint32_t count, data, dataremaining;
3070 uint8_t* tmp;
3071
3072 tmp = hmmc->pTxBuffPtr;
3073 dataremaining = hmmc->TxXferSize;
3074
3075 if (dataremaining > 0U)
3076 {
3077 /* Write data to SDIO Tx FIFO */
3078 for(count = 0U; count < 8U; count++)
3079 {
3080 data = (uint32_t)(*tmp);
3081 tmp++;
3082 dataremaining--;
3083 data |= ((uint32_t)(*tmp) << 8U);
3084 tmp++;
3085 dataremaining--;
3086 data |= ((uint32_t)(*tmp) << 16U);
3087 tmp++;
3088 dataremaining--;
3089 data |= ((uint32_t)(*tmp) << 24U);
3090 tmp++;
3091 dataremaining--;
3092 (void)SDIO_WriteFIFO(hmmc->Instance, &data);
3093 }
3094
3095 hmmc->pTxBuffPtr = tmp;
3096 hmmc->TxXferSize = dataremaining;
3097 }
3098 }
3099
3100 /**
3101 * @brief Update the power class of the device.
3102 * @param hmmc MMC handle
3103 * @param Wide Wide of MMC bus
3104 * @param Speed Speed of the MMC bus
3105 * @retval MMC Card error state
3106 */
MMC_PwrClassUpdate(MMC_HandleTypeDef * hmmc,uint32_t Wide)3107 static uint32_t MMC_PwrClassUpdate(MMC_HandleTypeDef *hmmc, uint32_t Wide)
3108 {
3109 uint32_t count;
3110 uint32_t response = 0U;
3111 uint32_t errorstate = HAL_MMC_ERROR_NONE;
3112 uint32_t power_class, supported_pwr_class;
3113
3114 if((Wide == SDIO_BUS_WIDE_8B) || (Wide == SDIO_BUS_WIDE_4B))
3115 {
3116 power_class = 0U; /* Default value after power-on or software reset */
3117
3118 /* Read the PowerClass field of the Extended CSD register */
3119 if(MMC_ReadExtCSD(hmmc, &power_class, 187, SDMMC_DATATIMEOUT) != HAL_OK) /* Field POWER_CLASS [187] */
3120 {
3121 errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
3122 }
3123 else
3124 {
3125 power_class = ((power_class >> 24U) & 0x000000FFU);
3126 }
3127
3128 /* Get the supported PowerClass field of the Extended CSD register */
3129 /* Field PWR_CL_26_xxx [201 or 203] */
3130 supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_26_INDEX/4)] >> MMC_EXT_CSD_PWR_CL_26_POS) & 0x000000FFU);
3131
3132 if(errorstate == HAL_MMC_ERROR_NONE)
3133 {
3134 if(Wide == SDIO_BUS_WIDE_8B)
3135 {
3136 /* Bit [7:4] : power class for 8-bits bus configuration - Bit [3:0] : power class for 4-bits bus configuration */
3137 supported_pwr_class = (supported_pwr_class >> 4U);
3138 }
3139
3140 if ((power_class & 0x0FU) != (supported_pwr_class & 0x0FU))
3141 {
3142 /* Need to change current power class */
3143 errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03BB0000U | ((supported_pwr_class & 0x0FU) << 8U)));
3144
3145 if(errorstate == HAL_MMC_ERROR_NONE)
3146 {
3147 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3148 count = SDMMC_MAX_TRIAL;
3149 do
3150 {
3151 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3152 if(errorstate != HAL_MMC_ERROR_NONE)
3153 {
3154 break;
3155 }
3156
3157 /* Get command response */
3158 response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
3159 count--;
3160 }while(((response & 0x100U) == 0U) && (count != 0U));
3161
3162 /* Check the status after the switch command execution */
3163 if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
3164 {
3165 /* Check the bit SWITCH_ERROR of the device status */
3166 if ((response & 0x80U) != 0U)
3167 {
3168 errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3169 }
3170 }
3171 else if (count == 0U)
3172 {
3173 errorstate = SDMMC_ERROR_TIMEOUT;
3174 }
3175 else
3176 {
3177 /* Nothing to do */
3178 }
3179 }
3180 }
3181 }
3182 }
3183
3184 return errorstate;
3185 }
3186
3187 /**
3188 * @}
3189 */
3190
3191 #endif /* SDIO */
3192
3193 #endif /* HAL_MMC_MODULE_ENABLED */
3194
3195 /**
3196 * @}
3197 */
3198
3199 /**
3200 * @}
3201 */
3202