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