1 /**
2 ******************************************************************************
3 * @file stm32f2xx_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 "stm32f2xx_hal.h"
256
257 /** @addtogroup STM32F2xx_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 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_FLAG_STBITERR))
671 {
672 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXFIFOHF) && (dataremaining > 0U))
673 {
674 /* Read data from SDIO Rx FIFO */
675 for(count = 0U; count < 8U; count++)
676 {
677 data = SDIO_ReadFIFO(hmmc->Instance);
678 *tempbuff = (uint8_t)(data & 0xFFU);
679 tempbuff++;
680 dataremaining--;
681 *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
682 tempbuff++;
683 dataremaining--;
684 *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
685 tempbuff++;
686 dataremaining--;
687 *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
688 tempbuff++;
689 dataremaining--;
690 }
691 }
692
693 if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U))
694 {
695 /* Clear all the static flags */
696 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
697 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
698 hmmc->State= HAL_MMC_STATE_READY;
699 return HAL_TIMEOUT;
700 }
701 }
702
703 /* Send stop transmission command in case of multiblock read */
704 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1U))
705 {
706 /* Send stop transmission command */
707 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
708 if(errorstate != HAL_MMC_ERROR_NONE)
709 {
710 /* Clear all the static flags */
711 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
712 hmmc->ErrorCode |= errorstate;
713 hmmc->State = HAL_MMC_STATE_READY;
714 return HAL_ERROR;
715 }
716 }
717
718 /* Get error state */
719 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DTIMEOUT))
720 {
721 /* Clear all the static flags */
722 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
723 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
724 hmmc->State = HAL_MMC_STATE_READY;
725 return HAL_ERROR;
726 }
727 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL))
728 {
729 /* Clear all the static flags */
730 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
731 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
732 hmmc->State = HAL_MMC_STATE_READY;
733 return HAL_ERROR;
734 }
735 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR))
736 {
737 /* Clear all the static flags */
738 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
739 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
740 hmmc->State = HAL_MMC_STATE_READY;
741 return HAL_ERROR;
742 }
743 else
744 {
745 /* Nothing to do */
746 }
747
748 /* Empty FIFO if there is still any data */
749 while ((__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXDAVL)) && (dataremaining > 0U))
750 {
751 data = SDIO_ReadFIFO(hmmc->Instance);
752 *tempbuff = (uint8_t)(data & 0xFFU);
753 tempbuff++;
754 dataremaining--;
755 *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
756 tempbuff++;
757 dataremaining--;
758 *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
759 tempbuff++;
760 dataremaining--;
761 *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
762 tempbuff++;
763 dataremaining--;
764
765 if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U))
766 {
767 /* Clear all the static flags */
768 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
769 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
770 hmmc->State= HAL_MMC_STATE_READY;
771 return HAL_ERROR;
772 }
773 }
774
775 /* Clear all the static flags */
776 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
777
778 hmmc->State = HAL_MMC_STATE_READY;
779
780 return HAL_OK;
781 }
782 else
783 {
784 hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
785 return HAL_ERROR;
786 }
787 }
788
789 /**
790 * @brief Allows to write block(s) to a specified address in a card. The Data
791 * transfer is managed by polling mode.
792 * @note This API should be followed by a check on the card state through
793 * HAL_MMC_GetCardState().
794 * @param hmmc: Pointer to MMC handle
795 * @param pData: pointer to the buffer that will contain the data to transmit
796 * @param BlockAdd: Block Address where data will be written
797 * @param NumberOfBlocks: Number of MMC blocks to write
798 * @param Timeout: Specify timeout value
799 * @retval HAL status
800 */
HAL_MMC_WriteBlocks(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks,uint32_t Timeout)801 HAL_StatusTypeDef HAL_MMC_WriteBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
802 {
803 SDIO_DataInitTypeDef config;
804 uint32_t errorstate;
805 uint32_t tickstart = HAL_GetTick();
806 uint32_t count, data, dataremaining;
807 uint32_t add = BlockAdd;
808 uint8_t *tempbuff = pData;
809
810 if(NULL == pData)
811 {
812 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
813 return HAL_ERROR;
814 }
815
816 if(hmmc->State == HAL_MMC_STATE_READY)
817 {
818 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
819
820 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
821 {
822 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
823 return HAL_ERROR;
824 }
825
826 hmmc->State = HAL_MMC_STATE_BUSY;
827
828 /* Initialize data control register */
829 hmmc->Instance->DCTRL = 0U;
830
831 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
832 {
833 add *= 512U;
834 }
835
836 /* Write Blocks in Polling mode */
837 if(NumberOfBlocks > 1U)
838 {
839 hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
840
841 /* Write Multi Block command */
842 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
843 }
844 else
845 {
846 hmmc->Context = MMC_CONTEXT_WRITE_SINGLE_BLOCK;
847
848 /* Write Single Block command */
849 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
850 }
851 if(errorstate != HAL_MMC_ERROR_NONE)
852 {
853 /* Clear all the static flags */
854 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
855 hmmc->ErrorCode |= errorstate;
856 hmmc->State = HAL_MMC_STATE_READY;
857 return HAL_ERROR;
858 }
859
860 /* Configure the MMC DPSM (Data Path State Machine) */
861 config.DataTimeOut = SDMMC_DATATIMEOUT;
862 config.DataLength = NumberOfBlocks * MMC_BLOCKSIZE;
863 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
864 config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
865 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
866 config.DPSM = SDIO_DPSM_ENABLE;
867 (void)SDIO_ConfigData(hmmc->Instance, &config);
868
869 /* Write block(s) in polling mode */
870 dataremaining = config.DataLength;
871 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_FLAG_STBITERR))
872 {
873 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXFIFOHE) && (dataremaining > 0U))
874 {
875 /* Write data to SDIO Tx FIFO */
876 for(count = 0U; count < 8U; count++)
877 {
878 data = (uint32_t)(*tempbuff);
879 tempbuff++;
880 dataremaining--;
881 data |= ((uint32_t)(*tempbuff) << 8U);
882 tempbuff++;
883 dataremaining--;
884 data |= ((uint32_t)(*tempbuff) << 16U);
885 tempbuff++;
886 dataremaining--;
887 data |= ((uint32_t)(*tempbuff) << 24U);
888 tempbuff++;
889 dataremaining--;
890 (void)SDIO_WriteFIFO(hmmc->Instance, &data);
891 }
892 }
893
894 if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U))
895 {
896 /* Clear all the static flags */
897 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
898 hmmc->ErrorCode |= errorstate;
899 hmmc->State = HAL_MMC_STATE_READY;
900 return HAL_TIMEOUT;
901 }
902 }
903
904 /* Send stop transmission command in case of multiblock write */
905 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1U))
906 {
907 /* Send stop transmission command */
908 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
909 if(errorstate != HAL_MMC_ERROR_NONE)
910 {
911 /* Clear all the static flags */
912 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
913 hmmc->ErrorCode |= errorstate;
914 hmmc->State = HAL_MMC_STATE_READY;
915 return HAL_ERROR;
916 }
917 }
918
919 /* Get error state */
920 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DTIMEOUT))
921 {
922 /* Clear all the static flags */
923 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
924 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
925 hmmc->State = HAL_MMC_STATE_READY;
926 return HAL_ERROR;
927 }
928 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL))
929 {
930 /* Clear all the static flags */
931 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
932 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
933 hmmc->State = HAL_MMC_STATE_READY;
934 return HAL_ERROR;
935 }
936 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR))
937 {
938 /* Clear all the static flags */
939 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
940 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
941 hmmc->State = HAL_MMC_STATE_READY;
942 return HAL_ERROR;
943 }
944 else
945 {
946 /* Nothing to do */
947 }
948
949 /* Clear all the static flags */
950 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
951
952 hmmc->State = HAL_MMC_STATE_READY;
953
954 return HAL_OK;
955 }
956 else
957 {
958 hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
959 return HAL_ERROR;
960 }
961 }
962
963 /**
964 * @brief Reads block(s) from a specified address in a card. The Data transfer
965 * is managed in interrupt mode.
966 * @note This API should be followed by a check on the card state through
967 * HAL_MMC_GetCardState().
968 * @note You could also check the IT transfer process through the MMC Rx
969 * interrupt event.
970 * @param hmmc: Pointer to MMC handle
971 * @param pData: Pointer to the buffer that will contain the received data
972 * @param BlockAdd: Block Address from where data is to be read
973 * @param NumberOfBlocks: Number of blocks to read.
974 * @retval HAL status
975 */
HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)976 HAL_StatusTypeDef HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
977 {
978 SDIO_DataInitTypeDef config;
979 uint32_t errorstate;
980 uint32_t add = BlockAdd;
981
982 if(NULL == pData)
983 {
984 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
985 return HAL_ERROR;
986 }
987
988 if(hmmc->State == HAL_MMC_STATE_READY)
989 {
990 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
991
992 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
993 {
994 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
995 return HAL_ERROR;
996 }
997
998 hmmc->State = HAL_MMC_STATE_BUSY;
999
1000 /* Initialize data control register */
1001 hmmc->Instance->DCTRL = 0U;
1002
1003 hmmc->pRxBuffPtr = pData;
1004 hmmc->RxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1005
1006 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_FLAG_RXFIFOHF));
1007
1008 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1009 {
1010 add *= 512U;
1011 }
1012
1013 /* Configure the MMC DPSM (Data Path State Machine) */
1014 config.DataTimeOut = SDMMC_DATATIMEOUT;
1015 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks;
1016 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
1017 config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
1018 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
1019 config.DPSM = SDIO_DPSM_ENABLE;
1020 (void)SDIO_ConfigData(hmmc->Instance, &config);
1021
1022 /* Read Blocks in IT mode */
1023 if(NumberOfBlocks > 1U)
1024 {
1025 hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_IT);
1026
1027 /* Read Multi Block command */
1028 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
1029 }
1030 else
1031 {
1032 hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_IT);
1033
1034 /* Read Single Block command */
1035 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
1036 }
1037
1038 if(errorstate != HAL_MMC_ERROR_NONE)
1039 {
1040 /* Clear all the static flags */
1041 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1042 hmmc->ErrorCode |= errorstate;
1043 hmmc->State = HAL_MMC_STATE_READY;
1044 return HAL_ERROR;
1045 }
1046
1047 return HAL_OK;
1048 }
1049 else
1050 {
1051 return HAL_BUSY;
1052 }
1053 }
1054
1055 /**
1056 * @brief Writes block(s) to a specified address in a card. The Data transfer
1057 * is managed in interrupt mode.
1058 * @note This API should be followed by a check on the card state through
1059 * HAL_MMC_GetCardState().
1060 * @note You could also check the IT transfer process through the MMC Tx
1061 * interrupt event.
1062 * @param hmmc: Pointer to MMC handle
1063 * @param pData: Pointer to the buffer that will contain the data to transmit
1064 * @param BlockAdd: Block Address where data will be written
1065 * @param NumberOfBlocks: Number of blocks to write
1066 * @retval HAL status
1067 */
HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)1068 HAL_StatusTypeDef HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
1069 {
1070 SDIO_DataInitTypeDef config;
1071 uint32_t errorstate;
1072 uint32_t add = BlockAdd;
1073
1074 if(NULL == pData)
1075 {
1076 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1077 return HAL_ERROR;
1078 }
1079
1080 if(hmmc->State == HAL_MMC_STATE_READY)
1081 {
1082 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1083
1084 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1085 {
1086 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1087 return HAL_ERROR;
1088 }
1089
1090 hmmc->State = HAL_MMC_STATE_BUSY;
1091
1092 /* Initialize data control register */
1093 hmmc->Instance->DCTRL = 0U;
1094
1095 hmmc->pTxBuffPtr = pData;
1096 hmmc->TxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1097
1098 /* Enable transfer interrupts */
1099 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_DATAEND | SDIO_FLAG_TXFIFOHE));
1100
1101 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1102 {
1103 add *= 512U;
1104 }
1105
1106 /* Write Blocks in Polling mode */
1107 if(NumberOfBlocks > 1U)
1108 {
1109 hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK| MMC_CONTEXT_IT);
1110
1111 /* Write Multi Block command */
1112 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
1113 }
1114 else
1115 {
1116 hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_IT);
1117
1118 /* Write Single Block command */
1119 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
1120 }
1121 if(errorstate != HAL_MMC_ERROR_NONE)
1122 {
1123 /* Clear all the static flags */
1124 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1125 hmmc->ErrorCode |= errorstate;
1126 hmmc->State = HAL_MMC_STATE_READY;
1127 return HAL_ERROR;
1128 }
1129
1130 /* Configure the MMC DPSM (Data Path State Machine) */
1131 config.DataTimeOut = SDMMC_DATATIMEOUT;
1132 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks;
1133 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
1134 config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
1135 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
1136 config.DPSM = SDIO_DPSM_ENABLE;
1137 (void)SDIO_ConfigData(hmmc->Instance, &config);
1138
1139 return HAL_OK;
1140 }
1141 else
1142 {
1143 return HAL_BUSY;
1144 }
1145 }
1146
1147 /**
1148 * @brief Reads block(s) from a specified address in a card. The Data transfer
1149 * is managed by DMA mode.
1150 * @note This API should be followed by a check on the card state through
1151 * HAL_MMC_GetCardState().
1152 * @note You could also check the DMA transfer process through the MMC Rx
1153 * interrupt event.
1154 * @param hmmc: Pointer MMC handle
1155 * @param pData: Pointer to the buffer that will contain the received data
1156 * @param BlockAdd: Block Address from where data is to be read
1157 * @param NumberOfBlocks: Number of blocks to read.
1158 * @retval HAL status
1159 */
HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)1160 HAL_StatusTypeDef HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
1161 {
1162 SDIO_DataInitTypeDef config;
1163 uint32_t errorstate;
1164 uint32_t add = BlockAdd;
1165
1166 if(NULL == pData)
1167 {
1168 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1169 return HAL_ERROR;
1170 }
1171
1172 if(hmmc->State == HAL_MMC_STATE_READY)
1173 {
1174 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1175
1176 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1177 {
1178 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1179 return HAL_ERROR;
1180 }
1181
1182 hmmc->State = HAL_MMC_STATE_BUSY;
1183
1184 /* Initialize data control register */
1185 hmmc->Instance->DCTRL = 0U;
1186
1187 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND));
1188
1189 /* Set the DMA transfer complete callback */
1190 hmmc->hdmarx->XferCpltCallback = MMC_DMAReceiveCplt;
1191
1192 /* Set the DMA error callback */
1193 hmmc->hdmarx->XferErrorCallback = MMC_DMAError;
1194
1195 /* Set the DMA Abort callback */
1196 hmmc->hdmarx->XferAbortCallback = NULL;
1197
1198 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1199 {
1200 add *= 512U;
1201 }
1202
1203 /* Force DMA Direction */
1204 hmmc->hdmarx->Init.Direction = DMA_PERIPH_TO_MEMORY;
1205 MODIFY_REG(hmmc->hdmarx->Instance->CR, DMA_SxCR_DIR, hmmc->hdmarx->Init.Direction);
1206
1207 /* Enable the DMA Channel */
1208 if(HAL_DMA_Start_IT(hmmc->hdmarx, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)pData, (uint32_t)(MMC_BLOCKSIZE * NumberOfBlocks)/4) != HAL_OK)
1209 {
1210 __HAL_MMC_DISABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND));
1211 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1212 hmmc->ErrorCode = HAL_MMC_ERROR_DMA;
1213 hmmc->State = HAL_MMC_STATE_READY;
1214 return HAL_ERROR;
1215 }
1216 else
1217 {
1218 /* Enable MMC DMA transfer */
1219 __HAL_MMC_DMA_ENABLE(hmmc);
1220
1221 /* Configure the MMC DPSM (Data Path State Machine) */
1222 config.DataTimeOut = SDMMC_DATATIMEOUT;
1223 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks;
1224 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
1225 config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
1226 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
1227 config.DPSM = SDIO_DPSM_ENABLE;
1228 (void)SDIO_ConfigData(hmmc->Instance, &config);
1229
1230 /* Read Blocks in DMA mode */
1231 if(NumberOfBlocks > 1U)
1232 {
1233 hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
1234
1235 /* Read Multi Block command */
1236 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
1237 }
1238 else
1239 {
1240 hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_DMA);
1241
1242 /* Read Single Block command */
1243 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
1244 }
1245 if(errorstate != HAL_MMC_ERROR_NONE)
1246 {
1247 /* Clear all the static flags */
1248 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1249 __HAL_MMC_DISABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND));
1250 hmmc->ErrorCode = errorstate;
1251 hmmc->State = HAL_MMC_STATE_READY;
1252 return HAL_ERROR;
1253 }
1254
1255 return HAL_OK;
1256 }
1257 }
1258 else
1259 {
1260 return HAL_BUSY;
1261 }
1262 }
1263
1264 /**
1265 * @brief Writes block(s) to a specified address in a card. The Data transfer
1266 * is managed by DMA mode.
1267 * @note This API should be followed by a check on the card state through
1268 * HAL_MMC_GetCardState().
1269 * @note You could also check the DMA transfer process through the MMC Tx
1270 * interrupt event.
1271 * @param hmmc: Pointer to MMC handle
1272 * @param pData: Pointer to the buffer that will contain the data to transmit
1273 * @param BlockAdd: Block Address where data will be written
1274 * @param NumberOfBlocks: Number of blocks to write
1275 * @retval HAL status
1276 */
HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)1277 HAL_StatusTypeDef HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
1278 {
1279 SDIO_DataInitTypeDef config;
1280 uint32_t errorstate;
1281 uint32_t add = BlockAdd;
1282
1283 if(NULL == pData)
1284 {
1285 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1286 return HAL_ERROR;
1287 }
1288
1289 if(hmmc->State == HAL_MMC_STATE_READY)
1290 {
1291 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1292
1293 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1294 {
1295 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1296 return HAL_ERROR;
1297 }
1298
1299 hmmc->State = HAL_MMC_STATE_BUSY;
1300
1301 /* Initialize data control register */
1302 hmmc->Instance->DCTRL = 0U;
1303
1304 /* Enable MMC Error interrupts */
1305 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR));
1306
1307 /* Set the DMA transfer complete callback */
1308 hmmc->hdmatx->XferCpltCallback = MMC_DMATransmitCplt;
1309
1310 /* Set the DMA error callback */
1311 hmmc->hdmatx->XferErrorCallback = MMC_DMAError;
1312
1313 /* Set the DMA Abort callback */
1314 hmmc->hdmatx->XferAbortCallback = NULL;
1315
1316 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1317 {
1318 add *= 512U;
1319 }
1320
1321
1322 /* Write Blocks in Polling mode */
1323 if(NumberOfBlocks > 1U)
1324 {
1325 hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
1326
1327 /* Write Multi Block command */
1328 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
1329 }
1330 else
1331 {
1332 hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_DMA);
1333
1334 /* Write Single Block command */
1335 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
1336 }
1337 if(errorstate != HAL_MMC_ERROR_NONE)
1338 {
1339 /* Clear all the static flags */
1340 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1341 __HAL_MMC_DISABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_DATAEND));
1342 hmmc->ErrorCode |= errorstate;
1343 hmmc->State = HAL_MMC_STATE_READY;
1344 return HAL_ERROR;
1345 }
1346
1347 /* Enable SDIO DMA transfer */
1348 __HAL_MMC_DMA_ENABLE(hmmc);
1349
1350 /* Force DMA Direction */
1351 hmmc->hdmatx->Init.Direction = DMA_MEMORY_TO_PERIPH;
1352 MODIFY_REG(hmmc->hdmatx->Instance->CR, DMA_SxCR_DIR, hmmc->hdmatx->Init.Direction);
1353
1354 /* Enable the DMA Channel */
1355 if(HAL_DMA_Start_IT(hmmc->hdmatx, (uint32_t)pData, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)(MMC_BLOCKSIZE * NumberOfBlocks)/4) != HAL_OK)
1356 {
1357 __HAL_MMC_DISABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_DATAEND));
1358 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1359 hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
1360 hmmc->State = HAL_MMC_STATE_READY;
1361 return HAL_ERROR;
1362 }
1363 else
1364 {
1365 /* Configure the MMC DPSM (Data Path State Machine) */
1366 config.DataTimeOut = SDMMC_DATATIMEOUT;
1367 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks;
1368 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
1369 config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
1370 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
1371 config.DPSM = SDIO_DPSM_ENABLE;
1372 (void)SDIO_ConfigData(hmmc->Instance, &config);
1373
1374 return HAL_OK;
1375 }
1376 }
1377 else
1378 {
1379 return HAL_BUSY;
1380 }
1381 }
1382
1383 /**
1384 * @brief Erases the specified memory area of the given MMC card.
1385 * @note This API should be followed by a check on the card state through
1386 * HAL_MMC_GetCardState().
1387 * @param hmmc: Pointer to MMC handle
1388 * @param BlockStartAdd: Start Block address
1389 * @param BlockEndAdd: End Block address
1390 * @retval HAL status
1391 */
HAL_MMC_Erase(MMC_HandleTypeDef * hmmc,uint32_t BlockStartAdd,uint32_t BlockEndAdd)1392 HAL_StatusTypeDef HAL_MMC_Erase(MMC_HandleTypeDef *hmmc, uint32_t BlockStartAdd, uint32_t BlockEndAdd)
1393 {
1394 uint32_t errorstate;
1395 uint32_t start_add = BlockStartAdd;
1396 uint32_t end_add = BlockEndAdd;
1397
1398 if(hmmc->State == HAL_MMC_STATE_READY)
1399 {
1400 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1401
1402 if(end_add < start_add)
1403 {
1404 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1405 return HAL_ERROR;
1406 }
1407
1408 if(end_add > (hmmc->MmcCard.LogBlockNbr))
1409 {
1410 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1411 return HAL_ERROR;
1412 }
1413
1414 hmmc->State = HAL_MMC_STATE_BUSY;
1415
1416 /* Check if the card command class supports erase command */
1417 if(((hmmc->MmcCard.Class) & SDIO_CCCC_ERASE) == 0U)
1418 {
1419 /* Clear all the static flags */
1420 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1421 hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
1422 hmmc->State = HAL_MMC_STATE_READY;
1423 return HAL_ERROR;
1424 }
1425
1426 if((SDIO_GetResponse(hmmc->Instance, SDIO_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
1427 {
1428 /* Clear all the static flags */
1429 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1430 hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED;
1431 hmmc->State = HAL_MMC_STATE_READY;
1432 return HAL_ERROR;
1433 }
1434
1435 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1436 {
1437 start_add *= 512U;
1438 end_add *= 512U;
1439 }
1440
1441 /* Send CMD35 MMC_ERASE_GRP_START with argument as addr */
1442 errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, start_add);
1443 if(errorstate != HAL_MMC_ERROR_NONE)
1444 {
1445 /* Clear all the static flags */
1446 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1447 hmmc->ErrorCode |= errorstate;
1448 hmmc->State = HAL_MMC_STATE_READY;
1449 return HAL_ERROR;
1450 }
1451
1452 /* Send CMD36 MMC_ERASE_GRP_END with argument as addr */
1453 errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, end_add);
1454 if(errorstate != HAL_MMC_ERROR_NONE)
1455 {
1456 /* Clear all the static flags */
1457 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1458 hmmc->ErrorCode |= errorstate;
1459 hmmc->State = HAL_MMC_STATE_READY;
1460 return HAL_ERROR;
1461 }
1462
1463 /* Send CMD38 ERASE */
1464 errorstate = SDMMC_CmdErase(hmmc->Instance);
1465 if(errorstate != HAL_MMC_ERROR_NONE)
1466 {
1467 /* Clear all the static flags */
1468 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1469 hmmc->ErrorCode |= errorstate;
1470 hmmc->State = HAL_MMC_STATE_READY;
1471 return HAL_ERROR;
1472 }
1473
1474 hmmc->State = HAL_MMC_STATE_READY;
1475
1476 return HAL_OK;
1477 }
1478 else
1479 {
1480 return HAL_BUSY;
1481 }
1482 }
1483
1484 /**
1485 * @brief This function handles MMC card interrupt request.
1486 * @param hmmc: Pointer to MMC handle
1487 * @retval None
1488 */
HAL_MMC_IRQHandler(MMC_HandleTypeDef * hmmc)1489 void HAL_MMC_IRQHandler(MMC_HandleTypeDef *hmmc)
1490 {
1491 uint32_t errorstate;
1492 uint32_t context = hmmc->Context;
1493
1494 /* Check for SDIO interrupt flags */
1495 if((__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXFIFOHF) != RESET) && ((context & MMC_CONTEXT_IT) != 0U))
1496 {
1497 MMC_Read_IT(hmmc);
1498 }
1499
1500 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DATAEND) != RESET)
1501 {
1502 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_FLAG_DATAEND);
1503
1504 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
1505 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
1506
1507 hmmc->Instance->DCTRL &= ~(SDIO_DCTRL_DTEN);
1508
1509 if((context & MMC_CONTEXT_DMA) != 0U)
1510 {
1511 if((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)
1512 {
1513 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
1514 if(errorstate != HAL_MMC_ERROR_NONE)
1515 {
1516 hmmc->ErrorCode |= errorstate;
1517 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1518 hmmc->ErrorCallback(hmmc);
1519 #else
1520 HAL_MMC_ErrorCallback(hmmc);
1521 #endif
1522 }
1523 }
1524 if(((context & MMC_CONTEXT_READ_SINGLE_BLOCK) == 0U) && ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) == 0U))
1525 {
1526 /* Disable the DMA transfer for transmit request by setting the DMAEN bit
1527 in the MMC DCTRL register */
1528 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
1529
1530 hmmc->State = HAL_MMC_STATE_READY;
1531
1532 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1533 hmmc->TxCpltCallback(hmmc);
1534 #else
1535 HAL_MMC_TxCpltCallback(hmmc);
1536 #endif
1537 }
1538 }
1539 else if((context & MMC_CONTEXT_IT) != 0U)
1540 {
1541 /* Stop Transfer for Write Multi blocks or Read Multi blocks */
1542 if(((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
1543 {
1544 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
1545 if(errorstate != HAL_MMC_ERROR_NONE)
1546 {
1547 hmmc->ErrorCode |= errorstate;
1548 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1549 hmmc->ErrorCallback(hmmc);
1550 #else
1551 HAL_MMC_ErrorCallback(hmmc);
1552 #endif
1553 }
1554 }
1555
1556 /* Clear all the static flags */
1557 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
1558
1559 hmmc->State = HAL_MMC_STATE_READY;
1560 if(((context & MMC_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
1561 {
1562 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1563 hmmc->RxCpltCallback(hmmc);
1564 #else
1565 HAL_MMC_RxCpltCallback(hmmc);
1566 #endif
1567 }
1568 else
1569 {
1570 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1571 hmmc->TxCpltCallback(hmmc);
1572 #else
1573 HAL_MMC_TxCpltCallback(hmmc);
1574 #endif
1575 }
1576 }
1577 else
1578 {
1579 /* Nothing to do */
1580 }
1581 }
1582
1583 else if((__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXFIFOHE) != RESET) && ((context & MMC_CONTEXT_IT) != 0U))
1584 {
1585 MMC_Write_IT(hmmc);
1586 }
1587
1588 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_RXOVERR | SDIO_FLAG_TXUNDERR) != RESET)
1589 {
1590 /* Set Error code */
1591 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL) != RESET)
1592 {
1593 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
1594 }
1595 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DTIMEOUT) != RESET)
1596 {
1597 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
1598 }
1599 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR) != RESET)
1600 {
1601 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
1602 }
1603 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR) != RESET)
1604 {
1605 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
1606 }
1607
1608 /* Clear All flags */
1609 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS | SDIO_FLAG_STBITERR);
1610
1611 /* Disable all interrupts */
1612 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
1613 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR | SDIO_IT_STBITERR);
1614
1615 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
1616
1617 if((context & MMC_CONTEXT_IT) != 0U)
1618 {
1619 /* Set the MMC state to ready to be able to start again the process */
1620 hmmc->State = HAL_MMC_STATE_READY;
1621 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1622 hmmc->ErrorCallback(hmmc);
1623 #else
1624 HAL_MMC_ErrorCallback(hmmc);
1625 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1626 }
1627 else if((context & MMC_CONTEXT_DMA) != 0U)
1628 {
1629 /* Abort the MMC DMA Streams */
1630 if(hmmc->hdmatx != NULL)
1631 {
1632 /* Set the DMA Tx abort callback */
1633 hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort;
1634 /* Abort DMA in IT mode */
1635 if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
1636 {
1637 MMC_DMATxAbort(hmmc->hdmatx);
1638 }
1639 }
1640 else if(hmmc->hdmarx != NULL)
1641 {
1642 /* Set the DMA Rx abort callback */
1643 hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort;
1644 /* Abort DMA in IT mode */
1645 if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
1646 {
1647 MMC_DMARxAbort(hmmc->hdmarx);
1648 }
1649 }
1650 else
1651 {
1652 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1653 hmmc->State = HAL_MMC_STATE_READY;
1654 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1655 hmmc->AbortCpltCallback(hmmc);
1656 #else
1657 HAL_MMC_AbortCallback(hmmc);
1658 #endif
1659 }
1660 }
1661 else
1662 {
1663 /* Nothing to do */
1664 }
1665 }
1666
1667 else
1668 {
1669 /* Nothing to do */
1670 }
1671 }
1672
1673 /**
1674 * @brief return the MMC state
1675 * @param hmmc: Pointer to mmc handle
1676 * @retval HAL state
1677 */
HAL_MMC_GetState(MMC_HandleTypeDef * hmmc)1678 HAL_MMC_StateTypeDef HAL_MMC_GetState(MMC_HandleTypeDef *hmmc)
1679 {
1680 return hmmc->State;
1681 }
1682
1683 /**
1684 * @brief Return the MMC error code
1685 * @param hmmc : Pointer to a MMC_HandleTypeDef structure that contains
1686 * the configuration information.
1687 * @retval MMC Error Code
1688 */
HAL_MMC_GetError(MMC_HandleTypeDef * hmmc)1689 uint32_t HAL_MMC_GetError(MMC_HandleTypeDef *hmmc)
1690 {
1691 return hmmc->ErrorCode;
1692 }
1693
1694 /**
1695 * @brief Tx Transfer completed callbacks
1696 * @param hmmc: Pointer to MMC handle
1697 * @retval None
1698 */
HAL_MMC_TxCpltCallback(MMC_HandleTypeDef * hmmc)1699 __weak void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef *hmmc)
1700 {
1701 /* Prevent unused argument(s) compilation warning */
1702 UNUSED(hmmc);
1703
1704 /* NOTE : This function should not be modified, when the callback is needed,
1705 the HAL_MMC_TxCpltCallback can be implemented in the user file
1706 */
1707 }
1708
1709 /**
1710 * @brief Rx Transfer completed callbacks
1711 * @param hmmc: Pointer MMC handle
1712 * @retval None
1713 */
HAL_MMC_RxCpltCallback(MMC_HandleTypeDef * hmmc)1714 __weak void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef *hmmc)
1715 {
1716 /* Prevent unused argument(s) compilation warning */
1717 UNUSED(hmmc);
1718
1719 /* NOTE : This function should not be modified, when the callback is needed,
1720 the HAL_MMC_RxCpltCallback can be implemented in the user file
1721 */
1722 }
1723
1724 /**
1725 * @brief MMC error callbacks
1726 * @param hmmc: Pointer MMC handle
1727 * @retval None
1728 */
HAL_MMC_ErrorCallback(MMC_HandleTypeDef * hmmc)1729 __weak void HAL_MMC_ErrorCallback(MMC_HandleTypeDef *hmmc)
1730 {
1731 /* Prevent unused argument(s) compilation warning */
1732 UNUSED(hmmc);
1733
1734 /* NOTE : This function should not be modified, when the callback is needed,
1735 the HAL_MMC_ErrorCallback can be implemented in the user file
1736 */
1737 }
1738
1739 /**
1740 * @brief MMC Abort callbacks
1741 * @param hmmc: Pointer MMC handle
1742 * @retval None
1743 */
HAL_MMC_AbortCallback(MMC_HandleTypeDef * hmmc)1744 __weak void HAL_MMC_AbortCallback(MMC_HandleTypeDef *hmmc)
1745 {
1746 /* Prevent unused argument(s) compilation warning */
1747 UNUSED(hmmc);
1748
1749 /* NOTE : This function should not be modified, when the callback is needed,
1750 the HAL_MMC_AbortCallback can be implemented in the user file
1751 */
1752 }
1753
1754 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1755 /**
1756 * @brief Register a User MMC Callback
1757 * To be used instead of the weak (surcharged) predefined callback
1758 * @param hmmc : MMC handle
1759 * @param CallbackId : ID of the callback to be registered
1760 * This parameter can be one of the following values:
1761 * @arg @ref HAL_MMC_TX_CPLT_CB_ID MMC Tx Complete Callback ID
1762 * @arg @ref HAL_MMC_RX_CPLT_CB_ID MMC Rx Complete Callback ID
1763 * @arg @ref HAL_MMC_ERROR_CB_ID MMC Error Callback ID
1764 * @arg @ref HAL_MMC_ABORT_CB_ID MMC Abort Callback ID
1765 * @arg @ref HAL_MMC_MSP_INIT_CB_ID MMC MspInit Callback ID
1766 * @arg @ref HAL_MMC_MSP_DEINIT_CB_ID MMC MspDeInit Callback ID
1767 * @param pCallback : pointer to the Callback function
1768 * @retval status
1769 */
HAL_MMC_RegisterCallback(MMC_HandleTypeDef * hmmc,HAL_MMC_CallbackIDTypeDef CallbackId,pMMC_CallbackTypeDef pCallback)1770 HAL_StatusTypeDef HAL_MMC_RegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId, pMMC_CallbackTypeDef pCallback)
1771 {
1772 HAL_StatusTypeDef status = HAL_OK;
1773
1774 if(pCallback == NULL)
1775 {
1776 /* Update the error code */
1777 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1778 return HAL_ERROR;
1779 }
1780
1781 /* Process locked */
1782 __HAL_LOCK(hmmc);
1783
1784 if(hmmc->State == HAL_MMC_STATE_READY)
1785 {
1786 switch (CallbackId)
1787 {
1788 case HAL_MMC_TX_CPLT_CB_ID :
1789 hmmc->TxCpltCallback = pCallback;
1790 break;
1791 case HAL_MMC_RX_CPLT_CB_ID :
1792 hmmc->RxCpltCallback = pCallback;
1793 break;
1794 case HAL_MMC_ERROR_CB_ID :
1795 hmmc->ErrorCallback = pCallback;
1796 break;
1797 case HAL_MMC_ABORT_CB_ID :
1798 hmmc->AbortCpltCallback = pCallback;
1799 break;
1800 case HAL_MMC_MSP_INIT_CB_ID :
1801 hmmc->MspInitCallback = pCallback;
1802 break;
1803 case HAL_MMC_MSP_DEINIT_CB_ID :
1804 hmmc->MspDeInitCallback = pCallback;
1805 break;
1806 default :
1807 /* Update the error code */
1808 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1809 /* update return status */
1810 status = HAL_ERROR;
1811 break;
1812 }
1813 }
1814 else if (hmmc->State == HAL_MMC_STATE_RESET)
1815 {
1816 switch (CallbackId)
1817 {
1818 case HAL_MMC_MSP_INIT_CB_ID :
1819 hmmc->MspInitCallback = pCallback;
1820 break;
1821 case HAL_MMC_MSP_DEINIT_CB_ID :
1822 hmmc->MspDeInitCallback = pCallback;
1823 break;
1824 default :
1825 /* Update the error code */
1826 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1827 /* update return status */
1828 status = HAL_ERROR;
1829 break;
1830 }
1831 }
1832 else
1833 {
1834 /* Update the error code */
1835 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1836 /* update return status */
1837 status = HAL_ERROR;
1838 }
1839
1840 /* Release Lock */
1841 __HAL_UNLOCK(hmmc);
1842 return status;
1843 }
1844
1845 /**
1846 * @brief Unregister a User MMC Callback
1847 * MMC Callback is redirected to the weak (surcharged) predefined callback
1848 * @param hmmc : MMC handle
1849 * @param CallbackId : ID of the callback to be unregistered
1850 * This parameter can be one of the following values:
1851 * @arg @ref HAL_MMC_TX_CPLT_CB_ID MMC Tx Complete Callback ID
1852 * @arg @ref HAL_MMC_RX_CPLT_CB_ID MMC Rx Complete Callback ID
1853 * @arg @ref HAL_MMC_ERROR_CB_ID MMC Error Callback ID
1854 * @arg @ref HAL_MMC_ABORT_CB_ID MMC Abort Callback ID
1855 * @arg @ref HAL_MMC_MSP_INIT_CB_ID MMC MspInit Callback ID
1856 * @arg @ref HAL_MMC_MSP_DEINIT_CB_ID MMC MspDeInit Callback ID
1857 * @retval status
1858 */
HAL_MMC_UnRegisterCallback(MMC_HandleTypeDef * hmmc,HAL_MMC_CallbackIDTypeDef CallbackId)1859 HAL_StatusTypeDef HAL_MMC_UnRegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId)
1860 {
1861 HAL_StatusTypeDef status = HAL_OK;
1862
1863 /* Process locked */
1864 __HAL_LOCK(hmmc);
1865
1866 if(hmmc->State == HAL_MMC_STATE_READY)
1867 {
1868 switch (CallbackId)
1869 {
1870 case HAL_MMC_TX_CPLT_CB_ID :
1871 hmmc->TxCpltCallback = HAL_MMC_TxCpltCallback;
1872 break;
1873 case HAL_MMC_RX_CPLT_CB_ID :
1874 hmmc->RxCpltCallback = HAL_MMC_RxCpltCallback;
1875 break;
1876 case HAL_MMC_ERROR_CB_ID :
1877 hmmc->ErrorCallback = HAL_MMC_ErrorCallback;
1878 break;
1879 case HAL_MMC_ABORT_CB_ID :
1880 hmmc->AbortCpltCallback = HAL_MMC_AbortCallback;
1881 break;
1882 case HAL_MMC_MSP_INIT_CB_ID :
1883 hmmc->MspInitCallback = HAL_MMC_MspInit;
1884 break;
1885 case HAL_MMC_MSP_DEINIT_CB_ID :
1886 hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
1887 break;
1888 default :
1889 /* Update the error code */
1890 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1891 /* update return status */
1892 status = HAL_ERROR;
1893 break;
1894 }
1895 }
1896 else if (hmmc->State == HAL_MMC_STATE_RESET)
1897 {
1898 switch (CallbackId)
1899 {
1900 case HAL_MMC_MSP_INIT_CB_ID :
1901 hmmc->MspInitCallback = HAL_MMC_MspInit;
1902 break;
1903 case HAL_MMC_MSP_DEINIT_CB_ID :
1904 hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
1905 break;
1906 default :
1907 /* Update the error code */
1908 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1909 /* update return status */
1910 status = HAL_ERROR;
1911 break;
1912 }
1913 }
1914 else
1915 {
1916 /* Update the error code */
1917 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1918 /* update return status */
1919 status = HAL_ERROR;
1920 }
1921
1922 /* Release Lock */
1923 __HAL_UNLOCK(hmmc);
1924 return status;
1925 }
1926 #endif
1927
1928 /**
1929 * @}
1930 */
1931
1932 /** @addtogroup MMC_Exported_Functions_Group3
1933 * @brief management functions
1934 *
1935 @verbatim
1936 ==============================================================================
1937 ##### Peripheral Control functions #####
1938 ==============================================================================
1939 [..]
1940 This subsection provides a set of functions allowing to control the MMC card
1941 operations and get the related information
1942
1943 @endverbatim
1944 * @{
1945 */
1946
1947 /**
1948 * @brief Returns information the information of the card which are stored on
1949 * the CID register.
1950 * @param hmmc: Pointer to MMC handle
1951 * @param pCID: Pointer to a HAL_MMC_CIDTypedef structure that
1952 * contains all CID register parameters
1953 * @retval HAL status
1954 */
HAL_MMC_GetCardCID(MMC_HandleTypeDef * hmmc,HAL_MMC_CardCIDTypeDef * pCID)1955 HAL_StatusTypeDef HAL_MMC_GetCardCID(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCIDTypeDef *pCID)
1956 {
1957 pCID->ManufacturerID = (uint8_t)((hmmc->CID[0] & 0xFF000000U) >> 24U);
1958
1959 pCID->OEM_AppliID = (uint16_t)((hmmc->CID[0] & 0x00FFFF00U) >> 8U);
1960
1961 pCID->ProdName1 = (((hmmc->CID[0] & 0x000000FFU) << 24U) | ((hmmc->CID[1] & 0xFFFFFF00U) >> 8U));
1962
1963 pCID->ProdName2 = (uint8_t)(hmmc->CID[1] & 0x000000FFU);
1964
1965 pCID->ProdRev = (uint8_t)((hmmc->CID[2] & 0xFF000000U) >> 24U);
1966
1967 pCID->ProdSN = (((hmmc->CID[2] & 0x00FFFFFFU) << 8U) | ((hmmc->CID[3] & 0xFF000000U) >> 24U));
1968
1969 pCID->Reserved1 = (uint8_t)((hmmc->CID[3] & 0x00F00000U) >> 20U);
1970
1971 pCID->ManufactDate = (uint16_t)((hmmc->CID[3] & 0x000FFF00U) >> 8U);
1972
1973 pCID->CID_CRC = (uint8_t)((hmmc->CID[3] & 0x000000FEU) >> 1U);
1974
1975 pCID->Reserved2 = 1U;
1976
1977 return HAL_OK;
1978 }
1979
1980 /**
1981 * @brief Returns information the information of the card which are stored on
1982 * the CSD register.
1983 * @param hmmc: Pointer to MMC handle
1984 * @param pCSD: Pointer to a HAL_MMC_CardCSDTypeDef structure that
1985 * contains all CSD register parameters
1986 * @retval HAL status
1987 */
HAL_MMC_GetCardCSD(MMC_HandleTypeDef * hmmc,HAL_MMC_CardCSDTypeDef * pCSD)1988 HAL_StatusTypeDef HAL_MMC_GetCardCSD(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCSDTypeDef *pCSD)
1989 {
1990 uint32_t block_nbr = 0;
1991
1992 pCSD->CSDStruct = (uint8_t)((hmmc->CSD[0] & 0xC0000000U) >> 30U);
1993
1994 pCSD->SysSpecVersion = (uint8_t)((hmmc->CSD[0] & 0x3C000000U) >> 26U);
1995
1996 pCSD->Reserved1 = (uint8_t)((hmmc->CSD[0] & 0x03000000U) >> 24U);
1997
1998 pCSD->TAAC = (uint8_t)((hmmc->CSD[0] & 0x00FF0000U) >> 16U);
1999
2000 pCSD->NSAC = (uint8_t)((hmmc->CSD[0] & 0x0000FF00U) >> 8U);
2001
2002 pCSD->MaxBusClkFrec = (uint8_t)(hmmc->CSD[0] & 0x000000FFU);
2003
2004 pCSD->CardComdClasses = (uint16_t)((hmmc->CSD[1] & 0xFFF00000U) >> 20U);
2005
2006 pCSD->RdBlockLen = (uint8_t)((hmmc->CSD[1] & 0x000F0000U) >> 16U);
2007
2008 pCSD->PartBlockRead = (uint8_t)((hmmc->CSD[1] & 0x00008000U) >> 15U);
2009
2010 pCSD->WrBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00004000U) >> 14U);
2011
2012 pCSD->RdBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00002000U) >> 13U);
2013
2014 pCSD->DSRImpl = (uint8_t)((hmmc->CSD[1] & 0x00001000U) >> 12U);
2015
2016 pCSD->Reserved2 = 0U; /*!< Reserved */
2017
2018 pCSD->DeviceSize = (((hmmc->CSD[1] & 0x000003FFU) << 2U) | ((hmmc->CSD[2] & 0xC0000000U) >> 30U));
2019
2020 pCSD->MaxRdCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x38000000U) >> 27U);
2021
2022 pCSD->MaxRdCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x07000000U) >> 24U);
2023
2024 pCSD->MaxWrCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x00E00000U) >> 21U);
2025
2026 pCSD->MaxWrCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x001C0000U) >> 18U);
2027
2028 pCSD->DeviceSizeMul = (uint8_t)((hmmc->CSD[2] & 0x00038000U) >> 15U);
2029
2030 if(MMC_ReadExtCSD(hmmc, &block_nbr, 212, 0x0FFFFFFFU) != HAL_OK) /* Field SEC_COUNT [215:212] */
2031 {
2032 return HAL_ERROR;
2033 }
2034
2035 if(hmmc->MmcCard.CardType == MMC_LOW_CAPACITY_CARD)
2036 {
2037 hmmc->MmcCard.BlockNbr = (pCSD->DeviceSize + 1U) ;
2038 hmmc->MmcCard.BlockNbr *= (1UL << ((pCSD->DeviceSizeMul & 0x07U) + 2U));
2039 hmmc->MmcCard.BlockSize = (1UL << (pCSD->RdBlockLen & 0x0FU));
2040 hmmc->MmcCard.LogBlockNbr = (hmmc->MmcCard.BlockNbr) * ((hmmc->MmcCard.BlockSize) / 512U);
2041 hmmc->MmcCard.LogBlockSize = 512U;
2042 }
2043 else if(hmmc->MmcCard.CardType == MMC_HIGH_CAPACITY_CARD)
2044 {
2045 hmmc->MmcCard.BlockNbr = block_nbr;
2046 hmmc->MmcCard.LogBlockNbr = hmmc->MmcCard.BlockNbr;
2047 hmmc->MmcCard.BlockSize = 512U;
2048 hmmc->MmcCard.LogBlockSize = hmmc->MmcCard.BlockSize;
2049 }
2050 else
2051 {
2052 /* Clear all the static flags */
2053 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
2054 hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2055 hmmc->State = HAL_MMC_STATE_READY;
2056 return HAL_ERROR;
2057 }
2058
2059 pCSD->EraseGrSize = (uint8_t)((hmmc->CSD[2] & 0x00004000U) >> 14U);
2060
2061 pCSD->EraseGrMul = (uint8_t)((hmmc->CSD[2] & 0x00003F80U) >> 7U);
2062
2063 pCSD->WrProtectGrSize = (uint8_t)(hmmc->CSD[2] & 0x0000007FU);
2064
2065 pCSD->WrProtectGrEnable = (uint8_t)((hmmc->CSD[3] & 0x80000000U) >> 31U);
2066
2067 pCSD->ManDeflECC = (uint8_t)((hmmc->CSD[3] & 0x60000000U) >> 29U);
2068
2069 pCSD->WrSpeedFact = (uint8_t)((hmmc->CSD[3] & 0x1C000000U) >> 26U);
2070
2071 pCSD->MaxWrBlockLen= (uint8_t)((hmmc->CSD[3] & 0x03C00000U) >> 22U);
2072
2073 pCSD->WriteBlockPaPartial = (uint8_t)((hmmc->CSD[3] & 0x00200000U) >> 21U);
2074
2075 pCSD->Reserved3 = 0;
2076
2077 pCSD->ContentProtectAppli = (uint8_t)((hmmc->CSD[3] & 0x00010000U) >> 16U);
2078
2079 pCSD->FileFormatGroup = (uint8_t)((hmmc->CSD[3] & 0x00008000U) >> 15U);
2080
2081 pCSD->CopyFlag = (uint8_t)((hmmc->CSD[3] & 0x00004000U) >> 14U);
2082
2083 pCSD->PermWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00002000U) >> 13U);
2084
2085 pCSD->TempWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00001000U) >> 12U);
2086
2087 pCSD->FileFormat = (uint8_t)((hmmc->CSD[3] & 0x00000C00U) >> 10U);
2088
2089 pCSD->ECC= (uint8_t)((hmmc->CSD[3] & 0x00000300U) >> 8U);
2090
2091 pCSD->CSD_CRC = (uint8_t)((hmmc->CSD[3] & 0x000000FEU) >> 1U);
2092
2093 pCSD->Reserved4 = 1;
2094
2095 return HAL_OK;
2096 }
2097
2098 /**
2099 * @brief Gets the MMC card info.
2100 * @param hmmc: Pointer to MMC handle
2101 * @param pCardInfo: Pointer to the HAL_MMC_CardInfoTypeDef structure that
2102 * will contain the MMC card status information
2103 * @retval HAL status
2104 */
HAL_MMC_GetCardInfo(MMC_HandleTypeDef * hmmc,HAL_MMC_CardInfoTypeDef * pCardInfo)2105 HAL_StatusTypeDef HAL_MMC_GetCardInfo(MMC_HandleTypeDef *hmmc, HAL_MMC_CardInfoTypeDef *pCardInfo)
2106 {
2107 pCardInfo->CardType = (uint32_t)(hmmc->MmcCard.CardType);
2108 pCardInfo->Class = (uint32_t)(hmmc->MmcCard.Class);
2109 pCardInfo->RelCardAdd = (uint32_t)(hmmc->MmcCard.RelCardAdd);
2110 pCardInfo->BlockNbr = (uint32_t)(hmmc->MmcCard.BlockNbr);
2111 pCardInfo->BlockSize = (uint32_t)(hmmc->MmcCard.BlockSize);
2112 pCardInfo->LogBlockNbr = (uint32_t)(hmmc->MmcCard.LogBlockNbr);
2113 pCardInfo->LogBlockSize = (uint32_t)(hmmc->MmcCard.LogBlockSize);
2114
2115 return HAL_OK;
2116 }
2117
2118 /**
2119 * @brief Returns information the information of the card which are stored on
2120 * the Extended CSD register.
2121 * @param hmmc Pointer to MMC handle
2122 * @param pExtCSD Pointer to a memory area (512 bytes) that contains all
2123 * Extended CSD register parameters
2124 * @param Timeout Specify timeout value
2125 * @retval HAL status
2126 */
HAL_MMC_GetCardExtCSD(MMC_HandleTypeDef * hmmc,uint32_t * pExtCSD,uint32_t Timeout)2127 HAL_StatusTypeDef HAL_MMC_GetCardExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pExtCSD, uint32_t Timeout)
2128 {
2129 SDIO_DataInitTypeDef config;
2130 uint32_t errorstate;
2131 uint32_t tickstart = HAL_GetTick();
2132 uint32_t count;
2133 uint32_t *tmp_buf;
2134
2135 if(NULL == pExtCSD)
2136 {
2137 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
2138 return HAL_ERROR;
2139 }
2140
2141 if(hmmc->State == HAL_MMC_STATE_READY)
2142 {
2143 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
2144
2145 hmmc->State = HAL_MMC_STATE_BUSY;
2146
2147 /* Initialize data control register */
2148 hmmc->Instance->DCTRL = 0;
2149
2150 /* Initiaize the destination pointer */
2151 tmp_buf = pExtCSD;
2152
2153 /* Configure the MMC DPSM (Data Path State Machine) */
2154 config.DataTimeOut = SDMMC_DATATIMEOUT;
2155 config.DataLength = 512;
2156 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
2157 config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
2158 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
2159 config.DPSM = SDIO_DPSM_ENABLE;
2160 (void)SDIO_ConfigData(hmmc->Instance, &config);
2161
2162 /* Send ExtCSD Read command to Card */
2163 errorstate = SDMMC_CmdSendEXTCSD(hmmc->Instance, 0);
2164 if(errorstate != HAL_MMC_ERROR_NONE)
2165 {
2166 /* Clear all the static flags */
2167 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
2168 hmmc->ErrorCode |= errorstate;
2169 hmmc->State = HAL_MMC_STATE_READY;
2170 return HAL_ERROR;
2171 }
2172
2173 /* Poll on SDMMC flags */
2174 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND))
2175 {
2176 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXFIFOHF))
2177 {
2178 /* Read data from SDMMC Rx FIFO */
2179 for(count = 0U; count < 8U; count++)
2180 {
2181 *tmp_buf = SDIO_ReadFIFO(hmmc->Instance);
2182 tmp_buf++;
2183 }
2184 }
2185
2186 if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U))
2187 {
2188 /* Clear all the static flags */
2189 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
2190 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
2191 hmmc->State= HAL_MMC_STATE_READY;
2192 return HAL_TIMEOUT;
2193 }
2194 }
2195
2196 /* Get error state */
2197 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DTIMEOUT))
2198 {
2199 /* Clear all the static flags */
2200 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
2201 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
2202 hmmc->State = HAL_MMC_STATE_READY;
2203 return HAL_ERROR;
2204 }
2205 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL))
2206 {
2207 /* Clear all the static flags */
2208 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
2209 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
2210 hmmc->State = HAL_MMC_STATE_READY;
2211 return HAL_ERROR;
2212 }
2213 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR))
2214 {
2215 /* Clear all the static flags */
2216 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
2217 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
2218 hmmc->State = HAL_MMC_STATE_READY;
2219 return HAL_ERROR;
2220 }
2221 else
2222 {
2223 /* Nothing to do */
2224 }
2225
2226 /* Clear all the static flags */
2227 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
2228 hmmc->State = HAL_MMC_STATE_READY;
2229 }
2230
2231 return HAL_OK;
2232 }
2233
2234 /**
2235 * @brief Enables wide bus operation for the requested card if supported by
2236 * card.
2237 * @param hmmc: Pointer to MMC handle
2238 * @param WideMode: Specifies the MMC card wide bus mode
2239 * This parameter can be one of the following values:
2240 * @arg SDIO_BUS_WIDE_8B: 8-bit data transfer
2241 * @arg SDIO_BUS_WIDE_4B: 4-bit data transfer
2242 * @arg SDIO_BUS_WIDE_1B: 1-bit data transfer
2243 * @retval HAL status
2244 */
HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef * hmmc,uint32_t WideMode)2245 HAL_StatusTypeDef HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef *hmmc, uint32_t WideMode)
2246 {
2247 uint32_t count;
2248 SDIO_InitTypeDef Init;
2249 uint32_t errorstate;
2250 uint32_t response = 0U;
2251
2252 /* Check the parameters */
2253 assert_param(IS_SDIO_BUS_WIDE(WideMode));
2254
2255 /* Change State */
2256 hmmc->State = HAL_MMC_STATE_BUSY;
2257
2258 errorstate = MMC_PwrClassUpdate(hmmc, WideMode);
2259
2260 if(errorstate == HAL_MMC_ERROR_NONE)
2261 {
2262 if(WideMode == SDIO_BUS_WIDE_8B)
2263 {
2264 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U);
2265 }
2266 else if(WideMode == SDIO_BUS_WIDE_4B)
2267 {
2268 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U);
2269 }
2270 else if(WideMode == SDIO_BUS_WIDE_1B)
2271 {
2272 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70000U);
2273 }
2274 else
2275 {
2276 /* WideMode is not a valid argument*/
2277 errorstate = HAL_MMC_ERROR_PARAM;
2278 }
2279
2280 /* Check for switch error and violation of the trial number of sending CMD 13 */
2281 if(errorstate == HAL_MMC_ERROR_NONE)
2282 {
2283 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2284 count = SDMMC_MAX_TRIAL;
2285 do
2286 {
2287 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2288 if(errorstate != HAL_MMC_ERROR_NONE)
2289 {
2290 break;
2291 }
2292
2293 /* Get command response */
2294 response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
2295 count--;
2296 }while(((response & 0x100U) == 0U) && (count != 0U));
2297
2298 /* Check the status after the switch command execution */
2299 if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
2300 {
2301 /* Check the bit SWITCH_ERROR of the device status */
2302 if ((response & 0x80U) != 0U)
2303 {
2304 errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
2305 }
2306 else
2307 {
2308 /* Configure the SDIO peripheral */
2309 Init = hmmc->Init;
2310 Init.BusWide = WideMode;
2311 (void)SDIO_Init(hmmc->Instance, Init);
2312 }
2313 }
2314 else if (count == 0U)
2315 {
2316 errorstate = SDMMC_ERROR_TIMEOUT;
2317 }
2318 else
2319 {
2320 /* Nothing to do */
2321 }
2322 }
2323 }
2324
2325 /* Change State */
2326 hmmc->State = HAL_MMC_STATE_READY;
2327
2328 if(errorstate != HAL_MMC_ERROR_NONE)
2329 {
2330 /* Clear all the static flags */
2331 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2332 hmmc->ErrorCode |= errorstate;
2333 return HAL_ERROR;
2334 }
2335
2336 return HAL_OK;
2337 }
2338
2339 /**
2340 * @brief Gets the current mmc card data state.
2341 * @param hmmc: pointer to MMC handle
2342 * @retval Card state
2343 */
HAL_MMC_GetCardState(MMC_HandleTypeDef * hmmc)2344 HAL_MMC_CardStateTypeDef HAL_MMC_GetCardState(MMC_HandleTypeDef *hmmc)
2345 {
2346 uint32_t cardstate;
2347 uint32_t errorstate;
2348 uint32_t resp1 = 0U;
2349
2350 errorstate = MMC_SendStatus(hmmc, &resp1);
2351 if(errorstate != HAL_MMC_ERROR_NONE)
2352 {
2353 hmmc->ErrorCode |= errorstate;
2354 }
2355
2356 cardstate = ((resp1 >> 9U) & 0x0FU);
2357
2358 return (HAL_MMC_CardStateTypeDef)cardstate;
2359 }
2360
2361 /**
2362 * @brief Abort the current transfer and disable the MMC.
2363 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2364 * the configuration information for MMC module.
2365 * @retval HAL status
2366 */
HAL_MMC_Abort(MMC_HandleTypeDef * hmmc)2367 HAL_StatusTypeDef HAL_MMC_Abort(MMC_HandleTypeDef *hmmc)
2368 {
2369 HAL_MMC_CardStateTypeDef CardState;
2370
2371 /* DIsable All interrupts */
2372 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
2373 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
2374
2375 /* Clear All flags */
2376 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
2377
2378 if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL))
2379 {
2380 /* Disable the MMC DMA request */
2381 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
2382
2383 /* Abort the MMC DMA Tx Stream */
2384 if(hmmc->hdmatx != NULL)
2385 {
2386 if(HAL_DMA_Abort(hmmc->hdmatx) != HAL_OK)
2387 {
2388 hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
2389 }
2390 }
2391 /* Abort the MMC DMA Rx Stream */
2392 if(hmmc->hdmarx != NULL)
2393 {
2394 if(HAL_DMA_Abort(hmmc->hdmarx) != HAL_OK)
2395 {
2396 hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
2397 }
2398 }
2399 }
2400
2401 hmmc->State = HAL_MMC_STATE_READY;
2402
2403 /* Initialize the MMC operation */
2404 hmmc->Context = MMC_CONTEXT_NONE;
2405
2406 CardState = HAL_MMC_GetCardState(hmmc);
2407 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2408 {
2409 hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
2410 }
2411 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2412 {
2413 return HAL_ERROR;
2414 }
2415 return HAL_OK;
2416 }
2417
2418 /**
2419 * @brief Abort the current transfer and disable the MMC (IT mode).
2420 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2421 * the configuration information for MMC module.
2422 * @retval HAL status
2423 */
HAL_MMC_Abort_IT(MMC_HandleTypeDef * hmmc)2424 HAL_StatusTypeDef HAL_MMC_Abort_IT(MMC_HandleTypeDef *hmmc)
2425 {
2426 HAL_MMC_CardStateTypeDef CardState;
2427
2428 /* DIsable All interrupts */
2429 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
2430 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
2431
2432 /* Clear All flags */
2433 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
2434
2435 if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL))
2436 {
2437 /* Disable the MMC DMA request */
2438 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
2439
2440 /* Abort the MMC DMA Tx Stream */
2441 if(hmmc->hdmatx != NULL)
2442 {
2443 hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort;
2444 if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
2445 {
2446 hmmc->hdmatx = NULL;
2447 }
2448 }
2449 /* Abort the MMC DMA Rx Stream */
2450 if(hmmc->hdmarx != NULL)
2451 {
2452 hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort;
2453 if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
2454 {
2455 hmmc->hdmarx = NULL;
2456 }
2457 }
2458 }
2459
2460 /* No transfer ongoing on both DMA channels*/
2461 if((hmmc->hdmatx == NULL) && (hmmc->hdmarx == NULL))
2462 {
2463 CardState = HAL_MMC_GetCardState(hmmc);
2464 hmmc->State = HAL_MMC_STATE_READY;
2465
2466 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2467 {
2468 hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
2469 }
2470 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2471 {
2472 return HAL_ERROR;
2473 }
2474 else
2475 {
2476 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2477 hmmc->AbortCpltCallback(hmmc);
2478 #else
2479 HAL_MMC_AbortCallback(hmmc);
2480 #endif
2481 }
2482 }
2483
2484 return HAL_OK;
2485 }
2486
2487 /**
2488 * @}
2489 */
2490
2491 /**
2492 * @}
2493 */
2494
2495 /* Private function ----------------------------------------------------------*/
2496 /** @addtogroup MMC_Private_Functions
2497 * @{
2498 */
2499
2500 /**
2501 * @brief DMA MMC transmit process complete callback
2502 * @param hdma: DMA handle
2503 * @retval None
2504 */
MMC_DMATransmitCplt(DMA_HandleTypeDef * hdma)2505 static void MMC_DMATransmitCplt(DMA_HandleTypeDef *hdma)
2506 {
2507 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2508
2509 /* Enable DATAEND Interrupt */
2510 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DATAEND));
2511 }
2512
2513 /**
2514 * @brief DMA MMC receive process complete callback
2515 * @param hdma: DMA handle
2516 * @retval None
2517 */
MMC_DMAReceiveCplt(DMA_HandleTypeDef * hdma)2518 static void MMC_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
2519 {
2520 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2521 uint32_t errorstate;
2522
2523 /* Send stop command in multiblock write */
2524 if(hmmc->Context == (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA))
2525 {
2526 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
2527 if(errorstate != HAL_MMC_ERROR_NONE)
2528 {
2529 hmmc->ErrorCode |= errorstate;
2530 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2531 hmmc->ErrorCallback(hmmc);
2532 #else
2533 HAL_MMC_ErrorCallback(hmmc);
2534 #endif
2535 }
2536 }
2537
2538 /* Disable the DMA transfer for transmit request by setting the DMAEN bit
2539 in the MMC DCTRL register */
2540 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
2541
2542 /* Clear all the static flags */
2543 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
2544
2545 hmmc->State = HAL_MMC_STATE_READY;
2546
2547 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2548 hmmc->RxCpltCallback(hmmc);
2549 #else
2550 HAL_MMC_RxCpltCallback(hmmc);
2551 #endif
2552 }
2553
2554 /**
2555 * @brief DMA MMC communication error callback
2556 * @param hdma: DMA handle
2557 * @retval None
2558 */
MMC_DMAError(DMA_HandleTypeDef * hdma)2559 static void MMC_DMAError(DMA_HandleTypeDef *hdma)
2560 {
2561 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2562 HAL_MMC_CardStateTypeDef CardState;
2563 uint32_t RxErrorCode, TxErrorCode;
2564
2565 /* if DMA error is FIFO error ignore it */
2566 if(HAL_DMA_GetError(hdma) != HAL_DMA_ERROR_FE)
2567 {
2568 RxErrorCode = hmmc->hdmarx->ErrorCode;
2569 TxErrorCode = hmmc->hdmatx->ErrorCode;
2570 if((RxErrorCode == HAL_DMA_ERROR_TE) || (TxErrorCode == HAL_DMA_ERROR_TE))
2571 {
2572 /* Clear All flags */
2573 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
2574
2575 /* Disable All interrupts */
2576 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
2577 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
2578
2579 hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
2580 CardState = HAL_MMC_GetCardState(hmmc);
2581 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2582 {
2583 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
2584 }
2585
2586 hmmc->State= HAL_MMC_STATE_READY;
2587 }
2588
2589 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2590 hmmc->ErrorCallback(hmmc);
2591 #else
2592 HAL_MMC_ErrorCallback(hmmc);
2593 #endif
2594 }
2595 }
2596
2597 /**
2598 * @brief DMA MMC Tx Abort callback
2599 * @param hdma: DMA handle
2600 * @retval None
2601 */
MMC_DMATxAbort(DMA_HandleTypeDef * hdma)2602 static void MMC_DMATxAbort(DMA_HandleTypeDef *hdma)
2603 {
2604 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2605 HAL_MMC_CardStateTypeDef CardState;
2606
2607 if(hmmc->hdmatx != NULL)
2608 {
2609 hmmc->hdmatx = NULL;
2610 }
2611
2612 /* All DMA channels are aborted */
2613 if(hmmc->hdmarx == NULL)
2614 {
2615 CardState = HAL_MMC_GetCardState(hmmc);
2616 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
2617 hmmc->State = HAL_MMC_STATE_READY;
2618 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2619 {
2620 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
2621
2622 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2623 {
2624 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2625 hmmc->AbortCpltCallback(hmmc);
2626 #else
2627 HAL_MMC_AbortCallback(hmmc);
2628 #endif
2629 }
2630 else
2631 {
2632 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2633 hmmc->ErrorCallback(hmmc);
2634 #else
2635 HAL_MMC_ErrorCallback(hmmc);
2636 #endif
2637 }
2638 }
2639 }
2640 }
2641
2642 /**
2643 * @brief DMA MMC Rx Abort callback
2644 * @param hdma: DMA handle
2645 * @retval None
2646 */
MMC_DMARxAbort(DMA_HandleTypeDef * hdma)2647 static void MMC_DMARxAbort(DMA_HandleTypeDef *hdma)
2648 {
2649 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2650 HAL_MMC_CardStateTypeDef CardState;
2651
2652 if(hmmc->hdmarx != NULL)
2653 {
2654 hmmc->hdmarx = NULL;
2655 }
2656
2657 /* All DMA channels are aborted */
2658 if(hmmc->hdmatx == NULL)
2659 {
2660 CardState = HAL_MMC_GetCardState(hmmc);
2661 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
2662 hmmc->State = HAL_MMC_STATE_READY;
2663 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2664 {
2665 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
2666
2667 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2668 {
2669 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2670 hmmc->AbortCpltCallback(hmmc);
2671 #else
2672 HAL_MMC_AbortCallback(hmmc);
2673 #endif
2674 }
2675 else
2676 {
2677 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2678 hmmc->ErrorCallback(hmmc);
2679 #else
2680 HAL_MMC_ErrorCallback(hmmc);
2681 #endif
2682 }
2683 }
2684 }
2685 }
2686
2687 /**
2688 * @brief Initializes the mmc card.
2689 * @param hmmc: Pointer to MMC handle
2690 * @retval MMC Card error state
2691 */
MMC_InitCard(MMC_HandleTypeDef * hmmc)2692 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc)
2693 {
2694 HAL_MMC_CardCSDTypeDef CSD;
2695 uint32_t errorstate;
2696 uint16_t mmc_rca = 2U;
2697 MMC_InitTypeDef Init;
2698
2699 /* Check the power State */
2700 if(SDIO_GetPowerState(hmmc->Instance) == 0U)
2701 {
2702 /* Power off */
2703 return HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
2704 }
2705
2706 /* Send CMD2 ALL_SEND_CID */
2707 errorstate = SDMMC_CmdSendCID(hmmc->Instance);
2708 if(errorstate != HAL_MMC_ERROR_NONE)
2709 {
2710 return errorstate;
2711 }
2712 else
2713 {
2714 /* Get Card identification number data */
2715 hmmc->CID[0U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
2716 hmmc->CID[1U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP2);
2717 hmmc->CID[2U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP3);
2718 hmmc->CID[3U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP4);
2719 }
2720
2721 /* Send CMD3 SET_REL_ADDR with RCA = 2 (should be greater than 1) */
2722 /* MMC Card publishes its RCA. */
2723 errorstate = SDMMC_CmdSetRelAddMmc(hmmc->Instance, mmc_rca);
2724 if(errorstate != HAL_MMC_ERROR_NONE)
2725 {
2726 return errorstate;
2727 }
2728
2729 /* Get the MMC card RCA */
2730 hmmc->MmcCard.RelCardAdd = mmc_rca;
2731
2732 /* Send CMD9 SEND_CSD with argument as card's RCA */
2733 errorstate = SDMMC_CmdSendCSD(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
2734 if(errorstate != HAL_MMC_ERROR_NONE)
2735 {
2736 return errorstate;
2737 }
2738 else
2739 {
2740 /* Get Card Specific Data */
2741 hmmc->CSD[0U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
2742 hmmc->CSD[1U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP2);
2743 hmmc->CSD[2U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP3);
2744 hmmc->CSD[3U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP4);
2745 }
2746
2747 /* Get the Card Class */
2748 hmmc->MmcCard.Class = (SDIO_GetResponse(hmmc->Instance, SDIO_RESP2) >> 20U);
2749
2750 /* Select the Card */
2751 errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2752 if(errorstate != HAL_MMC_ERROR_NONE)
2753 {
2754 return errorstate;
2755 }
2756
2757 /* Get CSD parameters */
2758 if (HAL_MMC_GetCardCSD(hmmc, &CSD) != HAL_OK)
2759 {
2760 return hmmc->ErrorCode;
2761 }
2762
2763 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2764 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2765 if(errorstate != HAL_MMC_ERROR_NONE)
2766 {
2767 hmmc->ErrorCode |= errorstate;
2768 }
2769
2770 /* Get Extended CSD parameters */
2771 if (HAL_MMC_GetCardExtCSD(hmmc, hmmc->Ext_CSD, SDMMC_DATATIMEOUT) != HAL_OK)
2772 {
2773 return hmmc->ErrorCode;
2774 }
2775
2776 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2777 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2778 if(errorstate != HAL_MMC_ERROR_NONE)
2779 {
2780 hmmc->ErrorCode |= errorstate;
2781 }
2782
2783 /* Configure the SDIO peripheral */
2784 Init = hmmc->Init;
2785 Init.BusWide = SDIO_BUS_WIDE_1B;
2786 (void)SDIO_Init(hmmc->Instance, Init);
2787
2788 /* All cards are initialized */
2789 return HAL_MMC_ERROR_NONE;
2790 }
2791
2792 /**
2793 * @brief Enquires cards about their operating voltage and configures clock
2794 * controls and stores MMC information that will be needed in future
2795 * in the MMC handle.
2796 * @param hmmc: Pointer to MMC handle
2797 * @retval error state
2798 */
MMC_PowerON(MMC_HandleTypeDef * hmmc)2799 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc)
2800 {
2801 __IO uint32_t count = 0U;
2802 uint32_t response = 0U, validvoltage = 0U;
2803 uint32_t errorstate;
2804
2805 /* CMD0: GO_IDLE_STATE */
2806 errorstate = SDMMC_CmdGoIdleState(hmmc->Instance);
2807 if(errorstate != HAL_MMC_ERROR_NONE)
2808 {
2809 return errorstate;
2810 }
2811
2812 while(validvoltage == 0U)
2813 {
2814 if(count++ == SDMMC_MAX_VOLT_TRIAL)
2815 {
2816 return HAL_MMC_ERROR_INVALID_VOLTRANGE;
2817 }
2818
2819 /* SEND CMD1 APP_CMD with voltage range as argument */
2820 errorstate = SDMMC_CmdOpCondition(hmmc->Instance, MMC_VOLTAGE_RANGE);
2821 if(errorstate != HAL_MMC_ERROR_NONE)
2822 {
2823 return HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2824 }
2825
2826 /* Get command response */
2827 response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
2828
2829 /* Get operating voltage*/
2830 validvoltage = (((response >> 31U) == 1U) ? 1U : 0U);
2831 }
2832
2833 /* When power routine is finished and command returns valid voltage */
2834 if (((response & (0xFF000000U)) >> 24U) == 0xC0U)
2835 {
2836 hmmc->MmcCard.CardType = MMC_HIGH_CAPACITY_CARD;
2837 }
2838 else
2839 {
2840 hmmc->MmcCard.CardType = MMC_LOW_CAPACITY_CARD;
2841 }
2842
2843 return HAL_MMC_ERROR_NONE;
2844 }
2845
2846 /**
2847 * @brief Turns the SDIO output signals off.
2848 * @param hmmc: Pointer to MMC handle
2849 * @retval None
2850 */
MMC_PowerOFF(MMC_HandleTypeDef * hmmc)2851 static void MMC_PowerOFF(MMC_HandleTypeDef *hmmc)
2852 {
2853 /* Set Power State to OFF */
2854 (void)SDIO_PowerState_OFF(hmmc->Instance);
2855 }
2856
2857 /**
2858 * @brief Returns the current card's status.
2859 * @param hmmc: Pointer to MMC handle
2860 * @param pCardStatus: pointer to the buffer that will contain the MMC card
2861 * status (Card Status register)
2862 * @retval error state
2863 */
MMC_SendStatus(MMC_HandleTypeDef * hmmc,uint32_t * pCardStatus)2864 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus)
2865 {
2866 uint32_t errorstate;
2867
2868 if(pCardStatus == NULL)
2869 {
2870 return HAL_MMC_ERROR_PARAM;
2871 }
2872
2873 /* Send Status command */
2874 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
2875 if(errorstate != HAL_MMC_ERROR_NONE)
2876 {
2877 return errorstate;
2878 }
2879
2880 /* Get MMC card status */
2881 *pCardStatus = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
2882
2883 return HAL_MMC_ERROR_NONE;
2884 }
2885
2886 /**
2887 * @brief Reads extended CSD register to get the sectors number of the device
2888 * @param hmmc: Pointer to MMC handle
2889 * @param pFieldData: Pointer to the read buffer
2890 * @param FieldIndex: Index of the field to be read
2891 * @param Timeout: Specify timeout value
2892 * @retval HAL status
2893 */
MMC_ReadExtCSD(MMC_HandleTypeDef * hmmc,uint32_t * pFieldData,uint16_t FieldIndex,uint32_t Timeout)2894 static uint32_t MMC_ReadExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pFieldData, uint16_t FieldIndex, uint32_t Timeout)
2895 {
2896 SDIO_DataInitTypeDef config;
2897 uint32_t errorstate;
2898 uint32_t tickstart = HAL_GetTick();
2899 uint32_t count;
2900 uint32_t i = 0;
2901 uint32_t tmp_data;
2902
2903 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
2904
2905 /* Initialize data control register */
2906 hmmc->Instance->DCTRL = 0;
2907
2908 /* Configure the MMC DPSM (Data Path State Machine) */
2909 config.DataTimeOut = SDMMC_DATATIMEOUT;
2910 config.DataLength = 512;
2911 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
2912 config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
2913 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
2914 config.DPSM = SDIO_DPSM_ENABLE;
2915 (void)SDIO_ConfigData(hmmc->Instance, &config);
2916
2917 /* Set Block Size for Card */
2918 errorstate = SDMMC_CmdSendEXTCSD(hmmc->Instance, 0);
2919 if(errorstate != HAL_MMC_ERROR_NONE)
2920 {
2921 /* Clear all the static flags */
2922 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
2923 hmmc->ErrorCode |= errorstate;
2924 hmmc->State = HAL_MMC_STATE_READY;
2925 return HAL_ERROR;
2926 }
2927
2928 /* Poll on SDMMC flags */
2929 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND))
2930 {
2931 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXFIFOHF))
2932 {
2933 /* Read data from SDMMC Rx FIFO */
2934 for(count = 0U; count < 8U; count++)
2935 {
2936 tmp_data = SDIO_ReadFIFO(hmmc->Instance);
2937 /* eg : SEC_COUNT : FieldIndex = 212 => i+count = 53 */
2938 /* DEVICE_TYPE : FieldIndex = 196 => i+count = 49 */
2939 if ((i + count) == ((uint32_t)FieldIndex/4U))
2940 {
2941 *pFieldData = tmp_data;
2942 }
2943 }
2944 i += 8U;
2945 }
2946
2947 if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U))
2948 {
2949 /* Clear all the static flags */
2950 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
2951 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
2952 hmmc->State= HAL_MMC_STATE_READY;
2953 return HAL_TIMEOUT;
2954 }
2955 }
2956
2957 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2958 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16));
2959 if(errorstate != HAL_MMC_ERROR_NONE)
2960 {
2961 hmmc->ErrorCode |= errorstate;
2962 }
2963
2964 /* Clear all the static flags */
2965 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS);
2966
2967 hmmc->State = HAL_MMC_STATE_READY;
2968
2969 return HAL_OK;
2970 }
2971
2972
2973 /**
2974 * @brief Wrap up reading in non-blocking mode.
2975 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2976 * the configuration information.
2977 * @retval None
2978 */
MMC_Read_IT(MMC_HandleTypeDef * hmmc)2979 static void MMC_Read_IT(MMC_HandleTypeDef *hmmc)
2980 {
2981 uint32_t count, data, dataremaining;
2982 uint8_t* tmp;
2983
2984 tmp = hmmc->pRxBuffPtr;
2985 dataremaining = hmmc->RxXferSize;
2986
2987 if (dataremaining > 0U)
2988 {
2989 /* Read data from SDIO Rx FIFO */
2990 for(count = 0U; count < 8U; count++)
2991 {
2992 data = SDIO_ReadFIFO(hmmc->Instance);
2993 *tmp = (uint8_t)(data & 0xFFU);
2994 tmp++;
2995 dataremaining--;
2996 *tmp = (uint8_t)((data >> 8U) & 0xFFU);
2997 tmp++;
2998 dataremaining--;
2999 *tmp = (uint8_t)((data >> 16U) & 0xFFU);
3000 tmp++;
3001 dataremaining--;
3002 *tmp = (uint8_t)((data >> 24U) & 0xFFU);
3003 tmp++;
3004 dataremaining--;
3005 }
3006
3007 hmmc->pRxBuffPtr = tmp;
3008 hmmc->RxXferSize = dataremaining;
3009 }
3010 }
3011
3012 /**
3013 * @brief Wrap up writing in non-blocking mode.
3014 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
3015 * the configuration information.
3016 * @retval None
3017 */
MMC_Write_IT(MMC_HandleTypeDef * hmmc)3018 static void MMC_Write_IT(MMC_HandleTypeDef *hmmc)
3019 {
3020 uint32_t count, data, dataremaining;
3021 uint8_t* tmp;
3022
3023 tmp = hmmc->pTxBuffPtr;
3024 dataremaining = hmmc->TxXferSize;
3025
3026 if (dataremaining > 0U)
3027 {
3028 /* Write data to SDIO Tx FIFO */
3029 for(count = 0U; count < 8U; count++)
3030 {
3031 data = (uint32_t)(*tmp);
3032 tmp++;
3033 dataremaining--;
3034 data |= ((uint32_t)(*tmp) << 8U);
3035 tmp++;
3036 dataremaining--;
3037 data |= ((uint32_t)(*tmp) << 16U);
3038 tmp++;
3039 dataremaining--;
3040 data |= ((uint32_t)(*tmp) << 24U);
3041 tmp++;
3042 dataremaining--;
3043 (void)SDIO_WriteFIFO(hmmc->Instance, &data);
3044 }
3045
3046 hmmc->pTxBuffPtr = tmp;
3047 hmmc->TxXferSize = dataremaining;
3048 }
3049 }
3050
3051 /**
3052 * @brief Update the power class of the device.
3053 * @param hmmc MMC handle
3054 * @param Wide Wide of MMC bus
3055 * @param Speed Speed of the MMC bus
3056 * @retval MMC Card error state
3057 */
MMC_PwrClassUpdate(MMC_HandleTypeDef * hmmc,uint32_t Wide)3058 static uint32_t MMC_PwrClassUpdate(MMC_HandleTypeDef *hmmc, uint32_t Wide)
3059 {
3060 uint32_t count;
3061 uint32_t response = 0U;
3062 uint32_t errorstate = HAL_MMC_ERROR_NONE;
3063 uint32_t power_class, supported_pwr_class;
3064
3065 if((Wide == SDIO_BUS_WIDE_8B) || (Wide == SDIO_BUS_WIDE_4B))
3066 {
3067 power_class = 0U; /* Default value after power-on or software reset */
3068
3069 /* Read the PowerClass field of the Extended CSD register */
3070 if(MMC_ReadExtCSD(hmmc, &power_class, 187, SDMMC_DATATIMEOUT) != HAL_OK) /* Field POWER_CLASS [187] */
3071 {
3072 errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
3073 }
3074 else
3075 {
3076 power_class = ((power_class >> 24U) & 0x000000FFU);
3077 }
3078
3079 /* Get the supported PowerClass field of the Extended CSD register */
3080 /* Field PWR_CL_26_xxx [201 or 203] */
3081 supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_26_INDEX/4)] >> MMC_EXT_CSD_PWR_CL_26_POS) & 0x000000FFU);
3082
3083 if(errorstate == HAL_MMC_ERROR_NONE)
3084 {
3085 if(Wide == SDIO_BUS_WIDE_8B)
3086 {
3087 /* Bit [7:4] : power class for 8-bits bus configuration - Bit [3:0] : power class for 4-bits bus configuration */
3088 supported_pwr_class = (supported_pwr_class >> 4U);
3089 }
3090
3091 if ((power_class & 0x0FU) != (supported_pwr_class & 0x0FU))
3092 {
3093 /* Need to change current power class */
3094 errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03BB0000U | ((supported_pwr_class & 0x0FU) << 8U)));
3095
3096 if(errorstate == HAL_MMC_ERROR_NONE)
3097 {
3098 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3099 count = SDMMC_MAX_TRIAL;
3100 do
3101 {
3102 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3103 if(errorstate != HAL_MMC_ERROR_NONE)
3104 {
3105 break;
3106 }
3107
3108 /* Get command response */
3109 response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
3110 count--;
3111 }while(((response & 0x100U) == 0U) && (count != 0U));
3112
3113 /* Check the status after the switch command execution */
3114 if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
3115 {
3116 /* Check the bit SWITCH_ERROR of the device status */
3117 if ((response & 0x80U) != 0U)
3118 {
3119 errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3120 }
3121 }
3122 else if (count == 0U)
3123 {
3124 errorstate = SDMMC_ERROR_TIMEOUT;
3125 }
3126 else
3127 {
3128 /* Nothing to do */
3129 }
3130 }
3131 }
3132 }
3133 }
3134
3135 return errorstate;
3136 }
3137
3138 /**
3139 * @}
3140 */
3141
3142 #endif /* SDIO */
3143
3144 #endif /* HAL_MMC_MODULE_ENABLED */
3145
3146 /**
3147 * @}
3148 */
3149
3150 /**
3151 * @}
3152 */
3153