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