1 /**
2 ******************************************************************************
3 * @file stm32f7xx_hal_mmc.c
4 * @author MCD Application Team
5 * @brief MMC card HAL module driver.
6 * This file provides firmware functions to manage the following
7 * functionalities of the Secure Digital (MMC) peripheral:
8 * + Initialization and de-initialization functions
9 * + IO operation functions
10 * + Peripheral Control functions
11 * + MMC card Control functions
12 *
13 ******************************************************************************
14 * @attention
15 *
16 * Copyright (c) 2017 STMicroelectronics.
17 * All rights reserved.
18 *
19 * This software is licensed under terms that can be found in the LICENSE file
20 * in the root directory of this software component.
21 * If no LICENSE file comes with this software, it is provided AS-IS.
22 *
23 ******************************************************************************
24 @verbatim
25 ==============================================================================
26 ##### How to use this driver #####
27 ==============================================================================
28 [..]
29 This driver implements a high level communication layer for read and write from/to
30 this memory. The needed STM32 hardware resources (SDMMC and GPIO) are performed by
31 the user in HAL_MMC_MspInit() function (MSP layer).
32 Basically, the MSP layer configuration should be the same as we provide in the
33 examples.
34 You can easily tailor this configuration according to hardware resources.
35
36 [..]
37 This driver is a generic layered driver for SDMMC memories which uses the HAL
38 SDMMC driver functions to interface with MMC and eMMC cards devices.
39 It is used as follows:
40
41 (#)Initialize the SDMMC low level resources by implement the HAL_MMC_MspInit() API:
42 (##) Enable the SDMMC interface clock using __HAL_RCC_SDMMC_CLK_ENABLE();
43 (##) SDMMC pins configuration for MMC card
44 (+++) Enable the clock for the SDMMC GPIOs using the functions __HAL_RCC_GPIOx_CLK_ENABLE();
45 (+++) Configure these SDMMC pins as alternate function pull-up using HAL_GPIO_Init()
46 and according to your pin assignment;
47 (##) 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 "stm32f7xx_hal.h"
256
257 /** @addtogroup STM32F7xx_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(SDMMC1)
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_SDMMC_ALL_INSTANCE(hmmc->Instance));
362 assert_param(IS_SDMMC_CLOCK_EDGE(hmmc->Init.ClockEdge));
363 assert_param(IS_SDMMC_CLOCK_BYPASS(hmmc->Init.ClockBypass));
364 assert_param(IS_SDMMC_CLOCK_POWER_SAVE(hmmc->Init.ClockPowerSave));
365 assert_param(IS_SDMMC_BUS_WIDE(hmmc->Init.BusWide));
366 assert_param(IS_SDMMC_HARDWARE_FLOW_CONTROL(hmmc->Init.HardwareFlowControl));
367 assert_param(IS_SDMMC_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 != SDMMC_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 SDMMC peripheral configuration for MMC card initialization */
436 Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
437 Init.ClockBypass = SDMMC_CLOCK_BYPASS_DISABLE;
438 Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
439 Init.BusWide = SDMMC_BUS_WIDE_1B;
440 Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
441 Init.ClockDiv = SDMMC_INIT_CLK_DIV;
442
443 /* Initialize SDMMC peripheral interface with default configuration */
444 status = SDMMC_Init(hmmc->Instance, Init);
445 if(status == HAL_ERROR)
446 {
447 return HAL_ERROR;
448 }
449
450 /* Disable SDMMC Clock */
451 __HAL_MMC_DISABLE(hmmc);
452
453 /* Set Power State to ON */
454 status = SDMMC_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, SDMMC_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_SDMMC_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 SDMMC_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 = SDMMC_DATABLOCK_SIZE_512B;
639 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
640 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
641 config.DPSM = SDMMC_DPSM_ENABLE;
642 (void)SDMMC_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, SDMMC_STATIC_FLAGS);
663 hmmc->ErrorCode |= errorstate;
664 hmmc->State = HAL_MMC_STATE_READY;
665 return HAL_ERROR;
666 }
667
668 /* Poll on SDMMC flags */
669 dataremaining = config.DataLength;
670 while(!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
671 {
672 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining > 0U))
673 {
674 /* Read data from SDMMC Rx FIFO */
675 for(count = 0U; count < 8U; count++)
676 {
677 data = SDMMC_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, SDMMC_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, SDMMC_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, SDMMC_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, SDMMC_FLAG_DTIMEOUT))
720 {
721 /* Clear all the static flags */
722 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_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, SDMMC_FLAG_DCRCFAIL))
728 {
729 /* Clear all the static flags */
730 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_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, SDMMC_FLAG_RXOVERR))
736 {
737 /* Clear all the static flags */
738 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_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, SDMMC_FLAG_RXDAVL)) && (dataremaining > 0U))
750 {
751 data = SDMMC_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, SDMMC_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, SDMMC_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 SDMMC_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, SDMMC_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 = SDMMC_DATABLOCK_SIZE_512B;
864 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
865 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
866 config.DPSM = SDMMC_DPSM_ENABLE;
867 (void)SDMMC_ConfigData(hmmc->Instance, &config);
868
869 /* Write block(s) in polling mode */
870 dataremaining = config.DataLength;
871 while(!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
872 {
873 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining > 0U))
874 {
875 /* Write data to SDMMC 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)SDMMC_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, SDMMC_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, SDMMC_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, SDMMC_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, SDMMC_FLAG_DTIMEOUT))
921 {
922 /* Clear all the static flags */
923 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_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, SDMMC_FLAG_DCRCFAIL))
929 {
930 /* Clear all the static flags */
931 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_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, SDMMC_FLAG_TXUNDERR))
937 {
938 /* Clear all the static flags */
939 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_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, SDMMC_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 SDMMC_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, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND | SDMMC_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 = SDMMC_DATABLOCK_SIZE_512B;
1017 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
1018 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
1019 config.DPSM = SDMMC_DPSM_ENABLE;
1020 (void)SDMMC_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, SDMMC_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 SDMMC_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, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND | SDMMC_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, SDMMC_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 = SDMMC_DATABLOCK_SIZE_512B;
1134 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
1135 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
1136 config.DPSM = SDMMC_DPSM_ENABLE;
1137 (void)SDMMC_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 SDMMC_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, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_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, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND));
1211 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_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 = SDMMC_DATABLOCK_SIZE_512B;
1225 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
1226 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
1227 config.DPSM = SDMMC_DPSM_ENABLE;
1228 (void)SDMMC_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, SDMMC_STATIC_FLAGS);
1249 __HAL_MMC_DISABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_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 SDMMC_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, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_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, SDMMC_STATIC_FLAGS);
1341 __HAL_MMC_DISABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND));
1342 hmmc->ErrorCode |= errorstate;
1343 hmmc->State = HAL_MMC_STATE_READY;
1344 return HAL_ERROR;
1345 }
1346
1347 /* Enable SDMMC 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, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND));
1358 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_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 = SDMMC_DATABLOCK_SIZE_512B;
1369 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
1370 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
1371 config.DPSM = SDMMC_DPSM_ENABLE;
1372 (void)SDMMC_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) & SDMMC_CCCC_ERASE) == 0U)
1418 {
1419 /* Clear all the static flags */
1420 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_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((SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
1427 {
1428 /* Clear all the static flags */
1429 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_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, SDMMC_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, SDMMC_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, SDMMC_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 SDMMC interrupt flags */
1495 if((__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) != RESET) && ((context & MMC_CONTEXT_IT) != 0U))
1496 {
1497 MMC_Read_IT(hmmc);
1498 }
1499
1500 else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) != RESET)
1501 {
1502 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_DATAEND);
1503
1504 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT |\
1505 SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR | SDMMC_IT_TXFIFOHE |\
1506 SDMMC_IT_RXFIFOHF);
1507
1508 hmmc->Instance->DCTRL &= ~(SDMMC_DCTRL_DTEN);
1509
1510 if((context & MMC_CONTEXT_DMA) != 0U)
1511 {
1512 if((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)
1513 {
1514 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
1515 if(errorstate != HAL_MMC_ERROR_NONE)
1516 {
1517 hmmc->ErrorCode |= errorstate;
1518 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1519 hmmc->ErrorCallback(hmmc);
1520 #else
1521 HAL_MMC_ErrorCallback(hmmc);
1522 #endif
1523 }
1524 }
1525 if(((context & MMC_CONTEXT_READ_SINGLE_BLOCK) == 0U) && ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) == 0U))
1526 {
1527 /* Disable the DMA transfer for transmit request by setting the DMAEN bit
1528 in the MMC DCTRL register */
1529 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN);
1530
1531 hmmc->State = HAL_MMC_STATE_READY;
1532
1533 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1534 hmmc->TxCpltCallback(hmmc);
1535 #else
1536 HAL_MMC_TxCpltCallback(hmmc);
1537 #endif
1538 }
1539 }
1540 else if((context & MMC_CONTEXT_IT) != 0U)
1541 {
1542 /* Stop Transfer for Write Multi blocks or Read Multi blocks */
1543 if(((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
1544 {
1545 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
1546 if(errorstate != HAL_MMC_ERROR_NONE)
1547 {
1548 hmmc->ErrorCode |= errorstate;
1549 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1550 hmmc->ErrorCallback(hmmc);
1551 #else
1552 HAL_MMC_ErrorCallback(hmmc);
1553 #endif
1554 }
1555 }
1556
1557 /* Clear all the static flags */
1558 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
1559
1560 hmmc->State = HAL_MMC_STATE_READY;
1561 if(((context & MMC_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
1562 {
1563 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1564 hmmc->RxCpltCallback(hmmc);
1565 #else
1566 HAL_MMC_RxCpltCallback(hmmc);
1567 #endif
1568 }
1569 else
1570 {
1571 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1572 hmmc->TxCpltCallback(hmmc);
1573 #else
1574 HAL_MMC_TxCpltCallback(hmmc);
1575 #endif
1576 }
1577 }
1578 else
1579 {
1580 /* Nothing to do */
1581 }
1582 }
1583
1584 else if((__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) != RESET) && ((context & MMC_CONTEXT_IT) != 0U))
1585 {
1586 MMC_Write_IT(hmmc);
1587 }
1588
1589 else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_RXOVERR | SDMMC_FLAG_TXUNDERR) != RESET)
1590 {
1591 /* Set Error code */
1592 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL) != RESET)
1593 {
1594 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
1595 }
1596 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT) != RESET)
1597 {
1598 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
1599 }
1600 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR) != RESET)
1601 {
1602 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
1603 }
1604 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR) != RESET)
1605 {
1606 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
1607 }
1608
1609 /* Clear All flags */
1610 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
1611
1612 /* Disable all interrupts */
1613 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\
1614 SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR);
1615
1616 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
1617
1618 if((context & MMC_CONTEXT_IT) != 0U)
1619 {
1620 /* Set the MMC state to ready to be able to start again the process */
1621 hmmc->State = HAL_MMC_STATE_READY;
1622 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1623 hmmc->ErrorCallback(hmmc);
1624 #else
1625 HAL_MMC_ErrorCallback(hmmc);
1626 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1627 }
1628 else if((context & MMC_CONTEXT_DMA) != 0U)
1629 {
1630 /* Abort the MMC DMA Streams */
1631 if(hmmc->hdmatx != NULL)
1632 {
1633 /* Set the DMA Tx abort callback */
1634 hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort;
1635 /* Abort DMA in IT mode */
1636 if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
1637 {
1638 MMC_DMATxAbort(hmmc->hdmatx);
1639 }
1640 }
1641 else if(hmmc->hdmarx != NULL)
1642 {
1643 /* Set the DMA Rx abort callback */
1644 hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort;
1645 /* Abort DMA in IT mode */
1646 if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
1647 {
1648 MMC_DMARxAbort(hmmc->hdmarx);
1649 }
1650 }
1651 else
1652 {
1653 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1654 hmmc->State = HAL_MMC_STATE_READY;
1655 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1656 hmmc->AbortCpltCallback(hmmc);
1657 #else
1658 HAL_MMC_AbortCallback(hmmc);
1659 #endif
1660 }
1661 }
1662 else
1663 {
1664 /* Nothing to do */
1665 }
1666 }
1667
1668 else
1669 {
1670 /* Nothing to do */
1671 }
1672 }
1673
1674 /**
1675 * @brief return the MMC state
1676 * @param hmmc: Pointer to mmc handle
1677 * @retval HAL state
1678 */
HAL_MMC_GetState(MMC_HandleTypeDef * hmmc)1679 HAL_MMC_StateTypeDef HAL_MMC_GetState(MMC_HandleTypeDef *hmmc)
1680 {
1681 return hmmc->State;
1682 }
1683
1684 /**
1685 * @brief Return the MMC error code
1686 * @param hmmc : Pointer to a MMC_HandleTypeDef structure that contains
1687 * the configuration information.
1688 * @retval MMC Error Code
1689 */
HAL_MMC_GetError(MMC_HandleTypeDef * hmmc)1690 uint32_t HAL_MMC_GetError(MMC_HandleTypeDef *hmmc)
1691 {
1692 return hmmc->ErrorCode;
1693 }
1694
1695 /**
1696 * @brief Tx Transfer completed callbacks
1697 * @param hmmc: Pointer to MMC handle
1698 * @retval None
1699 */
HAL_MMC_TxCpltCallback(MMC_HandleTypeDef * hmmc)1700 __weak void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef *hmmc)
1701 {
1702 /* Prevent unused argument(s) compilation warning */
1703 UNUSED(hmmc);
1704
1705 /* NOTE : This function should not be modified, when the callback is needed,
1706 the HAL_MMC_TxCpltCallback can be implemented in the user file
1707 */
1708 }
1709
1710 /**
1711 * @brief Rx Transfer completed callbacks
1712 * @param hmmc: Pointer MMC handle
1713 * @retval None
1714 */
HAL_MMC_RxCpltCallback(MMC_HandleTypeDef * hmmc)1715 __weak void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef *hmmc)
1716 {
1717 /* Prevent unused argument(s) compilation warning */
1718 UNUSED(hmmc);
1719
1720 /* NOTE : This function should not be modified, when the callback is needed,
1721 the HAL_MMC_RxCpltCallback can be implemented in the user file
1722 */
1723 }
1724
1725 /**
1726 * @brief MMC error callbacks
1727 * @param hmmc: Pointer MMC handle
1728 * @retval None
1729 */
HAL_MMC_ErrorCallback(MMC_HandleTypeDef * hmmc)1730 __weak void HAL_MMC_ErrorCallback(MMC_HandleTypeDef *hmmc)
1731 {
1732 /* Prevent unused argument(s) compilation warning */
1733 UNUSED(hmmc);
1734
1735 /* NOTE : This function should not be modified, when the callback is needed,
1736 the HAL_MMC_ErrorCallback can be implemented in the user file
1737 */
1738 }
1739
1740 /**
1741 * @brief MMC Abort callbacks
1742 * @param hmmc: Pointer MMC handle
1743 * @retval None
1744 */
HAL_MMC_AbortCallback(MMC_HandleTypeDef * hmmc)1745 __weak void HAL_MMC_AbortCallback(MMC_HandleTypeDef *hmmc)
1746 {
1747 /* Prevent unused argument(s) compilation warning */
1748 UNUSED(hmmc);
1749
1750 /* NOTE : This function should not be modified, when the callback is needed,
1751 the HAL_MMC_AbortCallback can be implemented in the user file
1752 */
1753 }
1754
1755 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1756 /**
1757 * @brief Register a User MMC Callback
1758 * To be used instead of the weak (surcharged) predefined callback
1759 * @param hmmc : MMC handle
1760 * @param CallbackId : ID of the callback to be registered
1761 * This parameter can be one of the following values:
1762 * @arg @ref HAL_MMC_TX_CPLT_CB_ID MMC Tx Complete Callback ID
1763 * @arg @ref HAL_MMC_RX_CPLT_CB_ID MMC Rx Complete Callback ID
1764 * @arg @ref HAL_MMC_ERROR_CB_ID MMC Error Callback ID
1765 * @arg @ref HAL_MMC_ABORT_CB_ID MMC Abort Callback ID
1766 * @arg @ref HAL_MMC_MSP_INIT_CB_ID MMC MspInit Callback ID
1767 * @arg @ref HAL_MMC_MSP_DEINIT_CB_ID MMC MspDeInit Callback ID
1768 * @param pCallback : pointer to the Callback function
1769 * @retval status
1770 */
HAL_MMC_RegisterCallback(MMC_HandleTypeDef * hmmc,HAL_MMC_CallbackIDTypeDef CallbackId,pMMC_CallbackTypeDef pCallback)1771 HAL_StatusTypeDef HAL_MMC_RegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId, pMMC_CallbackTypeDef pCallback)
1772 {
1773 HAL_StatusTypeDef status = HAL_OK;
1774
1775 if(pCallback == NULL)
1776 {
1777 /* Update the error code */
1778 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1779 return HAL_ERROR;
1780 }
1781
1782 /* Process locked */
1783 __HAL_LOCK(hmmc);
1784
1785 if(hmmc->State == HAL_MMC_STATE_READY)
1786 {
1787 switch (CallbackId)
1788 {
1789 case HAL_MMC_TX_CPLT_CB_ID :
1790 hmmc->TxCpltCallback = pCallback;
1791 break;
1792 case HAL_MMC_RX_CPLT_CB_ID :
1793 hmmc->RxCpltCallback = pCallback;
1794 break;
1795 case HAL_MMC_ERROR_CB_ID :
1796 hmmc->ErrorCallback = pCallback;
1797 break;
1798 case HAL_MMC_ABORT_CB_ID :
1799 hmmc->AbortCpltCallback = pCallback;
1800 break;
1801 case HAL_MMC_MSP_INIT_CB_ID :
1802 hmmc->MspInitCallback = pCallback;
1803 break;
1804 case HAL_MMC_MSP_DEINIT_CB_ID :
1805 hmmc->MspDeInitCallback = pCallback;
1806 break;
1807 default :
1808 /* Update the error code */
1809 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1810 /* update return status */
1811 status = HAL_ERROR;
1812 break;
1813 }
1814 }
1815 else if (hmmc->State == HAL_MMC_STATE_RESET)
1816 {
1817 switch (CallbackId)
1818 {
1819 case HAL_MMC_MSP_INIT_CB_ID :
1820 hmmc->MspInitCallback = pCallback;
1821 break;
1822 case HAL_MMC_MSP_DEINIT_CB_ID :
1823 hmmc->MspDeInitCallback = pCallback;
1824 break;
1825 default :
1826 /* Update the error code */
1827 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1828 /* update return status */
1829 status = HAL_ERROR;
1830 break;
1831 }
1832 }
1833 else
1834 {
1835 /* Update the error code */
1836 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1837 /* update return status */
1838 status = HAL_ERROR;
1839 }
1840
1841 /* Release Lock */
1842 __HAL_UNLOCK(hmmc);
1843 return status;
1844 }
1845
1846 /**
1847 * @brief Unregister a User MMC Callback
1848 * MMC Callback is redirected to the weak (surcharged) predefined callback
1849 * @param hmmc : MMC handle
1850 * @param CallbackId : ID of the callback to be unregistered
1851 * This parameter can be one of the following values:
1852 * @arg @ref HAL_MMC_TX_CPLT_CB_ID MMC Tx Complete Callback ID
1853 * @arg @ref HAL_MMC_RX_CPLT_CB_ID MMC Rx Complete Callback ID
1854 * @arg @ref HAL_MMC_ERROR_CB_ID MMC Error Callback ID
1855 * @arg @ref HAL_MMC_ABORT_CB_ID MMC Abort Callback ID
1856 * @arg @ref HAL_MMC_MSP_INIT_CB_ID MMC MspInit Callback ID
1857 * @arg @ref HAL_MMC_MSP_DEINIT_CB_ID MMC MspDeInit Callback ID
1858 * @retval status
1859 */
HAL_MMC_UnRegisterCallback(MMC_HandleTypeDef * hmmc,HAL_MMC_CallbackIDTypeDef CallbackId)1860 HAL_StatusTypeDef HAL_MMC_UnRegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId)
1861 {
1862 HAL_StatusTypeDef status = HAL_OK;
1863
1864 /* Process locked */
1865 __HAL_LOCK(hmmc);
1866
1867 if(hmmc->State == HAL_MMC_STATE_READY)
1868 {
1869 switch (CallbackId)
1870 {
1871 case HAL_MMC_TX_CPLT_CB_ID :
1872 hmmc->TxCpltCallback = HAL_MMC_TxCpltCallback;
1873 break;
1874 case HAL_MMC_RX_CPLT_CB_ID :
1875 hmmc->RxCpltCallback = HAL_MMC_RxCpltCallback;
1876 break;
1877 case HAL_MMC_ERROR_CB_ID :
1878 hmmc->ErrorCallback = HAL_MMC_ErrorCallback;
1879 break;
1880 case HAL_MMC_ABORT_CB_ID :
1881 hmmc->AbortCpltCallback = HAL_MMC_AbortCallback;
1882 break;
1883 case HAL_MMC_MSP_INIT_CB_ID :
1884 hmmc->MspInitCallback = HAL_MMC_MspInit;
1885 break;
1886 case HAL_MMC_MSP_DEINIT_CB_ID :
1887 hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
1888 break;
1889 default :
1890 /* Update the error code */
1891 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1892 /* update return status */
1893 status = HAL_ERROR;
1894 break;
1895 }
1896 }
1897 else if (hmmc->State == HAL_MMC_STATE_RESET)
1898 {
1899 switch (CallbackId)
1900 {
1901 case HAL_MMC_MSP_INIT_CB_ID :
1902 hmmc->MspInitCallback = HAL_MMC_MspInit;
1903 break;
1904 case HAL_MMC_MSP_DEINIT_CB_ID :
1905 hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
1906 break;
1907 default :
1908 /* Update the error code */
1909 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1910 /* update return status */
1911 status = HAL_ERROR;
1912 break;
1913 }
1914 }
1915 else
1916 {
1917 /* Update the error code */
1918 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1919 /* update return status */
1920 status = HAL_ERROR;
1921 }
1922
1923 /* Release Lock */
1924 __HAL_UNLOCK(hmmc);
1925 return status;
1926 }
1927 #endif
1928
1929 /**
1930 * @}
1931 */
1932
1933 /** @addtogroup MMC_Exported_Functions_Group3
1934 * @brief management functions
1935 *
1936 @verbatim
1937 ==============================================================================
1938 ##### Peripheral Control functions #####
1939 ==============================================================================
1940 [..]
1941 This subsection provides a set of functions allowing to control the MMC card
1942 operations and get the related information
1943
1944 @endverbatim
1945 * @{
1946 */
1947
1948 /**
1949 * @brief Returns information the information of the card which are stored on
1950 * the CID register.
1951 * @param hmmc: Pointer to MMC handle
1952 * @param pCID: Pointer to a HAL_MMC_CIDTypedef structure that
1953 * contains all CID register parameters
1954 * @retval HAL status
1955 */
HAL_MMC_GetCardCID(MMC_HandleTypeDef * hmmc,HAL_MMC_CardCIDTypeDef * pCID)1956 HAL_StatusTypeDef HAL_MMC_GetCardCID(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCIDTypeDef *pCID)
1957 {
1958 pCID->ManufacturerID = (uint8_t)((hmmc->CID[0] & 0xFF000000U) >> 24U);
1959
1960 pCID->OEM_AppliID = (uint16_t)((hmmc->CID[0] & 0x00FFFF00U) >> 8U);
1961
1962 pCID->ProdName1 = (((hmmc->CID[0] & 0x000000FFU) << 24U) | ((hmmc->CID[1] & 0xFFFFFF00U) >> 8U));
1963
1964 pCID->ProdName2 = (uint8_t)(hmmc->CID[1] & 0x000000FFU);
1965
1966 pCID->ProdRev = (uint8_t)((hmmc->CID[2] & 0xFF000000U) >> 24U);
1967
1968 pCID->ProdSN = (((hmmc->CID[2] & 0x00FFFFFFU) << 8U) | ((hmmc->CID[3] & 0xFF000000U) >> 24U));
1969
1970 pCID->Reserved1 = (uint8_t)((hmmc->CID[3] & 0x00F00000U) >> 20U);
1971
1972 pCID->ManufactDate = (uint16_t)((hmmc->CID[3] & 0x000FFF00U) >> 8U);
1973
1974 pCID->CID_CRC = (uint8_t)((hmmc->CID[3] & 0x000000FEU) >> 1U);
1975
1976 pCID->Reserved2 = 1U;
1977
1978 return HAL_OK;
1979 }
1980
1981 /**
1982 * @brief Returns information the information of the card which are stored on
1983 * the CSD register.
1984 * @param hmmc: Pointer to MMC handle
1985 * @param pCSD: Pointer to a HAL_MMC_CardCSDTypeDef structure that
1986 * contains all CSD register parameters
1987 * @retval HAL status
1988 */
HAL_MMC_GetCardCSD(MMC_HandleTypeDef * hmmc,HAL_MMC_CardCSDTypeDef * pCSD)1989 HAL_StatusTypeDef HAL_MMC_GetCardCSD(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCSDTypeDef *pCSD)
1990 {
1991 uint32_t block_nbr = 0;
1992
1993 pCSD->CSDStruct = (uint8_t)((hmmc->CSD[0] & 0xC0000000U) >> 30U);
1994
1995 pCSD->SysSpecVersion = (uint8_t)((hmmc->CSD[0] & 0x3C000000U) >> 26U);
1996
1997 pCSD->Reserved1 = (uint8_t)((hmmc->CSD[0] & 0x03000000U) >> 24U);
1998
1999 pCSD->TAAC = (uint8_t)((hmmc->CSD[0] & 0x00FF0000U) >> 16U);
2000
2001 pCSD->NSAC = (uint8_t)((hmmc->CSD[0] & 0x0000FF00U) >> 8U);
2002
2003 pCSD->MaxBusClkFrec = (uint8_t)(hmmc->CSD[0] & 0x000000FFU);
2004
2005 pCSD->CardComdClasses = (uint16_t)((hmmc->CSD[1] & 0xFFF00000U) >> 20U);
2006
2007 pCSD->RdBlockLen = (uint8_t)((hmmc->CSD[1] & 0x000F0000U) >> 16U);
2008
2009 pCSD->PartBlockRead = (uint8_t)((hmmc->CSD[1] & 0x00008000U) >> 15U);
2010
2011 pCSD->WrBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00004000U) >> 14U);
2012
2013 pCSD->RdBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00002000U) >> 13U);
2014
2015 pCSD->DSRImpl = (uint8_t)((hmmc->CSD[1] & 0x00001000U) >> 12U);
2016
2017 pCSD->Reserved2 = 0U; /*!< Reserved */
2018
2019 pCSD->DeviceSize = (((hmmc->CSD[1] & 0x000003FFU) << 2U) | ((hmmc->CSD[2] & 0xC0000000U) >> 30U));
2020
2021 pCSD->MaxRdCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x38000000U) >> 27U);
2022
2023 pCSD->MaxRdCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x07000000U) >> 24U);
2024
2025 pCSD->MaxWrCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x00E00000U) >> 21U);
2026
2027 pCSD->MaxWrCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x001C0000U) >> 18U);
2028
2029 pCSD->DeviceSizeMul = (uint8_t)((hmmc->CSD[2] & 0x00038000U) >> 15U);
2030
2031 if(MMC_ReadExtCSD(hmmc, &block_nbr, 212, 0x0FFFFFFFU) != HAL_OK) /* Field SEC_COUNT [215:212] */
2032 {
2033 return HAL_ERROR;
2034 }
2035
2036 if(hmmc->MmcCard.CardType == MMC_LOW_CAPACITY_CARD)
2037 {
2038 hmmc->MmcCard.BlockNbr = (pCSD->DeviceSize + 1U) ;
2039 hmmc->MmcCard.BlockNbr *= (1UL << ((pCSD->DeviceSizeMul & 0x07U) + 2U));
2040 hmmc->MmcCard.BlockSize = (1UL << (pCSD->RdBlockLen & 0x0FU));
2041 hmmc->MmcCard.LogBlockNbr = (hmmc->MmcCard.BlockNbr) * ((hmmc->MmcCard.BlockSize) / 512U);
2042 hmmc->MmcCard.LogBlockSize = 512U;
2043 }
2044 else if(hmmc->MmcCard.CardType == MMC_HIGH_CAPACITY_CARD)
2045 {
2046 hmmc->MmcCard.BlockNbr = block_nbr;
2047 hmmc->MmcCard.LogBlockNbr = hmmc->MmcCard.BlockNbr;
2048 hmmc->MmcCard.BlockSize = 512U;
2049 hmmc->MmcCard.LogBlockSize = hmmc->MmcCard.BlockSize;
2050 }
2051 else
2052 {
2053 /* Clear all the static flags */
2054 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2055 hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2056 hmmc->State = HAL_MMC_STATE_READY;
2057 return HAL_ERROR;
2058 }
2059
2060 pCSD->EraseGrSize = (uint8_t)((hmmc->CSD[2] & 0x00004000U) >> 14U);
2061
2062 pCSD->EraseGrMul = (uint8_t)((hmmc->CSD[2] & 0x00003F80U) >> 7U);
2063
2064 pCSD->WrProtectGrSize = (uint8_t)(hmmc->CSD[2] & 0x0000007FU);
2065
2066 pCSD->WrProtectGrEnable = (uint8_t)((hmmc->CSD[3] & 0x80000000U) >> 31U);
2067
2068 pCSD->ManDeflECC = (uint8_t)((hmmc->CSD[3] & 0x60000000U) >> 29U);
2069
2070 pCSD->WrSpeedFact = (uint8_t)((hmmc->CSD[3] & 0x1C000000U) >> 26U);
2071
2072 pCSD->MaxWrBlockLen= (uint8_t)((hmmc->CSD[3] & 0x03C00000U) >> 22U);
2073
2074 pCSD->WriteBlockPaPartial = (uint8_t)((hmmc->CSD[3] & 0x00200000U) >> 21U);
2075
2076 pCSD->Reserved3 = 0;
2077
2078 pCSD->ContentProtectAppli = (uint8_t)((hmmc->CSD[3] & 0x00010000U) >> 16U);
2079
2080 pCSD->FileFormatGroup = (uint8_t)((hmmc->CSD[3] & 0x00008000U) >> 15U);
2081
2082 pCSD->CopyFlag = (uint8_t)((hmmc->CSD[3] & 0x00004000U) >> 14U);
2083
2084 pCSD->PermWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00002000U) >> 13U);
2085
2086 pCSD->TempWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00001000U) >> 12U);
2087
2088 pCSD->FileFormat = (uint8_t)((hmmc->CSD[3] & 0x00000C00U) >> 10U);
2089
2090 pCSD->ECC= (uint8_t)((hmmc->CSD[3] & 0x00000300U) >> 8U);
2091
2092 pCSD->CSD_CRC = (uint8_t)((hmmc->CSD[3] & 0x000000FEU) >> 1U);
2093
2094 pCSD->Reserved4 = 1;
2095
2096 return HAL_OK;
2097 }
2098
2099 /**
2100 * @brief Gets the MMC card info.
2101 * @param hmmc: Pointer to MMC handle
2102 * @param pCardInfo: Pointer to the HAL_MMC_CardInfoTypeDef structure that
2103 * will contain the MMC card status information
2104 * @retval HAL status
2105 */
HAL_MMC_GetCardInfo(MMC_HandleTypeDef * hmmc,HAL_MMC_CardInfoTypeDef * pCardInfo)2106 HAL_StatusTypeDef HAL_MMC_GetCardInfo(MMC_HandleTypeDef *hmmc, HAL_MMC_CardInfoTypeDef *pCardInfo)
2107 {
2108 pCardInfo->CardType = (uint32_t)(hmmc->MmcCard.CardType);
2109 pCardInfo->Class = (uint32_t)(hmmc->MmcCard.Class);
2110 pCardInfo->RelCardAdd = (uint32_t)(hmmc->MmcCard.RelCardAdd);
2111 pCardInfo->BlockNbr = (uint32_t)(hmmc->MmcCard.BlockNbr);
2112 pCardInfo->BlockSize = (uint32_t)(hmmc->MmcCard.BlockSize);
2113 pCardInfo->LogBlockNbr = (uint32_t)(hmmc->MmcCard.LogBlockNbr);
2114 pCardInfo->LogBlockSize = (uint32_t)(hmmc->MmcCard.LogBlockSize);
2115
2116 return HAL_OK;
2117 }
2118
2119 /**
2120 * @brief Returns information the information of the card which are stored on
2121 * the Extended CSD register.
2122 * @param hmmc Pointer to MMC handle
2123 * @param pExtCSD Pointer to a memory area (512 bytes) that contains all
2124 * Extended CSD register parameters
2125 * @param Timeout Specify timeout value
2126 * @retval HAL status
2127 */
HAL_MMC_GetCardExtCSD(MMC_HandleTypeDef * hmmc,uint32_t * pExtCSD,uint32_t Timeout)2128 HAL_StatusTypeDef HAL_MMC_GetCardExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pExtCSD, uint32_t Timeout)
2129 {
2130 SDMMC_DataInitTypeDef config;
2131 uint32_t errorstate;
2132 uint32_t tickstart = HAL_GetTick();
2133 uint32_t count;
2134 uint32_t *tmp_buf;
2135
2136 if(NULL == pExtCSD)
2137 {
2138 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
2139 return HAL_ERROR;
2140 }
2141
2142 if(hmmc->State == HAL_MMC_STATE_READY)
2143 {
2144 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
2145
2146 hmmc->State = HAL_MMC_STATE_BUSY;
2147
2148 /* Initialize data control register */
2149 hmmc->Instance->DCTRL = 0;
2150
2151 /* Initiaize the destination pointer */
2152 tmp_buf = pExtCSD;
2153
2154 /* Configure the MMC DPSM (Data Path State Machine) */
2155 config.DataTimeOut = SDMMC_DATATIMEOUT;
2156 config.DataLength = 512;
2157 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
2158 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
2159 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
2160 config.DPSM = SDMMC_DPSM_ENABLE;
2161 (void)SDMMC_ConfigData(hmmc->Instance, &config);
2162
2163 /* Send ExtCSD Read command to Card */
2164 errorstate = SDMMC_CmdSendEXTCSD(hmmc->Instance, 0);
2165 if(errorstate != HAL_MMC_ERROR_NONE)
2166 {
2167 /* Clear all the static flags */
2168 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2169 hmmc->ErrorCode |= errorstate;
2170 hmmc->State = HAL_MMC_STATE_READY;
2171 return HAL_ERROR;
2172 }
2173
2174 /* Poll on SDMMC flags */
2175 while(!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
2176 {
2177 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF))
2178 {
2179 /* Read data from SDMMC Rx FIFO */
2180 for(count = 0U; count < 8U; count++)
2181 {
2182 *tmp_buf = SDMMC_ReadFIFO(hmmc->Instance);
2183 tmp_buf++;
2184 }
2185 }
2186
2187 if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U))
2188 {
2189 /* Clear all the static flags */
2190 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2191 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
2192 hmmc->State= HAL_MMC_STATE_READY;
2193 return HAL_TIMEOUT;
2194 }
2195 }
2196
2197 /* Get error state */
2198 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
2199 {
2200 /* Clear all the static flags */
2201 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2202 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
2203 hmmc->State = HAL_MMC_STATE_READY;
2204 return HAL_ERROR;
2205 }
2206 else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
2207 {
2208 /* Clear all the static flags */
2209 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2210 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
2211 hmmc->State = HAL_MMC_STATE_READY;
2212 return HAL_ERROR;
2213 }
2214 else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR))
2215 {
2216 /* Clear all the static flags */
2217 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2218 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
2219 hmmc->State = HAL_MMC_STATE_READY;
2220 return HAL_ERROR;
2221 }
2222 else
2223 {
2224 /* Nothing to do */
2225 }
2226
2227 /* Clear all the static flags */
2228 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2229 hmmc->State = HAL_MMC_STATE_READY;
2230 }
2231
2232 return HAL_OK;
2233 }
2234
2235 /**
2236 * @brief Enables wide bus operation for the requested card if supported by
2237 * card.
2238 * @param hmmc: Pointer to MMC handle
2239 * @param WideMode: Specifies the MMC card wide bus mode
2240 * This parameter can be one of the following values:
2241 * @arg SDMMC_BUS_WIDE_8B: 8-bit data transfer
2242 * @arg SDMMC_BUS_WIDE_4B: 4-bit data transfer
2243 * @arg SDMMC_BUS_WIDE_1B: 1-bit data transfer
2244 * @retval HAL status
2245 */
HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef * hmmc,uint32_t WideMode)2246 HAL_StatusTypeDef HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef *hmmc, uint32_t WideMode)
2247 {
2248 uint32_t count;
2249 SDMMC_InitTypeDef Init;
2250 uint32_t errorstate;
2251 uint32_t response = 0U;
2252
2253 /* Check the parameters */
2254 assert_param(IS_SDMMC_BUS_WIDE(WideMode));
2255
2256 /* Change State */
2257 hmmc->State = HAL_MMC_STATE_BUSY;
2258
2259 errorstate = MMC_PwrClassUpdate(hmmc, WideMode);
2260
2261 if(errorstate == HAL_MMC_ERROR_NONE)
2262 {
2263 if(WideMode == SDMMC_BUS_WIDE_8B)
2264 {
2265 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U);
2266 }
2267 else if(WideMode == SDMMC_BUS_WIDE_4B)
2268 {
2269 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U);
2270 }
2271 else if(WideMode == SDMMC_BUS_WIDE_1B)
2272 {
2273 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70000U);
2274 }
2275 else
2276 {
2277 /* WideMode is not a valid argument*/
2278 errorstate = HAL_MMC_ERROR_PARAM;
2279 }
2280
2281 /* Check for switch error and violation of the trial number of sending CMD 13 */
2282 if(errorstate == HAL_MMC_ERROR_NONE)
2283 {
2284 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2285 count = SDMMC_MAX_TRIAL;
2286 do
2287 {
2288 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2289 if(errorstate != HAL_MMC_ERROR_NONE)
2290 {
2291 break;
2292 }
2293
2294 /* Get command response */
2295 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
2296 count--;
2297 }while(((response & 0x100U) == 0U) && (count != 0U));
2298
2299 /* Check the status after the switch command execution */
2300 if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
2301 {
2302 /* Check the bit SWITCH_ERROR of the device status */
2303 if ((response & 0x80U) != 0U)
2304 {
2305 errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
2306 }
2307 else
2308 {
2309 /* Configure the SDMMC peripheral */
2310 Init = hmmc->Init;
2311 Init.BusWide = WideMode;
2312 (void)SDMMC_Init(hmmc->Instance, Init);
2313 }
2314 }
2315 else if (count == 0U)
2316 {
2317 errorstate = SDMMC_ERROR_TIMEOUT;
2318 }
2319 else
2320 {
2321 /* Nothing to do */
2322 }
2323 }
2324 }
2325
2326 /* Change State */
2327 hmmc->State = HAL_MMC_STATE_READY;
2328
2329 if(errorstate != HAL_MMC_ERROR_NONE)
2330 {
2331 /* Clear all the static flags */
2332 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2333 hmmc->ErrorCode |= errorstate;
2334 return HAL_ERROR;
2335 }
2336
2337 return HAL_OK;
2338 }
2339
2340 /**
2341 * @brief Gets the current mmc card data state.
2342 * @param hmmc: pointer to MMC handle
2343 * @retval Card state
2344 */
HAL_MMC_GetCardState(MMC_HandleTypeDef * hmmc)2345 HAL_MMC_CardStateTypeDef HAL_MMC_GetCardState(MMC_HandleTypeDef *hmmc)
2346 {
2347 uint32_t cardstate;
2348 uint32_t errorstate;
2349 uint32_t resp1 = 0U;
2350
2351 errorstate = MMC_SendStatus(hmmc, &resp1);
2352 if(errorstate != HAL_MMC_ERROR_NONE)
2353 {
2354 hmmc->ErrorCode |= errorstate;
2355 }
2356
2357 cardstate = ((resp1 >> 9U) & 0x0FU);
2358
2359 return (HAL_MMC_CardStateTypeDef)cardstate;
2360 }
2361
2362 /**
2363 * @brief Abort the current transfer and disable the MMC.
2364 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2365 * the configuration information for MMC module.
2366 * @retval HAL status
2367 */
HAL_MMC_Abort(MMC_HandleTypeDef * hmmc)2368 HAL_StatusTypeDef HAL_MMC_Abort(MMC_HandleTypeDef *hmmc)
2369 {
2370 HAL_MMC_CardStateTypeDef CardState;
2371
2372 /* DIsable All interrupts */
2373 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\
2374 SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR);
2375
2376 /* Clear All flags */
2377 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2378
2379 if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL))
2380 {
2381 /* Disable the MMC DMA request */
2382 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN);
2383
2384 /* Abort the MMC DMA Tx Stream */
2385 if(hmmc->hdmatx != NULL)
2386 {
2387 if(HAL_DMA_Abort(hmmc->hdmatx) != HAL_OK)
2388 {
2389 hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
2390 }
2391 }
2392 /* Abort the MMC DMA Rx Stream */
2393 if(hmmc->hdmarx != NULL)
2394 {
2395 if(HAL_DMA_Abort(hmmc->hdmarx) != HAL_OK)
2396 {
2397 hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
2398 }
2399 }
2400 }
2401
2402 hmmc->State = HAL_MMC_STATE_READY;
2403
2404 /* Initialize the MMC operation */
2405 hmmc->Context = MMC_CONTEXT_NONE;
2406
2407 CardState = HAL_MMC_GetCardState(hmmc);
2408 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2409 {
2410 hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
2411 }
2412 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2413 {
2414 return HAL_ERROR;
2415 }
2416 return HAL_OK;
2417 }
2418
2419 /**
2420 * @brief Abort the current transfer and disable the MMC (IT mode).
2421 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2422 * the configuration information for MMC module.
2423 * @retval HAL status
2424 */
HAL_MMC_Abort_IT(MMC_HandleTypeDef * hmmc)2425 HAL_StatusTypeDef HAL_MMC_Abort_IT(MMC_HandleTypeDef *hmmc)
2426 {
2427 HAL_MMC_CardStateTypeDef CardState;
2428
2429 /* DIsable All interrupts */
2430 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\
2431 SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR);
2432
2433 /* Clear All flags */
2434 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2435
2436 if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL))
2437 {
2438 /* Disable the MMC DMA request */
2439 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN);
2440
2441 /* Abort the MMC DMA Tx Stream */
2442 if(hmmc->hdmatx != NULL)
2443 {
2444 hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort;
2445 if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
2446 {
2447 hmmc->hdmatx = NULL;
2448 }
2449 }
2450 /* Abort the MMC DMA Rx Stream */
2451 if(hmmc->hdmarx != NULL)
2452 {
2453 hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort;
2454 if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
2455 {
2456 hmmc->hdmarx = NULL;
2457 }
2458 }
2459 }
2460
2461 /* No transfer ongoing on both DMA channels*/
2462 if((hmmc->hdmatx == NULL) && (hmmc->hdmarx == NULL))
2463 {
2464 CardState = HAL_MMC_GetCardState(hmmc);
2465 hmmc->State = HAL_MMC_STATE_READY;
2466
2467 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2468 {
2469 hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
2470 }
2471 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2472 {
2473 return HAL_ERROR;
2474 }
2475 else
2476 {
2477 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2478 hmmc->AbortCpltCallback(hmmc);
2479 #else
2480 HAL_MMC_AbortCallback(hmmc);
2481 #endif
2482 }
2483 }
2484
2485 return HAL_OK;
2486 }
2487
2488 /**
2489 * @}
2490 */
2491
2492 /**
2493 * @}
2494 */
2495
2496 /* Private function ----------------------------------------------------------*/
2497 /** @addtogroup MMC_Private_Functions
2498 * @{
2499 */
2500
2501 /**
2502 * @brief DMA MMC transmit process complete callback
2503 * @param hdma: DMA handle
2504 * @retval None
2505 */
MMC_DMATransmitCplt(DMA_HandleTypeDef * hdma)2506 static void MMC_DMATransmitCplt(DMA_HandleTypeDef *hdma)
2507 {
2508 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2509
2510 /* Enable DATAEND Interrupt */
2511 __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DATAEND));
2512 }
2513
2514 /**
2515 * @brief DMA MMC receive process complete callback
2516 * @param hdma: DMA handle
2517 * @retval None
2518 */
MMC_DMAReceiveCplt(DMA_HandleTypeDef * hdma)2519 static void MMC_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
2520 {
2521 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2522 uint32_t errorstate;
2523
2524 /* Send stop command in multiblock write */
2525 if(hmmc->Context == (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA))
2526 {
2527 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
2528 if(errorstate != HAL_MMC_ERROR_NONE)
2529 {
2530 hmmc->ErrorCode |= errorstate;
2531 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2532 hmmc->ErrorCallback(hmmc);
2533 #else
2534 HAL_MMC_ErrorCallback(hmmc);
2535 #endif
2536 }
2537 }
2538
2539 /* Disable the DMA transfer for transmit request by setting the DMAEN bit
2540 in the MMC DCTRL register */
2541 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN);
2542
2543 /* Clear all the static flags */
2544 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2545
2546 hmmc->State = HAL_MMC_STATE_READY;
2547
2548 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2549 hmmc->RxCpltCallback(hmmc);
2550 #else
2551 HAL_MMC_RxCpltCallback(hmmc);
2552 #endif
2553 }
2554
2555 /**
2556 * @brief DMA MMC communication error callback
2557 * @param hdma: DMA handle
2558 * @retval None
2559 */
MMC_DMAError(DMA_HandleTypeDef * hdma)2560 static void MMC_DMAError(DMA_HandleTypeDef *hdma)
2561 {
2562 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2563 HAL_MMC_CardStateTypeDef CardState;
2564 uint32_t RxErrorCode, TxErrorCode;
2565
2566 /* if DMA error is FIFO error ignore it */
2567 if(HAL_DMA_GetError(hdma) != HAL_DMA_ERROR_FE)
2568 {
2569 RxErrorCode = hmmc->hdmarx->ErrorCode;
2570 TxErrorCode = hmmc->hdmatx->ErrorCode;
2571 if((RxErrorCode == HAL_DMA_ERROR_TE) || (TxErrorCode == HAL_DMA_ERROR_TE))
2572 {
2573 /* Clear All flags */
2574 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2575
2576 /* Disable All interrupts */
2577 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\
2578 SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR);
2579
2580 hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
2581 CardState = HAL_MMC_GetCardState(hmmc);
2582 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2583 {
2584 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
2585 }
2586
2587 hmmc->State= HAL_MMC_STATE_READY;
2588 }
2589
2590 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2591 hmmc->ErrorCallback(hmmc);
2592 #else
2593 HAL_MMC_ErrorCallback(hmmc);
2594 #endif
2595 }
2596 }
2597
2598 /**
2599 * @brief DMA MMC Tx Abort callback
2600 * @param hdma: DMA handle
2601 * @retval None
2602 */
MMC_DMATxAbort(DMA_HandleTypeDef * hdma)2603 static void MMC_DMATxAbort(DMA_HandleTypeDef *hdma)
2604 {
2605 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2606 HAL_MMC_CardStateTypeDef CardState;
2607
2608 if(hmmc->hdmatx != NULL)
2609 {
2610 hmmc->hdmatx = NULL;
2611 }
2612
2613 /* All DMA channels are aborted */
2614 if(hmmc->hdmarx == NULL)
2615 {
2616 CardState = HAL_MMC_GetCardState(hmmc);
2617 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
2618 hmmc->State = HAL_MMC_STATE_READY;
2619 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2620 {
2621 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
2622
2623 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2624 {
2625 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2626 hmmc->AbortCpltCallback(hmmc);
2627 #else
2628 HAL_MMC_AbortCallback(hmmc);
2629 #endif
2630 }
2631 else
2632 {
2633 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2634 hmmc->ErrorCallback(hmmc);
2635 #else
2636 HAL_MMC_ErrorCallback(hmmc);
2637 #endif
2638 }
2639 }
2640 }
2641 }
2642
2643 /**
2644 * @brief DMA MMC Rx Abort callback
2645 * @param hdma: DMA handle
2646 * @retval None
2647 */
MMC_DMARxAbort(DMA_HandleTypeDef * hdma)2648 static void MMC_DMARxAbort(DMA_HandleTypeDef *hdma)
2649 {
2650 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2651 HAL_MMC_CardStateTypeDef CardState;
2652
2653 if(hmmc->hdmarx != NULL)
2654 {
2655 hmmc->hdmarx = NULL;
2656 }
2657
2658 /* All DMA channels are aborted */
2659 if(hmmc->hdmatx == NULL)
2660 {
2661 CardState = HAL_MMC_GetCardState(hmmc);
2662 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
2663 hmmc->State = HAL_MMC_STATE_READY;
2664 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2665 {
2666 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
2667
2668 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2669 {
2670 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2671 hmmc->AbortCpltCallback(hmmc);
2672 #else
2673 HAL_MMC_AbortCallback(hmmc);
2674 #endif
2675 }
2676 else
2677 {
2678 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2679 hmmc->ErrorCallback(hmmc);
2680 #else
2681 HAL_MMC_ErrorCallback(hmmc);
2682 #endif
2683 }
2684 }
2685 }
2686 }
2687
2688 /**
2689 * @brief Initializes the mmc card.
2690 * @param hmmc: Pointer to MMC handle
2691 * @retval MMC Card error state
2692 */
MMC_InitCard(MMC_HandleTypeDef * hmmc)2693 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc)
2694 {
2695 HAL_MMC_CardCSDTypeDef CSD;
2696 uint32_t errorstate;
2697 uint16_t mmc_rca = 2U;
2698 MMC_InitTypeDef Init;
2699
2700 /* Check the power State */
2701 if(SDMMC_GetPowerState(hmmc->Instance) == 0U)
2702 {
2703 /* Power off */
2704 return HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
2705 }
2706
2707 /* Send CMD2 ALL_SEND_CID */
2708 errorstate = SDMMC_CmdSendCID(hmmc->Instance);
2709 if(errorstate != HAL_MMC_ERROR_NONE)
2710 {
2711 return errorstate;
2712 }
2713 else
2714 {
2715 /* Get Card identification number data */
2716 hmmc->CID[0U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
2717 hmmc->CID[1U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2);
2718 hmmc->CID[2U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP3);
2719 hmmc->CID[3U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP4);
2720 }
2721
2722 /* Send CMD3 SET_REL_ADDR with RCA = 2 (should be greater than 1) */
2723 /* MMC Card publishes its RCA. */
2724 errorstate = SDMMC_CmdSetRelAddMmc(hmmc->Instance, mmc_rca);
2725 if(errorstate != HAL_MMC_ERROR_NONE)
2726 {
2727 return errorstate;
2728 }
2729
2730 /* Get the MMC card RCA */
2731 hmmc->MmcCard.RelCardAdd = mmc_rca;
2732
2733 /* Send CMD9 SEND_CSD with argument as card's RCA */
2734 errorstate = SDMMC_CmdSendCSD(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
2735 if(errorstate != HAL_MMC_ERROR_NONE)
2736 {
2737 return errorstate;
2738 }
2739 else
2740 {
2741 /* Get Card Specific Data */
2742 hmmc->CSD[0U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
2743 hmmc->CSD[1U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2);
2744 hmmc->CSD[2U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP3);
2745 hmmc->CSD[3U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP4);
2746 }
2747
2748 /* Get the Card Class */
2749 hmmc->MmcCard.Class = (SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2) >> 20U);
2750
2751 /* Select the Card */
2752 errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2753 if(errorstate != HAL_MMC_ERROR_NONE)
2754 {
2755 return errorstate;
2756 }
2757
2758 /* Get CSD parameters */
2759 if (HAL_MMC_GetCardCSD(hmmc, &CSD) != HAL_OK)
2760 {
2761 return hmmc->ErrorCode;
2762 }
2763
2764 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2765 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2766 if(errorstate != HAL_MMC_ERROR_NONE)
2767 {
2768 hmmc->ErrorCode |= errorstate;
2769 }
2770
2771 /* Get Extended CSD parameters */
2772 if (HAL_MMC_GetCardExtCSD(hmmc, hmmc->Ext_CSD, SDMMC_DATATIMEOUT) != HAL_OK)
2773 {
2774 return hmmc->ErrorCode;
2775 }
2776
2777 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2778 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2779 if(errorstate != HAL_MMC_ERROR_NONE)
2780 {
2781 hmmc->ErrorCode |= errorstate;
2782 }
2783
2784 /* Configure the SDMMC peripheral */
2785 Init = hmmc->Init;
2786 Init.BusWide = SDMMC_BUS_WIDE_1B;
2787 (void)SDMMC_Init(hmmc->Instance, Init);
2788
2789 /* All cards are initialized */
2790 return HAL_MMC_ERROR_NONE;
2791 }
2792
2793 /**
2794 * @brief Enquires cards about their operating voltage and configures clock
2795 * controls and stores MMC information that will be needed in future
2796 * in the MMC handle.
2797 * @param hmmc: Pointer to MMC handle
2798 * @retval error state
2799 */
MMC_PowerON(MMC_HandleTypeDef * hmmc)2800 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc)
2801 {
2802 __IO uint32_t count = 0U;
2803 uint32_t response = 0U, validvoltage = 0U;
2804 uint32_t errorstate;
2805
2806 /* CMD0: GO_IDLE_STATE */
2807 errorstate = SDMMC_CmdGoIdleState(hmmc->Instance);
2808 if(errorstate != HAL_MMC_ERROR_NONE)
2809 {
2810 return errorstate;
2811 }
2812
2813 while(validvoltage == 0U)
2814 {
2815 if(count++ == SDMMC_MAX_VOLT_TRIAL)
2816 {
2817 return HAL_MMC_ERROR_INVALID_VOLTRANGE;
2818 }
2819
2820 /* SEND CMD1 APP_CMD with voltage range as argument */
2821 errorstate = SDMMC_CmdOpCondition(hmmc->Instance, MMC_VOLTAGE_RANGE);
2822 if(errorstate != HAL_MMC_ERROR_NONE)
2823 {
2824 return HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2825 }
2826
2827 /* Get command response */
2828 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
2829
2830 /* Get operating voltage*/
2831 validvoltage = (((response >> 31U) == 1U) ? 1U : 0U);
2832 }
2833
2834 /* When power routine is finished and command returns valid voltage */
2835 if (((response & (0xFF000000U)) >> 24U) == 0xC0U)
2836 {
2837 hmmc->MmcCard.CardType = MMC_HIGH_CAPACITY_CARD;
2838 }
2839 else
2840 {
2841 hmmc->MmcCard.CardType = MMC_LOW_CAPACITY_CARD;
2842 }
2843
2844 return HAL_MMC_ERROR_NONE;
2845 }
2846
2847 /**
2848 * @brief Turns the SDMMC output signals off.
2849 * @param hmmc: Pointer to MMC handle
2850 * @retval None
2851 */
MMC_PowerOFF(MMC_HandleTypeDef * hmmc)2852 static void MMC_PowerOFF(MMC_HandleTypeDef *hmmc)
2853 {
2854 /* Set Power State to OFF */
2855 (void)SDMMC_PowerState_OFF(hmmc->Instance);
2856 }
2857
2858 /**
2859 * @brief Returns the current card's status.
2860 * @param hmmc: Pointer to MMC handle
2861 * @param pCardStatus: pointer to the buffer that will contain the MMC card
2862 * status (Card Status register)
2863 * @retval error state
2864 */
MMC_SendStatus(MMC_HandleTypeDef * hmmc,uint32_t * pCardStatus)2865 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus)
2866 {
2867 uint32_t errorstate;
2868
2869 if(pCardStatus == NULL)
2870 {
2871 return HAL_MMC_ERROR_PARAM;
2872 }
2873
2874 /* Send Status command */
2875 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
2876 if(errorstate != HAL_MMC_ERROR_NONE)
2877 {
2878 return errorstate;
2879 }
2880
2881 /* Get MMC card status */
2882 *pCardStatus = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
2883
2884 return HAL_MMC_ERROR_NONE;
2885 }
2886
2887 /**
2888 * @brief Reads extended CSD register to get the sectors number of the device
2889 * @param hmmc: Pointer to MMC handle
2890 * @param pFieldData: Pointer to the read buffer
2891 * @param FieldIndex: Index of the field to be read
2892 * @param Timeout: Specify timeout value
2893 * @retval HAL status
2894 */
MMC_ReadExtCSD(MMC_HandleTypeDef * hmmc,uint32_t * pFieldData,uint16_t FieldIndex,uint32_t Timeout)2895 static uint32_t MMC_ReadExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pFieldData, uint16_t FieldIndex, uint32_t Timeout)
2896 {
2897 SDMMC_DataInitTypeDef config;
2898 uint32_t errorstate;
2899 uint32_t tickstart = HAL_GetTick();
2900 uint32_t count;
2901 uint32_t i = 0;
2902 uint32_t tmp_data;
2903
2904 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
2905
2906 /* Initialize data control register */
2907 hmmc->Instance->DCTRL = 0;
2908
2909 /* Configure the MMC DPSM (Data Path State Machine) */
2910 config.DataTimeOut = SDMMC_DATATIMEOUT;
2911 config.DataLength = 512;
2912 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
2913 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
2914 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
2915 config.DPSM = SDMMC_DPSM_ENABLE;
2916 (void)SDMMC_ConfigData(hmmc->Instance, &config);
2917
2918 /* Set Block Size for Card */
2919 errorstate = SDMMC_CmdSendEXTCSD(hmmc->Instance, 0);
2920 if(errorstate != HAL_MMC_ERROR_NONE)
2921 {
2922 /* Clear all the static flags */
2923 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2924 hmmc->ErrorCode |= errorstate;
2925 hmmc->State = HAL_MMC_STATE_READY;
2926 return HAL_ERROR;
2927 }
2928
2929 /* Poll on SDMMC flags */
2930 while(!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
2931 {
2932 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF))
2933 {
2934 /* Read data from SDMMC Rx FIFO */
2935 for(count = 0U; count < 8U; count++)
2936 {
2937 tmp_data = SDMMC_ReadFIFO(hmmc->Instance);
2938 /* eg : SEC_COUNT : FieldIndex = 212 => i+count = 53 */
2939 /* DEVICE_TYPE : FieldIndex = 196 => i+count = 49 */
2940 if ((i + count) == ((uint32_t)FieldIndex/4U))
2941 {
2942 *pFieldData = tmp_data;
2943 }
2944 }
2945 i += 8U;
2946 }
2947
2948 if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U))
2949 {
2950 /* Clear all the static flags */
2951 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2952 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
2953 hmmc->State= HAL_MMC_STATE_READY;
2954 return HAL_TIMEOUT;
2955 }
2956 }
2957
2958 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2959 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16));
2960 if(errorstate != HAL_MMC_ERROR_NONE)
2961 {
2962 hmmc->ErrorCode |= errorstate;
2963 }
2964
2965 /* Clear all the static flags */
2966 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2967
2968 hmmc->State = HAL_MMC_STATE_READY;
2969
2970 return HAL_OK;
2971 }
2972
2973
2974 /**
2975 * @brief Wrap up reading in non-blocking mode.
2976 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2977 * the configuration information.
2978 * @retval None
2979 */
MMC_Read_IT(MMC_HandleTypeDef * hmmc)2980 static void MMC_Read_IT(MMC_HandleTypeDef *hmmc)
2981 {
2982 uint32_t count, data, dataremaining;
2983 uint8_t* tmp;
2984
2985 tmp = hmmc->pRxBuffPtr;
2986 dataremaining = hmmc->RxXferSize;
2987
2988 if (dataremaining > 0U)
2989 {
2990 /* Read data from SDMMC Rx FIFO */
2991 for(count = 0U; count < 8U; count++)
2992 {
2993 data = SDMMC_ReadFIFO(hmmc->Instance);
2994 *tmp = (uint8_t)(data & 0xFFU);
2995 tmp++;
2996 dataremaining--;
2997 *tmp = (uint8_t)((data >> 8U) & 0xFFU);
2998 tmp++;
2999 dataremaining--;
3000 *tmp = (uint8_t)((data >> 16U) & 0xFFU);
3001 tmp++;
3002 dataremaining--;
3003 *tmp = (uint8_t)((data >> 24U) & 0xFFU);
3004 tmp++;
3005 dataremaining--;
3006 }
3007
3008 hmmc->pRxBuffPtr = tmp;
3009 hmmc->RxXferSize = dataremaining;
3010 }
3011 }
3012
3013 /**
3014 * @brief Wrap up writing in non-blocking mode.
3015 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
3016 * the configuration information.
3017 * @retval None
3018 */
MMC_Write_IT(MMC_HandleTypeDef * hmmc)3019 static void MMC_Write_IT(MMC_HandleTypeDef *hmmc)
3020 {
3021 uint32_t count, data, dataremaining;
3022 uint8_t* tmp;
3023
3024 tmp = hmmc->pTxBuffPtr;
3025 dataremaining = hmmc->TxXferSize;
3026
3027 if (dataremaining > 0U)
3028 {
3029 /* Write data to SDMMC Tx FIFO */
3030 for(count = 0U; count < 8U; count++)
3031 {
3032 data = (uint32_t)(*tmp);
3033 tmp++;
3034 dataremaining--;
3035 data |= ((uint32_t)(*tmp) << 8U);
3036 tmp++;
3037 dataremaining--;
3038 data |= ((uint32_t)(*tmp) << 16U);
3039 tmp++;
3040 dataremaining--;
3041 data |= ((uint32_t)(*tmp) << 24U);
3042 tmp++;
3043 dataremaining--;
3044 (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
3045 }
3046
3047 hmmc->pTxBuffPtr = tmp;
3048 hmmc->TxXferSize = dataremaining;
3049 }
3050 }
3051
3052 /**
3053 * @brief Update the power class of the device.
3054 * @param hmmc MMC handle
3055 * @param Wide Wide of MMC bus
3056 * @param Speed Speed of the MMC bus
3057 * @retval MMC Card error state
3058 */
MMC_PwrClassUpdate(MMC_HandleTypeDef * hmmc,uint32_t Wide)3059 static uint32_t MMC_PwrClassUpdate(MMC_HandleTypeDef *hmmc, uint32_t Wide)
3060 {
3061 uint32_t count;
3062 uint32_t response = 0U;
3063 uint32_t errorstate = HAL_MMC_ERROR_NONE;
3064 uint32_t power_class, supported_pwr_class;
3065
3066 if((Wide == SDMMC_BUS_WIDE_8B) || (Wide == SDMMC_BUS_WIDE_4B))
3067 {
3068 power_class = 0U; /* Default value after power-on or software reset */
3069
3070 /* Read the PowerClass field of the Extended CSD register */
3071 if(MMC_ReadExtCSD(hmmc, &power_class, 187, SDMMC_DATATIMEOUT) != HAL_OK) /* Field POWER_CLASS [187] */
3072 {
3073 errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
3074 }
3075 else
3076 {
3077 power_class = ((power_class >> 24U) & 0x000000FFU);
3078 }
3079
3080 /* Get the supported PowerClass field of the Extended CSD register */
3081 /* Field PWR_CL_26_xxx [201 or 203] */
3082 supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_26_INDEX/4)] >> MMC_EXT_CSD_PWR_CL_26_POS) & 0x000000FFU);
3083
3084 if(errorstate == HAL_MMC_ERROR_NONE)
3085 {
3086 if(Wide == SDMMC_BUS_WIDE_8B)
3087 {
3088 /* Bit [7:4] : power class for 8-bits bus configuration - Bit [3:0] : power class for 4-bits bus configuration */
3089 supported_pwr_class = (supported_pwr_class >> 4U);
3090 }
3091
3092 if ((power_class & 0x0FU) != (supported_pwr_class & 0x0FU))
3093 {
3094 /* Need to change current power class */
3095 errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03BB0000U | ((supported_pwr_class & 0x0FU) << 8U)));
3096
3097 if(errorstate == HAL_MMC_ERROR_NONE)
3098 {
3099 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3100 count = SDMMC_MAX_TRIAL;
3101 do
3102 {
3103 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3104 if(errorstate != HAL_MMC_ERROR_NONE)
3105 {
3106 break;
3107 }
3108
3109 /* Get command response */
3110 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3111 count--;
3112 }while(((response & 0x100U) == 0U) && (count != 0U));
3113
3114 /* Check the status after the switch command execution */
3115 if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
3116 {
3117 /* Check the bit SWITCH_ERROR of the device status */
3118 if ((response & 0x80U) != 0U)
3119 {
3120 errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3121 }
3122 }
3123 else if (count == 0U)
3124 {
3125 errorstate = SDMMC_ERROR_TIMEOUT;
3126 }
3127 else
3128 {
3129 /* Nothing to do */
3130 }
3131 }
3132 }
3133 }
3134 }
3135
3136 return errorstate;
3137 }
3138
3139 /**
3140 * @}
3141 */
3142
3143 #endif /* SDMMC1 */
3144
3145 #endif /* HAL_MMC_MODULE_ENABLED */
3146
3147 /**
3148 * @}
3149 */
3150
3151 /**
3152 * @}
3153 */
3154