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   ******************************************************************************
14   * @attention
15   *
16   * Copyright (c) 2017 STMicroelectronics.
17   * All rights reserved.
18   *
19   * This software is licensed under terms that can be found in the LICENSE file
20   * in the root directory of this software component.
21   * If no LICENSE file comes with this software, it is provided AS-IS.
22   *
23   ******************************************************************************
24   @verbatim
25   ==============================================================================
26                         ##### How to use this driver #####
27   ==============================================================================
28   [..]
29     This driver implements a high level communication layer for read and write from/to
30     this memory. The needed STM32 hardware resources (SDMMC and GPIO) are performed by
31     the user in HAL_MMC_MspInit() function (MSP layer).
32     Basically, the MSP layer configuration should be the same as we provide in the
33     examples.
34     You can easily tailor this configuration according to hardware resources.
35 
36   [..]
37     This driver is a generic layered driver for SDMMC memories which uses the HAL
38     SDMMC driver functions to interface with MMC and eMMC cards devices.
39     It is used as follows:
40 
41     (#)Initialize the SDMMC low level resources by implement the HAL_MMC_MspInit() API:
42         (##) Enable the SDMMC interface clock using __HAL_RCC_SDMMC_CLK_ENABLE();
43         (##) SDMMC pins configuration for MMC card
44             (+++) Enable the clock for the SDMMC GPIOs using the functions __HAL_RCC_GPIOx_CLK_ENABLE();
45             (+++) Configure these SDMMC pins as alternate function pull-up using HAL_GPIO_Init()
46                   and according to your pin assignment;
47         (##) On STM32L4Rx/STM32L4Sxx devices, no DMA configuration is need, an internal DMA for SDMMC Peripheral is used.
48         (##) On other devices, perform DMA Configuration if you need to use DMA process (HAL_MMC_ReadBlocks_DMA()
49              and HAL_MMC_WriteBlocks_DMA() APIs).
50             (+++) Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE();
51             (+++) Configure the DMA using the function HAL_DMA_Init() with predeclared and filled.
52         (##) NVIC configuration if you need to use interrupt process when using DMA transfer.
53             (+++) Configure the SDMMC and DMA interrupt priorities using function HAL_NVIC_SetPriority();
54                   DMA priority is superior to SDMMC's priority
55             (+++) Enable the NVIC DMA and SDMMC IRQs using function HAL_NVIC_EnableIRQ()
56             (+++) SDMMC interrupts are managed using the macros __HAL_MMC_ENABLE_IT()
57                   and __HAL_MMC_DISABLE_IT() inside the communication process.
58             (+++) SDMMC interrupts pending bits are managed using the macros __HAL_MMC_GET_IT()
59                   and __HAL_MMC_CLEAR_IT()
60         (##) NVIC configuration if you need to use interrupt process (HAL_MMC_ReadBlocks_IT()
61              and HAL_MMC_WriteBlocks_IT() APIs).
62             (+++) Configure the SDMMC interrupt priorities using function HAL_NVIC_SetPriority();
63             (+++) Enable the NVIC SDMMC IRQs using function HAL_NVIC_EnableIRQ()
64             (+++) SDMMC interrupts are managed using the macros __HAL_MMC_ENABLE_IT()
65                   and __HAL_MMC_DISABLE_IT() inside the communication process.
66             (+++) SDMMC interrupts pending bits are managed using the macros __HAL_MMC_GET_IT()
67                   and __HAL_MMC_CLEAR_IT()
68     (#) At this stage, you can perform MMC read/write/erase operations after MMC card initialization
69 
70 
71   *** MMC Card Initialization and configuration ***
72   ================================================
73   [..]
74     To initialize the MMC Card, use the HAL_MMC_Init() function. It Initializes
75     SDMMC Peripheral (STM32 side) and the MMC Card, and put it into StandBy State (Ready for data transfer).
76     This function provide the following operations:
77 
78     (#) Initialize the SDMMC peripheral interface with defaullt configuration.
79         The initialization process is done at 400KHz. You can change or adapt
80         this frequency by adjusting the "ClockDiv" field.
81         The MMC Card frequency (SDMMC_CK) is computed as follows:
82 
83            SDMMC_CK = SDMMCCLK / (2 * ClockDiv) on STM32L4Rx/STM32L4Sxx devices
84            SDMMC_CK = SDMMCCLK / (ClockDiv + 2) on other devices
85 
86         In initialization mode and according to the MMC Card standard,
87         make sure that the SDMMC_CK frequency doesn't exceed 400KHz.
88 
89         This phase of initialization is done through SDMMC_Init() and
90         SDMMC_PowerState_ON() SDMMC low level APIs.
91 
92     (#) Initialize the MMC card. The API used is HAL_MMC_InitCard().
93         This phase allows the card initialization and identification
94         and check the MMC Card type (Standard Capacity or High Capacity)
95         The initialization flow is compatible with MMC standard.
96 
97         This API (HAL_MMC_InitCard()) could be used also to reinitialize the card in case
98         of plug-off plug-in.
99 
100     (#) Configure the MMC Card Data transfer frequency. By Default, the card transfer
101         frequency by adjusting the "ClockDiv" field.
102         In transfer mode and according to the MMC Card standard, make sure that the
103         SDMMC_CK frequency doesn't exceed 25MHz and 100MHz in High-speed mode switch.
104 
105     (#) Select the corresponding MMC Card according to the address read with the step 2.
106 
107     (#) Configure the MMC Card in wide bus mode: 4-bits data.
108 
109   *** MMC Card Read operation ***
110   ==============================
111   [..]
112     (+) You can read from MMC card in polling mode by using function HAL_MMC_ReadBlocks().
113         This function support only 512-bytes block length (the block size should be
114         chosen as 512 bytes).
115         You can choose either one block read operation or multiple block read operation
116         by adjusting the "NumberOfBlocks" parameter.
117         After this, you have to ensure that the transfer is done correctly. The check is done
118         through HAL_MMC_GetCardState() function for MMC card state.
119 
120     (+) You can read from MMC card in DMA mode by using function HAL_MMC_ReadBlocks_DMA().
121         This function support only 512-bytes block length (the block size should be
122         chosen as 512 bytes).
123         You can choose either one block read operation or multiple block read operation
124         by adjusting the "NumberOfBlocks" parameter.
125         After this, you have to ensure that the transfer is done correctly. The check is done
126         through HAL_MMC_GetCardState() function for MMC card state.
127         You could also check the DMA transfer process through the MMC Rx interrupt event.
128 
129     (+) You can read from MMC card in Interrupt mode by using function HAL_MMC_ReadBlocks_IT().
130         This function allows the read of 512 bytes blocks.
131         You can choose either one block read operation or multiple block read operation
132         by adjusting the "NumberOfBlocks" parameter.
133         After this, you have to ensure that the transfer is done correctly. The check is done
134         through HAL_MMC_GetCardState() function for MMC card state.
135         You could also check the IT transfer process through the MMC Rx interrupt event.
136 
137   *** MMC Card Write operation ***
138   ===============================
139   [..]
140     (+) You can write to MMC card in polling mode by using function HAL_MMC_WriteBlocks().
141         This function support only 512-bytes block length (the block size should be
142         chosen as 512 bytes).
143         You can choose either one block read operation or multiple block read operation
144         by adjusting the "NumberOfBlocks" parameter.
145         After this, you have to ensure that the transfer is done correctly. The check is done
146         through HAL_MMC_GetCardState() function for MMC card state.
147 
148     (+) You can write to MMC card in DMA mode by using function HAL_MMC_WriteBlocks_DMA().
149         This function support only 512-bytes block length (the block size should be
150         chosen as 512 byte).
151         You can choose either one block read operation or multiple block read operation
152         by adjusting the "NumberOfBlocks" parameter.
153         After this, you have to ensure that the transfer is done correctly. The check is done
154         through HAL_MMC_GetCardState() function for MMC card state.
155         You could also check the DMA transfer process through the MMC Tx interrupt event.
156 
157     (+) You can write to MMC card in Interrupt mode by using function HAL_MMC_WriteBlocks_IT().
158         This function allows the read of 512 bytes blocks.
159         You can choose either one block read operation or multiple block read operation
160         by adjusting the "NumberOfBlocks" parameter.
161         After this, you have to ensure that the transfer is done correctly. The check is done
162         through HAL_MMC_GetCardState() function for MMC card state.
163         You could also check the IT transfer process through the MMC Tx interrupt event.
164 
165   *** MMC card information ***
166   ===========================
167   [..]
168     (+) To get MMC card information, you can use the function HAL_MMC_GetCardInfo().
169         It returns useful information about the MMC card such as block size, card type,
170         block number ...
171 
172   *** MMC card CSD register ***
173   ============================
174   [..]
175     (+) The HAL_MMC_GetCardCSD() API allows to get the parameters of the CSD register.
176         Some of the CSD parameters are useful for card initialization and identification.
177 
178   *** MMC card CID register ***
179   ============================
180   [..]
181     (+) The HAL_MMC_GetCardCID() API allows to get the parameters of the CID register.
182         Some of the CID parameters are useful for card initialization and identification.
183 
184   *** MMC HAL driver macros list ***
185   ==================================
186   [..]
187     Below the list of most used macros in MMC HAL driver.
188 
189     (+) __HAL_MMC_ENABLE : Enable the MMC device
190     (+) __HAL_MMC_DISABLE : Disable the MMC device
191     (+) __HAL_MMC_DMA_ENABLE: Enable the SDMMC DMA transfer
192     (+) __HAL_MMC_DMA_DISABLE: Disable the SDMMC DMA transfer
193     (+) __HAL_MMC_ENABLE_IT: Enable the MMC device interrupt
194     (+) __HAL_MMC_DISABLE_IT: Disable the MMC device interrupt
195     (+) __HAL_MMC_GET_FLAG:Check whether the specified MMC flag is set or not
196     (+) __HAL_MMC_CLEAR_FLAG: Clear the MMC's pending flags
197 
198   [..]
199     (@) You can refer to the MMC HAL driver header file for more useful macros
200 
201   *** Callback registration ***
202   =============================================
203   [..]
204     The compilation define USE_HAL_MMC_REGISTER_CALLBACKS when set to 1
205     allows the user to configure dynamically the driver callbacks.
206 
207     Use Functions HAL_MMC_RegisterCallback() to register a user callback,
208     it allows to register following callbacks:
209       (+) TxCpltCallback : callback when a transmission transfer is completed.
210       (+) RxCpltCallback : callback when a reception transfer is completed.
211       (+) ErrorCallback : callback when error occurs.
212       (+) AbortCpltCallback : callback when abort is completed.
213       (+) Read_DMADblBuf0CpltCallback : callback when the DMA reception of first buffer is completed.
214       (+) Read_DMADblBuf1CpltCallback : callback when the DMA reception of second buffer is completed.
215       (+) Write_DMADblBuf0CpltCallback : callback when the DMA transmission of first buffer is completed.
216       (+) Write_DMADblBuf1CpltCallback : callback when the DMA transmission of second buffer is completed.
217       (+) MspInitCallback    : MMC MspInit.
218       (+) MspDeInitCallback  : MMC MspDeInit.
219     This function takes as parameters the HAL peripheral handle, the Callback ID
220     and a pointer to the user callback function.
221 
222     Use function HAL_MMC_UnRegisterCallback() to reset a callback to the default
223     weak (surcharged) function. It allows to reset following callbacks:
224       (+) TxCpltCallback : callback when a transmission transfer is completed.
225       (+) RxCpltCallback : callback when a reception transfer is completed.
226       (+) ErrorCallback : callback when error occurs.
227       (+) AbortCpltCallback : callback when abort is completed.
228       (+) Read_DMADblBuf0CpltCallback : callback when the DMA reception of first buffer is completed.
229       (+) Read_DMADblBuf1CpltCallback : callback when the DMA reception of second buffer is completed.
230       (+) Write_DMADblBuf0CpltCallback : callback when the DMA transmission of first buffer is completed.
231       (+) Write_DMADblBuf1CpltCallback : callback when the DMA transmission of second buffer is completed.
232       (+) MspInitCallback    : MMC MspInit.
233       (+) MspDeInitCallback  : MMC MspDeInit.
234     This function) takes as parameters the HAL peripheral handle and the Callback ID.
235 
236     By default, after the HAL_MMC_Init and if the state is HAL_MMC_STATE_RESET
237     all callbacks are reset to the corresponding legacy weak (surcharged) functions.
238     Exception done for MspInit and MspDeInit callbacks that are respectively
239     reset to the legacy weak (surcharged) functions in the HAL_MMC_Init
240     and HAL_MMC_DeInit only when these callbacks are null (not registered beforehand).
241     If not, MspInit or MspDeInit are not null, the HAL_MMC_Init and HAL_MMC_DeInit
242     keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
243 
244     Callbacks can be registered/unregistered in READY state only.
245     Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
246     in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
247     during the Init/DeInit.
248     In that case first register the MspInit/MspDeInit user callbacks
249     using HAL_MMC_RegisterCallback before calling HAL_MMC_DeInit
250     or HAL_MMC_Init function.
251 
252     When The compilation define USE_HAL_MMC_REGISTER_CALLBACKS is set to 0 or
253     not defined, the callback registering feature is not available
254     and weak (surcharged) callbacks are used.
255 
256   @endverbatim
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 #if defined (VDD_VALUE) && (VDD_VALUE <= 1950U)
281 #define MMC_VOLTAGE_RANGE               EMMC_LOW_VOLTAGE_RANGE
282 
283 #define MMC_EXT_CSD_PWR_CL_26_INDEX     201
284 #define MMC_EXT_CSD_PWR_CL_52_INDEX     200
285 #define MMC_EXT_CSD_PWR_CL_DDR_52_INDEX 238
286 
287 #define MMC_EXT_CSD_PWR_CL_26_POS       8
288 #define MMC_EXT_CSD_PWR_CL_52_POS       0
289 #define MMC_EXT_CSD_PWR_CL_DDR_52_POS   16
290 #else
291 #define MMC_VOLTAGE_RANGE               EMMC_HIGH_VOLTAGE_RANGE
292 
293 #define MMC_EXT_CSD_PWR_CL_26_INDEX     203
294 #define MMC_EXT_CSD_PWR_CL_52_INDEX     202
295 #define MMC_EXT_CSD_PWR_CL_DDR_52_INDEX 239
296 
297 #define MMC_EXT_CSD_PWR_CL_26_POS       24
298 #define MMC_EXT_CSD_PWR_CL_52_POS       16
299 #define MMC_EXT_CSD_PWR_CL_DDR_52_POS   24
300 #endif
301 
302 #define MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_INDEX 216
303 #define MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_POS   0
304 #define MMC_EXT_CSD_S_A_TIMEOUT_INDEX             217
305 #define MMC_EXT_CSD_S_A_TIMEOUT_POS               8
306 
307 /* Frequencies used in the driver for clock divider calculation */
308 #define MMC_INIT_FREQ                   400000U   /* Initalization phase : 400 kHz max */
309 #define MMC_HIGH_SPEED_FREQ             52000000U /* High speed phase : 52 MHz max */
310 /**
311   * @}
312   */
313 
314 /* Private macro -------------------------------------------------------------*/
315 /* Private variables ---------------------------------------------------------*/
316 /* Private function prototypes -----------------------------------------------*/
317 /* Private functions ---------------------------------------------------------*/
318 /** @defgroup MMC_Private_Functions MMC Private Functions
319   * @{
320   */
321 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc);
322 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc);
323 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus);
324 static void     MMC_PowerOFF(MMC_HandleTypeDef *hmmc);
325 static void     MMC_Write_IT(MMC_HandleTypeDef *hmmc);
326 static void     MMC_Read_IT(MMC_HandleTypeDef *hmmc);
327 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
328 static void     MMC_DMATransmitCplt(DMA_HandleTypeDef *hdma);
329 static void     MMC_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
330 static void     MMC_DMAError(DMA_HandleTypeDef *hdma);
331 static void     MMC_DMATxAbort(DMA_HandleTypeDef *hdma);
332 static void     MMC_DMARxAbort(DMA_HandleTypeDef *hdma);
333 #else
334 static uint32_t MMC_HighSpeed(MMC_HandleTypeDef *hmmc, FunctionalState state);
335 static uint32_t MMC_DDR_Mode(MMC_HandleTypeDef *hmmc, FunctionalState state);
336 #endif
337 static HAL_StatusTypeDef MMC_ReadExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pFieldData, uint16_t FieldIndex, uint32_t Timeout);
338 static uint32_t MMC_PwrClassUpdate(MMC_HandleTypeDef *hmmc, uint32_t Wide, uint32_t Speed);
339 
340 /**
341   * @}
342   */
343 /* Exported functions --------------------------------------------------------*/
344 /** @defgroup MMC_Exported_Functions MMC Exported Functions
345   * @{
346   */
347 
348 /** @defgroup MMC_Exported_Functions_Group1 MMC_Exported_Functions_Group1
349  *  @brief   Initialization and de-initialization functions
350  *
351 @verbatim
352   ==============================================================================
353           ##### Initialization and de-initialization functions #####
354   ==============================================================================
355   [..]
356     This section provides functions allowing to initialize/de-initialize the MMC
357     card device to be ready for use.
358 
359 @endverbatim
360   * @{
361   */
362 
363 /**
364   * @brief  Initializes the MMC according to the specified parameters in the
365             MMC_HandleTypeDef and create the associated handle.
366   * @param  hmmc Pointer to the MMC handle
367   * @retval HAL status
368   */
HAL_MMC_Init(MMC_HandleTypeDef * hmmc)369 HAL_StatusTypeDef HAL_MMC_Init(MMC_HandleTypeDef *hmmc)
370 {
371   /* Check the MMC handle allocation */
372   if(hmmc == NULL)
373   {
374     return HAL_ERROR;
375   }
376 
377   /* Check the parameters */
378   assert_param(IS_SDMMC_ALL_INSTANCE(hmmc->Instance));
379   assert_param(IS_SDMMC_CLOCK_EDGE(hmmc->Init.ClockEdge));
380 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
381   assert_param(IS_SDMMC_CLOCK_BYPASS(hmmc->Init.ClockBypass));
382 #endif
383   assert_param(IS_SDMMC_CLOCK_POWER_SAVE(hmmc->Init.ClockPowerSave));
384   assert_param(IS_SDMMC_BUS_WIDE(hmmc->Init.BusWide));
385   assert_param(IS_SDMMC_HARDWARE_FLOW_CONTROL(hmmc->Init.HardwareFlowControl));
386   assert_param(IS_SDMMC_CLKDIV(hmmc->Init.ClockDiv));
387 
388   if(hmmc->State == HAL_MMC_STATE_RESET)
389   {
390     /* Allocate lock resource and initialize it */
391     hmmc->Lock = HAL_UNLOCKED;
392 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
393     /* Reset Callback pointers in HAL_MMC_STATE_RESET only */
394     hmmc->TxCpltCallback    = HAL_MMC_TxCpltCallback;
395     hmmc->RxCpltCallback    = HAL_MMC_RxCpltCallback;
396     hmmc->ErrorCallback     = HAL_MMC_ErrorCallback;
397     hmmc->AbortCpltCallback = HAL_MMC_AbortCallback;
398 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
399     hmmc->Read_DMADblBuf0CpltCallback = HAL_MMCEx_Read_DMADoubleBuffer0CpltCallback;
400     hmmc->Read_DMADblBuf1CpltCallback = HAL_MMCEx_Read_DMADoubleBuffer1CpltCallback;
401     hmmc->Write_DMADblBuf0CpltCallback = HAL_MMCEx_Write_DMADoubleBuffer0CpltCallback;
402     hmmc->Write_DMADblBuf1CpltCallback = HAL_MMCEx_Write_DMADoubleBuffer1CpltCallback;
403 #endif
404 
405     if(hmmc->MspInitCallback == NULL)
406     {
407       hmmc->MspInitCallback = HAL_MMC_MspInit;
408     }
409 
410     /* Init the low level hardware */
411     hmmc->MspInitCallback(hmmc);
412 #else
413     /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
414     HAL_MMC_MspInit(hmmc);
415 #endif
416   }
417 
418   hmmc->State = HAL_MMC_STATE_BUSY;
419 
420   /* Initialize the Card parameters */
421   if(HAL_MMC_InitCard(hmmc) == HAL_ERROR)
422   {
423     return HAL_ERROR;
424   }
425 
426   /* Initialize the error code */
427   hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
428 
429   /* Initialize the MMC operation */
430   hmmc->Context = MMC_CONTEXT_NONE;
431 
432   /* Initialize the MMC state */
433   hmmc->State = HAL_MMC_STATE_READY;
434 
435   /* Configure bus width */
436   if (hmmc->Init.BusWide != SDMMC_BUS_WIDE_1B)
437   {
438     if (HAL_MMC_ConfigWideBusOperation(hmmc, hmmc->Init.BusWide) != HAL_OK)
439     {
440       return HAL_ERROR;
441     }
442   }
443 
444   return HAL_OK;
445 }
446 
447 /**
448   * @brief  Initializes the MMC Card.
449   * @param  hmmc Pointer to MMC handle
450   * @note   This function initializes the MMC card. It could be used when a card
451             re-initialization is needed.
452   * @retval HAL status
453   */
HAL_MMC_InitCard(MMC_HandleTypeDef * hmmc)454 HAL_StatusTypeDef HAL_MMC_InitCard(MMC_HandleTypeDef *hmmc)
455 {
456   uint32_t errorstate;
457   MMC_InitTypeDef Init;
458   uint32_t sdmmc_clk;
459 
460   /* Default SDMMC peripheral configuration for MMC card initialization */
461   Init.ClockEdge           = SDMMC_CLOCK_EDGE_RISING;
462 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
463   Init.ClockBypass         = SDMMC_CLOCK_BYPASS_DISABLE;
464 #endif
465   Init.ClockPowerSave      = SDMMC_CLOCK_POWER_SAVE_DISABLE;
466   Init.BusWide             = SDMMC_BUS_WIDE_1B;
467   Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
468 
469   /* Init Clock should be less or equal to 400Khz*/
470   sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC1);
471   if (sdmmc_clk == 0U)
472   {
473       hmmc->State = HAL_MMC_STATE_READY;
474       hmmc->ErrorCode = SDMMC_ERROR_INVALID_PARAMETER;
475       return HAL_ERROR;
476   }
477 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
478   Init.ClockDiv = ((sdmmc_clk/MMC_INIT_FREQ) - 2U);
479 #else
480   Init.ClockDiv = sdmmc_clk/(2U*MMC_INIT_FREQ);
481   Init.Transceiver = SDMMC_TRANSCEIVER_DISABLE;
482 #endif
483 
484   /* Initialize SDMMC peripheral interface with default configuration */
485   (void)SDMMC_Init(hmmc->Instance, Init);
486 
487 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
488   /* Disable SDMMC Clock */
489   __HAL_MMC_DISABLE(hmmc);
490 #endif
491 
492   /* Set Power State to ON */
493   (void)SDMMC_PowerState_ON(hmmc->Instance);
494 
495 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
496   /* Enable MMC Clock */
497   __HAL_MMC_ENABLE(hmmc);
498 #endif
499 
500   /* wait 74 Cycles: required power up waiting time before starting
501      the MMC initialization sequence */
502 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
503   sdmmc_clk = sdmmc_clk/(Init.ClockDiv + 2U);
504 #else
505   sdmmc_clk = sdmmc_clk/(2U*Init.ClockDiv);
506 #endif
507   HAL_Delay(1U+ (74U*1000U/(sdmmc_clk)));
508 
509   /* Identify card operating voltage */
510   errorstate = MMC_PowerON(hmmc);
511   if(errorstate != HAL_MMC_ERROR_NONE)
512   {
513     hmmc->State = HAL_MMC_STATE_READY;
514     hmmc->ErrorCode |= errorstate;
515     return HAL_ERROR;
516   }
517 
518   /* Card initialization */
519   errorstate = MMC_InitCard(hmmc);
520   if(errorstate != HAL_MMC_ERROR_NONE)
521   {
522     hmmc->State = HAL_MMC_STATE_READY;
523     hmmc->ErrorCode |= errorstate;
524     return HAL_ERROR;
525   }
526 
527   /* Set Block Size for Card */
528   errorstate = SDMMC_CmdBlockLength(hmmc->Instance, MMC_BLOCKSIZE);
529   if(errorstate != HAL_MMC_ERROR_NONE)
530   {
531     /* Clear all the static flags */
532     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
533     hmmc->ErrorCode |= errorstate;
534     hmmc->State = HAL_MMC_STATE_READY;
535     return HAL_ERROR;
536   }
537 
538   return HAL_OK;
539 }
540 
541 /**
542   * @brief  De-Initializes the MMC card.
543   * @param  hmmc Pointer to MMC handle
544   * @retval HAL status
545   */
HAL_MMC_DeInit(MMC_HandleTypeDef * hmmc)546 HAL_StatusTypeDef HAL_MMC_DeInit(MMC_HandleTypeDef *hmmc)
547 {
548   /* Check the MMC handle allocation */
549   if(hmmc == NULL)
550   {
551     return HAL_ERROR;
552   }
553 
554   /* Check the parameters */
555   assert_param(IS_SDMMC_ALL_INSTANCE(hmmc->Instance));
556 
557   hmmc->State = HAL_MMC_STATE_BUSY;
558 
559   /* Set MMC power state to off */
560   MMC_PowerOFF(hmmc);
561 
562 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
563   if(hmmc->MspDeInitCallback == NULL)
564   {
565     hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
566   }
567 
568   /* DeInit the low level hardware */
569   hmmc->MspDeInitCallback(hmmc);
570 #else
571   /* De-Initialize the MSP layer */
572   HAL_MMC_MspDeInit(hmmc);
573 #endif
574 
575   hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
576   hmmc->State = HAL_MMC_STATE_RESET;
577 
578   return HAL_OK;
579 }
580 
581 
582 /**
583   * @brief  Initializes the MMC MSP.
584   * @param  hmmc Pointer to MMC handle
585   * @retval None
586   */
HAL_MMC_MspInit(MMC_HandleTypeDef * hmmc)587 __weak void HAL_MMC_MspInit(MMC_HandleTypeDef *hmmc)
588 {
589   /* Prevent unused argument(s) compilation warning */
590   UNUSED(hmmc);
591 
592   /* NOTE : This function Should not be modified, when the callback is needed,
593             the HAL_MMC_MspInit could be implemented in the user file
594    */
595 }
596 
597 /**
598   * @brief  De-Initialize MMC MSP.
599   * @param  hmmc Pointer to MMC handle
600   * @retval None
601   */
HAL_MMC_MspDeInit(MMC_HandleTypeDef * hmmc)602 __weak void HAL_MMC_MspDeInit(MMC_HandleTypeDef *hmmc)
603 {
604   /* Prevent unused argument(s) compilation warning */
605   UNUSED(hmmc);
606 
607   /* NOTE : This function Should not be modified, when the callback is needed,
608             the HAL_MMC_MspDeInit could be implemented in the user file
609    */
610 }
611 
612 /**
613   * @}
614   */
615 
616 /** @addtogroup MMC_Exported_Functions_Group2
617  *  @brief   Data transfer functions
618  *
619 @verbatim
620   ==============================================================================
621                         ##### IO operation functions #####
622   ==============================================================================
623   [..]
624     This subsection provides a set of functions allowing to manage the data
625     transfer from/to MMC card.
626 
627 @endverbatim
628   * @{
629   */
630 
631 /**
632   * @brief  Reads block(s) from a specified address in a card. The Data transfer
633   *         is managed by polling mode.
634   * @note   This API should be followed by a check on the card state through
635   *         HAL_MMC_GetCardState().
636   * @param  hmmc Pointer to MMC handle
637   * @param  pData pointer to the buffer that will contain the received data
638   * @param  BlockAdd Block Address from where data is to be read
639   * @param  NumberOfBlocks Number of MMC blocks to read
640   * @param  Timeout Specify timeout value
641   * @retval HAL status
642   */
HAL_MMC_ReadBlocks(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks,uint32_t Timeout)643 HAL_StatusTypeDef HAL_MMC_ReadBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
644 {
645   SDMMC_DataInitTypeDef config;
646   uint32_t errorstate;
647   uint32_t tickstart = HAL_GetTick();
648   uint32_t count, data, dataremaining;
649   uint32_t add = BlockAdd;
650   uint8_t *tempbuff = pData;
651 
652   if(NULL == pData)
653   {
654     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
655     return HAL_ERROR;
656   }
657 
658   if(hmmc->State == HAL_MMC_STATE_READY)
659   {
660     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
661 
662     if((add + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
663     {
664       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
665       return HAL_ERROR;
666     }
667 
668     hmmc->State = HAL_MMC_STATE_BUSY;
669 
670     /* Initialize data control register */
671     hmmc->Instance->DCTRL = 0U;
672 
673     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
674     {
675       add *= 512U;
676     }
677 
678     /* Configure the MMC DPSM (Data Path State Machine) */
679     config.DataTimeOut   = SDMMC_DATATIMEOUT;
680     config.DataLength    = NumberOfBlocks * MMC_BLOCKSIZE;
681     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
682     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
683     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
684 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
685     config.DPSM          = SDMMC_DPSM_ENABLE;
686 #else
687     config.DPSM          = SDMMC_DPSM_DISABLE;
688 #endif
689     (void)SDMMC_ConfigData(hmmc->Instance, &config);
690 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
691     __SDMMC_CMDTRANS_ENABLE( hmmc->Instance);
692 #endif
693 
694     /* Read block(s) in polling mode */
695     if(NumberOfBlocks > 1U)
696     {
697       hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
698 
699       /* Read Multi Block command */
700       errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
701     }
702     else
703     {
704       hmmc->Context = MMC_CONTEXT_READ_SINGLE_BLOCK;
705 
706       /* Read Single Block command */
707       errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
708     }
709     if(errorstate != HAL_MMC_ERROR_NONE)
710     {
711       /* Clear all the static flags */
712       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
713       hmmc->ErrorCode |= errorstate;
714       hmmc->State = HAL_MMC_STATE_READY;
715       hmmc->Context = MMC_CONTEXT_NONE;
716       return HAL_ERROR;
717     }
718 
719     /* Poll on SDMMC flags */
720     dataremaining = config.DataLength;
721     while(!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
722     {
723       if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining > 0U))
724       {
725         /* Read data from SDMMC Rx FIFO */
726         for(count = 0U; count < 8U; count++)
727         {
728           data = SDMMC_ReadFIFO(hmmc->Instance);
729           *tempbuff = (uint8_t)(data & 0xFFU);
730           tempbuff++;
731           dataremaining--;
732           *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
733           tempbuff++;
734           dataremaining--;
735           *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
736           tempbuff++;
737           dataremaining--;
738           *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
739           tempbuff++;
740           dataremaining--;
741         }
742       }
743 
744       if(((HAL_GetTick()-tickstart) >=  Timeout) || (Timeout == 0U))
745       {
746         /* Clear all the static flags */
747         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
748         hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
749         hmmc->State= HAL_MMC_STATE_READY;
750         hmmc->Context = MMC_CONTEXT_NONE;
751         return HAL_TIMEOUT;
752       }
753     }
754 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
755     __SDMMC_CMDTRANS_DISABLE( hmmc->Instance);
756 #endif
757 
758     /* Send stop transmission command in case of multiblock read */
759     if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U))
760     {
761       /* Send stop transmission command */
762       errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
763       if(errorstate != HAL_MMC_ERROR_NONE)
764       {
765         /* Clear all the static flags */
766         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
767         hmmc->ErrorCode |= errorstate;
768         hmmc->State = HAL_MMC_STATE_READY;
769         hmmc->Context = MMC_CONTEXT_NONE;
770         return HAL_ERROR;
771       }
772     }
773 
774     /* Get error state */
775     if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
776     {
777       /* Clear all the static flags */
778       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
779       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
780       hmmc->State = HAL_MMC_STATE_READY;
781       hmmc->Context = MMC_CONTEXT_NONE;
782       return HAL_ERROR;
783     }
784     else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
785     {
786       /* Clear all the static flags */
787       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
788       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
789       hmmc->State = HAL_MMC_STATE_READY;
790       hmmc->Context = MMC_CONTEXT_NONE;
791       return HAL_ERROR;
792     }
793     else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR))
794     {
795       /* Clear all the static flags */
796       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
797       hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
798       hmmc->State = HAL_MMC_STATE_READY;
799       hmmc->Context = MMC_CONTEXT_NONE;
800       return HAL_ERROR;
801     }
802     else
803     {
804       /* Nothing to do */
805     }
806 
807 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
808     /* Empty FIFO if there is still any data */
809     while ((__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXDAVL)) && (dataremaining > 0U))
810     {
811       data = SDMMC_ReadFIFO(hmmc->Instance);
812       *tempbuff = (uint8_t)(data & 0xFFU);
813       tempbuff++;
814       dataremaining--;
815       *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
816       tempbuff++;
817       dataremaining--;
818       *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
819       tempbuff++;
820       dataremaining--;
821       *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
822       tempbuff++;
823       dataremaining--;
824 
825       if(((HAL_GetTick()-tickstart) >=  Timeout) || (Timeout == 0U))
826       {
827         /* Clear all the static flags */
828         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
829         hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
830         hmmc->State= HAL_MMC_STATE_READY;
831         hmmc->Context = MMC_CONTEXT_NONE;
832         return HAL_ERROR;
833       }
834     }
835 #endif
836 
837     /* Clear all the static flags */
838     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
839 
840     hmmc->State = HAL_MMC_STATE_READY;
841 
842     return HAL_OK;
843   }
844   else
845   {
846     hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
847     return HAL_ERROR;
848   }
849 }
850 
851 /**
852   * @brief  Allows to write block(s) to a specified address in a card. The Data
853   *         transfer is managed by polling mode.
854   * @note   This API should be followed by a check on the card state through
855   *         HAL_MMC_GetCardState().
856   * @param  hmmc Pointer to MMC handle
857   * @param  pData pointer to the buffer that will contain the data to transmit
858   * @param  BlockAdd Block Address where data will be written
859   * @param  NumberOfBlocks Number of MMC blocks to write
860   * @param  Timeout Specify timeout value
861   * @retval HAL status
862   */
HAL_MMC_WriteBlocks(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks,uint32_t Timeout)863 HAL_StatusTypeDef HAL_MMC_WriteBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
864 {
865   SDMMC_DataInitTypeDef config;
866   uint32_t errorstate;
867   uint32_t tickstart = HAL_GetTick();
868   uint32_t count, data, dataremaining;
869   uint32_t add = BlockAdd;
870   uint8_t *tempbuff = pData;
871 
872   if(NULL == pData)
873   {
874     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
875     return HAL_ERROR;
876   }
877 
878   if(hmmc->State == HAL_MMC_STATE_READY)
879   {
880     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
881 
882     if((add + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
883     {
884       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
885       return HAL_ERROR;
886     }
887 
888     hmmc->State = HAL_MMC_STATE_BUSY;
889 
890     /* Initialize data control register */
891     hmmc->Instance->DCTRL = 0U;
892 
893     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
894     {
895       add *= 512U;
896     }
897 
898 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
899     /* Configure the MMC DPSM (Data Path State Machine) */
900     config.DataTimeOut   = SDMMC_DATATIMEOUT;
901     config.DataLength    = NumberOfBlocks * MMC_BLOCKSIZE;
902     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
903     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
904     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
905     config.DPSM          = SDMMC_DPSM_DISABLE;
906     (void)SDMMC_ConfigData(hmmc->Instance, &config);
907     __SDMMC_CMDTRANS_ENABLE( hmmc->Instance);
908 #endif
909 
910     /* Write Blocks in Polling mode */
911     if(NumberOfBlocks > 1U)
912     {
913       hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
914 
915       /* Write Multi Block command */
916       errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
917     }
918     else
919     {
920       hmmc->Context = MMC_CONTEXT_WRITE_SINGLE_BLOCK;
921 
922       /* Write Single Block command */
923       errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
924     }
925     if(errorstate != HAL_MMC_ERROR_NONE)
926     {
927       /* Clear all the static flags */
928       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
929       hmmc->ErrorCode |= errorstate;
930       hmmc->State = HAL_MMC_STATE_READY;
931       hmmc->Context = MMC_CONTEXT_NONE;
932       return HAL_ERROR;
933     }
934 
935 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
936     /* Configure the MMC DPSM (Data Path State Machine) */
937     config.DataTimeOut   = SDMMC_DATATIMEOUT;
938     config.DataLength    = NumberOfBlocks * MMC_BLOCKSIZE;
939     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
940     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
941     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
942     config.DPSM          = SDMMC_DPSM_ENABLE;
943     (void)SDMMC_ConfigData(hmmc->Instance, &config);
944 #endif
945 
946     /* Write block(s) in polling mode */
947     dataremaining = config.DataLength;
948     while(!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
949     {
950       if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining > 0U))
951       {
952         /* Write data to SDMMC Tx FIFO */
953         for(count = 0U; count < 8U; count++)
954         {
955           data = (uint32_t)(*tempbuff);
956           tempbuff++;
957           dataremaining--;
958           data |= ((uint32_t)(*tempbuff) << 8U);
959           tempbuff++;
960           dataremaining--;
961           data |= ((uint32_t)(*tempbuff) << 16U);
962           tempbuff++;
963           dataremaining--;
964           data |= ((uint32_t)(*tempbuff) << 24U);
965           tempbuff++;
966           dataremaining--;
967           (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
968         }
969       }
970 
971       if(((HAL_GetTick()-tickstart) >=  Timeout) || (Timeout == 0U))
972       {
973         /* Clear all the static flags */
974         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
975         hmmc->ErrorCode |= errorstate;
976         hmmc->State = HAL_MMC_STATE_READY;
977         hmmc->Context = MMC_CONTEXT_NONE;
978         return HAL_TIMEOUT;
979       }
980     }
981 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
982     __SDMMC_CMDTRANS_DISABLE( hmmc->Instance);
983 #endif
984 
985     /* Send stop transmission command in case of multiblock write */
986     if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U))
987     {
988       /* Send stop transmission command */
989       errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
990       if(errorstate != HAL_MMC_ERROR_NONE)
991       {
992         /* Clear all the static flags */
993         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
994         hmmc->ErrorCode |= errorstate;
995         hmmc->State = HAL_MMC_STATE_READY;
996         hmmc->Context = MMC_CONTEXT_NONE;
997         return HAL_ERROR;
998       }
999     }
1000 
1001     /* Get error state */
1002     if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
1003     {
1004       /* Clear all the static flags */
1005       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1006       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
1007       hmmc->State = HAL_MMC_STATE_READY;
1008       hmmc->Context = MMC_CONTEXT_NONE;
1009       return HAL_ERROR;
1010     }
1011     else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
1012     {
1013       /* Clear all the static flags */
1014       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1015       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
1016       hmmc->State = HAL_MMC_STATE_READY;
1017       hmmc->Context = MMC_CONTEXT_NONE;
1018       return HAL_ERROR;
1019     }
1020     else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
1021     {
1022       /* Clear all the static flags */
1023       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1024       hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
1025       hmmc->State = HAL_MMC_STATE_READY;
1026       hmmc->Context = MMC_CONTEXT_NONE;
1027       return HAL_ERROR;
1028     }
1029     else
1030     {
1031       /* Nothing to do */
1032     }
1033 
1034     /* Clear all the static flags */
1035     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
1036 
1037     hmmc->State = HAL_MMC_STATE_READY;
1038 
1039     return HAL_OK;
1040   }
1041   else
1042   {
1043     hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
1044     return HAL_ERROR;
1045   }
1046 }
1047 
1048 /**
1049   * @brief  Reads block(s) from a specified address in a card. The Data transfer
1050   *         is managed in interrupt mode.
1051   * @note   This API should be followed by a check on the card state through
1052   *         HAL_MMC_GetCardState().
1053   * @note   You could also check the IT transfer process through the MMC Rx
1054   *         interrupt event.
1055   * @param  hmmc Pointer to MMC handle
1056   * @param  pData Pointer to the buffer that will contain the received data
1057   * @param  BlockAdd Block Address from where data is to be read
1058   * @param  NumberOfBlocks Number of blocks to read.
1059   * @retval HAL status
1060   */
HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)1061 HAL_StatusTypeDef HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
1062 {
1063   SDMMC_DataInitTypeDef config;
1064   uint32_t errorstate;
1065   uint32_t add = BlockAdd;
1066 
1067   if(NULL == pData)
1068   {
1069     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1070     return HAL_ERROR;
1071   }
1072 
1073   if(hmmc->State == HAL_MMC_STATE_READY)
1074   {
1075     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1076 
1077     if((add + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1078     {
1079       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1080       return HAL_ERROR;
1081     }
1082 
1083     hmmc->State = HAL_MMC_STATE_BUSY;
1084 
1085     /* Initialize data control register */
1086     hmmc->Instance->DCTRL = 0U;
1087 
1088     hmmc->pRxBuffPtr = pData;
1089     hmmc->RxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1090 
1091     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1092     {
1093       add *= 512U;
1094     }
1095 
1096     /* Configure the MMC DPSM (Data Path State Machine) */
1097     config.DataTimeOut   = SDMMC_DATATIMEOUT;
1098     config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
1099     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1100     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
1101     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
1102 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
1103     config.DPSM          = SDMMC_DPSM_ENABLE;
1104 #else
1105     config.DPSM          = SDMMC_DPSM_DISABLE;
1106 #endif
1107     (void)SDMMC_ConfigData(hmmc->Instance, &config);
1108 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
1109     __SDMMC_CMDTRANS_ENABLE( hmmc->Instance);
1110 #endif
1111     /* Read Blocks in IT mode */
1112     if(NumberOfBlocks > 1U)
1113     {
1114       hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_IT);
1115 
1116       /* Read Multi Block command */
1117       errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
1118     }
1119     else
1120     {
1121       hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_IT);
1122 
1123       /* Read Single Block command */
1124       errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
1125     }
1126 
1127     if(errorstate != HAL_MMC_ERROR_NONE)
1128     {
1129       /* Clear all the static flags */
1130       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1131       hmmc->ErrorCode |= errorstate;
1132       hmmc->State = HAL_MMC_STATE_READY;
1133       hmmc->Context = MMC_CONTEXT_NONE;
1134       return HAL_ERROR;
1135     }
1136 
1137     __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND | SDMMC_FLAG_RXFIFOHF));
1138 
1139     return HAL_OK;
1140   }
1141   else
1142   {
1143     return HAL_BUSY;
1144   }
1145 }
1146 
1147 /**
1148   * @brief  Writes block(s) to a specified address in a card. The Data transfer
1149   *         is managed in interrupt mode.
1150   * @note   This API should be followed by a check on the card state through
1151   *         HAL_MMC_GetCardState().
1152   * @note   You could also check the IT transfer process through the MMC Tx
1153   *         interrupt event.
1154   * @param  hmmc Pointer to MMC handle
1155   * @param  pData Pointer to the buffer that will contain the data to transmit
1156   * @param  BlockAdd Block Address where data will be written
1157   * @param  NumberOfBlocks Number of blocks to write
1158   * @retval HAL status
1159   */
HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)1160 HAL_StatusTypeDef HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
1161 {
1162   SDMMC_DataInitTypeDef config;
1163   uint32_t errorstate;
1164   uint32_t add = BlockAdd;
1165 
1166   if(NULL == pData)
1167   {
1168     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1169     return HAL_ERROR;
1170   }
1171 
1172   if(hmmc->State == HAL_MMC_STATE_READY)
1173   {
1174     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1175 
1176     if((add + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1177     {
1178       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1179       return HAL_ERROR;
1180     }
1181 
1182     hmmc->State = HAL_MMC_STATE_BUSY;
1183 
1184     /* Initialize data control register */
1185     hmmc->Instance->DCTRL = 0U;
1186 
1187     hmmc->pTxBuffPtr = pData;
1188     hmmc->TxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1189 
1190     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1191     {
1192       add *= 512U;
1193     }
1194 
1195 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
1196     /* Configure the MMC DPSM (Data Path State Machine) */
1197     config.DataTimeOut   = SDMMC_DATATIMEOUT;
1198     config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
1199     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1200     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
1201     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
1202     config.DPSM          = SDMMC_DPSM_DISABLE;
1203     (void)SDMMC_ConfigData(hmmc->Instance, &config);
1204 
1205     __SDMMC_CMDTRANS_ENABLE( hmmc->Instance);
1206 #endif
1207 
1208     /* Write Blocks in Polling mode */
1209     if(NumberOfBlocks > 1U)
1210     {
1211       hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK| MMC_CONTEXT_IT);
1212 
1213       /* Write Multi Block command */
1214       errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
1215     }
1216     else
1217     {
1218       hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_IT);
1219 
1220       /* Write Single Block command */
1221       errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
1222     }
1223     if(errorstate != HAL_MMC_ERROR_NONE)
1224     {
1225       /* Clear all the static flags */
1226       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1227       hmmc->ErrorCode |= errorstate;
1228       hmmc->State = HAL_MMC_STATE_READY;
1229       hmmc->Context = MMC_CONTEXT_NONE;
1230       return HAL_ERROR;
1231     }
1232 
1233 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
1234     /* Configure the MMC DPSM (Data Path State Machine) */
1235     config.DataTimeOut   = SDMMC_DATATIMEOUT;
1236     config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
1237     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1238     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
1239     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
1240     config.DPSM          = SDMMC_DPSM_ENABLE;
1241     (void)SDMMC_ConfigData(hmmc->Instance, &config);
1242 #endif
1243 
1244     /* Enable transfer interrupts */
1245     __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND | SDMMC_FLAG_TXFIFOHE));
1246 
1247     return HAL_OK;
1248   }
1249   else
1250   {
1251     return HAL_BUSY;
1252   }
1253 }
1254 
1255 /**
1256   * @brief  Reads block(s) from a specified address in a card. The Data transfer
1257   *         is managed by DMA mode.
1258   * @note   This API should be followed by a check on the card state through
1259   *         HAL_MMC_GetCardState().
1260   * @note   You could also check the DMA transfer process through the MMC Rx
1261   *         interrupt event.
1262   * @param  hmmc Pointer MMC handle
1263   * @param  pData Pointer to the buffer that will contain the received data
1264   * @param  BlockAdd Block Address from where data is to be read
1265   * @param  NumberOfBlocks Number of blocks to read.
1266   * @retval HAL status
1267   */
HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)1268 HAL_StatusTypeDef HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
1269 {
1270   SDMMC_DataInitTypeDef config;
1271   uint32_t errorstate;
1272   uint32_t add = BlockAdd;
1273 
1274   if(NULL == pData)
1275   {
1276     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1277     return HAL_ERROR;
1278   }
1279 
1280   if(hmmc->State == HAL_MMC_STATE_READY)
1281   {
1282     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1283 
1284     if((add + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1285     {
1286       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1287       return HAL_ERROR;
1288     }
1289 
1290     hmmc->State = HAL_MMC_STATE_BUSY;
1291 
1292     /* Initialize data control register */
1293     hmmc->Instance->DCTRL = 0U;
1294 
1295 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
1296     /* Set the DMA transfer complete callback */
1297     hmmc->hdmarx->XferCpltCallback = MMC_DMAReceiveCplt;
1298 
1299     /* Set the DMA error callback */
1300     hmmc->hdmarx->XferErrorCallback = MMC_DMAError;
1301 
1302     /* Set the DMA Abort callback */
1303     hmmc->hdmarx->XferAbortCallback = NULL;
1304 
1305 #else
1306     hmmc->pRxBuffPtr = pData;
1307     hmmc->RxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1308 #endif
1309 
1310     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1311     {
1312       add *= 512U;
1313     }
1314 
1315 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
1316     /* Configure the MMC DPSM (Data Path State Machine) */
1317     config.DataTimeOut   = SDMMC_DATATIMEOUT;
1318     config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
1319     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1320     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
1321     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
1322     config.DPSM          = SDMMC_DPSM_DISABLE;
1323     (void)SDMMC_ConfigData(hmmc->Instance, &config);
1324 
1325     __SDMMC_CMDTRANS_ENABLE( hmmc->Instance);
1326     hmmc->Instance->IDMABASE0 = (uint32_t) pData ;
1327     hmmc->Instance->IDMACTRL  = SDMMC_ENABLE_IDMA_SINGLE_BUFF;
1328 #else
1329     /* Enable the DMA Channel */
1330     if(HAL_DMA_Start_IT(hmmc->hdmarx, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)pData, (uint32_t)(MMC_BLOCKSIZE * NumberOfBlocks)/4) != HAL_OK)
1331     {
1332       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1333       hmmc->ErrorCode = HAL_MMC_ERROR_DMA;
1334       hmmc->State = HAL_MMC_STATE_READY;
1335       return HAL_ERROR;
1336     }
1337     else
1338     {
1339       /* Enable MMC DMA transfer */
1340       __HAL_MMC_DMA_ENABLE(hmmc);
1341 
1342       /* Configure the MMC DPSM (Data Path State Machine) */
1343       config.DataTimeOut   = SDMMC_DATATIMEOUT;
1344       config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
1345       config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1346       config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
1347       config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
1348       config.DPSM          = SDMMC_DPSM_ENABLE;
1349       (void)SDMMC_ConfigData(hmmc->Instance, &config);
1350 #endif
1351 
1352       /* Read Blocks in DMA mode */
1353       if(NumberOfBlocks > 1U)
1354       {
1355         hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
1356 
1357         /* Read Multi Block command */
1358         errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
1359       }
1360       else
1361       {
1362         hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_DMA);
1363 
1364         /* Read Single Block command */
1365         errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
1366       }
1367       if(errorstate != HAL_MMC_ERROR_NONE)
1368       {
1369         /* Clear all the static flags */
1370         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1371         hmmc->ErrorCode = errorstate;
1372         hmmc->State = HAL_MMC_STATE_READY;
1373         hmmc->Context = MMC_CONTEXT_NONE;
1374         return HAL_ERROR;
1375       }
1376 
1377       /* Enable transfer interrupts */
1378       __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND));
1379 
1380       return HAL_OK;
1381 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
1382     }
1383 #endif
1384   }
1385   else
1386   {
1387     return HAL_BUSY;
1388   }
1389 }
1390 
1391 /**
1392   * @brief  Writes block(s) to a specified address in a card. The Data transfer
1393   *         is managed by DMA mode.
1394   * @note   This API should be followed by a check on the card state through
1395   *         HAL_MMC_GetCardState().
1396   * @note   You could also check the DMA transfer process through the MMC Tx
1397   *         interrupt event.
1398   * @param  hmmc Pointer to MMC handle
1399   * @param  pData Pointer to the buffer that will contain the data to transmit
1400   * @param  BlockAdd Block Address where data will be written
1401   * @param  NumberOfBlocks Number of blocks to write
1402   * @retval HAL status
1403   */
HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef * hmmc,uint8_t * pData,uint32_t BlockAdd,uint32_t NumberOfBlocks)1404 HAL_StatusTypeDef HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
1405 {
1406   SDMMC_DataInitTypeDef config;
1407   uint32_t errorstate;
1408   uint32_t add = BlockAdd;
1409 
1410   if(NULL == pData)
1411   {
1412     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1413     return HAL_ERROR;
1414   }
1415 
1416   if(hmmc->State == HAL_MMC_STATE_READY)
1417   {
1418     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1419 
1420     if((add + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1421     {
1422       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1423       return HAL_ERROR;
1424     }
1425 
1426     hmmc->State = HAL_MMC_STATE_BUSY;
1427 
1428     /* Initialize data control register */
1429     hmmc->Instance->DCTRL = 0U;
1430 
1431 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
1432     /* Set the DMA transfer complete callback */
1433     hmmc->hdmatx->XferCpltCallback = MMC_DMATransmitCplt;
1434 
1435     /* Set the DMA error callback */
1436     hmmc->hdmatx->XferErrorCallback = MMC_DMAError;
1437 
1438     /* Set the DMA Abort callback */
1439     hmmc->hdmatx->XferAbortCallback = NULL;
1440 #else
1441     hmmc->pTxBuffPtr = pData;
1442     hmmc->TxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1443 #endif
1444 
1445     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1446     {
1447       add *= 512U;
1448     }
1449 
1450 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
1451     /* Configure the MMC DPSM (Data Path State Machine) */
1452     config.DataTimeOut   = SDMMC_DATATIMEOUT;
1453     config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
1454     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1455     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
1456     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
1457     config.DPSM          = SDMMC_DPSM_DISABLE;
1458     (void)SDMMC_ConfigData(hmmc->Instance, &config);
1459 
1460     __SDMMC_CMDTRANS_ENABLE( hmmc->Instance);
1461 
1462     hmmc->Instance->IDMABASE0 = (uint32_t) pData ;
1463     hmmc->Instance->IDMACTRL  = SDMMC_ENABLE_IDMA_SINGLE_BUFF;
1464 #endif
1465 
1466     /* Write Blocks in Polling mode */
1467     if(NumberOfBlocks > 1U)
1468     {
1469       hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
1470 
1471       /* Write Multi Block command */
1472       errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
1473     }
1474     else
1475     {
1476       hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_DMA);
1477 
1478       /* Write Single Block command */
1479       errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
1480     }
1481     if(errorstate != HAL_MMC_ERROR_NONE)
1482     {
1483       /* Clear all the static flags */
1484       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1485       hmmc->ErrorCode |= errorstate;
1486       hmmc->State = HAL_MMC_STATE_READY;
1487       hmmc->Context = MMC_CONTEXT_NONE;
1488       return HAL_ERROR;
1489     }
1490 
1491 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
1492     /* Enable SDMMC DMA transfer */
1493     __HAL_MMC_DMA_ENABLE(hmmc);
1494 
1495     /* Enable the DMA Channel */
1496     if(HAL_DMA_Start_IT(hmmc->hdmatx, (uint32_t)pData, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)(MMC_BLOCKSIZE * NumberOfBlocks)/4) != HAL_OK)
1497     {
1498       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1499       hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
1500       hmmc->State = HAL_MMC_STATE_READY;
1501       hmmc->Context = MMC_CONTEXT_NONE;
1502       return HAL_ERROR;
1503     }
1504     else
1505     {
1506       /* Configure the MMC DPSM (Data Path State Machine) */
1507       config.DataTimeOut   = SDMMC_DATATIMEOUT;
1508       config.DataLength    = MMC_BLOCKSIZE * NumberOfBlocks;
1509       config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1510       config.TransferDir   = SDMMC_TRANSFER_DIR_TO_CARD;
1511       config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
1512       config.DPSM          = SDMMC_DPSM_ENABLE;
1513       (void)SDMMC_ConfigData(hmmc->Instance, &config);
1514 
1515       /* Enable MMC Error interrupts */
1516       __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR));
1517 
1518       return HAL_OK;
1519     }
1520 #else
1521     /* Enable MMC Error interrupts */
1522     __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND));
1523 
1524     return HAL_OK;
1525 #endif
1526   }
1527   else
1528   {
1529     return HAL_BUSY;
1530   }
1531 }
1532 
1533 /**
1534   * @brief  Erases the specified memory area of the given MMC card.
1535   * @note   This API should be followed by a check on the card state through
1536   *         HAL_MMC_GetCardState().
1537   * @param  hmmc Pointer to MMC handle
1538   * @param  BlockStartAdd Start Block address
1539   * @param  BlockEndAdd End Block address
1540   * @retval HAL status
1541   */
HAL_MMC_Erase(MMC_HandleTypeDef * hmmc,uint32_t BlockStartAdd,uint32_t BlockEndAdd)1542 HAL_StatusTypeDef HAL_MMC_Erase(MMC_HandleTypeDef *hmmc, uint32_t BlockStartAdd, uint32_t BlockEndAdd)
1543 {
1544   uint32_t errorstate;
1545   uint32_t start_add = BlockStartAdd;
1546   uint32_t end_add = BlockEndAdd;
1547 
1548   if(hmmc->State == HAL_MMC_STATE_READY)
1549   {
1550     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1551 
1552     if(end_add < start_add)
1553     {
1554       hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1555       return HAL_ERROR;
1556     }
1557 
1558     if(end_add > (hmmc->MmcCard.LogBlockNbr))
1559     {
1560       hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1561       return HAL_ERROR;
1562     }
1563 
1564     hmmc->State = HAL_MMC_STATE_BUSY;
1565 
1566     /* Check if the card command class supports erase command */
1567     if(((hmmc->MmcCard.Class) & SDMMC_CCCC_ERASE) == 0U)
1568     {
1569       /* Clear all the static flags */
1570       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1571       hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
1572       hmmc->State = HAL_MMC_STATE_READY;
1573       return HAL_ERROR;
1574     }
1575 
1576     if((SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
1577     {
1578       /* Clear all the static flags */
1579       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1580       hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED;
1581       hmmc->State = HAL_MMC_STATE_READY;
1582       return HAL_ERROR;
1583     }
1584 
1585     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1586     {
1587       start_add *= 512U;
1588       end_add   *= 512U;
1589     }
1590 
1591     /* Send CMD35 MMC_ERASE_GRP_START with argument as addr  */
1592     errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, start_add);
1593     if(errorstate != HAL_MMC_ERROR_NONE)
1594     {
1595       /* Clear all the static flags */
1596       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1597       hmmc->ErrorCode |= errorstate;
1598       hmmc->State = HAL_MMC_STATE_READY;
1599       return HAL_ERROR;
1600     }
1601 
1602     /* Send CMD36 MMC_ERASE_GRP_END with argument as addr  */
1603     errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, end_add);
1604     if(errorstate != HAL_MMC_ERROR_NONE)
1605     {
1606       /* Clear all the static flags */
1607       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1608       hmmc->ErrorCode |= errorstate;
1609       hmmc->State = HAL_MMC_STATE_READY;
1610       return HAL_ERROR;
1611     }
1612 
1613     /* Send CMD38 ERASE */
1614     errorstate = SDMMC_CmdErase(hmmc->Instance, 0UL);
1615     if(errorstate != HAL_MMC_ERROR_NONE)
1616     {
1617       /* Clear all the static flags */
1618       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1619       hmmc->ErrorCode |= errorstate;
1620       hmmc->State = HAL_MMC_STATE_READY;
1621       return HAL_ERROR;
1622     }
1623 
1624     hmmc->State = HAL_MMC_STATE_READY;
1625 
1626     return HAL_OK;
1627   }
1628   else
1629   {
1630     return HAL_BUSY;
1631   }
1632 }
1633 
1634 /**
1635   * @brief  This function handles MMC card interrupt request.
1636   * @param  hmmc Pointer to MMC handle
1637   * @retval None
1638   */
HAL_MMC_IRQHandler(MMC_HandleTypeDef * hmmc)1639 void HAL_MMC_IRQHandler(MMC_HandleTypeDef *hmmc)
1640 {
1641   uint32_t errorstate;
1642   uint32_t context = hmmc->Context;
1643 
1644   /* Check for SDMMC interrupt flags */
1645   if((__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) != RESET) && ((context & MMC_CONTEXT_IT) != 0U))
1646   {
1647     MMC_Read_IT(hmmc);
1648   }
1649 
1650   else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) != RESET)
1651   {
1652     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_DATAEND);
1653 
1654     __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND  | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT |\
1655                                SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR  | SDMMC_IT_TXFIFOHE |\
1656                                SDMMC_IT_RXFIFOHF);
1657 
1658 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
1659     hmmc->Instance->DCTRL &= ~(SDMMC_DCTRL_DTEN);
1660 #else
1661     __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_IDMABTC);
1662     __SDMMC_CMDTRANS_DISABLE( hmmc->Instance);
1663 #endif
1664 
1665     if((context & MMC_CONTEXT_DMA) != 0U)
1666     {
1667 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
1668       hmmc->Instance->DLEN = 0;
1669       hmmc->Instance->DCTRL = 0;
1670       hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA ;
1671 
1672       /* Stop Transfer for Write Multi blocks or Read Multi blocks */
1673       if(((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
1674       {
1675         errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
1676         if(errorstate != HAL_MMC_ERROR_NONE)
1677         {
1678           hmmc->ErrorCode |= errorstate;
1679 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1680           hmmc->ErrorCallback(hmmc);
1681 #else
1682           HAL_MMC_ErrorCallback(hmmc);
1683 #endif
1684         }
1685       }
1686 
1687       /* Clear all the static flags */
1688       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
1689 
1690       hmmc->State = HAL_MMC_STATE_READY;
1691       hmmc->Context = MMC_CONTEXT_NONE;
1692       if(((context & MMC_CONTEXT_WRITE_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
1693       {
1694 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1695         hmmc->TxCpltCallback(hmmc);
1696 #else
1697         HAL_MMC_TxCpltCallback(hmmc);
1698 #endif
1699       }
1700       if(((context & MMC_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
1701       {
1702 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1703         hmmc->RxCpltCallback(hmmc);
1704 #else
1705         HAL_MMC_RxCpltCallback(hmmc);
1706 #endif
1707       }
1708 #else
1709       if((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)
1710       {
1711         errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
1712         if(errorstate != HAL_MMC_ERROR_NONE)
1713         {
1714           hmmc->ErrorCode |= errorstate;
1715 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1716           hmmc->ErrorCallback(hmmc);
1717 #else
1718           HAL_MMC_ErrorCallback(hmmc);
1719 #endif
1720         }
1721       }
1722       if(((context & MMC_CONTEXT_READ_SINGLE_BLOCK) == 0U) && ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) == 0U))
1723       {
1724         /* Disable the DMA transfer for transmit request by setting the DMAEN bit
1725         in the MMC DCTRL register */
1726         hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN);
1727 
1728         hmmc->State = HAL_MMC_STATE_READY;
1729         hmmc->Context = MMC_CONTEXT_NONE;
1730 
1731 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1732         hmmc->TxCpltCallback(hmmc);
1733 #else
1734         HAL_MMC_TxCpltCallback(hmmc);
1735 #endif
1736       }
1737 #endif
1738     }
1739     else if((context & MMC_CONTEXT_IT) != 0U)
1740     {
1741       /* Stop Transfer for Write Multi blocks or Read Multi blocks */
1742       if(((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
1743       {
1744         errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
1745         if(errorstate != HAL_MMC_ERROR_NONE)
1746         {
1747           hmmc->ErrorCode |= errorstate;
1748 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1749           hmmc->ErrorCallback(hmmc);
1750 #else
1751           HAL_MMC_ErrorCallback(hmmc);
1752 #endif
1753         }
1754       }
1755 
1756       /* Clear all the static flags */
1757       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
1758 
1759       hmmc->State = HAL_MMC_STATE_READY;
1760       hmmc->Context = MMC_CONTEXT_NONE;
1761       if(((context & MMC_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
1762       {
1763 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1764         hmmc->RxCpltCallback(hmmc);
1765 #else
1766         HAL_MMC_RxCpltCallback(hmmc);
1767 #endif
1768       }
1769       else
1770       {
1771 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1772         hmmc->TxCpltCallback(hmmc);
1773 #else
1774         HAL_MMC_TxCpltCallback(hmmc);
1775 #endif
1776       }
1777     }
1778     else
1779     {
1780       /* Nothing to do */
1781     }
1782   }
1783 
1784   else if((__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) != RESET) && ((context & MMC_CONTEXT_IT) != 0U))
1785   {
1786     MMC_Write_IT(hmmc);
1787   }
1788 
1789   else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL| SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_RXOVERR | SDMMC_FLAG_TXUNDERR) != RESET)
1790   {
1791     /* Set Error code */
1792     if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_DCRCFAIL) != RESET)
1793     {
1794       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
1795     }
1796     if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_DTIMEOUT) != RESET)
1797     {
1798       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
1799     }
1800     if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_RXOVERR) != RESET)
1801     {
1802       hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
1803     }
1804     if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_TXUNDERR) != RESET)
1805     {
1806       hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
1807     }
1808 
1809     /* Clear All flags */
1810     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
1811 
1812     /* Disable all interrupts */
1813     __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\
1814                                SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR);
1815 
1816 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
1817     __SDMMC_CMDTRANS_DISABLE( hmmc->Instance);
1818     hmmc->Instance->DCTRL |= SDMMC_DCTRL_FIFORST;
1819     hmmc->Instance->CMD |= SDMMC_CMD_CMDSTOP;
1820 #endif
1821     hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
1822 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
1823     hmmc->Instance->CMD &= ~(SDMMC_CMD_CMDSTOP);
1824     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_DABORT);
1825 #endif
1826 
1827     if((context & MMC_CONTEXT_IT) != 0U)
1828     {
1829       /* Set the MMC state to ready to be able to start again the process */
1830       hmmc->State = HAL_MMC_STATE_READY;
1831       hmmc->Context = MMC_CONTEXT_NONE;
1832 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1833       hmmc->ErrorCallback(hmmc);
1834 #else
1835       HAL_MMC_ErrorCallback(hmmc);
1836 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1837     }
1838     else if((context & MMC_CONTEXT_DMA) != 0U)
1839     {
1840 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
1841       if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
1842       {
1843         /* Disable Internal DMA */
1844         __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_IDMABTC);
1845         hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA;
1846 
1847         /* Set the MMC state to ready to be able to start again the process */
1848         hmmc->State = HAL_MMC_STATE_READY;
1849 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1850         hmmc->ErrorCallback(hmmc);
1851 #else
1852         HAL_MMC_ErrorCallback(hmmc);
1853 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1854       }
1855 #else
1856       /* Abort the MMC DMA Streams */
1857       if(hmmc->hdmatx != NULL)
1858       {
1859         /* Set the DMA Tx abort callback */
1860         hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort;
1861         /* Abort DMA in IT mode */
1862         if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
1863         {
1864           MMC_DMATxAbort(hmmc->hdmatx);
1865         }
1866       }
1867       else if(hmmc->hdmarx != NULL)
1868       {
1869         /* Set the DMA Rx abort callback */
1870         hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort;
1871         /* Abort DMA in IT mode */
1872         if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
1873         {
1874           MMC_DMARxAbort(hmmc->hdmarx);
1875         }
1876       }
1877       else
1878       {
1879         hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1880         hmmc->State = HAL_MMC_STATE_READY;
1881         hmmc->Context = MMC_CONTEXT_NONE;
1882 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1883         hmmc->AbortCpltCallback(hmmc);
1884 #else
1885         HAL_MMC_AbortCallback(hmmc);
1886 #endif
1887       }
1888 #endif
1889     }
1890     else
1891     {
1892       /* Nothing to do */
1893     }
1894   }
1895 
1896 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
1897   else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_IDMABTC) != RESET)
1898   {
1899     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_IT_IDMABTC);
1900     if(READ_BIT(hmmc->Instance->IDMACTRL, SDMMC_IDMA_IDMABACT) == 0U)
1901     {
1902       /* Current buffer is buffer0, Transfer complete for buffer1 */
1903       if((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)
1904       {
1905 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1906         hmmc->Write_DMADblBuf1CpltCallback(hmmc);
1907 #else
1908         HAL_MMCEx_Write_DMADoubleBuffer1CpltCallback(hmmc);
1909 #endif
1910       }
1911       else /* MMC_CONTEXT_READ_MULTIPLE_BLOCK */
1912       {
1913 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1914         hmmc->Read_DMADblBuf1CpltCallback(hmmc);
1915 #else
1916         HAL_MMCEx_Read_DMADoubleBuffer1CpltCallback(hmmc);
1917 #endif
1918       }
1919     }
1920     else /* MMC_DMA_BUFFER1 */
1921     {
1922       /* Current buffer is buffer1, Transfer complete for buffer0 */
1923       if((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)
1924       {
1925 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1926         hmmc->Write_DMADblBuf0CpltCallback(hmmc);
1927 #else
1928         HAL_MMCEx_Write_DMADoubleBuffer0CpltCallback(hmmc);
1929 #endif
1930       }
1931       else /* MMC_CONTEXT_READ_MULTIPLE_BLOCK */
1932       {
1933 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1934         hmmc->Read_DMADblBuf0CpltCallback(hmmc);
1935 #else
1936         HAL_MMCEx_Read_DMADoubleBuffer0CpltCallback(hmmc);
1937 #endif
1938       }
1939     }
1940   }
1941 #endif
1942 
1943   else
1944   {
1945     /* Nothing to do */
1946   }
1947 }
1948 
1949 /**
1950   * @brief return the MMC state
1951   * @param hmmc Pointer to mmc handle
1952   * @retval HAL state
1953   */
HAL_MMC_GetState(MMC_HandleTypeDef * hmmc)1954 HAL_MMC_StateTypeDef HAL_MMC_GetState(MMC_HandleTypeDef *hmmc)
1955 {
1956   return hmmc->State;
1957 }
1958 
1959 /**
1960 * @brief  Return the MMC error code
1961 * @param  hmmc : Pointer to a MMC_HandleTypeDef structure that contains
1962   *              the configuration information.
1963 * @retval MMC Error Code
1964 */
HAL_MMC_GetError(MMC_HandleTypeDef * hmmc)1965 uint32_t HAL_MMC_GetError(MMC_HandleTypeDef *hmmc)
1966 {
1967   return hmmc->ErrorCode;
1968 }
1969 
1970 /**
1971   * @brief Tx Transfer completed callbacks
1972   * @param hmmc Pointer to MMC handle
1973   * @retval None
1974   */
HAL_MMC_TxCpltCallback(MMC_HandleTypeDef * hmmc)1975 __weak void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef *hmmc)
1976 {
1977   /* Prevent unused argument(s) compilation warning */
1978   UNUSED(hmmc);
1979 
1980   /* NOTE : This function should not be modified, when the callback is needed,
1981             the HAL_MMC_TxCpltCallback can be implemented in the user file
1982    */
1983 }
1984 
1985 /**
1986   * @brief Rx Transfer completed callbacks
1987   * @param hmmc Pointer MMC handle
1988   * @retval None
1989   */
HAL_MMC_RxCpltCallback(MMC_HandleTypeDef * hmmc)1990 __weak void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef *hmmc)
1991 {
1992   /* Prevent unused argument(s) compilation warning */
1993   UNUSED(hmmc);
1994 
1995   /* NOTE : This function should not be modified, when the callback is needed,
1996             the HAL_MMC_RxCpltCallback can be implemented in the user file
1997    */
1998 }
1999 
2000 /**
2001   * @brief MMC error callbacks
2002   * @param hmmc Pointer MMC handle
2003   * @retval None
2004   */
HAL_MMC_ErrorCallback(MMC_HandleTypeDef * hmmc)2005 __weak void HAL_MMC_ErrorCallback(MMC_HandleTypeDef *hmmc)
2006 {
2007   /* Prevent unused argument(s) compilation warning */
2008   UNUSED(hmmc);
2009 
2010   /* NOTE : This function should not be modified, when the callback is needed,
2011             the HAL_MMC_ErrorCallback can be implemented in the user file
2012    */
2013 }
2014 
2015 /**
2016   * @brief MMC Abort callbacks
2017   * @param hmmc Pointer MMC handle
2018   * @retval None
2019   */
HAL_MMC_AbortCallback(MMC_HandleTypeDef * hmmc)2020 __weak void HAL_MMC_AbortCallback(MMC_HandleTypeDef *hmmc)
2021 {
2022   /* Prevent unused argument(s) compilation warning */
2023   UNUSED(hmmc);
2024 
2025   /* NOTE : This function should not be modified, when the callback is needed,
2026             the HAL_MMC_AbortCallback can be implemented in the user file
2027    */
2028 }
2029 
2030 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2031 /**
2032   * @brief  Register a User MMC Callback
2033   *         To be used instead of the weak (surcharged) predefined callback
2034   * @param hmmc : MMC handle
2035   * @param CallbackId : ID of the callback to be registered
2036   *        This parameter can be one of the following values:
2037   *          @arg @ref HAL_MMC_TX_CPLT_CB_ID                 MMC Tx Complete Callback ID
2038   *          @arg @ref HAL_MMC_RX_CPLT_CB_ID                 MMC Rx Complete Callback ID
2039   *          @arg @ref HAL_MMC_ERROR_CB_ID                   MMC Error Callback ID
2040   *          @arg @ref HAL_MMC_ABORT_CB_ID                   MMC Abort Callback ID
2041   *          @arg @ref HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID  MMC DMA Rx Double buffer 0 Callback ID
2042   *          @arg @ref HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID  MMC DMA Rx Double buffer 1 Callback ID
2043   *          @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID MMC DMA Tx Double buffer 0 Callback ID
2044   *          @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID MMC DMA Tx Double buffer 1 Callback ID
2045   *          @arg @ref HAL_MMC_MSP_INIT_CB_ID                MMC MspInit Callback ID
2046   *          @arg @ref HAL_MMC_MSP_DEINIT_CB_ID              MMC MspDeInit Callback ID
2047   * @param pCallback : pointer to the Callback function
2048   * @retval status
2049   */
HAL_MMC_RegisterCallback(MMC_HandleTypeDef * hmmc,HAL_MMC_CallbackIDTypeDef CallbackId,pMMC_CallbackTypeDef pCallback)2050 HAL_StatusTypeDef HAL_MMC_RegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId, pMMC_CallbackTypeDef pCallback)
2051 {
2052   HAL_StatusTypeDef status = HAL_OK;
2053 
2054   if(pCallback == NULL)
2055   {
2056     /* Update the error code */
2057     hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
2058     return HAL_ERROR;
2059   }
2060 
2061   /* Process locked */
2062   __HAL_LOCK(hmmc);
2063 
2064   if(hmmc->State == HAL_MMC_STATE_READY)
2065   {
2066     switch (CallbackId)
2067     {
2068     case HAL_MMC_TX_CPLT_CB_ID :
2069       hmmc->TxCpltCallback = pCallback;
2070       break;
2071     case HAL_MMC_RX_CPLT_CB_ID :
2072       hmmc->RxCpltCallback = pCallback;
2073       break;
2074     case HAL_MMC_ERROR_CB_ID :
2075       hmmc->ErrorCallback = pCallback;
2076       break;
2077     case HAL_MMC_ABORT_CB_ID :
2078       hmmc->AbortCpltCallback = pCallback;
2079       break;
2080 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
2081     case HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID :
2082       hmmc->Read_DMADblBuf0CpltCallback = pCallback;
2083       break;
2084     case HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID :
2085       hmmc->Read_DMADblBuf1CpltCallback = pCallback;
2086       break;
2087     case HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID :
2088       hmmc->Write_DMADblBuf0CpltCallback = pCallback;
2089       break;
2090     case HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID :
2091       hmmc->Write_DMADblBuf1CpltCallback = pCallback;
2092       break;
2093 #endif
2094     case HAL_MMC_MSP_INIT_CB_ID :
2095       hmmc->MspInitCallback = pCallback;
2096       break;
2097     case HAL_MMC_MSP_DEINIT_CB_ID :
2098       hmmc->MspDeInitCallback = pCallback;
2099       break;
2100     default :
2101       /* Update the error code */
2102       hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
2103       /* update return status */
2104       status =  HAL_ERROR;
2105       break;
2106     }
2107   }
2108   else if (hmmc->State == HAL_MMC_STATE_RESET)
2109   {
2110     switch (CallbackId)
2111     {
2112     case HAL_MMC_MSP_INIT_CB_ID :
2113       hmmc->MspInitCallback = pCallback;
2114       break;
2115     case HAL_MMC_MSP_DEINIT_CB_ID :
2116       hmmc->MspDeInitCallback = pCallback;
2117       break;
2118     default :
2119       /* Update the error code */
2120       hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
2121       /* update return status */
2122       status =  HAL_ERROR;
2123       break;
2124     }
2125   }
2126   else
2127   {
2128     /* Update the error code */
2129     hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
2130     /* update return status */
2131     status =  HAL_ERROR;
2132   }
2133 
2134   /* Release Lock */
2135   __HAL_UNLOCK(hmmc);
2136   return status;
2137 }
2138 
2139 /**
2140   * @brief  Unregister a User MMC Callback
2141   *         MMC Callback is redirected to the weak (surcharged) predefined callback
2142   * @param hmmc : MMC handle
2143   * @param CallbackId : ID of the callback to be unregistered
2144   *        This parameter can be one of the following values:
2145   *          @arg @ref HAL_MMC_TX_CPLT_CB_ID                 MMC Tx Complete Callback ID
2146   *          @arg @ref HAL_MMC_RX_CPLT_CB_ID                 MMC Rx Complete Callback ID
2147   *          @arg @ref HAL_MMC_ERROR_CB_ID                   MMC Error Callback ID
2148   *          @arg @ref HAL_MMC_ABORT_CB_ID                   MMC Abort Callback ID
2149   *          @arg @ref HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID  MMC DMA Rx Double buffer 0 Callback ID
2150   *          @arg @ref HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID  MMC DMA Rx Double buffer 1 Callback ID
2151   *          @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID MMC DMA Tx Double buffer 0 Callback ID
2152   *          @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID MMC DMA Tx Double buffer 1 Callback ID
2153   *          @arg @ref HAL_MMC_MSP_INIT_CB_ID                MMC MspInit Callback ID
2154   *          @arg @ref HAL_MMC_MSP_DEINIT_CB_ID              MMC MspDeInit Callback ID
2155   * @retval status
2156   */
HAL_MMC_UnRegisterCallback(MMC_HandleTypeDef * hmmc,HAL_MMC_CallbackIDTypeDef CallbackId)2157 HAL_StatusTypeDef HAL_MMC_UnRegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId)
2158 {
2159   HAL_StatusTypeDef status = HAL_OK;
2160 
2161   /* Process locked */
2162   __HAL_LOCK(hmmc);
2163 
2164   if(hmmc->State == HAL_MMC_STATE_READY)
2165   {
2166     switch (CallbackId)
2167     {
2168     case HAL_MMC_TX_CPLT_CB_ID :
2169       hmmc->TxCpltCallback = HAL_MMC_TxCpltCallback;
2170       break;
2171     case HAL_MMC_RX_CPLT_CB_ID :
2172       hmmc->RxCpltCallback = HAL_MMC_RxCpltCallback;
2173       break;
2174     case HAL_MMC_ERROR_CB_ID :
2175       hmmc->ErrorCallback = HAL_MMC_ErrorCallback;
2176       break;
2177     case HAL_MMC_ABORT_CB_ID :
2178       hmmc->AbortCpltCallback = HAL_MMC_AbortCallback;
2179       break;
2180 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
2181     case HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID :
2182       hmmc->Read_DMADblBuf0CpltCallback = HAL_MMCEx_Read_DMADoubleBuffer0CpltCallback;
2183       break;
2184     case HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID :
2185       hmmc->Read_DMADblBuf1CpltCallback = HAL_MMCEx_Read_DMADoubleBuffer1CpltCallback;
2186       break;
2187     case HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID :
2188       hmmc->Write_DMADblBuf0CpltCallback = HAL_MMCEx_Write_DMADoubleBuffer0CpltCallback;
2189       break;
2190     case HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID :
2191       hmmc->Write_DMADblBuf1CpltCallback = HAL_MMCEx_Write_DMADoubleBuffer1CpltCallback;
2192       break;
2193 #endif
2194     case HAL_MMC_MSP_INIT_CB_ID :
2195       hmmc->MspInitCallback = HAL_MMC_MspInit;
2196       break;
2197     case HAL_MMC_MSP_DEINIT_CB_ID :
2198       hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
2199       break;
2200     default :
2201       /* Update the error code */
2202       hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
2203       /* update return status */
2204       status =  HAL_ERROR;
2205       break;
2206     }
2207   }
2208   else if (hmmc->State == HAL_MMC_STATE_RESET)
2209   {
2210     switch (CallbackId)
2211     {
2212     case HAL_MMC_MSP_INIT_CB_ID :
2213       hmmc->MspInitCallback = HAL_MMC_MspInit;
2214       break;
2215     case HAL_MMC_MSP_DEINIT_CB_ID :
2216       hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
2217       break;
2218     default :
2219       /* Update the error code */
2220       hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
2221       /* update return status */
2222       status =  HAL_ERROR;
2223       break;
2224     }
2225   }
2226   else
2227   {
2228     /* Update the error code */
2229     hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
2230     /* update return status */
2231     status =  HAL_ERROR;
2232   }
2233 
2234   /* Release Lock */
2235   __HAL_UNLOCK(hmmc);
2236   return status;
2237 }
2238 #endif
2239 
2240 /**
2241   * @}
2242   */
2243 
2244 /** @addtogroup MMC_Exported_Functions_Group3
2245  *  @brief   management functions
2246  *
2247 @verbatim
2248   ==============================================================================
2249                       ##### Peripheral Control functions #####
2250   ==============================================================================
2251   [..]
2252     This subsection provides a set of functions allowing to control the MMC card
2253     operations and get the related information
2254 
2255 @endverbatim
2256   * @{
2257   */
2258 
2259 /**
2260   * @brief  Returns information the information of the card which are stored on
2261   *         the CID register.
2262   * @param  hmmc Pointer to MMC handle
2263   * @param  pCID Pointer to a HAL_MMC_CIDTypedef structure that
2264   *         contains all CID register parameters
2265   * @retval HAL status
2266   */
HAL_MMC_GetCardCID(MMC_HandleTypeDef * hmmc,HAL_MMC_CardCIDTypeDef * pCID)2267 HAL_StatusTypeDef HAL_MMC_GetCardCID(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCIDTypeDef *pCID)
2268 {
2269   pCID->ManufacturerID = (uint8_t)((hmmc->CID[0] & 0xFF000000U) >> 24U);
2270 
2271   pCID->OEM_AppliID = (uint16_t)((hmmc->CID[0] & 0x00FFFF00U) >> 8U);
2272 
2273   pCID->ProdName1 = (((hmmc->CID[0] & 0x000000FFU) << 24U) | ((hmmc->CID[1] & 0xFFFFFF00U) >> 8U));
2274 
2275   pCID->ProdName2 = (uint8_t)(hmmc->CID[1] & 0x000000FFU);
2276 
2277   pCID->ProdRev = (uint8_t)((hmmc->CID[2] & 0xFF000000U) >> 24U);
2278 
2279   pCID->ProdSN = (((hmmc->CID[2] & 0x00FFFFFFU) << 8U) | ((hmmc->CID[3] & 0xFF000000U) >> 24U));
2280 
2281   pCID->Reserved1 = (uint8_t)((hmmc->CID[3] & 0x00F00000U) >> 20U);
2282 
2283   pCID->ManufactDate = (uint16_t)((hmmc->CID[3] & 0x000FFF00U) >> 8U);
2284 
2285   pCID->CID_CRC = (uint8_t)((hmmc->CID[3] & 0x000000FEU) >> 1U);
2286 
2287   pCID->Reserved2 = 1U;
2288 
2289   return HAL_OK;
2290 }
2291 
2292 /**
2293   * @brief  Returns information the information of the card which are stored on
2294   *         the CSD register.
2295   * @param  hmmc Pointer to MMC handle
2296   * @param  pCSD Pointer to a HAL_MMC_CardCSDTypeDef structure that
2297   *         contains all CSD register parameters
2298   * @retval HAL status
2299   */
HAL_MMC_GetCardCSD(MMC_HandleTypeDef * hmmc,HAL_MMC_CardCSDTypeDef * pCSD)2300 HAL_StatusTypeDef HAL_MMC_GetCardCSD(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCSDTypeDef *pCSD)
2301 {
2302   uint32_t block_nbr = 0;
2303 
2304   pCSD->CSDStruct = (uint8_t)((hmmc->CSD[0] & 0xC0000000U) >> 30U);
2305 
2306   pCSD->SysSpecVersion = (uint8_t)((hmmc->CSD[0] & 0x3C000000U) >> 26U);
2307 
2308   pCSD->Reserved1 = (uint8_t)((hmmc->CSD[0] & 0x03000000U) >> 24U);
2309 
2310   pCSD->TAAC = (uint8_t)((hmmc->CSD[0] & 0x00FF0000U) >> 16U);
2311 
2312   pCSD->NSAC = (uint8_t)((hmmc->CSD[0] & 0x0000FF00U) >> 8U);
2313 
2314   pCSD->MaxBusClkFrec = (uint8_t)(hmmc->CSD[0] & 0x000000FFU);
2315 
2316   pCSD->CardComdClasses = (uint16_t)((hmmc->CSD[1] & 0xFFF00000U) >> 20U);
2317 
2318   pCSD->RdBlockLen = (uint8_t)((hmmc->CSD[1] & 0x000F0000U) >> 16U);
2319 
2320   pCSD->PartBlockRead   = (uint8_t)((hmmc->CSD[1] & 0x00008000U) >> 15U);
2321 
2322   pCSD->WrBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00004000U) >> 14U);
2323 
2324   pCSD->RdBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00002000U) >> 13U);
2325 
2326   pCSD->DSRImpl = (uint8_t)((hmmc->CSD[1] & 0x00001000U) >> 12U);
2327 
2328   pCSD->Reserved2 = 0U; /*!< Reserved */
2329 
2330   if(MMC_ReadExtCSD(hmmc, &block_nbr, 212, 0x0FFFFFFFU) != HAL_OK) /* Field SEC_COUNT [215:212] */
2331   {
2332     return HAL_ERROR;
2333   }
2334 
2335   if(hmmc->MmcCard.CardType == MMC_LOW_CAPACITY_CARD)
2336   {
2337     pCSD->DeviceSize = (((hmmc->CSD[1] & 0x000003FFU) << 2U) | ((hmmc->CSD[2] & 0xC0000000U) >> 30U));
2338 
2339     pCSD->MaxRdCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x38000000U) >> 27U);
2340 
2341     pCSD->MaxRdCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x07000000U) >> 24U);
2342 
2343     pCSD->MaxWrCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x00E00000U) >> 21U);
2344 
2345     pCSD->MaxWrCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x001C0000U) >> 18U);
2346 
2347     pCSD->DeviceSizeMul = (uint8_t)((hmmc->CSD[2] & 0x00038000U) >> 15U);
2348 
2349     hmmc->MmcCard.BlockNbr  = (pCSD->DeviceSize + 1U) ;
2350     hmmc->MmcCard.BlockNbr *= (1UL << ((pCSD->DeviceSizeMul & 0x07U) + 2U));
2351     hmmc->MmcCard.BlockSize = (1UL << (pCSD->RdBlockLen & 0x0FU));
2352 
2353     hmmc->MmcCard.LogBlockNbr =  (hmmc->MmcCard.BlockNbr) * ((hmmc->MmcCard.BlockSize) / 512U);
2354     hmmc->MmcCard.LogBlockSize = 512U;
2355   }
2356   else if(hmmc->MmcCard.CardType == MMC_HIGH_CAPACITY_CARD)
2357   {
2358     hmmc->MmcCard.BlockNbr = block_nbr;
2359     hmmc->MmcCard.LogBlockNbr = hmmc->MmcCard.BlockNbr;
2360     hmmc->MmcCard.BlockSize = 512U;
2361     hmmc->MmcCard.LogBlockSize = hmmc->MmcCard.BlockSize;
2362   }
2363   else
2364   {
2365     /* Clear all the static flags */
2366     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2367     hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2368     hmmc->State = HAL_MMC_STATE_READY;
2369     return HAL_ERROR;
2370   }
2371 
2372   pCSD->EraseGrSize = (uint8_t)((hmmc->CSD[2] & 0x00004000U) >> 14U);
2373 
2374   pCSD->EraseGrMul = (uint8_t)((hmmc->CSD[2] & 0x00003F80U) >> 7U);
2375 
2376   pCSD->WrProtectGrSize = (uint8_t)(hmmc->CSD[2] & 0x0000007FU);
2377 
2378   pCSD->WrProtectGrEnable = (uint8_t)((hmmc->CSD[3] & 0x80000000U) >> 31U);
2379 
2380   pCSD->ManDeflECC = (uint8_t)((hmmc->CSD[3] & 0x60000000U) >> 29U);
2381 
2382   pCSD->WrSpeedFact = (uint8_t)((hmmc->CSD[3] & 0x1C000000U) >> 26U);
2383 
2384   pCSD->MaxWrBlockLen= (uint8_t)((hmmc->CSD[3] & 0x03C00000U) >> 22U);
2385 
2386   pCSD->WriteBlockPaPartial = (uint8_t)((hmmc->CSD[3] & 0x00200000U) >> 21U);
2387 
2388   pCSD->Reserved3 = 0;
2389 
2390   pCSD->ContentProtectAppli = (uint8_t)((hmmc->CSD[3] & 0x00010000U) >> 16U);
2391 
2392   pCSD->FileFormatGroup = (uint8_t)((hmmc->CSD[3] & 0x00008000U) >> 15U);
2393 
2394   pCSD->CopyFlag = (uint8_t)((hmmc->CSD[3] & 0x00004000U) >> 14U);
2395 
2396   pCSD->PermWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00002000U) >> 13U);
2397 
2398   pCSD->TempWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00001000U) >> 12U);
2399 
2400   pCSD->FileFormat = (uint8_t)((hmmc->CSD[3] & 0x00000C00U) >> 10U);
2401 
2402   pCSD->ECC= (uint8_t)((hmmc->CSD[3] & 0x00000300U) >> 8U);
2403 
2404   pCSD->CSD_CRC = (uint8_t)((hmmc->CSD[3] & 0x000000FEU) >> 1U);
2405 
2406   pCSD->Reserved4 = 1;
2407 
2408   return HAL_OK;
2409 }
2410 
2411 /**
2412   * @brief  Gets the MMC card info.
2413   * @param  hmmc Pointer to MMC handle
2414   * @param  pCardInfo Pointer to the HAL_MMC_CardInfoTypeDef structure that
2415   *         will contain the MMC card status information
2416   * @retval HAL status
2417   */
HAL_MMC_GetCardInfo(MMC_HandleTypeDef * hmmc,HAL_MMC_CardInfoTypeDef * pCardInfo)2418 HAL_StatusTypeDef HAL_MMC_GetCardInfo(MMC_HandleTypeDef *hmmc, HAL_MMC_CardInfoTypeDef *pCardInfo)
2419 {
2420   pCardInfo->CardType     = (uint32_t)(hmmc->MmcCard.CardType);
2421   pCardInfo->Class        = (uint32_t)(hmmc->MmcCard.Class);
2422   pCardInfo->RelCardAdd   = (uint32_t)(hmmc->MmcCard.RelCardAdd);
2423   pCardInfo->BlockNbr     = (uint32_t)(hmmc->MmcCard.BlockNbr);
2424   pCardInfo->BlockSize    = (uint32_t)(hmmc->MmcCard.BlockSize);
2425   pCardInfo->LogBlockNbr  = (uint32_t)(hmmc->MmcCard.LogBlockNbr);
2426   pCardInfo->LogBlockSize = (uint32_t)(hmmc->MmcCard.LogBlockSize);
2427 
2428   return HAL_OK;
2429 }
2430 
2431 /**
2432   * @brief  Returns information the information of the card which are stored on
2433   *         the Extended CSD register.
2434   * @param  hmmc Pointer to MMC handle
2435   * @param  pExtCSD Pointer to a memory area (512 bytes) that contains all
2436   *         Extended CSD register parameters
2437   * @param  Timeout Specify timeout value
2438   * @retval HAL status
2439   */
HAL_MMC_GetCardExtCSD(MMC_HandleTypeDef * hmmc,uint32_t * pExtCSD,uint32_t Timeout)2440 HAL_StatusTypeDef HAL_MMC_GetCardExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pExtCSD, uint32_t Timeout)
2441 {
2442   SDMMC_DataInitTypeDef config;
2443   uint32_t errorstate;
2444   uint32_t tickstart = HAL_GetTick();
2445   uint32_t count;
2446   uint32_t *tmp_buf;
2447 
2448   if(NULL == pExtCSD)
2449   {
2450     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
2451     return HAL_ERROR;
2452   }
2453 
2454   if(hmmc->State == HAL_MMC_STATE_READY)
2455   {
2456     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
2457 
2458     hmmc->State = HAL_MMC_STATE_BUSY;
2459 
2460     /* Initialize data control register */
2461     hmmc->Instance->DCTRL = 0;
2462 
2463     /* Initiaize the destination pointer */
2464     tmp_buf = pExtCSD;
2465 
2466     /* Configure the MMC DPSM (Data Path State Machine) */
2467     config.DataTimeOut   = SDMMC_DATATIMEOUT;
2468     config.DataLength    = 512;
2469     config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
2470     config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
2471     config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
2472 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
2473     config.DPSM          = SDMMC_DPSM_ENABLE;
2474 #else
2475     config.DPSM          = SDMMC_DPSM_DISABLE;
2476 #endif
2477     (void)SDMMC_ConfigData(hmmc->Instance, &config);
2478 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
2479     __SDMMC_CMDTRANS_ENABLE( hmmc->Instance);
2480 #endif
2481 
2482     /* Send ExtCSD Read command to Card */
2483     errorstate = SDMMC_CmdSendEXTCSD(hmmc->Instance, 0);
2484     if(errorstate != HAL_MMC_ERROR_NONE)
2485     {
2486       /* Clear all the static flags */
2487       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2488       hmmc->ErrorCode |= errorstate;
2489       hmmc->State = HAL_MMC_STATE_READY;
2490       return HAL_ERROR;
2491     }
2492 
2493     /* Poll on SDMMC flags */
2494     while(!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
2495     {
2496       if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF))
2497       {
2498         /* Read data from SDMMC Rx FIFO */
2499         for(count = 0U; count < 8U; count++)
2500         {
2501           *tmp_buf = SDMMC_ReadFIFO(hmmc->Instance);
2502           tmp_buf++;
2503         }
2504       }
2505 
2506       if(((HAL_GetTick()-tickstart) >=  Timeout) || (Timeout == 0U))
2507       {
2508         /* Clear all the static flags */
2509         __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2510         hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
2511         hmmc->State= HAL_MMC_STATE_READY;
2512         return HAL_TIMEOUT;
2513       }
2514     }
2515 
2516 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
2517     __SDMMC_CMDTRANS_DISABLE( hmmc->Instance);
2518 #endif
2519 
2520     /* Get error state */
2521     if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
2522     {
2523       /* Clear all the static flags */
2524       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2525       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
2526       hmmc->State = HAL_MMC_STATE_READY;
2527       return HAL_ERROR;
2528     }
2529     else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
2530     {
2531       /* Clear all the static flags */
2532       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2533       hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
2534       hmmc->State = HAL_MMC_STATE_READY;
2535       return HAL_ERROR;
2536     }
2537     else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR))
2538     {
2539       /* Clear all the static flags */
2540       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2541       hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
2542       hmmc->State = HAL_MMC_STATE_READY;
2543       return HAL_ERROR;
2544     }
2545     else
2546     {
2547       /* Nothing to do */
2548     }
2549 
2550     /* Clear all the static flags */
2551     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2552     hmmc->State = HAL_MMC_STATE_READY;
2553   }
2554 
2555   return HAL_OK;
2556 }
2557 
2558 /**
2559   * @brief  Enables wide bus operation for the requested card if supported by
2560   *         card.
2561   * @param  hmmc Pointer to MMC handle
2562   * @param  WideMode Specifies the MMC card wide bus mode
2563   *          This parameter can be one of the following values:
2564   *            @arg SDMMC_BUS_WIDE_8B: 8-bit data transfer
2565   *            @arg SDMMC_BUS_WIDE_4B: 4-bit data transfer
2566   *            @arg SDMMC_BUS_WIDE_1B: 1-bit data transfer
2567   * @retval HAL status
2568   */
HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef * hmmc,uint32_t WideMode)2569 HAL_StatusTypeDef HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef *hmmc, uint32_t WideMode)
2570 {
2571   uint32_t count;
2572   SDMMC_InitTypeDef Init;
2573   uint32_t errorstate;
2574   uint32_t response = 0U;
2575 
2576   /* Check the parameters */
2577   assert_param(IS_SDMMC_BUS_WIDE(WideMode));
2578 
2579   /* Change State */
2580   hmmc->State = HAL_MMC_STATE_BUSY;
2581 
2582 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
2583   /* Check and update the power class if needed */
2584   if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) != 0U)
2585   {
2586     if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) != 0U)
2587     {
2588       errorstate = MMC_PwrClassUpdate(hmmc, WideMode, SDMMC_SPEED_MODE_DDR);
2589     }
2590     else
2591     {
2592       errorstate = MMC_PwrClassUpdate(hmmc, WideMode, SDMMC_SPEED_MODE_HIGH);
2593     }
2594   }
2595   else
2596   {
2597     errorstate = MMC_PwrClassUpdate(hmmc, WideMode, SDMMC_SPEED_MODE_DEFAULT);
2598   }
2599 #else
2600   errorstate = MMC_PwrClassUpdate(hmmc, WideMode, 0U);
2601 #endif
2602 
2603   if(errorstate == HAL_MMC_ERROR_NONE)
2604   {
2605     if(WideMode == SDMMC_BUS_WIDE_8B)
2606     {
2607       errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U);
2608     }
2609     else if(WideMode == SDMMC_BUS_WIDE_4B)
2610     {
2611       errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U);
2612     }
2613     else if(WideMode == SDMMC_BUS_WIDE_1B)
2614     {
2615       errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70000U);
2616     }
2617     else
2618     {
2619       /* WideMode is not a valid argument*/
2620       errorstate = HAL_MMC_ERROR_PARAM;
2621     }
2622 
2623     /* Check for switch error and violation of the trial number of sending CMD 13 */
2624     if(errorstate == HAL_MMC_ERROR_NONE)
2625     {
2626       /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2627       count = SDMMC_MAX_TRIAL;
2628       do
2629       {
2630         errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2631         if(errorstate != HAL_MMC_ERROR_NONE)
2632         {
2633           break;
2634         }
2635 
2636         /* Get command response */
2637         response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
2638         count--;
2639       }while(((response & 0x100U) == 0U) && (count != 0U));
2640 
2641       /* Check the status after the switch command execution */
2642       if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
2643       {
2644         /* Check the bit SWITCH_ERROR of the device status */
2645         if ((response & 0x80U) != 0U)
2646         {
2647           errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
2648         }
2649         else
2650         {
2651           /* Configure the SDMMC peripheral */
2652           Init = hmmc->Init;
2653           Init.BusWide = WideMode;
2654           (void)SDMMC_Init(hmmc->Instance, Init);
2655         }
2656       }
2657       else if (count == 0U)
2658       {
2659         errorstate = SDMMC_ERROR_TIMEOUT;
2660       }
2661       else
2662       {
2663         /* Nothing to do */
2664       }
2665     }
2666   }
2667 
2668   /* Change State */
2669   hmmc->State = HAL_MMC_STATE_READY;
2670 
2671   if(errorstate != HAL_MMC_ERROR_NONE)
2672   {
2673     /* Clear all the static flags */
2674     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2675     hmmc->ErrorCode |= errorstate;
2676     return HAL_ERROR;
2677   }
2678 
2679   return HAL_OK;
2680 }
2681 
2682 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
2683 /**
2684   * @brief  Configure the speed bus mode
2685   * @param  hmmc Pointer to the MMC handle
2686   * @param  SpeedMode Specifies the MMC card speed bus mode
2687   *          This parameter can be one of the following values:
2688   *            @arg SDMMC_SPEED_MODE_AUTO: Max speed mode supported by the card
2689   *            @arg SDMMC_SPEED_MODE_DEFAULT: Default Speed (MMC @ 26MHz)
2690   *            @arg SDMMC_SPEED_MODE_HIGH: High Speed (MMC @ 52 MHz)
2691   *            @arg SDMMC_SPEED_MODE_DDR: High Speed DDR (MMC DDR @ 52 MHz)
2692   * @retval HAL status
2693   */
2694 
HAL_MMC_ConfigSpeedBusOperation(MMC_HandleTypeDef * hmmc,uint32_t SpeedMode)2695 HAL_StatusTypeDef HAL_MMC_ConfigSpeedBusOperation(MMC_HandleTypeDef *hmmc, uint32_t SpeedMode)
2696 {
2697   uint32_t tickstart;
2698   HAL_StatusTypeDef status = HAL_OK;
2699   uint32_t device_type;
2700   uint32_t errorstate;
2701 
2702   /* Check the parameters */
2703   assert_param(IS_SDMMC_SPEED_MODE(SpeedMode));
2704 
2705   /* Change State */
2706   hmmc->State = HAL_MMC_STATE_BUSY;
2707 
2708   /* Field DEVICE_TYPE [196 = 49*4] of Extended CSD register */
2709   device_type = (hmmc->Ext_CSD[49] & 0x000000FFU);
2710 
2711   switch (SpeedMode)
2712   {
2713     case SDMMC_SPEED_MODE_AUTO:
2714     {
2715       if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS) != 0U) && ((device_type & 0x04U) != 0U))
2716       {
2717         /* High Speed DDR mode allowed */
2718         errorstate = MMC_HighSpeed(hmmc, ENABLE);
2719         if(errorstate != HAL_MMC_ERROR_NONE)
2720         {
2721           hmmc->ErrorCode |= errorstate;
2722         }
2723         else
2724         {
2725           if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_CLKDIV) != 0U)
2726           {
2727             /* DDR mode not supported with CLKDIV = 0 */
2728             errorstate = MMC_DDR_Mode(hmmc, ENABLE);
2729             if(errorstate != HAL_MMC_ERROR_NONE)
2730             {
2731               hmmc->ErrorCode |= errorstate;
2732             }
2733           }
2734         }
2735       }
2736       else if ((device_type & 0x02U) != 0U)
2737       {
2738         /* High Speed mode allowed */
2739         errorstate = MMC_HighSpeed(hmmc, ENABLE);
2740         if(errorstate != HAL_MMC_ERROR_NONE)
2741         {
2742           hmmc->ErrorCode |= errorstate;
2743         }
2744       }
2745       else
2746       {
2747         /* Nothing to do : keep current speed */
2748       }
2749       break;
2750     }
2751     case SDMMC_SPEED_MODE_DDR:
2752     {
2753       if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS) != 0U) && ((device_type & 0x04U) != 0U))
2754       {
2755         /* High Speed DDR mode allowed */
2756         errorstate = MMC_HighSpeed(hmmc, ENABLE);
2757         if(errorstate != HAL_MMC_ERROR_NONE)
2758         {
2759           hmmc->ErrorCode |= errorstate;
2760         }
2761         else
2762         {
2763           if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_CLKDIV) != 0U)
2764           {
2765             /* DDR mode not supported with CLKDIV = 0 */
2766             errorstate = MMC_DDR_Mode(hmmc, ENABLE);
2767             if(errorstate != HAL_MMC_ERROR_NONE)
2768             {
2769               hmmc->ErrorCode |= errorstate;
2770             }
2771           }
2772         }
2773       }
2774       else
2775       {
2776         /* High Speed DDR mode not allowed */
2777         hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2778         status = HAL_ERROR;
2779       }
2780       break;
2781     }
2782     case SDMMC_SPEED_MODE_HIGH:
2783     {
2784       if ((device_type & 0x02U) != 0U)
2785       {
2786         /* High Speed mode allowed */
2787         errorstate = MMC_HighSpeed(hmmc, ENABLE);
2788         if(errorstate != HAL_MMC_ERROR_NONE)
2789         {
2790           hmmc->ErrorCode |= errorstate;
2791         }
2792       }
2793       else
2794       {
2795         /* High Speed mode not allowed */
2796         hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2797         status = HAL_ERROR;
2798       }
2799       break;
2800     }
2801     case SDMMC_SPEED_MODE_DEFAULT:
2802     {
2803       if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) != 0U)
2804       {
2805         /* High Speed DDR mode activated */
2806         errorstate = MMC_DDR_Mode(hmmc, DISABLE);
2807         if(errorstate != HAL_MMC_ERROR_NONE)
2808         {
2809           hmmc->ErrorCode |= errorstate;
2810         }
2811       }
2812       if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) != 0U)
2813       {
2814         /* High Speed mode activated */
2815         errorstate = MMC_HighSpeed(hmmc, DISABLE);
2816         if(errorstate != HAL_MMC_ERROR_NONE)
2817         {
2818           hmmc->ErrorCode |= errorstate;
2819         }
2820       }
2821       break;
2822     }
2823     default:
2824       hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
2825       status = HAL_ERROR;
2826       break;
2827   }
2828 
2829   /* Verify that MMC card is ready to use after Speed mode switch*/
2830   tickstart = HAL_GetTick();
2831   while ((HAL_MMC_GetCardState(hmmc) != HAL_MMC_CARD_TRANSFER))
2832   {
2833     if ((HAL_GetTick() - tickstart) >=  SDMMC_DATATIMEOUT)
2834     {
2835       hmmc->ErrorCode = HAL_MMC_ERROR_TIMEOUT;
2836       hmmc->State = HAL_MMC_STATE_READY;
2837       return HAL_TIMEOUT;
2838     }
2839   }
2840 
2841   /* Change State */
2842   hmmc->State = HAL_MMC_STATE_READY;
2843   return status;
2844 }
2845 #endif
2846 
2847 /**
2848   * @brief  Gets the current mmc card data state.
2849   * @param  hmmc pointer to MMC handle
2850   * @retval Card state
2851   */
HAL_MMC_GetCardState(MMC_HandleTypeDef * hmmc)2852 HAL_MMC_CardStateTypeDef HAL_MMC_GetCardState(MMC_HandleTypeDef *hmmc)
2853 {
2854   uint32_t cardstate;
2855   uint32_t errorstate;
2856   uint32_t resp1 = 0U;
2857 
2858   errorstate = MMC_SendStatus(hmmc, &resp1);
2859   if(errorstate != HAL_MMC_ERROR_NONE)
2860   {
2861     hmmc->ErrorCode |= errorstate;
2862   }
2863 
2864   cardstate = ((resp1 >> 9U) & 0x0FU);
2865 
2866   return (HAL_MMC_CardStateTypeDef)cardstate;
2867 }
2868 
2869 /**
2870   * @brief  Abort the current transfer and disable the MMC.
2871   * @param  hmmc pointer to a MMC_HandleTypeDef structure that contains
2872   *                the configuration information for MMC module.
2873   * @retval HAL status
2874   */
HAL_MMC_Abort(MMC_HandleTypeDef * hmmc)2875 HAL_StatusTypeDef HAL_MMC_Abort(MMC_HandleTypeDef *hmmc)
2876 {
2877   HAL_MMC_CardStateTypeDef CardState;
2878 
2879   /* DIsable All interrupts */
2880   __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\
2881                            SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR);
2882 
2883   /* Clear All flags */
2884   __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2885 
2886 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
2887   if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL))
2888   {
2889     /* Disable the MMC DMA request */
2890     hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN);
2891 
2892     /* Abort the MMC DMA Tx Stream */
2893     if(hmmc->hdmatx != NULL)
2894     {
2895       if(HAL_DMA_Abort(hmmc->hdmatx) != HAL_OK)
2896       {
2897         hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
2898       }
2899     }
2900     /* Abort the MMC DMA Rx Stream */
2901     if(hmmc->hdmarx != NULL)
2902     {
2903       if(HAL_DMA_Abort(hmmc->hdmarx) != HAL_OK)
2904       {
2905         hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
2906       }
2907     }
2908   }
2909 #else
2910   /* If IDMA Context, disable Internal DMA */
2911   hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA;
2912 #endif
2913 
2914   hmmc->State = HAL_MMC_STATE_READY;
2915 
2916   /* Initialize the MMC operation */
2917   hmmc->Context = MMC_CONTEXT_NONE;
2918 
2919   CardState = HAL_MMC_GetCardState(hmmc);
2920   if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2921   {
2922     hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
2923   }
2924   if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2925   {
2926     return HAL_ERROR;
2927   }
2928   return HAL_OK;
2929 }
2930 
2931 /**
2932   * @brief  Abort the current transfer and disable the MMC (IT mode).
2933   * @param  hmmc pointer to a MMC_HandleTypeDef structure that contains
2934   *                the configuration information for MMC module.
2935   * @retval HAL status
2936   */
HAL_MMC_Abort_IT(MMC_HandleTypeDef * hmmc)2937 HAL_StatusTypeDef HAL_MMC_Abort_IT(MMC_HandleTypeDef *hmmc)
2938 {
2939   HAL_MMC_CardStateTypeDef CardState;
2940 
2941   /* DIsable All interrupts */
2942   __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\
2943                            SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR);
2944 
2945 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
2946   /* If IDMA Context, disable Internal DMA */
2947   hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA;
2948 #endif
2949 
2950   /* Clear All flags */
2951   __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2952 
2953 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
2954   if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL))
2955   {
2956     /* Disable the MMC DMA request */
2957     hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN);
2958 
2959     /* Abort the MMC DMA Tx Stream */
2960     if(hmmc->hdmatx != NULL)
2961     {
2962       hmmc->hdmatx->XferAbortCallback =  MMC_DMATxAbort;
2963       if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
2964       {
2965         hmmc->hdmatx = NULL;
2966       }
2967     }
2968     /* Abort the MMC DMA Rx Stream */
2969     if(hmmc->hdmarx != NULL)
2970     {
2971       hmmc->hdmarx->XferAbortCallback =  MMC_DMARxAbort;
2972       if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
2973       {
2974         hmmc->hdmarx = NULL;
2975       }
2976     }
2977   }
2978 
2979   /* No transfer ongoing on both DMA channels*/
2980   if((hmmc->hdmatx == NULL) && (hmmc->hdmarx == NULL))
2981   {
2982 #endif
2983     CardState = HAL_MMC_GetCardState(hmmc);
2984     hmmc->State = HAL_MMC_STATE_READY;
2985 
2986     if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2987     {
2988       hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
2989     }
2990     if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2991     {
2992       return HAL_ERROR;
2993     }
2994     else
2995     {
2996 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2997       hmmc->AbortCpltCallback(hmmc);
2998 #else
2999       HAL_MMC_AbortCallback(hmmc);
3000 #endif
3001 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
3002     }
3003 #endif
3004   }
3005 
3006   return HAL_OK;
3007 }
3008 
3009 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
3010 /**
3011   * @brief  Perform specific commands sequence for the different type of erase.
3012   * @note   This API should be followed by a check on the card state through
3013   *         HAL_MMC_GetCardState().
3014   * @param  hmmc Pointer to MMC handle
3015   * @param  EraseType Specifies the type of erase to be performed
3016   *          This parameter can be one of the following values:
3017   *            @arg HAL_MMC_ERASE Erase the erase groups identified by CMD35 & 36
3018   *            @arg HAL_MMC_TRIM Erase the write blocks identified by CMD35 & 36
3019   *            @arg HAL_MMC_DISCARD Discard the write blocks identified by CMD35 & 36
3020   *            @arg HAL_MMC_SECURE_ERASE Perform a secure purge according SRT on the erase groups identified by CMD35 & 36
3021   *            @arg HAL_MMC_SECURE_TRIM_STEP1 Mark the write blocks identified by CMD35 & 36 for secure erase
3022   *            @arg HAL_MMC_SECURE_TRIM_STEP2 Perform a secure purge according SRT on the write blocks previously identified
3023   * @param  BlockStartAdd Start Block address
3024   * @param  BlockEndAdd End Block address
3025   * @retval HAL status
3026   */
HAL_MMC_EraseSequence(MMC_HandleTypeDef * hmmc,uint32_t EraseType,uint32_t BlockStartAdd,uint32_t BlockEndAdd)3027 HAL_StatusTypeDef HAL_MMC_EraseSequence(MMC_HandleTypeDef *hmmc, uint32_t EraseType, uint32_t BlockStartAdd, uint32_t BlockEndAdd)
3028 {
3029   uint32_t errorstate;
3030   uint32_t start_add = BlockStartAdd;
3031   uint32_t end_add = BlockEndAdd;
3032   uint32_t tickstart = HAL_GetTick();
3033 
3034   /* Check the erase type value is correct */
3035   assert_param(IS_MMC_ERASE_TYPE(EraseType));
3036 
3037   /* Check the coherence between start and end address */
3038   if(end_add < start_add)
3039   {
3040     hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
3041     return HAL_ERROR;
3042   }
3043 
3044   /* Check that the end address is not out of range of device memory */
3045   if(end_add > (hmmc->MmcCard.LogBlockNbr))
3046   {
3047     hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
3048     return HAL_ERROR;
3049   }
3050 
3051   /* Check if the card command class supports erase command */
3052   if(((hmmc->MmcCard.Class) & SDMMC_CCCC_ERASE) == 0U)
3053   {
3054     hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
3055     return HAL_ERROR;
3056   }
3057 
3058   /* Check the state of the driver */
3059   if(hmmc->State == HAL_MMC_STATE_READY)
3060   {
3061     /* Change State */
3062     hmmc->State = HAL_MMC_STATE_BUSY;
3063 
3064     /* Check that the card is not locked */
3065     if((SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
3066     {
3067       hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED;
3068       hmmc->State = HAL_MMC_STATE_READY;
3069       return HAL_ERROR;
3070     }
3071 
3072     /* In case of low capacity card, the address is not block number but bytes */
3073     if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
3074     {
3075       start_add *= 512U;
3076       end_add   *= 512U;
3077     }
3078 
3079     /* Send CMD35 MMC_ERASE_GRP_START with start address as argument */
3080     errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, start_add);
3081     if(errorstate == HAL_MMC_ERROR_NONE)
3082     {
3083       /* Send CMD36 MMC_ERASE_GRP_END with end address as argument */
3084       errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, end_add);
3085       if(errorstate == HAL_MMC_ERROR_NONE)
3086       {
3087         /* Send CMD38 ERASE with erase type as argument */
3088         errorstate = SDMMC_CmdErase(hmmc->Instance, EraseType);
3089         if(errorstate == HAL_MMC_ERROR_NONE)
3090         {
3091           if ((EraseType == HAL_MMC_SECURE_ERASE) || (EraseType == HAL_MMC_SECURE_TRIM_STEP2))
3092           {
3093             /* Wait that the device is ready by checking the D0 line */
3094             while((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
3095             {
3096               if((HAL_GetTick()-tickstart) >= SDMMC_MAXERASETIMEOUT)
3097               {
3098                 errorstate = HAL_MMC_ERROR_TIMEOUT;
3099               }
3100             }
3101 
3102             /* Clear the flag corresponding to end D0 bus line */
3103             __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
3104           }
3105         }
3106       }
3107     }
3108 
3109     /* Change State */
3110     hmmc->State = HAL_MMC_STATE_READY;
3111 
3112     /* Manage errors */
3113     if(errorstate != HAL_MMC_ERROR_NONE)
3114     {
3115       /* Clear all the static flags */
3116       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3117       hmmc->ErrorCode |= errorstate;
3118 
3119       if(errorstate != HAL_MMC_ERROR_TIMEOUT)
3120       {
3121         return HAL_ERROR;
3122       }
3123       else
3124       {
3125         return HAL_TIMEOUT;
3126       }
3127     }
3128     else
3129     {
3130       return HAL_OK;
3131     }
3132   }
3133   else
3134   {
3135     return HAL_BUSY;
3136   }
3137 }
3138 
3139 /**
3140   * @brief  Perform sanitize operation on the device.
3141   * @note   This API should be followed by a check on the card state through
3142   *         HAL_MMC_GetCardState().
3143   * @param  hmmc Pointer to MMC handle
3144   * @retval HAL status
3145   */
HAL_MMC_Sanitize(MMC_HandleTypeDef * hmmc)3146 HAL_StatusTypeDef HAL_MMC_Sanitize(MMC_HandleTypeDef *hmmc)
3147 {
3148   uint32_t errorstate, response = 0U, count;
3149   uint32_t tickstart = HAL_GetTick();
3150 
3151   /* Check the state of the driver */
3152   if(hmmc->State == HAL_MMC_STATE_READY)
3153   {
3154     /* Change State */
3155     hmmc->State = HAL_MMC_STATE_BUSY;
3156 
3157     /* Index : 165 - Value : 0x01 */
3158     errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03A50100U);
3159     if(errorstate == HAL_MMC_ERROR_NONE)
3160     {
3161       /* Wait that the device is ready by checking the D0 line */
3162       while((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
3163       {
3164         if((HAL_GetTick()-tickstart) >= SDMMC_MAXERASETIMEOUT)
3165         {
3166           errorstate = HAL_MMC_ERROR_TIMEOUT;
3167         }
3168       }
3169 
3170       /* Clear the flag corresponding to end D0 bus line */
3171       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
3172 
3173       if(errorstate == HAL_MMC_ERROR_NONE)
3174       {
3175         /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3176         count = SDMMC_MAX_TRIAL;
3177         do
3178         {
3179           errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3180           if(errorstate != HAL_MMC_ERROR_NONE)
3181           {
3182             break;
3183           }
3184 
3185           /* Get command response */
3186           response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3187           count--;
3188         }while(((response & 0x100U) == 0U) && (count != 0U));
3189 
3190         /* Check the status after the switch command execution */
3191         if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
3192         {
3193           /* Check the bit SWITCH_ERROR of the device status */
3194           if ((response & 0x80U) != 0U)
3195           {
3196             errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
3197           }
3198         }
3199         else if (count == 0U)
3200         {
3201           errorstate = SDMMC_ERROR_TIMEOUT;
3202         }
3203         else
3204         {
3205           /* Nothing to do */
3206         }
3207       }
3208     }
3209 
3210     /* Change State */
3211     hmmc->State = HAL_MMC_STATE_READY;
3212 
3213     /* Manage errors */
3214     if(errorstate != HAL_MMC_ERROR_NONE)
3215     {
3216       /* Clear all the static flags */
3217       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3218       hmmc->ErrorCode |= errorstate;
3219 
3220       if(errorstate != HAL_MMC_ERROR_TIMEOUT)
3221       {
3222         return HAL_ERROR;
3223       }
3224       else
3225       {
3226         return HAL_TIMEOUT;
3227       }
3228     }
3229     else
3230     {
3231       return HAL_OK;
3232     }
3233   }
3234   else
3235   {
3236     return HAL_BUSY;
3237   }
3238 }
3239 
3240 /**
3241   * @brief  Configure the Secure Removal Type (SRT) in the Extended CSD register.
3242   * @note   This API should be followed by a check on the card state through
3243   *         HAL_MMC_GetCardState().
3244   * @param  hmmc Pointer to MMC handle
3245   * @param  SRTMode Specifies the type of erase to be performed
3246   *          This parameter can be one of the following values:
3247   *            @arg HAL_MMC_SRT_ERASE Information removed by an erase
3248   *            @arg HAL_MMC_SRT_WRITE_CHAR_ERASE Information removed by an overwriting with a character followed by an erase
3249   *            @arg HAL_MMC_SRT_WRITE_CHAR_COMPL_RANDOM Information removed by an overwriting with a character, its complement then a random character
3250   *            @arg HAL_MMC_SRT_VENDOR_DEFINED Information removed using a vendor defined
3251   * @retval HAL status
3252   */
HAL_MMC_ConfigSecRemovalType(MMC_HandleTypeDef * hmmc,uint32_t SRTMode)3253 HAL_StatusTypeDef HAL_MMC_ConfigSecRemovalType(MMC_HandleTypeDef *hmmc, uint32_t SRTMode)
3254 {
3255   uint32_t srt, errorstate, response = 0U, count;
3256 
3257   /* Check the erase type value is correct */
3258   assert_param(IS_MMC_SRT_TYPE(SRTMode));
3259 
3260   /* Check the state of the driver */
3261   if(hmmc->State == HAL_MMC_STATE_READY)
3262   {
3263     /* Get the supported values by the device */
3264     if(HAL_MMC_GetSupportedSecRemovalType(hmmc, &srt) == HAL_OK)
3265     {
3266       /* Change State */
3267       hmmc->State = HAL_MMC_STATE_BUSY;
3268 
3269       /* Check the value passed as parameter is supported by the device */
3270       if((SRTMode & srt) != 0U)
3271       {
3272         /* Index : 16 - Value : SRTMode */
3273         srt |= ((POSITION_VAL(SRTMode)) << 4U);
3274         errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03100000U | (srt << 8U)));
3275         if(errorstate == HAL_MMC_ERROR_NONE)
3276         {
3277           /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3278           count = SDMMC_MAX_TRIAL;
3279           do
3280           {
3281             errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3282             if(errorstate != HAL_MMC_ERROR_NONE)
3283             {
3284               break;
3285             }
3286 
3287             /* Get command response */
3288             response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3289             count--;
3290           }while(((response & 0x100U) == 0U) && (count != 0U));
3291 
3292           /* Check the status after the switch command execution */
3293           if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
3294           {
3295             /* Check the bit SWITCH_ERROR of the device status */
3296             if ((response & 0x80U) != 0U)
3297             {
3298               errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
3299             }
3300           }
3301           else if (count == 0U)
3302           {
3303             errorstate = SDMMC_ERROR_TIMEOUT;
3304           }
3305           else
3306           {
3307             /* Nothing to do */
3308           }
3309         }
3310       }
3311       else
3312       {
3313         errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3314       }
3315 
3316       /* Change State */
3317       hmmc->State = HAL_MMC_STATE_READY;
3318     }
3319     else
3320     {
3321       errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
3322     }
3323 
3324     /* Manage errors */
3325     if(errorstate != HAL_MMC_ERROR_NONE)
3326     {
3327       /* Clear all the static flags */
3328       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3329       hmmc->ErrorCode |= errorstate;
3330       return HAL_ERROR;
3331     }
3332     else
3333     {
3334       return HAL_OK;
3335     }
3336   }
3337   else
3338   {
3339     return HAL_BUSY;
3340   }
3341 }
3342 
3343 /**
3344   * @brief  Gets the supported values of the the Secure Removal Type (SRT).
3345   * @param  hmmc pointer to MMC handle
3346   * @param  SupportedSRT pointer for supported SRT value
3347   *          This parameter is a bit field of the following values:
3348   *            @arg HAL_MMC_SRT_ERASE Information removed by an erase
3349   *            @arg HAL_MMC_SRT_WRITE_CHAR_ERASE Information removed by an overwriting with a character followed by an erase
3350   *            @arg HAL_MMC_SRT_WRITE_CHAR_COMPL_RANDOM Information removed by an overwriting with a character, its complement then a random character
3351   *            @arg HAL_MMC_SRT_VENDOR_DEFINED Information removed using a vendor defined
3352   * @retval HAL status
3353   */
HAL_MMC_GetSupportedSecRemovalType(MMC_HandleTypeDef * hmmc,uint32_t * SupportedSRT)3354 HAL_StatusTypeDef HAL_MMC_GetSupportedSecRemovalType(MMC_HandleTypeDef *hmmc, uint32_t *SupportedSRT)
3355 {
3356   /* Check the state of the driver */
3357   if(hmmc->State == HAL_MMC_STATE_READY)
3358   {
3359     /* Change State */
3360     hmmc->State = HAL_MMC_STATE_BUSY;
3361 
3362     /* Read field SECURE_REMOVAL_TYPE [16 = 4*4] of the Extended CSD register */
3363     *SupportedSRT = (hmmc->Ext_CSD[4] & 0x0000000FU); /* Bits [3:0] of field 16 */
3364 
3365     /* Change State */
3366     hmmc->State = HAL_MMC_STATE_READY;
3367 
3368     return HAL_OK;
3369   }
3370   else
3371   {
3372     return HAL_BUSY;
3373   }
3374 }
3375 
3376 /**
3377   * @brief  Switch the device from Standby State to Sleep State.
3378   * @param  hmmc pointer to MMC handle
3379   * @retval HAL status
3380   */
HAL_MMC_SleepDevice(MMC_HandleTypeDef * hmmc)3381 HAL_StatusTypeDef HAL_MMC_SleepDevice(MMC_HandleTypeDef *hmmc)
3382 {
3383   uint32_t errorstate, sleep_timeout, timeout, count, response = 0U;
3384   uint32_t tickstart = HAL_GetTick();
3385 
3386   /* Check the state of the driver */
3387   if(hmmc->State == HAL_MMC_STATE_READY)
3388   {
3389     /* Change State */
3390     hmmc->State = HAL_MMC_STATE_BUSY;
3391 
3392     /* Set the power-off notification to powered-on : Ext_CSD[34] = 1 */
3393     errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03220100U));
3394     if (errorstate == HAL_MMC_ERROR_NONE)
3395     {
3396       /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3397       count = SDMMC_MAX_TRIAL;
3398       do
3399       {
3400         errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3401         if(errorstate != HAL_MMC_ERROR_NONE)
3402         {
3403           break;
3404         }
3405 
3406         /* Get command response */
3407         response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3408         count--;
3409       }while(((response & 0x100U) == 0U) && (count != 0U));
3410 
3411       /* Check the status after the switch command execution */
3412       if (count == 0U)
3413       {
3414         errorstate = SDMMC_ERROR_TIMEOUT;
3415       }
3416       else if (errorstate == HAL_MMC_ERROR_NONE)
3417       {
3418         /* Check the bit SWITCH_ERROR of the device status */
3419         if ((response & 0x80U) != 0U)
3420         {
3421           errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3422         }
3423         else
3424         {
3425           /* Set the power-off notification to sleep notification : Ext_CSD[34] = 4 */
3426           errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03220400U));
3427           if (errorstate == HAL_MMC_ERROR_NONE)
3428           {
3429             /* Field SLEEP_NOTIFICATION_TIME [216] */
3430             sleep_timeout = ((hmmc->Ext_CSD[(MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_INDEX/4)] >> MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_POS) & 0x000000FFU);
3431 
3432             /* Sleep/Awake Timeout = 10�s * 2^SLEEP_NOTIFICATION_TIME, max value of SLEEP_NOTIFICATION_TIME is 0x17 */
3433             /* In HAL, the tick interrupt occurs each ms */
3434             timeout = (((1UL << (sleep_timeout & 0x1FU)) / 100U) + 1U);
3435 
3436             /* Wait that the device is ready by checking the D0 line */
3437             while((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
3438             {
3439               if((HAL_GetTick() - tickstart) >= timeout)
3440               {
3441                 errorstate = SDMMC_ERROR_TIMEOUT;
3442               }
3443             }
3444 
3445             /* Clear the flag corresponding to end D0 bus line */
3446             __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
3447 
3448             if (errorstate == HAL_MMC_ERROR_NONE)
3449             {
3450               /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3451               count = SDMMC_MAX_TRIAL;
3452               do
3453               {
3454                 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3455                 if(errorstate != HAL_MMC_ERROR_NONE)
3456                 {
3457                   break;
3458                 }
3459 
3460                 /* Get command response */
3461                 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3462                 count--;
3463               }while(((response & 0x100U) == 0U) && (count != 0U));
3464 
3465               /* Check the status after the switch command execution */
3466               if (count == 0U)
3467               {
3468                 errorstate = SDMMC_ERROR_TIMEOUT;
3469               }
3470               else if (errorstate == HAL_MMC_ERROR_NONE)
3471               {
3472                 /* Check the bit SWITCH_ERROR of the device status */
3473                 if ((response & 0x80U) != 0U)
3474                 {
3475                   errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3476                 }
3477                 else
3478                 {
3479                   /* Switch the device in stand-by mode */
3480                   (void)SDMMC_CmdSelDesel(hmmc->Instance, 0U);
3481 
3482                   /* Field S_A_TIEMOUT [217] */
3483                   sleep_timeout = ((hmmc->Ext_CSD[(MMC_EXT_CSD_S_A_TIMEOUT_INDEX/4)] >> MMC_EXT_CSD_S_A_TIMEOUT_POS) & 0x000000FFU);
3484 
3485                   /* Sleep/Awake Timeout = 100ns * 2^S_A_TIMEOUT, max value of S_A_TIMEOUT is 0x17 */
3486                   /* In HAL, the tick interrupt occurs each ms */
3487                   timeout = (((1UL << (sleep_timeout & 0x1FU)) / 10000U) + 1U);
3488 
3489                   if (HAL_MMC_GetCardState(hmmc) == HAL_MMC_CARD_STANDBY)
3490                   {
3491                     /* Send CMD5 CMD_MMC_SLEEP_AWAKE with RCA and SLEEP as argument */
3492                     errorstate = SDMMC_CmdSleepMmc(hmmc->Instance, ((hmmc->MmcCard.RelCardAdd << 16U) | (0x1U << 15U)));
3493                     if (errorstate == HAL_MMC_ERROR_NONE)
3494                     {
3495                       /* Wait that the device is ready by checking the D0 line */
3496                       while((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
3497                       {
3498                         if((HAL_GetTick() - tickstart) >= timeout)
3499                         {
3500                           errorstate = SDMMC_ERROR_TIMEOUT;
3501                         }
3502                       }
3503 
3504                       /* Clear the flag corresponding to end D0 bus line */
3505                       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
3506                     }
3507                   }
3508                   else
3509                   {
3510                     errorstate = SDMMC_ERROR_REQUEST_NOT_APPLICABLE;
3511                   }
3512                 }
3513               }
3514               else
3515               {
3516                 /* Nothing to do */
3517               }
3518             }
3519           }
3520         }
3521       }
3522       else
3523       {
3524         /* Nothing to do */
3525       }
3526     }
3527 
3528     /* Change State */
3529     hmmc->State = HAL_MMC_STATE_READY;
3530 
3531     /* Manage errors */
3532     if (errorstate != HAL_MMC_ERROR_NONE)
3533     {
3534       /* Clear all the static flags */
3535       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3536       hmmc->ErrorCode |= errorstate;
3537 
3538       if (errorstate != HAL_MMC_ERROR_TIMEOUT)
3539       {
3540         return HAL_ERROR;
3541       }
3542       else
3543       {
3544         return HAL_TIMEOUT;
3545       }
3546     }
3547     else
3548     {
3549       return HAL_OK;
3550     }
3551   }
3552   else
3553   {
3554     return HAL_BUSY;
3555   }
3556 }
3557 
3558 /**
3559   * @brief  Switch the device from Sleep State to Standby State.
3560   * @param  hmmc pointer to MMC handle
3561   * @retval HAL status
3562   */
HAL_MMC_AwakeDevice(MMC_HandleTypeDef * hmmc)3563 HAL_StatusTypeDef HAL_MMC_AwakeDevice(MMC_HandleTypeDef *hmmc)
3564 {
3565   uint32_t errorstate, sleep_timeout, timeout, count, response = 0U;
3566   uint32_t tickstart = HAL_GetTick();
3567 
3568   /* Check the state of the driver */
3569   if (hmmc->State == HAL_MMC_STATE_READY)
3570   {
3571     /* Change State */
3572     hmmc->State = HAL_MMC_STATE_BUSY;
3573 
3574     /* Field S_A_TIEMOUT [217] */
3575     sleep_timeout = ((hmmc->Ext_CSD[(MMC_EXT_CSD_S_A_TIMEOUT_INDEX/4)] >> MMC_EXT_CSD_S_A_TIMEOUT_POS) & 0x000000FFU);
3576 
3577     /* Sleep/Awake Timeout = 100ns * 2^S_A_TIMEOUT, max value of S_A_TIMEOUT is 0x17 */
3578     /* In HAL, the tick interrupt occurs each ms */
3579     timeout = (((1UL << (sleep_timeout & 0x1FU)) / 10000U) + 1U);
3580 
3581     /* Send CMD5 CMD_MMC_SLEEP_AWAKE with RCA and AWAKE as argument */
3582     errorstate = SDMMC_CmdSleepMmc(hmmc->Instance, (hmmc->MmcCard.RelCardAdd << 16U));
3583     if (errorstate == HAL_MMC_ERROR_NONE)
3584     {
3585       /* Wait that the device is ready by checking the D0 line */
3586       while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE))
3587       {
3588         if((HAL_GetTick() - tickstart) >= timeout)
3589         {
3590           errorstate = SDMMC_ERROR_TIMEOUT;
3591         }
3592       }
3593 
3594       /* Clear the flag corresponding to end D0 bus line */
3595       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END);
3596 
3597       if (errorstate == HAL_MMC_ERROR_NONE)
3598       {
3599         if (HAL_MMC_GetCardState(hmmc) == HAL_MMC_CARD_STANDBY)
3600         {
3601           /* Switch the device in transfer mode */
3602           errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3603           if (errorstate == HAL_MMC_ERROR_NONE)
3604           {
3605             if (HAL_MMC_GetCardState(hmmc) == HAL_MMC_CARD_TRANSFER)
3606             {
3607               /* Set the power-off notification to powered-on : Ext_CSD[34] = 1 */
3608               errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03220100U));
3609               if (errorstate == HAL_MMC_ERROR_NONE)
3610               {
3611                 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3612                 count = SDMMC_MAX_TRIAL;
3613                 do
3614                 {
3615                   errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3616                   if(errorstate != HAL_MMC_ERROR_NONE)
3617                   {
3618                     break;
3619                   }
3620 
3621                   /* Get command response */
3622                   response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3623                   count--;
3624                 }while(((response & 0x100U) == 0U) && (count != 0U));
3625 
3626                 /* Check the status after the switch command execution */
3627                 if (count == 0U)
3628                 {
3629                   errorstate = SDMMC_ERROR_TIMEOUT;
3630                 }
3631                 else if (errorstate == HAL_MMC_ERROR_NONE)
3632                 {
3633                   /* Check the bit SWITCH_ERROR of the device status */
3634                   if ((response & 0x80U) != 0U)
3635                   {
3636                     errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3637                   }
3638                 }
3639                 else
3640                 {
3641                   /* Nothing to do */
3642                 }
3643               }
3644             }
3645             else
3646             {
3647               errorstate = SDMMC_ERROR_REQUEST_NOT_APPLICABLE;
3648             }
3649           }
3650         }
3651         else
3652         {
3653           errorstate = SDMMC_ERROR_REQUEST_NOT_APPLICABLE;
3654         }
3655       }
3656     }
3657 
3658     /* Change State */
3659     hmmc->State = HAL_MMC_STATE_READY;
3660 
3661     /* Manage errors */
3662     if (errorstate != HAL_MMC_ERROR_NONE)
3663     {
3664       /* Clear all the static flags */
3665       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3666       hmmc->ErrorCode |= errorstate;
3667 
3668       if (errorstate != HAL_MMC_ERROR_TIMEOUT)
3669       {
3670         return HAL_ERROR;
3671       }
3672       else
3673       {
3674         return HAL_TIMEOUT;
3675       }
3676     }
3677     else
3678     {
3679       return HAL_OK;
3680     }
3681   }
3682   else
3683   {
3684     return HAL_BUSY;
3685   }
3686 }
3687 #endif /* defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) */
3688 
3689 /**
3690   * @}
3691   */
3692 
3693 /**
3694   * @}
3695   */
3696 
3697 /* Private function ----------------------------------------------------------*/
3698 /** @addtogroup MMC_Private_Functions
3699   * @{
3700   */
3701 
3702 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx)
3703 /**
3704   * @brief  DMA MMC transmit process complete callback
3705   * @param  hdma DMA handle
3706   * @retval None
3707   */
MMC_DMATransmitCplt(DMA_HandleTypeDef * hdma)3708 static void MMC_DMATransmitCplt(DMA_HandleTypeDef *hdma)
3709 {
3710   MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
3711 
3712   /* Enable DATAEND Interrupt */
3713   __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DATAEND));
3714 }
3715 
3716 /**
3717   * @brief  DMA MMC receive process complete callback
3718   * @param  hdma DMA handle
3719   * @retval None
3720   */
MMC_DMAReceiveCplt(DMA_HandleTypeDef * hdma)3721 static void MMC_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
3722 {
3723   MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
3724   uint32_t errorstate;
3725 
3726   /* Send stop command in multiblock write */
3727   if(hmmc->Context == (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA))
3728   {
3729     errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
3730     if(errorstate != HAL_MMC_ERROR_NONE)
3731     {
3732       hmmc->ErrorCode |= errorstate;
3733 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
3734       hmmc->ErrorCallback(hmmc);
3735 #else
3736       HAL_MMC_ErrorCallback(hmmc);
3737 #endif
3738     }
3739   }
3740 
3741   /* Disable the DMA transfer for transmit request by setting the DMAEN bit
3742   in the MMC DCTRL register */
3743   hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN);
3744 
3745   /* Clear all the static flags */
3746   __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
3747 
3748   hmmc->State = HAL_MMC_STATE_READY;
3749   hmmc->Context = MMC_CONTEXT_NONE;
3750 
3751 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
3752   hmmc->RxCpltCallback(hmmc);
3753 #else
3754   HAL_MMC_RxCpltCallback(hmmc);
3755 #endif
3756 }
3757 
3758 /**
3759   * @brief  DMA MMC communication error callback
3760   * @param  hdma DMA handle
3761   * @retval None
3762   */
MMC_DMAError(DMA_HandleTypeDef * hdma)3763 static void MMC_DMAError(DMA_HandleTypeDef *hdma)
3764 {
3765   MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
3766   HAL_MMC_CardStateTypeDef CardState;
3767   uint32_t RxErrorCode, TxErrorCode;
3768 
3769   RxErrorCode = hmmc->hdmarx->ErrorCode;
3770   TxErrorCode = hmmc->hdmatx->ErrorCode;
3771   if((RxErrorCode == HAL_DMA_ERROR_TE) || (TxErrorCode == HAL_DMA_ERROR_TE))
3772   {
3773     /* Clear All flags */
3774     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
3775 
3776     /* Disable All interrupts */
3777     __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\
3778       SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR);
3779 
3780     hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
3781     CardState = HAL_MMC_GetCardState(hmmc);
3782     if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
3783     {
3784       hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
3785     }
3786 
3787     hmmc->State= HAL_MMC_STATE_READY;
3788     hmmc->Context = MMC_CONTEXT_NONE;
3789   }
3790 
3791 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
3792   hmmc->ErrorCallback(hmmc);
3793 #else
3794   HAL_MMC_ErrorCallback(hmmc);
3795 #endif
3796   }
3797 
3798 /**
3799   * @brief  DMA MMC Tx Abort callback
3800   * @param  hdma DMA handle
3801   * @retval None
3802   */
MMC_DMATxAbort(DMA_HandleTypeDef * hdma)3803 static void MMC_DMATxAbort(DMA_HandleTypeDef *hdma)
3804 {
3805   MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
3806   HAL_MMC_CardStateTypeDef CardState;
3807 
3808   if(hmmc->hdmatx != NULL)
3809   {
3810     hmmc->hdmatx = NULL;
3811   }
3812 
3813   /* All DMA channels are aborted */
3814   if(hmmc->hdmarx == NULL)
3815   {
3816     CardState = HAL_MMC_GetCardState(hmmc);
3817     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
3818     hmmc->State = HAL_MMC_STATE_READY;
3819     hmmc->Context = MMC_CONTEXT_NONE;
3820     if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
3821     {
3822       hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
3823 
3824       if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
3825       {
3826 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
3827         hmmc->AbortCpltCallback(hmmc);
3828 #else
3829         HAL_MMC_AbortCallback(hmmc);
3830 #endif
3831       }
3832       else
3833       {
3834 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
3835         hmmc->ErrorCallback(hmmc);
3836 #else
3837         HAL_MMC_ErrorCallback(hmmc);
3838 #endif
3839       }
3840     }
3841   }
3842 }
3843 
3844 /**
3845   * @brief  DMA MMC Rx Abort callback
3846   * @param  hdma DMA handle
3847   * @retval None
3848   */
MMC_DMARxAbort(DMA_HandleTypeDef * hdma)3849 static void MMC_DMARxAbort(DMA_HandleTypeDef *hdma)
3850 {
3851   MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
3852   HAL_MMC_CardStateTypeDef CardState;
3853 
3854   if(hmmc->hdmarx != NULL)
3855   {
3856     hmmc->hdmarx = NULL;
3857   }
3858 
3859   /* All DMA channels are aborted */
3860   if(hmmc->hdmatx == NULL)
3861   {
3862     CardState = HAL_MMC_GetCardState(hmmc);
3863     hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
3864     hmmc->State = HAL_MMC_STATE_READY;
3865     hmmc->Context = MMC_CONTEXT_NONE;
3866     if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
3867     {
3868       hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
3869 
3870       if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
3871       {
3872 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
3873         hmmc->AbortCpltCallback(hmmc);
3874 #else
3875         HAL_MMC_AbortCallback(hmmc);
3876 #endif
3877       }
3878       else
3879       {
3880 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
3881         hmmc->ErrorCallback(hmmc);
3882 #else
3883         HAL_MMC_ErrorCallback(hmmc);
3884 #endif
3885       }
3886     }
3887   }
3888 }
3889 #endif
3890 
3891 /**
3892   * @brief  Initializes the mmc card.
3893   * @param  hmmc Pointer to MMC handle
3894   * @retval MMC Card error state
3895   */
MMC_InitCard(MMC_HandleTypeDef * hmmc)3896 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc)
3897 {
3898   HAL_MMC_CardCSDTypeDef CSD;
3899   uint32_t errorstate;
3900   uint16_t mmc_rca = 2U;
3901   MMC_InitTypeDef Init;
3902 
3903   /* Check the power State */
3904   if(SDMMC_GetPowerState(hmmc->Instance) == 0U)
3905   {
3906     /* Power off */
3907     return HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
3908   }
3909 
3910   /* Send CMD2 ALL_SEND_CID */
3911   errorstate = SDMMC_CmdSendCID(hmmc->Instance);
3912   if(errorstate != HAL_MMC_ERROR_NONE)
3913   {
3914     return errorstate;
3915   }
3916   else
3917   {
3918     /* Get Card identification number data */
3919     hmmc->CID[0U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3920     hmmc->CID[1U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2);
3921     hmmc->CID[2U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP3);
3922     hmmc->CID[3U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP4);
3923   }
3924 
3925   /* Send CMD3 SET_REL_ADDR with RCA = 2 (should be greater than 1) */
3926   /* MMC Card publishes its RCA. */
3927   errorstate = SDMMC_CmdSetRelAddMmc(hmmc->Instance, mmc_rca);
3928   if(errorstate != HAL_MMC_ERROR_NONE)
3929   {
3930     return errorstate;
3931   }
3932 
3933   /* Get the MMC card RCA */
3934   hmmc->MmcCard.RelCardAdd = mmc_rca;
3935 
3936   /* Send CMD9 SEND_CSD with argument as card's RCA */
3937   errorstate = SDMMC_CmdSendCSD(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
3938   if(errorstate != HAL_MMC_ERROR_NONE)
3939   {
3940     return errorstate;
3941   }
3942   else
3943   {
3944     /* Get Card Specific Data */
3945     hmmc->CSD[0U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3946     hmmc->CSD[1U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2);
3947     hmmc->CSD[2U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP3);
3948     hmmc->CSD[3U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP4);
3949   }
3950 
3951   /* Get the Card Class */
3952   hmmc->MmcCard.Class = (SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2) >> 20U);
3953 
3954    /* Select the Card */
3955   errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3956   if(errorstate != HAL_MMC_ERROR_NONE)
3957   {
3958     return errorstate;
3959   }
3960 
3961   /* Get CSD parameters */
3962   if (HAL_MMC_GetCardCSD(hmmc, &CSD) != HAL_OK)
3963   {
3964     return hmmc->ErrorCode;
3965   }
3966 
3967   /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3968   errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3969   if(errorstate != HAL_MMC_ERROR_NONE)
3970   {
3971     hmmc->ErrorCode |= errorstate;
3972   }
3973 
3974   /* Get Extended CSD parameters */
3975   if (HAL_MMC_GetCardExtCSD(hmmc, hmmc->Ext_CSD, SDMMC_DATATIMEOUT) != HAL_OK)
3976   {
3977     return hmmc->ErrorCode;
3978   }
3979 
3980   /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3981   errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3982   if(errorstate != HAL_MMC_ERROR_NONE)
3983   {
3984     hmmc->ErrorCode |= errorstate;
3985   }
3986 
3987   /* Configure the SDMMC peripheral */
3988   Init = hmmc->Init;
3989   Init.BusWide = SDMMC_BUS_WIDE_1B;
3990   (void)SDMMC_Init(hmmc->Instance, Init);
3991 
3992   /* All cards are initialized */
3993   return HAL_MMC_ERROR_NONE;
3994 }
3995 
3996 /**
3997   * @brief  Enquires cards about their operating voltage and configures clock
3998   *         controls and stores MMC information that will be needed in future
3999   *         in the MMC handle.
4000   * @param  hmmc Pointer to MMC handle
4001   * @retval error state
4002   */
MMC_PowerON(MMC_HandleTypeDef * hmmc)4003 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc)
4004 {
4005   __IO uint32_t count = 0U;
4006   uint32_t response = 0U, validvoltage = 0U;
4007   uint32_t errorstate;
4008 
4009   /* CMD0: GO_IDLE_STATE */
4010   errorstate = SDMMC_CmdGoIdleState(hmmc->Instance);
4011   if(errorstate != HAL_MMC_ERROR_NONE)
4012   {
4013     return errorstate;
4014   }
4015 
4016   while(validvoltage == 0U)
4017   {
4018     if(count++ == SDMMC_MAX_VOLT_TRIAL)
4019     {
4020       return HAL_MMC_ERROR_INVALID_VOLTRANGE;
4021     }
4022 
4023     /* SEND CMD1 APP_CMD with voltage range as argument */
4024     errorstate = SDMMC_CmdOpCondition(hmmc->Instance, MMC_VOLTAGE_RANGE);
4025     if(errorstate != HAL_MMC_ERROR_NONE)
4026     {
4027       return HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
4028     }
4029 
4030     /* Get command response */
4031     response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
4032 
4033     /* Get operating voltage*/
4034     validvoltage = (((response >> 31U) == 1U) ? 1U : 0U);
4035   }
4036 
4037   /* When power routine is finished and command returns valid voltage */
4038   if (((response & (0xFF000000U)) >> 24) == 0xC0U)
4039   {
4040     hmmc->MmcCard.CardType = MMC_HIGH_CAPACITY_CARD;
4041   }
4042   else
4043   {
4044     hmmc->MmcCard.CardType = MMC_LOW_CAPACITY_CARD;
4045   }
4046 
4047   return HAL_MMC_ERROR_NONE;
4048 }
4049 
4050 /**
4051   * @brief  Turns the SDMMC output signals off.
4052   * @param  hmmc Pointer to MMC handle
4053   * @retval None
4054   */
MMC_PowerOFF(MMC_HandleTypeDef * hmmc)4055 static void MMC_PowerOFF(MMC_HandleTypeDef *hmmc)
4056 {
4057   /* Set Power State to OFF */
4058   (void)SDMMC_PowerState_OFF(hmmc->Instance);
4059 }
4060 
4061 /**
4062   * @brief  Returns the current card's status.
4063   * @param  hmmc Pointer to MMC handle
4064   * @param  pCardStatus pointer to the buffer that will contain the MMC card
4065   *         status (Card Status register)
4066   * @retval error state
4067   */
MMC_SendStatus(MMC_HandleTypeDef * hmmc,uint32_t * pCardStatus)4068 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus)
4069 {
4070   uint32_t errorstate;
4071 
4072   if(pCardStatus == NULL)
4073   {
4074     return HAL_MMC_ERROR_PARAM;
4075   }
4076 
4077   /* Send Status command */
4078   errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
4079   if(errorstate != HAL_MMC_ERROR_NONE)
4080   {
4081     return errorstate;
4082   }
4083 
4084   /* Get MMC card status */
4085   *pCardStatus = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
4086 
4087   return HAL_MMC_ERROR_NONE;
4088 }
4089 
4090 /**
4091   * @brief  Reads extended CSD register to get the sectors number of the device
4092   * @param  hmmc Pointer to MMC handle
4093   * @param  pFieldData Pointer to the read buffer
4094   * @param  FieldIndex Index of the field to be read
4095   * @param  Timeout Specify timeout value
4096   * @retval HAL status
4097   */
MMC_ReadExtCSD(MMC_HandleTypeDef * hmmc,uint32_t * pFieldData,uint16_t FieldIndex,uint32_t Timeout)4098 static HAL_StatusTypeDef MMC_ReadExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pFieldData, uint16_t FieldIndex, uint32_t Timeout)
4099 {
4100   SDMMC_DataInitTypeDef config;
4101   uint32_t errorstate;
4102   uint32_t tickstart = HAL_GetTick();
4103   uint32_t count;
4104   uint32_t i = 0;
4105   uint32_t tmp_data;
4106 
4107   hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
4108 
4109   /* Initialize data control register */
4110   hmmc->Instance->DCTRL = 0;
4111 
4112   /* Configure the MMC DPSM (Data Path State Machine) */
4113   config.DataTimeOut   = SDMMC_DATATIMEOUT;
4114   config.DataLength    = 512;
4115   config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
4116   config.TransferDir   = SDMMC_TRANSFER_DIR_TO_SDMMC;
4117   config.TransferMode  = SDMMC_TRANSFER_MODE_BLOCK;
4118   config.DPSM          = SDMMC_DPSM_ENABLE;
4119   (void)SDMMC_ConfigData(hmmc->Instance, &config);
4120 
4121   /* Set Block Size for Card */
4122   errorstate = SDMMC_CmdSendEXTCSD(hmmc->Instance, 0);
4123   if(errorstate != HAL_MMC_ERROR_NONE)
4124   {
4125     /* Clear all the static flags */
4126     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4127     hmmc->ErrorCode |= errorstate;
4128     hmmc->State = HAL_MMC_STATE_READY;
4129     return HAL_ERROR;
4130   }
4131 
4132   /* Poll on SDMMC flags */
4133   while(!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
4134   {
4135     if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF))
4136     {
4137       /* Read data from SDMMC Rx FIFO */
4138       for(count = 0U; count < 8U; count++)
4139       {
4140         tmp_data = SDMMC_ReadFIFO(hmmc->Instance);
4141         /* eg : SEC_COUNT   : FieldIndex = 212 => i+count = 53 */
4142         /*      DEVICE_TYPE : FieldIndex = 196 => i+count = 49 */
4143         if ((i + count) == ((uint32_t)FieldIndex/4U))
4144         {
4145           *pFieldData = tmp_data;
4146         }
4147       }
4148       i += 8U;
4149     }
4150 
4151     if(((HAL_GetTick()-tickstart) >=  Timeout) || (Timeout == 0U))
4152     {
4153       /* Clear all the static flags */
4154       __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4155       hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
4156       hmmc->State= HAL_MMC_STATE_READY;
4157       return HAL_TIMEOUT;
4158     }
4159   }
4160 
4161   /* Get error state */
4162   if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
4163   {
4164     /* Clear all the static flags */
4165     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4166     hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
4167     hmmc->State = HAL_MMC_STATE_READY;
4168     return HAL_ERROR;
4169   }
4170   else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
4171   {
4172     /* Clear all the static flags */
4173     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4174     hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
4175     hmmc->State = HAL_MMC_STATE_READY;
4176     return HAL_ERROR;
4177   }
4178   else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR))
4179   {
4180     /* Clear all the static flags */
4181     __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
4182     hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
4183     hmmc->State = HAL_MMC_STATE_READY;
4184     return HAL_ERROR;
4185   }
4186   else
4187   {
4188     /* Nothing to do */
4189   }
4190 
4191   /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
4192   errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16));
4193   if(errorstate != HAL_MMC_ERROR_NONE)
4194   {
4195     hmmc->ErrorCode |= errorstate;
4196   }
4197 
4198   /* Clear all the static flags */
4199   __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
4200 
4201   hmmc->State = HAL_MMC_STATE_READY;
4202 
4203   return HAL_OK;
4204 }
4205 
4206 /**
4207   * @brief  Wrap up reading in non-blocking mode.
4208   * @param  hmmc pointer to a MMC_HandleTypeDef structure that contains
4209   *              the configuration information.
4210   * @retval None
4211   */
MMC_Read_IT(MMC_HandleTypeDef * hmmc)4212 static void MMC_Read_IT(MMC_HandleTypeDef *hmmc)
4213 {
4214   uint32_t count, data, dataremaining;
4215   uint8_t* tmp;
4216 
4217   tmp = hmmc->pRxBuffPtr;
4218   dataremaining = hmmc->RxXferSize;
4219 
4220   if (dataremaining > 0U)
4221   {
4222     /* Read data from SDMMC Rx FIFO */
4223     for(count = 0U; count < 8U; count++)
4224     {
4225       data = SDMMC_ReadFIFO(hmmc->Instance);
4226       *tmp = (uint8_t)(data & 0xFFU);
4227       tmp++;
4228       dataremaining--;
4229       *tmp = (uint8_t)((data >> 8U) & 0xFFU);
4230       tmp++;
4231       dataremaining--;
4232       *tmp = (uint8_t)((data >> 16U) & 0xFFU);
4233       tmp++;
4234       dataremaining--;
4235       *tmp = (uint8_t)((data >> 24U) & 0xFFU);
4236       tmp++;
4237       dataremaining--;
4238     }
4239 
4240     hmmc->pRxBuffPtr = tmp;
4241     hmmc->RxXferSize = dataremaining;
4242   }
4243 }
4244 
4245 /**
4246   * @brief  Wrap up writing in non-blocking mode.
4247   * @param  hmmc pointer to a MMC_HandleTypeDef structure that contains
4248   *              the configuration information.
4249   * @retval None
4250   */
MMC_Write_IT(MMC_HandleTypeDef * hmmc)4251 static void MMC_Write_IT(MMC_HandleTypeDef *hmmc)
4252 {
4253   uint32_t count, data, dataremaining;
4254   uint8_t* tmp;
4255 
4256   tmp = hmmc->pTxBuffPtr;
4257   dataremaining = hmmc->TxXferSize;
4258 
4259   if (dataremaining > 0U)
4260   {
4261     /* Write data to SDMMC Tx FIFO */
4262     for(count = 0U; count < 8U; count++)
4263     {
4264       data = (uint32_t)(*tmp);
4265       tmp++;
4266       dataremaining--;
4267       data |= ((uint32_t)(*tmp) << 8U);
4268       tmp++;
4269       dataremaining--;
4270       data |= ((uint32_t)(*tmp) << 16U);
4271       tmp++;
4272       dataremaining--;
4273       data |= ((uint32_t)(*tmp) << 24U);
4274       tmp++;
4275       dataremaining--;
4276       (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
4277     }
4278 
4279     hmmc->pTxBuffPtr = tmp;
4280     hmmc->TxXferSize = dataremaining;
4281   }
4282 }
4283 
4284 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
4285 /**
4286   * @brief  Switches the MMC card to high speed mode.
4287   * @param  hmmc MMC handle
4288   * @param  state State of high speed mode
4289   * @retval MMC Card error state
4290   */
MMC_HighSpeed(MMC_HandleTypeDef * hmmc,FunctionalState state)4291 static uint32_t MMC_HighSpeed(MMC_HandleTypeDef *hmmc, FunctionalState state)
4292 {
4293   uint32_t errorstate = HAL_MMC_ERROR_NONE;
4294   uint32_t response = 0U, count;
4295   uint32_t sdmmc_clk;
4296   SDMMC_InitTypeDef Init;
4297 
4298   if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) != 0U) && (state == DISABLE))
4299   {
4300     errorstate = MMC_PwrClassUpdate(hmmc, (hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS), SDMMC_SPEED_MODE_DEFAULT);
4301     if(errorstate == HAL_MMC_ERROR_NONE)
4302     {
4303       /* Index : 185 - Value : 0 */
4304       errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B90000U);
4305     }
4306   }
4307 
4308   if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) == 0U) && (state != DISABLE))
4309   {
4310     errorstate = MMC_PwrClassUpdate(hmmc, (hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS), SDMMC_SPEED_MODE_HIGH);
4311     if(errorstate == HAL_MMC_ERROR_NONE)
4312     {
4313       /* Index : 185 - Value : 1 */
4314       errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B90100U);
4315     }
4316   }
4317 
4318   if(errorstate == HAL_MMC_ERROR_NONE)
4319   {
4320     /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
4321     count = SDMMC_MAX_TRIAL;
4322     do
4323     {
4324       errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
4325       if(errorstate != HAL_MMC_ERROR_NONE)
4326       {
4327         break;
4328       }
4329 
4330       /* Get command response */
4331       response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
4332       count--;
4333     }while(((response & 0x100U) == 0U) && (count != 0U));
4334 
4335     /* Check the status after the switch command execution */
4336     if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
4337     {
4338       /* Check the bit SWITCH_ERROR of the device status */
4339       if ((response & 0x80U) != 0U)
4340       {
4341         errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
4342       }
4343       else
4344       {
4345         /* Configure high speed */
4346         Init.ClockEdge           = hmmc->Init.ClockEdge;
4347         Init.ClockPowerSave      = hmmc->Init.ClockPowerSave;
4348         Init.BusWide             = (hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS);
4349         Init.HardwareFlowControl = hmmc->Init.HardwareFlowControl;
4350 
4351         if (state == DISABLE)
4352         {
4353           Init.ClockDiv = hmmc->Init.ClockDiv;
4354           (void)SDMMC_Init(hmmc->Instance, Init);
4355 
4356           CLEAR_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_BUSSPEED);
4357         }
4358         else
4359         {
4360           /* High Speed Clock should be less or equal to 52MHz*/
4361           sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC1);
4362           if (sdmmc_clk == 0U)
4363           {
4364             errorstate = SDMMC_ERROR_INVALID_PARAMETER;
4365           }
4366           else
4367           {
4368             Init.ClockDiv = sdmmc_clk/(2U*MMC_HIGH_SPEED_FREQ);
4369             (void)SDMMC_Init(hmmc->Instance, Init);
4370 
4371             SET_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_BUSSPEED);
4372           }
4373         }
4374       }
4375     }
4376     else if (count == 0U)
4377     {
4378       errorstate = SDMMC_ERROR_TIMEOUT;
4379     }
4380     else
4381     {
4382       /* Nothing to do */
4383     }
4384   }
4385 
4386   return errorstate;
4387 }
4388 
4389 /**
4390   * @brief  Switches the MMC card to Double Data Rate (DDR) mode.
4391   * @param  hmmc MMC handle
4392   * @param  state State of DDR mode
4393   * @retval MMC Card error state
4394   */
MMC_DDR_Mode(MMC_HandleTypeDef * hmmc,FunctionalState state)4395 static uint32_t MMC_DDR_Mode(MMC_HandleTypeDef *hmmc, FunctionalState state)
4396 {
4397   uint32_t errorstate = HAL_MMC_ERROR_NONE;
4398   uint32_t response = 0U, count;
4399 
4400   if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) != 0U) && (state == DISABLE))
4401   {
4402     if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS_0) != 0U)
4403     {
4404       errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_4B, SDMMC_SPEED_MODE_HIGH);
4405       if(errorstate == HAL_MMC_ERROR_NONE)
4406       {
4407         /* Index : 183 - Value : 1 */
4408         errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U);
4409       }
4410     }
4411     else
4412     {
4413       errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_8B, SDMMC_SPEED_MODE_HIGH);
4414       if(errorstate == HAL_MMC_ERROR_NONE)
4415       {
4416         /* Index : 183 - Value : 2 */
4417         errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U);
4418       }
4419     }
4420   }
4421 
4422   if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) == 0U) && (state != DISABLE))
4423   {
4424     if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS_0) != 0U)
4425     {
4426       errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_4B, SDMMC_SPEED_MODE_DDR);
4427       if(errorstate == HAL_MMC_ERROR_NONE)
4428       {
4429         /* Index : 183 - Value : 5 */
4430         errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70500U);
4431       }
4432     }
4433     else
4434     {
4435       errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_8B, SDMMC_SPEED_MODE_DDR);
4436       if(errorstate == HAL_MMC_ERROR_NONE)
4437       {
4438         /* Index : 183 - Value : 6 */
4439         errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70600U);
4440       }
4441     }
4442   }
4443 
4444   if(errorstate == HAL_MMC_ERROR_NONE)
4445   {
4446     /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
4447     count = SDMMC_MAX_TRIAL;
4448     do
4449     {
4450       errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
4451       if(errorstate != HAL_MMC_ERROR_NONE)
4452       {
4453         break;
4454       }
4455 
4456       /* Get command response */
4457       response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
4458       count--;
4459     }while(((response & 0x100U) == 0U) && (count != 0U));
4460 
4461     /* Check the status after the switch command execution */
4462     if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
4463     {
4464       /* Check the bit SWITCH_ERROR of the device status */
4465       if ((response & 0x80U) != 0U)
4466       {
4467         errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
4468       }
4469       else
4470       {
4471         /* Configure DDR mode */
4472         if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
4473         {
4474           if (state == DISABLE)
4475           {
4476             CLEAR_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_DDR);
4477           }
4478           else
4479           {
4480             SET_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_DDR);
4481           }
4482         }
4483       }
4484     }
4485     else if (count == 0U)
4486     {
4487       errorstate = SDMMC_ERROR_TIMEOUT;
4488     }
4489     else
4490     {
4491       /* Nothing to do */
4492     }
4493   }
4494 
4495   return errorstate;
4496 }
4497 #endif
4498 
4499 /**
4500   * @brief  Update the power class of the device.
4501   * @param  hmmc MMC handle
4502   * @param  Wide Wide of MMC bus
4503   * @param  Speed Speed of the MMC bus
4504   * @retval MMC Card error state
4505   */
MMC_PwrClassUpdate(MMC_HandleTypeDef * hmmc,uint32_t Wide,uint32_t Speed)4506 static uint32_t MMC_PwrClassUpdate(MMC_HandleTypeDef *hmmc, uint32_t Wide, uint32_t Speed)
4507 {
4508   uint32_t count;
4509   uint32_t response = 0U;
4510   uint32_t errorstate = HAL_MMC_ERROR_NONE;
4511   uint32_t power_class, supported_pwr_class;
4512 
4513   if((Wide == SDMMC_BUS_WIDE_8B) || (Wide == SDMMC_BUS_WIDE_4B))
4514   {
4515     power_class = 0U; /* Default value after power-on or software reset */
4516 
4517     /* Read the PowerClass field of the Extended CSD register */
4518     if(MMC_ReadExtCSD(hmmc, &power_class, 187, SDMMC_DATATIMEOUT) != HAL_OK) /* Field POWER_CLASS [187] */
4519     {
4520       errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR;
4521     }
4522     else
4523     {
4524       power_class = ((power_class >> 24U) & 0x000000FFU);
4525     }
4526 
4527     /* Get the supported PowerClass field of the Extended CSD register */
4528 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx)
4529     if (Speed == SDMMC_SPEED_MODE_DDR)
4530     {
4531       /* Field PWR_CL_DDR_52_xxx [238 or 239] */
4532       supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_DDR_52_INDEX/4)] >> MMC_EXT_CSD_PWR_CL_DDR_52_POS) & 0x000000FFU);
4533     }
4534     else if (Speed == SDMMC_SPEED_MODE_HIGH)
4535     {
4536       /* Field PWR_CL_52_xxx [200 or 202] */
4537       supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_52_INDEX/4)] >> MMC_EXT_CSD_PWR_CL_52_POS) & 0x000000FFU);
4538     }
4539     else
4540 #endif
4541     {
4542       /* Field PWR_CL_26_xxx [201 or 203] */
4543       supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_26_INDEX/4)] >> MMC_EXT_CSD_PWR_CL_26_POS) & 0x000000FFU);
4544     }
4545 
4546     if(errorstate == HAL_MMC_ERROR_NONE)
4547     {
4548       if(Wide == SDMMC_BUS_WIDE_8B)
4549       {
4550         /* Bit [7:4] : power class for 8-bits bus configuration - Bit [3:0] : power class for 4-bits bus configuration */
4551         supported_pwr_class = (supported_pwr_class >> 4U);
4552       }
4553 
4554       if ((power_class & 0x0FU) != (supported_pwr_class & 0x0FU))
4555       {
4556         /* Need to change current power class */
4557         errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03BB0000U | ((supported_pwr_class & 0x0FU) << 8U)));
4558 
4559         if(errorstate == HAL_MMC_ERROR_NONE)
4560         {
4561           /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
4562           count = SDMMC_MAX_TRIAL;
4563           do
4564           {
4565             errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
4566             if(errorstate != HAL_MMC_ERROR_NONE)
4567             {
4568               break;
4569             }
4570 
4571             /* Get command response */
4572             response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
4573             count--;
4574           }while(((response & 0x100U) == 0U) && (count != 0U));
4575 
4576           /* Check the status after the switch command execution */
4577           if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
4578           {
4579             /* Check the bit SWITCH_ERROR of the device status */
4580             if ((response & 0x80U) != 0U)
4581             {
4582               errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
4583             }
4584           }
4585           else if (count == 0U)
4586           {
4587             errorstate = SDMMC_ERROR_TIMEOUT;
4588           }
4589           else
4590           {
4591             /* Nothing to do */
4592           }
4593         }
4594       }
4595     }
4596   }
4597 
4598   return errorstate;
4599 }
4600 /**
4601   * @}
4602   */
4603 
4604 /**
4605   * @}
4606   */
4607 
4608 /**
4609   * @}
4610   */
4611 
4612 #endif /* HAL_MMC_MODULE_ENABLED */
4613 
4614 #endif /* SDMMC1 */
4615