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