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