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