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