Merge pull request #10592 from iNavFlight/MrD_Update-parameter-description
[inav.git] / lib / main / STM32H7 / Drivers / STM32H7xx_HAL_Driver / Src / stm32h7xx_hal_mmc.c
blob9774f142cb67302cdd7242040361dbbf326c3864
1 /**
2 ******************************************************************************
3 * @file stm32h7xx_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
13 @verbatim
14 ==============================================================================
15 ##### How to use this driver #####
16 ==============================================================================
17 [..]
18 This driver implements a high level communication layer for read and write from/to
19 this memory. The needed STM32 hardware resources (SDMMC and GPIO) are performed by
20 the user in HAL_MMC_MspInit() function (MSP layer).
21 Basically, the MSP layer configuration should be the same as we provide in the
22 examples.
23 You can easily tailor this configuration according to hardware resources.
25 [..]
26 This driver is a generic layered driver for SDMMC memories which uses the HAL
27 SDMMC driver functions to interface with MMC and eMMC cards devices.
28 It is used as follows:
30 (#)Initialize the SDMMC low level resources by implement the HAL_MMC_MspInit() API:
31 (##) Enable the SDMMC interface clock using __HAL_RCC_SDMMC_CLK_ENABLE();
32 (##) SDMMC pins configuration for MMC card
33 (+++) Enable the clock for the SDMMC GPIOs using the functions __HAL_RCC_GPIOx_CLK_ENABLE();
34 (+++) Configure these SDMMC pins as alternate function pull-up using HAL_GPIO_Init()
35 and according to your pin assignment;
36 (##) NVIC configuration if you need to use interrupt process (HAL_MMC_ReadBlocks_IT()
37 and HAL_MMC_WriteBlocks_IT() APIs).
38 (+++) Configure the SDMMC interrupt priorities using function HAL_NVIC_SetPriority();
39 (+++) Enable the NVIC SDMMC IRQs using function HAL_NVIC_EnableIRQ()
40 (+++) SDMMC interrupts are managed using the macros __HAL_MMC_ENABLE_IT()
41 and __HAL_MMC_DISABLE_IT() inside the communication process.
42 (+++) SDMMC interrupts pending bits are managed using the macros __HAL_MMC_GET_IT()
43 and __HAL_MMC_CLEAR_IT()
44 (##) No general propose DMA Configuration is needed, an Internal DMA for SDMMC Peripheral are used.
46 (#) At this stage, you can perform MMC read/write/erase operations after MMC card initialization
49 *** MMC Card Initialization and configuration ***
50 ================================================
51 [..]
52 To initialize the MMC Card, use the HAL_MMC_Init() function. It Initializes
53 SDMMC Peripheral (STM32 side) and the MMC Card, and put it into StandBy State (Ready for data transfer).
54 This function provide the following operations:
56 (#) Initialize the SDMMC peripheral interface with defaullt configuration.
57 The initialization process is done at 400KHz. You can change or adapt
58 this frequency by adjusting the "ClockDiv" field.
59 The MMC Card frequency (SDMMC_CK) is computed as follows:
61 SDMMC_CK = SDMMCCLK / (2 * ClockDiv)
63 In initialization mode and according to the MMC Card standard,
64 make sure that the SDMMC_CK frequency doesn't exceed 400KHz.
66 This phase of initialization is done through SDMMC_Init() and
67 SDMMC_PowerState_ON() SDMMC low level APIs.
69 (#) Initialize the MMC card. The API used is HAL_MMC_InitCard().
70 This phase allows the card initialization and identification
71 and check the MMC Card type (Standard Capacity or High Capacity)
72 The initialization flow is compatible with MMC standard.
74 This API (HAL_MMC_InitCard()) could be used also to reinitialize the card in case
75 of plug-off plug-in.
77 (#) Configure the MMC Card Data transfer frequency. By Default, the card transfer
78 frequency by adjusting the "ClockDiv" field.
79 In transfer mode and according to the MMC Card standard, make sure that the
80 SDMMC_CK frequency doesn't exceed 25MHz and 100MHz in High-speed mode switch.
82 (#) Select the corresponding MMC Card according to the address read with the step 2.
84 (#) Configure the MMC Card in wide bus mode: 4-bits data.
86 *** MMC Card Read operation ***
87 ==============================
88 [..]
89 (+) You can read from MMC card in polling mode by using function HAL_MMC_ReadBlocks().
90 This function support only 512-bytes block length (the block size should be
91 chosen as 512 bytes).
92 You can choose either one block read operation or multiple block read operation
93 by adjusting the "NumberOfBlocks" parameter.
94 After this, you have to ensure that the transfer is done correctly. The check is done
95 through HAL_MMC_GetCardState() function for MMC card state.
97 (+) You can read from MMC card in DMA mode by using function HAL_MMC_ReadBlocks_DMA().
98 This function support only 512-bytes block length (the block size should be
99 chosen as 512 bytes).
100 You can choose either one block read operation or multiple block read operation
101 by adjusting the "NumberOfBlocks" parameter.
102 After this, you have to ensure that the transfer is done correctly. The check is done
103 through HAL_MMC_GetCardState() function for MMC card state.
104 You could also check the DMA transfer process through the MMC Rx interrupt event.
106 (+) You can read from MMC card in Interrupt mode by using function HAL_MMC_ReadBlocks_IT().
107 This function allows the read of 512 bytes blocks.
108 You can choose either one block read operation or multiple block read operation
109 by adjusting the "NumberOfBlocks" parameter.
110 After this, you have to ensure that the transfer is done correctly. The check is done
111 through HAL_MMC_GetCardState() function for MMC card state.
112 You could also check the IT transfer process through the MMC Rx interrupt event.
114 *** MMC Card Write operation ***
115 ===============================
116 [..]
117 (+) You can write to MMC card in polling mode by using function HAL_MMC_WriteBlocks().
118 This function support only 512-bytes block length (the block size should be
119 chosen as 512 bytes).
120 You can choose either one block read operation or multiple block read operation
121 by adjusting the "NumberOfBlocks" parameter.
122 After this, you have to ensure that the transfer is done correctly. The check is done
123 through HAL_MMC_GetCardState() function for MMC card state.
125 (+) You can write to MMC card in DMA mode by using function HAL_MMC_WriteBlocks_DMA().
126 This function support only 512-bytes block length (the block size should be
127 chosen as 512 byte).
128 You can choose either one block read operation or multiple block read operation
129 by adjusting the "NumberOfBlocks" parameter.
130 After this, you have to ensure that the transfer is done correctly. The check is done
131 through HAL_MMC_GetCardState() function for MMC card state.
132 You could also check the DMA transfer process through the MMC Tx interrupt event.
134 (+) You can write to MMC card in Interrupt mode by using function HAL_MMC_WriteBlocks_IT().
135 This function allows the read of 512 bytes blocks.
136 You can choose either one block read operation or multiple block read operation
137 by adjusting the "NumberOfBlocks" parameter.
138 After this, you have to ensure that the transfer is done correctly. The check is done
139 through HAL_MMC_GetCardState() function for MMC card state.
140 You could also check the IT transfer process through the MMC Tx interrupt event.
142 *** MMC card information ***
143 ===========================
144 [..]
145 (+) To get MMC card information, you can use the function HAL_MMC_GetCardInfo().
146 It returns useful information about the MMC card such as block size, card type,
147 block number ...
149 *** MMC card CSD register ***
150 ============================
151 [..]
152 (+) The HAL_MMC_GetCardCSD() API allows to get the parameters of the CSD register.
153 Some of the CSD parameters are useful for card initialization and identification.
155 *** MMC card CID register ***
156 ============================
157 [..]
158 (+) The HAL_MMC_GetCardCID() API allows to get the parameters of the CID register.
159 Some of the CID parameters are useful for card initialization and identification.
161 *** MMC HAL driver macros list ***
162 ==================================
163 [..]
164 Below the list of most used macros in MMC HAL driver.
166 (+) __HAL_MMC_ENABLE_IT: Enable the MMC device interrupt
167 (+) __HAL_MMC_DISABLE_IT: Disable the MMC device interrupt
168 (+) __HAL_MMC_GET_FLAG:Check whether the specified MMC flag is set or not
169 (+) __HAL_MMC_CLEAR_FLAG: Clear the MMC's pending flags
171 [..]
172 (@) You can refer to the MMC HAL driver header file for more useful macros
174 *** Callback registration ***
175 =============================================
176 [..]
177 The compilation define USE_HAL_MMC_REGISTER_CALLBACKS when set to 1
178 allows the user to configure dynamically the driver callbacks.
180 Use Functions @ref HAL_MMC_RegisterCallback() to register a user callback,
181 it allows to register following callbacks:
182 (+) TxCpltCallback : callback when a transmission transfer is completed.
183 (+) RxCpltCallback : callback when a reception transfer is completed.
184 (+) ErrorCallback : callback when error occurs.
185 (+) AbortCpltCallback : callback when abort is completed.
186 (+) Read_DMADblBuf0CpltCallback : callback when the DMA reception of first buffer is completed.
187 (+) Read_DMADblBuf1CpltCallback : callback when the DMA reception of second buffer is completed.
188 (+) Write_DMADblBuf0CpltCallback : callback when the DMA transmission of first buffer is completed.
189 (+) Write_DMADblBuf1CpltCallback : callback when the DMA transmission of second buffer is completed.
190 (+) MspInitCallback : MMC MspInit.
191 (+) MspDeInitCallback : MMC MspDeInit.
192 This function takes as parameters the HAL peripheral handle, the Callback ID
193 and a pointer to the user callback function.
195 Use function @ref HAL_MMC_UnRegisterCallback() to reset a callback to the default
196 weak (surcharged) function. It allows to reset following callbacks:
197 (+) TxCpltCallback : callback when a transmission transfer is completed.
198 (+) RxCpltCallback : callback when a reception transfer is completed.
199 (+) ErrorCallback : callback when error occurs.
200 (+) AbortCpltCallback : callback when abort is completed.
201 (+) Read_DMADblBuf0CpltCallback : callback when the DMA reception of first buffer is completed.
202 (+) Read_DMADblBuf1CpltCallback : callback when the DMA reception of second buffer is completed.
203 (+) Write_DMADblBuf0CpltCallback : callback when the DMA transmission of first buffer is completed.
204 (+) Write_DMADblBuf1CpltCallback : callback when the DMA transmission of second buffer is completed.
205 (+) MspInitCallback : MMC MspInit.
206 (+) MspDeInitCallback : MMC MspDeInit.
207 This function) takes as parameters the HAL peripheral handle and the Callback ID.
209 By default, after the @ref HAL_MMC_Init and if the state is HAL_MMC_STATE_RESET
210 all callbacks are reset to the corresponding legacy weak (surcharged) functions.
211 Exception done for MspInit and MspDeInit callbacks that are respectively
212 reset to the legacy weak (surcharged) functions in the @ref HAL_MMC_Init
213 and @ref HAL_MMC_DeInit only when these callbacks are null (not registered beforehand).
214 If not, MspInit or MspDeInit are not null, the @ref HAL_MMC_Init and @ref HAL_MMC_DeInit
215 keep and use the user MspInit/MspDeInit callbacks (registered beforehand)
217 Callbacks can be registered/unregistered in READY state only.
218 Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered
219 in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used
220 during the Init/DeInit.
221 In that case first register the MspInit/MspDeInit user callbacks
222 using @ref HAL_MMC_RegisterCallback before calling @ref HAL_MMC_DeInit
223 or @ref HAL_MMC_Init function.
225 When The compilation define USE_HAL_MMC_REGISTER_CALLBACKS is set to 0 or
226 not defined, the callback registering feature is not available
227 and weak (surcharged) callbacks are used.
229 @endverbatim
230 ******************************************************************************
231 * @attention
233 * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
234 * All rights reserved.</center></h2>
236 * This software component is licensed by ST under BSD 3-Clause license,
237 * the "License"; You may not use this file except in compliance with the
238 * License. You may obtain a copy of the License at:
239 * opensource.org/licenses/BSD-3-Clause
241 ******************************************************************************
244 /* Includes ------------------------------------------------------------------*/
245 #include "stm32h7xx_hal.h"
247 /** @addtogroup STM32H7xx_HAL_Driver
248 * @{
251 /** @defgroup MMC MMC
252 * @brief MMC HAL module driver
253 * @{
256 #ifdef HAL_MMC_MODULE_ENABLED
258 /* Private typedef -----------------------------------------------------------*/
259 /* Private define ------------------------------------------------------------*/
260 /** @addtogroup MMC_Private_Defines
261 * @{
265 * @}
268 /* Private macro -------------------------------------------------------------*/
269 /* Private variables ---------------------------------------------------------*/
270 /* Private function prototypes -----------------------------------------------*/
271 /* Private functions ---------------------------------------------------------*/
272 /** @defgroup MMC_Private_Functions MMC Private Functions
273 * @{
275 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc);
276 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc);
277 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus);
278 static void MMC_PowerOFF(MMC_HandleTypeDef *hmmc);
279 static void MMC_Write_IT(MMC_HandleTypeDef *hmmc);
280 static void MMC_Read_IT(MMC_HandleTypeDef *hmmc);
281 static uint32_t MMC_HighSpeed(MMC_HandleTypeDef *hmmc, FunctionalState state);
282 static uint32_t MMC_DDR_Mode(MMC_HandleTypeDef *hmmc, FunctionalState state);
283 HAL_StatusTypeDef MMC_ReadExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pFieldData, uint16_t FieldIndex, uint32_t Timeout);
287 * @}
289 /* Exported functions --------------------------------------------------------*/
290 /** @addtogroup MMC_Exported_Functions
291 * @{
294 /** @addtogroup MMC_Exported_Functions_Group1
295 * @brief Initialization and de-initialization functions
297 @verbatim
298 ==============================================================================
299 ##### Initialization and de-initialization functions #####
300 ==============================================================================
301 [..]
302 This section provides functions allowing to initialize/de-initialize the MMC
303 card device to be ready for use.
305 @endverbatim
306 * @{
310 * @brief Initializes the MMC according to the specified parameters in the
311 MMC_HandleTypeDef and create the associated handle.
312 * @param hmmc: Pointer to the MMC handle
313 * @retval HAL status
315 HAL_StatusTypeDef HAL_MMC_Init(MMC_HandleTypeDef *hmmc)
317 /* Check the MMC handle allocation */
318 if(hmmc == NULL)
320 return HAL_ERROR;
323 /* Check the parameters */
324 assert_param(IS_SDMMC_ALL_INSTANCE(hmmc->Instance));
325 assert_param(IS_SDMMC_CLOCK_EDGE(hmmc->Init.ClockEdge));
326 assert_param(IS_SDMMC_CLOCK_POWER_SAVE(hmmc->Init.ClockPowerSave));
327 assert_param(IS_SDMMC_BUS_WIDE(hmmc->Init.BusWide));
328 assert_param(IS_SDMMC_HARDWARE_FLOW_CONTROL(hmmc->Init.HardwareFlowControl));
329 assert_param(IS_SDMMC_CLKDIV(hmmc->Init.ClockDiv));
331 if(hmmc->State == HAL_MMC_STATE_RESET)
333 /* Allocate lock resource and initialize it */
334 hmmc->Lock = HAL_UNLOCKED;
335 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
336 /* Reset Callback pointers in HAL_MMC_STATE_RESET only */
337 hmmc->TxCpltCallback = HAL_MMC_TxCpltCallback;
338 hmmc->RxCpltCallback = HAL_MMC_RxCpltCallback;
339 hmmc->ErrorCallback = HAL_MMC_ErrorCallback;
340 hmmc->AbortCpltCallback = HAL_MMC_AbortCallback;
341 hmmc->Read_DMADblBuf0CpltCallback = HAL_MMCEx_Read_DMADoubleBuf0CpltCallback;
342 hmmc->Read_DMADblBuf1CpltCallback = HAL_MMCEx_Read_DMADoubleBuf1CpltCallback;
343 hmmc->Write_DMADblBuf0CpltCallback = HAL_MMCEx_Write_DMADoubleBuf0CpltCallback;
344 hmmc->Write_DMADblBuf1CpltCallback = HAL_MMCEx_Write_DMADoubleBuf1CpltCallback;
346 if(hmmc->MspInitCallback == NULL)
348 hmmc->MspInitCallback = HAL_MMC_MspInit;
351 /* Init the low level hardware */
352 hmmc->MspInitCallback(hmmc);
353 #else
354 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
355 HAL_MMC_MspInit(hmmc);
356 #endif
359 hmmc->State = HAL_MMC_STATE_BUSY;
361 /* Initialize the Card parameters */
362 if(HAL_MMC_InitCard(hmmc) == HAL_ERROR)
364 return HAL_ERROR;
367 /* Initialize the error code */
368 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
370 /* Initialize the MMC operation */
371 hmmc->Context = MMC_CONTEXT_NONE;
373 /* Initialize the MMC state */
374 hmmc->State = HAL_MMC_STATE_READY;
376 return HAL_OK;
380 * @brief Initializes the MMC Card.
381 * @param hmmc: Pointer to MMC handle
382 * @note This function initializes the MMC card. It could be used when a card
383 re-initialization is needed.
384 * @retval HAL status
386 HAL_StatusTypeDef HAL_MMC_InitCard(MMC_HandleTypeDef *hmmc)
388 uint32_t errorstate;
389 MMC_InitTypeDef Init;
390 HAL_StatusTypeDef status;
392 /* Default SDMMC peripheral configuration for MMC card initialization */
393 Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
394 Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
395 Init.BusWide = SDMMC_BUS_WIDE_1B;
396 Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
397 Init.ClockDiv = SDMMC_INIT_CLK_DIV;
399 /* Initialize SDMMC peripheral interface with default configuration */
400 status = SDMMC_Init(hmmc->Instance, Init);
401 if(status == HAL_ERROR)
403 return HAL_ERROR;
406 /* Set Power State to ON */
407 status = SDMMC_PowerState_ON(hmmc->Instance);
408 if(status == HAL_ERROR)
410 return HAL_ERROR;
413 /* Identify card operating voltage */
414 errorstate = MMC_PowerON(hmmc);
415 if(errorstate != HAL_MMC_ERROR_NONE)
417 hmmc->State = HAL_MMC_STATE_READY;
418 hmmc->ErrorCode |= errorstate;
419 return HAL_ERROR;
422 /* Card initialization */
423 errorstate = MMC_InitCard(hmmc);
424 if(errorstate != HAL_MMC_ERROR_NONE)
426 hmmc->State = HAL_MMC_STATE_READY;
427 hmmc->ErrorCode |= errorstate;
428 return HAL_ERROR;
431 return HAL_OK;
435 * @brief De-Initializes the MMC card.
436 * @param hmmc: Pointer to MMC handle
437 * @retval HAL status
439 HAL_StatusTypeDef HAL_MMC_DeInit(MMC_HandleTypeDef *hmmc)
441 /* Check the MMC handle allocation */
442 if(hmmc == NULL)
444 return HAL_ERROR;
447 /* Check the parameters */
448 assert_param(IS_SDMMC_ALL_INSTANCE(hmmc->Instance));
450 hmmc->State = HAL_MMC_STATE_BUSY;
452 /* Set MMC power state to off */
453 MMC_PowerOFF(hmmc);
455 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
456 if(hmmc->MspDeInitCallback == NULL)
458 hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
461 /* DeInit the low level hardware */
462 hmmc->MspDeInitCallback(hmmc);
463 #else
464 /* De-Initialize the MSP layer */
465 HAL_MMC_MspDeInit(hmmc);
466 #endif
468 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
469 hmmc->State = HAL_MMC_STATE_RESET;
471 return HAL_OK;
476 * @brief Initializes the MMC MSP.
477 * @param hmmc: Pointer to MMC handle
478 * @retval None
480 __weak void HAL_MMC_MspInit(MMC_HandleTypeDef *hmmc)
482 /* Prevent unused argument(s) compilation warning */
483 UNUSED(hmmc);
485 /* NOTE : This function Should not be modified, when the callback is needed,
486 the HAL_MMC_MspInit could be implemented in the user file
491 * @brief De-Initialize MMC MSP.
492 * @param hmmc: Pointer to MMC handle
493 * @retval None
495 __weak void HAL_MMC_MspDeInit(MMC_HandleTypeDef *hmmc)
497 /* Prevent unused argument(s) compilation warning */
498 UNUSED(hmmc);
500 /* NOTE : This function Should not be modified, when the callback is needed,
501 the HAL_MMC_MspDeInit could be implemented in the user file
506 * @}
509 /** @addtogroup MMC_Exported_Functions_Group2
510 * @brief Data transfer functions
512 @verbatim
513 ==============================================================================
514 ##### IO operation functions #####
515 ==============================================================================
516 [..]
517 This subsection provides a set of functions allowing to manage the data
518 transfer from/to MMC card.
520 @endverbatim
521 * @{
525 * @brief Reads block(s) from a specified address in a card. The Data transfer
526 * is managed by polling mode.
527 * @note This API should be followed by a check on the card state through
528 * HAL_MMC_GetCardState().
529 * @param hmmc: Pointer to MMC handle
530 * @param pData: pointer to the buffer that will contain the received data
531 * @param BlockAdd: Block Address from where data is to be read
532 * @param NumberOfBlocks: Number of MMC blocks to read
533 * @param Timeout: Specify timeout value
534 * @retval HAL status
536 HAL_StatusTypeDef HAL_MMC_ReadBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
538 SDMMC_DataInitTypeDef config;
539 uint32_t errorstate;
540 uint32_t tickstart = HAL_GetTick();
541 uint32_t count, data, dataremaining;
542 uint32_t add = BlockAdd;
543 uint8_t *tempbuff = pData;
545 if(NULL == pData)
547 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
548 return HAL_ERROR;
551 if(hmmc->State == HAL_MMC_STATE_READY)
553 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
555 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
557 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
558 return HAL_ERROR;
561 hmmc->State = HAL_MMC_STATE_BUSY;
563 /* Initialize data control register */
564 hmmc->Instance->DCTRL = 0U;
566 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
568 add *= 512U;
571 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) == 0U)
573 /* Set Block Size for Card */
574 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, MMC_BLOCKSIZE);
575 if(errorstate != HAL_MMC_ERROR_NONE)
577 /* Clear all the static flags */
578 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
579 hmmc->ErrorCode |= errorstate;
580 hmmc->State = HAL_MMC_STATE_READY;
581 return HAL_ERROR;
585 /* Configure the MMC DPSM (Data Path State Machine) */
586 config.DataTimeOut = SDMMC_DATATIMEOUT;
587 config.DataLength = NumberOfBlocks * MMC_BLOCKSIZE;
588 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
589 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
590 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
591 config.DPSM = SDMMC_DPSM_DISABLE;
592 (void)SDMMC_ConfigData(hmmc->Instance, &config);
593 __SDMMC_CMDTRANS_ENABLE( hmmc->Instance);
595 /* Read block(s) in polling mode */
596 if(NumberOfBlocks > 1U)
598 hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
600 /* Read Multi Block command */
601 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
603 else
605 hmmc->Context = MMC_CONTEXT_READ_SINGLE_BLOCK;
607 /* Read Single Block command */
608 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
610 if(errorstate != HAL_MMC_ERROR_NONE)
612 /* Clear all the static flags */
613 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
614 hmmc->ErrorCode |= errorstate;
615 hmmc->State = HAL_MMC_STATE_READY;
616 return HAL_ERROR;
619 /* Poll on SDMMC flags */
620 dataremaining = config.DataLength;
621 while(!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
623 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining >= 32U))
625 /* Read data from SDMMC Rx FIFO */
626 for(count = 0U; count < 8U; count++)
628 data = SDMMC_ReadFIFO(hmmc->Instance);
629 *tempbuff = (uint8_t)(data & 0xFFU);
630 tempbuff++;
631 *tempbuff = (uint8_t)((data >> 8U) & 0xFFU);
632 tempbuff++;
633 *tempbuff = (uint8_t)((data >> 16U) & 0xFFU);
634 tempbuff++;
635 *tempbuff = (uint8_t)((data >> 24U) & 0xFFU);
636 tempbuff++;
638 dataremaining -= 32U;
641 if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U))
643 /* Clear all the static flags */
644 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
645 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
646 hmmc->State= HAL_MMC_STATE_READY;
647 return HAL_TIMEOUT;
650 __SDMMC_CMDTRANS_DISABLE( hmmc->Instance);
652 /* Send stop transmission command in case of multiblock read */
653 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U))
655 /* Send stop transmission command */
656 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
657 if(errorstate != HAL_MMC_ERROR_NONE)
659 /* Clear all the static flags */
660 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
661 hmmc->ErrorCode |= errorstate;
662 hmmc->State = HAL_MMC_STATE_READY;
663 return HAL_ERROR;
667 /* Get error state */
668 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
670 /* Clear all the static flags */
671 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
672 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
673 hmmc->State = HAL_MMC_STATE_READY;
674 return HAL_ERROR;
676 else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
678 /* Clear all the static flags */
679 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
680 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
681 hmmc->State = HAL_MMC_STATE_READY;
682 return HAL_ERROR;
684 else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR))
686 /* Clear all the static flags */
687 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
688 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
689 hmmc->State = HAL_MMC_STATE_READY;
690 return HAL_ERROR;
692 else
694 /* Nothing to do */
697 /* Clear all the static flags */
698 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
700 hmmc->State = HAL_MMC_STATE_READY;
702 return HAL_OK;
704 else
706 hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
707 return HAL_ERROR;
712 * @brief Allows to write block(s) to a specified address in a card. The Data
713 * transfer is managed by polling mode.
714 * @note This API should be followed by a check on the card state through
715 * HAL_MMC_GetCardState().
716 * @param hmmc: Pointer to MMC handle
717 * @param pData: pointer to the buffer that will contain the data to transmit
718 * @param BlockAdd: Block Address where data will be written
719 * @param NumberOfBlocks: Number of MMC blocks to write
720 * @param Timeout: Specify timeout value
721 * @retval HAL status
723 HAL_StatusTypeDef HAL_MMC_WriteBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
725 SDMMC_DataInitTypeDef config;
726 uint32_t errorstate;
727 uint32_t tickstart = HAL_GetTick();
728 uint32_t count, data, dataremaining;
729 uint32_t add = BlockAdd;
730 uint8_t *tempbuff = pData;
732 if(NULL == pData)
734 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
735 return HAL_ERROR;
738 if(hmmc->State == HAL_MMC_STATE_READY)
740 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
742 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
744 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
745 return HAL_ERROR;
748 hmmc->State = HAL_MMC_STATE_BUSY;
750 /* Initialize data control register */
751 hmmc->Instance->DCTRL = 0U;
753 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
755 add *= 512U;
758 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) == 0U)
760 /* Set Block Size for Card */
761 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, MMC_BLOCKSIZE);
762 if(errorstate != HAL_MMC_ERROR_NONE)
764 /* Clear all the static flags */
765 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
766 hmmc->ErrorCode |= errorstate;
767 hmmc->State = HAL_MMC_STATE_READY;
768 return HAL_ERROR;
772 /* Configure the MMC DPSM (Data Path State Machine) */
773 config.DataTimeOut = SDMMC_DATATIMEOUT;
774 config.DataLength = NumberOfBlocks * MMC_BLOCKSIZE;
775 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
776 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
777 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
778 config.DPSM = SDMMC_DPSM_DISABLE;
779 (void)SDMMC_ConfigData(hmmc->Instance, &config);
780 __SDMMC_CMDTRANS_ENABLE( hmmc->Instance);
782 /* Write Blocks in Polling mode */
783 if(NumberOfBlocks > 1U)
785 hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
787 /* Write Multi Block command */
788 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
790 else
792 hmmc->Context = MMC_CONTEXT_WRITE_SINGLE_BLOCK;
794 /* Write Single Block command */
795 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
797 if(errorstate != HAL_MMC_ERROR_NONE)
799 /* Clear all the static flags */
800 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
801 hmmc->ErrorCode |= errorstate;
802 hmmc->State = HAL_MMC_STATE_READY;
803 return HAL_ERROR;
806 /* Write block(s) in polling mode */
807 dataremaining = config.DataLength;
808 while(!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
810 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining >= 32U))
812 /* Write data to SDMMC Tx FIFO */
813 for(count = 0U; count < 8U; count++)
815 data = (uint32_t)(*tempbuff);
816 tempbuff++;
817 data |= ((uint32_t)(*tempbuff) << 8U);
818 tempbuff++;
819 data |= ((uint32_t)(*tempbuff) << 16U);
820 tempbuff++;
821 data |= ((uint32_t)(*tempbuff) << 24U);
822 tempbuff++;
823 (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
825 dataremaining -= 32U;
828 if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U))
830 /* Clear all the static flags */
831 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
832 hmmc->ErrorCode |= errorstate;
833 hmmc->State = HAL_MMC_STATE_READY;
834 return HAL_TIMEOUT;
837 __SDMMC_CMDTRANS_DISABLE( hmmc->Instance);
839 /* Send stop transmission command in case of multiblock write */
840 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U))
842 /* Send stop transmission command */
843 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
844 if(errorstate != HAL_MMC_ERROR_NONE)
846 /* Clear all the static flags */
847 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
848 hmmc->ErrorCode |= errorstate;
849 hmmc->State = HAL_MMC_STATE_READY;
850 return HAL_ERROR;
854 /* Get error state */
855 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
857 /* Clear all the static flags */
858 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
859 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
860 hmmc->State = HAL_MMC_STATE_READY;
861 return HAL_ERROR;
863 else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
865 /* Clear all the static flags */
866 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
867 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
868 hmmc->State = HAL_MMC_STATE_READY;
869 return HAL_ERROR;
871 else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
873 /* Clear all the static flags */
874 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
875 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
876 hmmc->State = HAL_MMC_STATE_READY;
877 return HAL_ERROR;
879 else
881 /* Nothing to do */
884 /* Clear all the static flags */
885 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
887 hmmc->State = HAL_MMC_STATE_READY;
889 return HAL_OK;
891 else
893 hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
894 return HAL_ERROR;
899 * @brief Reads block(s) from a specified address in a card. The Data transfer
900 * is managed in interrupt mode.
901 * @note This API should be followed by a check on the card state through
902 * HAL_MMC_GetCardState().
903 * @note You could also check the IT transfer process through the MMC Rx
904 * interrupt event.
905 * @param hmmc: Pointer to MMC handle
906 * @param pData: Pointer to the buffer that will contain the received data
907 * @param BlockAdd: Block Address from where data is to be read
908 * @param NumberOfBlocks: Number of blocks to read.
909 * @retval HAL status
911 HAL_StatusTypeDef HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
913 SDMMC_DataInitTypeDef config;
914 uint32_t errorstate;
915 uint32_t add = BlockAdd;
917 if(NULL == pData)
919 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
920 return HAL_ERROR;
923 if(hmmc->State == HAL_MMC_STATE_READY)
925 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
927 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
929 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
930 return HAL_ERROR;
933 hmmc->State = HAL_MMC_STATE_BUSY;
935 /* Initialize data control register */
936 hmmc->Instance->DCTRL = 0U;
938 hmmc->pRxBuffPtr = pData;
939 hmmc->RxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
941 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
943 add *= 512U;
946 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) == 0U)
948 /* Set Block Size for Card */
949 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, MMC_BLOCKSIZE);
950 if(errorstate != HAL_MMC_ERROR_NONE)
952 /* Clear all the static flags */
953 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
954 hmmc->ErrorCode |= errorstate;
955 hmmc->State = HAL_MMC_STATE_READY;
956 return HAL_ERROR;
960 /* Configure the MMC DPSM (Data Path State Machine) */
961 config.DataTimeOut = SDMMC_DATATIMEOUT;
962 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks;
963 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
964 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
965 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
966 config.DPSM = SDMMC_DPSM_DISABLE;
967 (void)SDMMC_ConfigData(hmmc->Instance, &config);
968 __SDMMC_CMDTRANS_ENABLE( hmmc->Instance);
970 /* Read Blocks in IT mode */
971 if(NumberOfBlocks > 1U)
973 hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_IT);
975 /* Read Multi Block command */
976 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
978 else
980 hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_IT);
982 /* Read Single Block command */
983 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
986 if(errorstate != HAL_MMC_ERROR_NONE)
988 /* Clear all the static flags */
989 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
990 hmmc->ErrorCode |= errorstate;
991 hmmc->State = HAL_MMC_STATE_READY;
992 return HAL_ERROR;
995 __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND | SDMMC_FLAG_RXFIFOHF));
997 return HAL_OK;
999 else
1001 return HAL_BUSY;
1006 * @brief Writes block(s) to a specified address in a card. The Data transfer
1007 * is managed in interrupt mode.
1008 * @note This API should be followed by a check on the card state through
1009 * HAL_MMC_GetCardState().
1010 * @note You could also check the IT transfer process through the MMC Tx
1011 * interrupt event.
1012 * @param hmmc: Pointer to MMC handle
1013 * @param pData: Pointer to the buffer that will contain the data to transmit
1014 * @param BlockAdd: Block Address where data will be written
1015 * @param NumberOfBlocks: Number of blocks to write
1016 * @retval HAL status
1018 HAL_StatusTypeDef HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
1020 SDMMC_DataInitTypeDef config;
1021 uint32_t errorstate;
1022 uint32_t add = BlockAdd;
1024 if(NULL == pData)
1026 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1027 return HAL_ERROR;
1030 if(hmmc->State == HAL_MMC_STATE_READY)
1032 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1034 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1036 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1037 return HAL_ERROR;
1040 hmmc->State = HAL_MMC_STATE_BUSY;
1042 /* Initialize data control register */
1043 hmmc->Instance->DCTRL = 0U;
1045 hmmc->pTxBuffPtr = pData;
1046 hmmc->TxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1048 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1050 add *= 512U;
1053 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) == 0U)
1055 /* Set Block Size for Card */
1056 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, MMC_BLOCKSIZE);
1057 if(errorstate != HAL_MMC_ERROR_NONE)
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;
1067 /* Configure the MMC DPSM (Data Path State Machine) */
1068 config.DataTimeOut = SDMMC_DATATIMEOUT;
1069 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks;
1070 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1071 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
1072 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
1073 config.DPSM = SDMMC_DPSM_DISABLE;
1074 (void)SDMMC_ConfigData(hmmc->Instance, &config);
1076 __SDMMC_CMDTRANS_ENABLE( hmmc->Instance);
1078 /* Write Blocks in Polling mode */
1079 if(NumberOfBlocks > 1U)
1081 hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK| MMC_CONTEXT_IT);
1083 /* Write Multi Block command */
1084 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
1086 else
1088 hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_IT);
1090 /* Write Single Block command */
1091 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
1093 if(errorstate != HAL_MMC_ERROR_NONE)
1095 /* Clear all the static flags */
1096 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1097 hmmc->ErrorCode |= errorstate;
1098 hmmc->State = HAL_MMC_STATE_READY;
1099 return HAL_ERROR;
1102 /* Enable transfer interrupts */
1103 __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND | SDMMC_FLAG_TXFIFOHE));
1105 return HAL_OK;
1107 else
1109 return HAL_BUSY;
1114 * @brief Reads block(s) from a specified address in a card. The Data transfer
1115 * is managed by DMA mode.
1116 * @note This API should be followed by a check on the card state through
1117 * HAL_MMC_GetCardState().
1118 * @note You could also check the DMA transfer process through the MMC Rx
1119 * interrupt event.
1120 * @param hmmc: Pointer MMC handle
1121 * @param pData: Pointer to the buffer that will contain the received data
1122 * @param BlockAdd: Block Address from where data is to be read
1123 * @param NumberOfBlocks: Number of blocks to read.
1124 * @retval HAL status
1126 HAL_StatusTypeDef HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
1128 SDMMC_DataInitTypeDef config;
1129 uint32_t errorstate;
1130 uint32_t add = BlockAdd;
1132 if(NULL == pData)
1134 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1135 return HAL_ERROR;
1138 if(hmmc->State == HAL_MMC_STATE_READY)
1140 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
1142 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1144 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1145 return HAL_ERROR;
1148 hmmc->State = HAL_MMC_STATE_BUSY;
1150 /* Initialize data control register */
1151 hmmc->Instance->DCTRL = 0U;
1153 hmmc->pRxBuffPtr = pData;
1154 hmmc->RxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1156 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1158 add *= 512U;
1161 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) == 0U)
1163 /* Set Block Size for Card */
1164 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, MMC_BLOCKSIZE);
1165 if(errorstate != HAL_MMC_ERROR_NONE)
1167 /* Clear all the static flags */
1168 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1169 hmmc->ErrorCode = errorstate;
1170 hmmc->State = HAL_MMC_STATE_READY;
1171 return HAL_ERROR;
1175 /* Configure the MMC DPSM (Data Path State Machine) */
1176 config.DataTimeOut = SDMMC_DATATIMEOUT;
1177 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks;
1178 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1179 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
1180 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
1181 config.DPSM = SDMMC_DPSM_DISABLE;
1182 (void)SDMMC_ConfigData(hmmc->Instance, &config);
1184 __SDMMC_CMDTRANS_ENABLE( hmmc->Instance);
1185 hmmc->Instance->IDMABASE0 = (uint32_t) pData ;
1186 hmmc->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_SINGLE_BUFF;
1188 /* Read Blocks in DMA mode */
1189 if(NumberOfBlocks > 1U)
1191 hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
1193 /* Read Multi Block command */
1194 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add);
1196 else
1198 hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_DMA);
1200 /* Read Single Block command */
1201 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add);
1203 if(errorstate != HAL_MMC_ERROR_NONE)
1205 /* Clear all the static flags */
1206 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1207 hmmc->ErrorCode = errorstate;
1208 hmmc->State = HAL_MMC_STATE_READY;
1209 return HAL_ERROR;
1212 /* Enable transfer interrupts */
1213 __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND));
1215 return HAL_OK;
1217 else
1219 return HAL_BUSY;
1224 * @brief Writes block(s) to a specified address in a card. The Data transfer
1225 * is managed by DMA mode.
1226 * @note This API should be followed by a check on the card state through
1227 * HAL_MMC_GetCardState().
1228 * @note You could also check the DMA transfer process through the MMC Tx
1229 * interrupt event.
1230 * @param hmmc: Pointer to MMC handle
1231 * @param pData: Pointer to the buffer that will contain the data to transmit
1232 * @param BlockAdd: Block Address where data will be written
1233 * @param NumberOfBlocks: Number of blocks to write
1234 * @retval HAL status
1236 HAL_StatusTypeDef HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
1238 SDMMC_DataInitTypeDef config;
1239 uint32_t errorstate;
1240 uint32_t add = BlockAdd;
1242 if(NULL == pData)
1244 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1245 return HAL_ERROR;
1248 if(hmmc->State == HAL_MMC_STATE_READY)
1250 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1252 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1254 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1255 return HAL_ERROR;
1258 hmmc->State = HAL_MMC_STATE_BUSY;
1260 /* Initialize data control register */
1261 hmmc->Instance->DCTRL = 0U;
1263 hmmc->pTxBuffPtr = pData;
1264 hmmc->TxXferSize = MMC_BLOCKSIZE * NumberOfBlocks;
1266 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1268 add *= 512U;
1271 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) == 0U)
1273 /* Set Block Size for Card */
1274 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, MMC_BLOCKSIZE);
1275 if(errorstate != HAL_MMC_ERROR_NONE)
1277 /* Clear all the static flags */
1278 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1279 hmmc->ErrorCode |= errorstate;
1280 hmmc->State = HAL_MMC_STATE_READY;
1281 return HAL_ERROR;
1285 /* Configure the MMC DPSM (Data Path State Machine) */
1286 config.DataTimeOut = SDMMC_DATATIMEOUT;
1287 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks;
1288 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1289 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
1290 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
1291 config.DPSM = SDMMC_DPSM_DISABLE;
1292 (void)SDMMC_ConfigData(hmmc->Instance, &config);
1294 __SDMMC_CMDTRANS_ENABLE( hmmc->Instance);
1296 hmmc->Instance->IDMABASE0 = (uint32_t) pData ;
1297 hmmc->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_SINGLE_BUFF;
1299 /* Write Blocks in Polling mode */
1300 if(NumberOfBlocks > 1U)
1302 hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
1304 /* Write Multi Block command */
1305 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add);
1307 else
1309 hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_DMA);
1311 /* Write Single Block command */
1312 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add);
1314 if(errorstate != HAL_MMC_ERROR_NONE)
1316 /* Clear all the static flags */
1317 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1318 hmmc->ErrorCode |= errorstate;
1319 hmmc->State = HAL_MMC_STATE_READY;
1320 return HAL_ERROR;
1323 /* Enable transfer interrupts */
1324 __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND));
1326 return HAL_OK;
1328 else
1330 return HAL_BUSY;
1335 * @brief Erases the specified memory area of the given MMC card.
1336 * @note This API should be followed by a check on the card state through
1337 * HAL_MMC_GetCardState().
1338 * @param hmmc: Pointer to MMC handle
1339 * @param BlockStartAdd: Start Block address
1340 * @param BlockEndAdd: End Block address
1341 * @retval HAL status
1343 HAL_StatusTypeDef HAL_MMC_Erase(MMC_HandleTypeDef *hmmc, uint32_t BlockStartAdd, uint32_t BlockEndAdd)
1345 uint32_t errorstate;
1346 uint32_t start_add = BlockStartAdd;
1347 uint32_t end_add = BlockEndAdd;
1349 if(hmmc->State == HAL_MMC_STATE_READY)
1351 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1353 if(end_add < start_add)
1355 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1356 return HAL_ERROR;
1359 if(end_add > (hmmc->MmcCard.LogBlockNbr))
1361 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1362 return HAL_ERROR;
1365 hmmc->State = HAL_MMC_STATE_BUSY;
1367 /* Check if the card command class supports erase command */
1368 if(((hmmc->MmcCard.Class) & SDMMC_CCCC_ERASE) == 0U)
1370 /* Clear all the static flags */
1371 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1372 hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
1373 hmmc->State = HAL_MMC_STATE_READY;
1374 return HAL_ERROR;
1377 if((SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
1379 /* Clear all the static flags */
1380 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1381 hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED;
1382 hmmc->State = HAL_MMC_STATE_READY;
1383 return HAL_ERROR;
1386 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD)
1388 start_add *= 512U;
1389 end_add *= 512U;
1392 /* Send CMD35 MMC_ERASE_GRP_START with argument as addr */
1393 errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, start_add);
1394 if(errorstate != HAL_MMC_ERROR_NONE)
1396 /* Clear all the static flags */
1397 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1398 hmmc->ErrorCode |= errorstate;
1399 hmmc->State = HAL_MMC_STATE_READY;
1400 return HAL_ERROR;
1403 /* Send CMD36 MMC_ERASE_GRP_END with argument as addr */
1404 errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, end_add);
1405 if(errorstate != HAL_MMC_ERROR_NONE)
1407 /* Clear all the static flags */
1408 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1409 hmmc->ErrorCode |= errorstate;
1410 hmmc->State = HAL_MMC_STATE_READY;
1411 return HAL_ERROR;
1414 /* Send CMD38 ERASE */
1415 errorstate = SDMMC_CmdErase(hmmc->Instance);
1416 if(errorstate != HAL_MMC_ERROR_NONE)
1418 /* Clear all the static flags */
1419 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1420 hmmc->ErrorCode |= errorstate;
1421 hmmc->State = HAL_MMC_STATE_READY;
1422 return HAL_ERROR;
1425 hmmc->State = HAL_MMC_STATE_READY;
1427 return HAL_OK;
1429 else
1431 return HAL_BUSY;
1436 * @brief This function handles MMC card interrupt request.
1437 * @param hmmc: Pointer to MMC handle
1438 * @retval None
1440 void HAL_MMC_IRQHandler(MMC_HandleTypeDef *hmmc)
1442 uint32_t errorstate;
1443 uint32_t context = hmmc->Context;
1445 /* Check for SDMMC interrupt flags */
1446 if((__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) != RESET) && ((context & MMC_CONTEXT_IT) != 0U))
1448 MMC_Read_IT(hmmc);
1451 else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) != RESET)
1453 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_DATAEND);
1455 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT |\
1456 SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR | SDMMC_IT_TXFIFOHE |\
1457 SDMMC_IT_RXFIFOHF);
1459 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_IDMABTC);
1460 __SDMMC_CMDTRANS_DISABLE( hmmc->Instance);
1462 if((context & MMC_CONTEXT_DMA) != 0U)
1464 hmmc->Instance->DLEN = 0;
1465 hmmc->Instance->DCTRL = 0;
1466 hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA ;
1468 /* Stop Transfer for Write Multi blocks or Read Multi blocks */
1469 if(((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
1471 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
1472 if(errorstate != HAL_MMC_ERROR_NONE)
1474 hmmc->ErrorCode |= errorstate;
1475 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1476 hmmc->ErrorCallback(hmmc);
1477 #else
1478 HAL_MMC_ErrorCallback(hmmc);
1479 #endif
1483 /* Clear all the static flags */
1484 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
1486 hmmc->State = HAL_MMC_STATE_READY;
1487 if(((context & MMC_CONTEXT_WRITE_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
1489 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1490 hmmc->TxCpltCallback(hmmc);
1491 #else
1492 HAL_MMC_TxCpltCallback(hmmc);
1493 #endif
1495 if(((context & MMC_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
1497 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1498 hmmc->RxCpltCallback(hmmc);
1499 #else
1500 HAL_MMC_RxCpltCallback(hmmc);
1501 #endif
1504 else if((context & MMC_CONTEXT_IT) != 0U)
1506 /* Stop Transfer for Write Multi blocks or Read Multi blocks */
1507 if(((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U))
1509 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
1510 if(errorstate != HAL_MMC_ERROR_NONE)
1512 hmmc->ErrorCode |= errorstate;
1513 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1514 hmmc->ErrorCallback(hmmc);
1515 #else
1516 HAL_MMC_ErrorCallback(hmmc);
1517 #endif
1521 /* Clear all the static flags */
1522 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
1524 hmmc->State = HAL_MMC_STATE_READY;
1525 if(((context & MMC_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U))
1527 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1528 hmmc->RxCpltCallback(hmmc);
1529 #else
1530 HAL_MMC_RxCpltCallback(hmmc);
1531 #endif
1533 else
1535 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1536 hmmc->TxCpltCallback(hmmc);
1537 #else
1538 HAL_MMC_TxCpltCallback(hmmc);
1539 #endif
1542 else
1544 /* Nothing to do */
1548 else if((__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) != RESET) && ((context & MMC_CONTEXT_IT) != 0U))
1550 MMC_Write_IT(hmmc);
1553 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL| SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_RXOVERR | SDMMC_FLAG_TXUNDERR) != RESET)
1555 /* Set Error code */
1556 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_DCRCFAIL) != RESET)
1558 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
1560 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_DTIMEOUT) != RESET)
1562 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
1564 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_RXOVERR) != RESET)
1566 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
1568 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_TXUNDERR) != RESET)
1570 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
1573 /* Clear All flags */
1574 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
1576 /* Disable all interrupts */
1577 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\
1578 SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR);
1580 __SDMMC_CMDTRANS_DISABLE( hmmc->Instance);
1581 hmmc->Instance->DCTRL |= SDMMC_DCTRL_FIFORST;
1582 hmmc->Instance->CMD |= SDMMC_CMD_CMDSTOP;
1583 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
1584 hmmc->Instance->CMD &= ~(SDMMC_CMD_CMDSTOP);
1585 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_DABORT);
1587 if((context & MMC_CONTEXT_IT) != 0U)
1589 /* Set the MMC state to ready to be able to start again the process */
1590 hmmc->State = HAL_MMC_STATE_READY;
1591 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1592 hmmc->ErrorCallback(hmmc);
1593 #else
1594 HAL_MMC_ErrorCallback(hmmc);
1595 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1597 else if((context & MMC_CONTEXT_DMA) != 0U)
1599 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
1601 /* Disable Internal DMA */
1602 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_IDMABTC);
1603 hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA;
1605 /* Set the MMC state to ready to be able to start again the process */
1606 hmmc->State = HAL_MMC_STATE_READY;
1607 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1608 hmmc->ErrorCallback(hmmc);
1609 #else
1610 HAL_MMC_ErrorCallback(hmmc);
1611 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1614 else
1616 /* Nothing to do */
1620 else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_IDMABTC) != RESET)
1622 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_IT_IDMABTC);
1623 if(READ_BIT(hmmc->Instance->IDMACTRL, SDMMC_IDMA_IDMABACT) == 0U)
1625 /* Current buffer is buffer0, Transfer complete for buffer1 */
1626 if((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)
1628 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1629 hmmc->Write_DMADblBuf1CpltCallback(hmmc);
1630 #else
1631 HAL_MMCEx_Write_DMADoubleBuf1CpltCallback(hmmc);
1632 #endif
1634 else /* MMC_CONTEXT_READ_MULTIPLE_BLOCK */
1636 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1637 hmmc->Read_DMADblBuf1CpltCallback(hmmc);
1638 #else
1639 HAL_MMCEx_Read_DMADoubleBuf1CpltCallback(hmmc);
1640 #endif
1643 else /* MMC_DMA_BUFFER1 */
1645 /* Current buffer is buffer1, Transfer complete for buffer0 */
1646 if((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)
1648 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1649 hmmc->Write_DMADblBuf0CpltCallback(hmmc);
1650 #else
1651 HAL_MMCEx_Write_DMADoubleBuf0CpltCallback(hmmc);
1652 #endif
1654 else /* MMC_CONTEXT_READ_MULTIPLE_BLOCK */
1656 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1657 hmmc->Read_DMADblBuf0CpltCallback(hmmc);
1658 #else
1659 HAL_MMCEx_Read_DMADoubleBuf0CpltCallback(hmmc);
1660 #endif
1665 else
1667 /* Nothing to do */
1672 * @brief return the MMC state
1673 * @param hmmc: Pointer to mmc handle
1674 * @retval HAL state
1676 HAL_MMC_StateTypeDef HAL_MMC_GetState(MMC_HandleTypeDef *hmmc)
1678 return hmmc->State;
1682 * @brief Return the MMC error code
1683 * @param hmmc : Pointer to a MMC_HandleTypeDef structure that contains
1684 * the configuration information.
1685 * @retval MMC Error Code
1687 uint32_t HAL_MMC_GetError(MMC_HandleTypeDef *hmmc)
1689 return hmmc->ErrorCode;
1693 * @brief Tx Transfer completed callbacks
1694 * @param hmmc: Pointer to MMC handle
1695 * @retval None
1697 __weak void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef *hmmc)
1699 /* Prevent unused argument(s) compilation warning */
1700 UNUSED(hmmc);
1702 /* NOTE : This function should not be modified, when the callback is needed,
1703 the HAL_MMC_TxCpltCallback can be implemented in the user file
1708 * @brief Rx Transfer completed callbacks
1709 * @param hmmc: Pointer MMC handle
1710 * @retval None
1712 __weak void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef *hmmc)
1714 /* Prevent unused argument(s) compilation warning */
1715 UNUSED(hmmc);
1717 /* NOTE : This function should not be modified, when the callback is needed,
1718 the HAL_MMC_RxCpltCallback can be implemented in the user file
1723 * @brief MMC error callbacks
1724 * @param hmmc: Pointer MMC handle
1725 * @retval None
1727 __weak void HAL_MMC_ErrorCallback(MMC_HandleTypeDef *hmmc)
1729 /* Prevent unused argument(s) compilation warning */
1730 UNUSED(hmmc);
1732 /* NOTE : This function should not be modified, when the callback is needed,
1733 the HAL_MMC_ErrorCallback can be implemented in the user file
1738 * @brief MMC Abort callbacks
1739 * @param hmmc: Pointer MMC handle
1740 * @retval None
1742 __weak void HAL_MMC_AbortCallback(MMC_HandleTypeDef *hmmc)
1744 /* Prevent unused argument(s) compilation warning */
1745 UNUSED(hmmc);
1747 /* NOTE : This function should not be modified, when the callback is needed,
1748 the HAL_MMC_AbortCallback can be implemented in the user file
1752 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1754 * @brief Register a User MMC Callback
1755 * To be used instead of the weak (surcharged) predefined callback
1756 * @param hmmc : MMC handle
1757 * @param CallbackId : ID of the callback to be registered
1758 * This parameter can be one of the following values:
1759 * @arg @ref HAL_MMC_TX_CPLT_CB_ID MMC Tx Complete Callback ID
1760 * @arg @ref HAL_MMC_RX_CPLT_CB_ID MMC Rx Complete Callback ID
1761 * @arg @ref HAL_MMC_ERROR_CB_ID MMC Error Callback ID
1762 * @arg @ref HAL_MMC_ABORT_CB_ID MMC Abort Callback ID
1763 * @arg @ref HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID MMC DMA Rx Double buffer 0 Callback ID
1764 * @arg @ref HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID MMC DMA Rx Double buffer 1 Callback ID
1765 * @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID MMC DMA Tx Double buffer 0 Callback ID
1766 * @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID MMC DMA Tx Double buffer 1 Callback ID
1767 * @arg @ref HAL_MMC_MSP_INIT_CB_ID MMC MspInit Callback ID
1768 * @arg @ref HAL_MMC_MSP_DEINIT_CB_ID MMC MspDeInit Callback ID
1769 * @param pCallback : pointer to the Callback function
1770 * @retval status
1772 HAL_StatusTypeDef HAL_MMC_RegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId, pMMC_CallbackTypeDef pCallback)
1774 HAL_StatusTypeDef status = HAL_OK;
1776 if(pCallback == NULL)
1778 /* Update the error code */
1779 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1780 return HAL_ERROR;
1783 /* Process locked */
1784 __HAL_LOCK(hmmc);
1786 if(hmmc->State == HAL_MMC_STATE_READY)
1788 switch (CallbackId)
1790 case HAL_MMC_TX_CPLT_CB_ID :
1791 hmmc->TxCpltCallback = pCallback;
1792 break;
1793 case HAL_MMC_RX_CPLT_CB_ID :
1794 hmmc->RxCpltCallback = pCallback;
1795 break;
1796 case HAL_MMC_ERROR_CB_ID :
1797 hmmc->ErrorCallback = pCallback;
1798 break;
1799 case HAL_MMC_ABORT_CB_ID :
1800 hmmc->AbortCpltCallback = pCallback;
1801 break;
1802 case HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID :
1803 hmmc->Read_DMADblBuf0CpltCallback = pCallback;
1804 break;
1805 case HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID :
1806 hmmc->Read_DMADblBuf1CpltCallback = pCallback;
1807 break;
1808 case HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID :
1809 hmmc->Write_DMADblBuf0CpltCallback = pCallback;
1810 break;
1811 case HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID :
1812 hmmc->Write_DMADblBuf1CpltCallback = pCallback;
1813 break;
1814 case HAL_MMC_MSP_INIT_CB_ID :
1815 hmmc->MspInitCallback = pCallback;
1816 break;
1817 case HAL_MMC_MSP_DEINIT_CB_ID :
1818 hmmc->MspDeInitCallback = pCallback;
1819 break;
1820 default :
1821 /* Update the error code */
1822 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1823 /* update return status */
1824 status = HAL_ERROR;
1825 break;
1828 else if (hmmc->State == HAL_MMC_STATE_RESET)
1830 switch (CallbackId)
1832 case HAL_MMC_MSP_INIT_CB_ID :
1833 hmmc->MspInitCallback = pCallback;
1834 break;
1835 case HAL_MMC_MSP_DEINIT_CB_ID :
1836 hmmc->MspDeInitCallback = pCallback;
1837 break;
1838 default :
1839 /* Update the error code */
1840 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1841 /* update return status */
1842 status = HAL_ERROR;
1843 break;
1846 else
1848 /* Update the error code */
1849 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1850 /* update return status */
1851 status = HAL_ERROR;
1854 /* Release Lock */
1855 __HAL_UNLOCK(hmmc);
1856 return status;
1860 * @brief Unregister a User MMC Callback
1861 * MMC Callback is redirected to the weak (surcharged) predefined callback
1862 * @param hmmc : MMC handle
1863 * @param CallbackId : ID of the callback to be unregistered
1864 * This parameter can be one of the following values:
1865 * @arg @ref HAL_MMC_TX_CPLT_CB_ID MMC Tx Complete Callback ID
1866 * @arg @ref HAL_MMC_RX_CPLT_CB_ID MMC Rx Complete Callback ID
1867 * @arg @ref HAL_MMC_ERROR_CB_ID MMC Error Callback ID
1868 * @arg @ref HAL_MMC_ABORT_CB_ID MMC Abort Callback ID
1869 * @arg @ref HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID MMC DMA Rx Double buffer 0 Callback ID
1870 * @arg @ref HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID MMC DMA Rx Double buffer 1 Callback ID
1871 * @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID MMC DMA Tx Double buffer 0 Callback ID
1872 * @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID MMC DMA Tx Double buffer 1 Callback ID
1873 * @arg @ref HAL_MMC_MSP_INIT_CB_ID MMC MspInit Callback ID
1874 * @arg @ref HAL_MMC_MSP_DEINIT_CB_ID MMC MspDeInit Callback ID
1875 * @retval status
1877 HAL_StatusTypeDef HAL_MMC_UnRegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId)
1879 HAL_StatusTypeDef status = HAL_OK;
1881 /* Process locked */
1882 __HAL_LOCK(hmmc);
1884 if(hmmc->State == HAL_MMC_STATE_READY)
1886 switch (CallbackId)
1888 case HAL_MMC_TX_CPLT_CB_ID :
1889 hmmc->TxCpltCallback = HAL_MMC_TxCpltCallback;
1890 break;
1891 case HAL_MMC_RX_CPLT_CB_ID :
1892 hmmc->RxCpltCallback = HAL_MMC_RxCpltCallback;
1893 break;
1894 case HAL_MMC_ERROR_CB_ID :
1895 hmmc->ErrorCallback = HAL_MMC_ErrorCallback;
1896 break;
1897 case HAL_MMC_ABORT_CB_ID :
1898 hmmc->AbortCpltCallback = HAL_MMC_AbortCallback;
1899 break;
1900 case HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID :
1901 hmmc->Read_DMADblBuf0CpltCallback = HAL_MMCEx_Read_DMADoubleBuf0CpltCallback;
1902 break;
1903 case HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID :
1904 hmmc->Read_DMADblBuf1CpltCallback = HAL_MMCEx_Read_DMADoubleBuf1CpltCallback;
1905 break;
1906 case HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID :
1907 hmmc->Write_DMADblBuf0CpltCallback = HAL_MMCEx_Write_DMADoubleBuf0CpltCallback;
1908 break;
1909 case HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID :
1910 hmmc->Write_DMADblBuf1CpltCallback = HAL_MMCEx_Write_DMADoubleBuf1CpltCallback;
1911 break;
1912 case HAL_MMC_MSP_INIT_CB_ID :
1913 hmmc->MspInitCallback = HAL_MMC_MspInit;
1914 break;
1915 case HAL_MMC_MSP_DEINIT_CB_ID :
1916 hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
1917 break;
1918 default :
1919 /* Update the error code */
1920 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1921 /* update return status */
1922 status = HAL_ERROR;
1923 break;
1926 else if (hmmc->State == HAL_MMC_STATE_RESET)
1928 switch (CallbackId)
1930 case HAL_MMC_MSP_INIT_CB_ID :
1931 hmmc->MspInitCallback = HAL_MMC_MspInit;
1932 break;
1933 case HAL_MMC_MSP_DEINIT_CB_ID :
1934 hmmc->MspDeInitCallback = HAL_MMC_MspDeInit;
1935 break;
1936 default :
1937 /* Update the error code */
1938 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1939 /* update return status */
1940 status = HAL_ERROR;
1941 break;
1944 else
1946 /* Update the error code */
1947 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK;
1948 /* update return status */
1949 status = HAL_ERROR;
1952 /* Release Lock */
1953 __HAL_UNLOCK(hmmc);
1954 return status;
1956 #endif
1959 * @}
1962 /** @addtogroup MMC_Exported_Functions_Group3
1963 * @brief management functions
1965 @verbatim
1966 ==============================================================================
1967 ##### Peripheral Control functions #####
1968 ==============================================================================
1969 [..]
1970 This subsection provides a set of functions allowing to control the MMC card
1971 operations and get the related information
1973 @endverbatim
1974 * @{
1978 * @brief Returns information the information of the card which are stored on
1979 * the CID register.
1980 * @param hmmc: Pointer to MMC handle
1981 * @param pCID: Pointer to a HAL_MMC_CIDTypedef structure that
1982 * contains all CID register parameters
1983 * @retval HAL status
1985 HAL_StatusTypeDef HAL_MMC_GetCardCID(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCIDTypeDef *pCID)
1987 pCID->ManufacturerID = (uint8_t)((hmmc->CID[0] & 0xFF000000U) >> 24U);
1989 pCID->OEM_AppliID = (uint16_t)((hmmc->CID[0] & 0x00FFFF00U) >> 8U);
1991 pCID->ProdName1 = (((hmmc->CID[0] & 0x000000FFU) << 24U) | ((hmmc->CID[1] & 0xFFFFFF00U) >> 8U));
1993 pCID->ProdName2 = (uint8_t)(hmmc->CID[1] & 0x000000FFU);
1995 pCID->ProdRev = (uint8_t)((hmmc->CID[2] & 0xFF000000U) >> 24U);
1997 pCID->ProdSN = (((hmmc->CID[2] & 0x00FFFFFFU) << 8U) | ((hmmc->CID[3] & 0xFF000000U) >> 24U));
1999 pCID->Reserved1 = (uint8_t)((hmmc->CID[3] & 0x00F00000U) >> 20U);
2001 pCID->ManufactDate = (uint16_t)((hmmc->CID[3] & 0x000FFF00U) >> 8U);
2003 pCID->CID_CRC = (uint8_t)((hmmc->CID[3] & 0x000000FEU) >> 1U);
2005 pCID->Reserved2 = 1U;
2007 return HAL_OK;
2011 * @brief Returns information the information of the card which are stored on
2012 * the CSD register.
2013 * @param hmmc: Pointer to MMC handle
2014 * @param pCSD: Pointer to a HAL_MMC_CardCSDTypeDef structure that
2015 * contains all CSD register parameters
2016 * @retval HAL status
2018 HAL_StatusTypeDef HAL_MMC_GetCardCSD(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCSDTypeDef *pCSD)
2020 uint32_t block_nbr = 0;
2022 pCSD->CSDStruct = (uint8_t)((hmmc->CSD[0] & 0xC0000000U) >> 30U);
2024 pCSD->SysSpecVersion = (uint8_t)((hmmc->CSD[0] & 0x3C000000U) >> 26U);
2026 pCSD->Reserved1 = (uint8_t)((hmmc->CSD[0] & 0x03000000U) >> 24U);
2028 pCSD->TAAC = (uint8_t)((hmmc->CSD[0] & 0x00FF0000U) >> 16U);
2030 pCSD->NSAC = (uint8_t)((hmmc->CSD[0] & 0x0000FF00U) >> 8U);
2032 pCSD->MaxBusClkFrec = (uint8_t)(hmmc->CSD[0] & 0x000000FFU);
2034 pCSD->CardComdClasses = (uint16_t)((hmmc->CSD[1] & 0xFFF00000U) >> 20U);
2036 pCSD->RdBlockLen = (uint8_t)((hmmc->CSD[1] & 0x000F0000U) >> 16U);
2038 pCSD->PartBlockRead = (uint8_t)((hmmc->CSD[1] & 0x00008000U) >> 15U);
2040 pCSD->WrBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00004000U) >> 14U);
2042 pCSD->RdBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00002000U) >> 13U);
2044 pCSD->DSRImpl = (uint8_t)((hmmc->CSD[1] & 0x00001000U) >> 12U);
2046 pCSD->Reserved2 = 0U; /*!< Reserved */
2048 if(MMC_ReadExtCSD(hmmc, &block_nbr, 212, 0x0FFFFFFFU) != HAL_OK) /* Field SEC_COUNT [215:212] */
2050 return HAL_ERROR;
2053 if(hmmc->MmcCard.CardType == MMC_LOW_CAPACITY_CARD)
2055 pCSD->DeviceSize = (((hmmc->CSD[1] & 0x000003FFU) << 2U) | ((hmmc->CSD[2] & 0xC0000000U) >> 30U));
2057 pCSD->MaxRdCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x38000000U) >> 27U);
2059 pCSD->MaxRdCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x07000000U) >> 24U);
2061 pCSD->MaxWrCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x00E00000U) >> 21U);
2063 pCSD->MaxWrCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x001C0000U) >> 18U);
2065 pCSD->DeviceSizeMul = (uint8_t)((hmmc->CSD[2] & 0x00038000U) >> 15U);
2067 hmmc->MmcCard.BlockNbr = (pCSD->DeviceSize + 1U) ;
2068 hmmc->MmcCard.BlockNbr *= (1UL << ((pCSD->DeviceSizeMul & 0x07U) + 2U));
2069 hmmc->MmcCard.BlockSize = (1UL << (pCSD->RdBlockLen & 0x0FU));
2071 hmmc->MmcCard.LogBlockNbr = (hmmc->MmcCard.BlockNbr) * ((hmmc->MmcCard.BlockSize) / 512U);
2072 hmmc->MmcCard.LogBlockSize = 512U;
2074 else if(hmmc->MmcCard.CardType == MMC_HIGH_CAPACITY_CARD)
2076 hmmc->MmcCard.BlockNbr = block_nbr;
2077 hmmc->MmcCard.LogBlockNbr = hmmc->MmcCard.BlockNbr;
2078 hmmc->MmcCard.BlockSize = 512U;
2079 hmmc->MmcCard.LogBlockSize = hmmc->MmcCard.BlockSize;
2081 else
2083 /* Clear all the static flags */
2084 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2085 hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2086 hmmc->State = HAL_MMC_STATE_READY;
2087 return HAL_ERROR;
2090 pCSD->EraseGrSize = (uint8_t)((hmmc->CSD[2] & 0x00004000U) >> 14U);
2092 pCSD->EraseGrMul = (uint8_t)((hmmc->CSD[2] & 0x00003F80U) >> 7U);
2094 pCSD->WrProtectGrSize = (uint8_t)(hmmc->CSD[2] & 0x0000007FU);
2096 pCSD->WrProtectGrEnable = (uint8_t)((hmmc->CSD[3] & 0x80000000U) >> 31U);
2098 pCSD->ManDeflECC = (uint8_t)((hmmc->CSD[3] & 0x60000000U) >> 29U);
2100 pCSD->WrSpeedFact = (uint8_t)((hmmc->CSD[3] & 0x1C000000U) >> 26U);
2102 pCSD->MaxWrBlockLen= (uint8_t)((hmmc->CSD[3] & 0x03C00000U) >> 22U);
2104 pCSD->WriteBlockPaPartial = (uint8_t)((hmmc->CSD[3] & 0x00200000U) >> 21U);
2106 pCSD->Reserved3 = 0;
2108 pCSD->ContentProtectAppli = (uint8_t)((hmmc->CSD[3] & 0x00010000U) >> 16U);
2110 pCSD->FileFormatGroup = (uint8_t)((hmmc->CSD[3] & 0x00008000U) >> 15U);
2112 pCSD->CopyFlag = (uint8_t)((hmmc->CSD[3] & 0x00004000U) >> 14U);
2114 pCSD->PermWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00002000U) >> 13U);
2116 pCSD->TempWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00001000U) >> 12U);
2118 pCSD->FileFormat = (uint8_t)((hmmc->CSD[3] & 0x00000C00U) >> 10U);
2120 pCSD->ECC= (uint8_t)((hmmc->CSD[3] & 0x00000300U) >> 8U);
2122 pCSD->CSD_CRC = (uint8_t)((hmmc->CSD[3] & 0x000000FEU) >> 1U);
2124 pCSD->Reserved4 = 1;
2126 return HAL_OK;
2130 * @brief Gets the MMC card info.
2131 * @param hmmc: Pointer to MMC handle
2132 * @param pCardInfo: Pointer to the HAL_MMC_CardInfoTypeDef structure that
2133 * will contain the MMC card status information
2134 * @retval HAL status
2136 HAL_StatusTypeDef HAL_MMC_GetCardInfo(MMC_HandleTypeDef *hmmc, HAL_MMC_CardInfoTypeDef *pCardInfo)
2138 pCardInfo->CardType = (uint32_t)(hmmc->MmcCard.CardType);
2139 pCardInfo->Class = (uint32_t)(hmmc->MmcCard.Class);
2140 pCardInfo->RelCardAdd = (uint32_t)(hmmc->MmcCard.RelCardAdd);
2141 pCardInfo->BlockNbr = (uint32_t)(hmmc->MmcCard.BlockNbr);
2142 pCardInfo->BlockSize = (uint32_t)(hmmc->MmcCard.BlockSize);
2143 pCardInfo->LogBlockNbr = (uint32_t)(hmmc->MmcCard.LogBlockNbr);
2144 pCardInfo->LogBlockSize = (uint32_t)(hmmc->MmcCard.LogBlockSize);
2146 return HAL_OK;
2150 * @brief Enables wide bus operation for the requested card if supported by
2151 * card.
2152 * @param hmmc: Pointer to MMC handle
2153 * @param WideMode: Specifies the MMC card wide bus mode
2154 * This parameter can be one of the following values:
2155 * @arg SDMMC_BUS_WIDE_8B: 8-bit data transfer
2156 * @arg SDMMC_BUS_WIDE_4B: 4-bit data transfer
2157 * @arg SDMMC_BUS_WIDE_1B: 1-bit data transfer
2158 * @retval HAL status
2160 HAL_StatusTypeDef HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef *hmmc, uint32_t WideMode)
2162 __IO uint32_t count = 0U;
2163 SDMMC_InitTypeDef Init;
2164 uint32_t errorstate;
2165 uint32_t response = 0U, busy = 0U;
2167 /* Check the parameters */
2168 assert_param(IS_SDMMC_BUS_WIDE(WideMode));
2170 /* Chnage Satte */
2171 hmmc->State = HAL_MMC_STATE_BUSY;
2173 if(WideMode == SDMMC_BUS_WIDE_8B)
2175 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U);
2176 if(errorstate != HAL_MMC_ERROR_NONE)
2178 hmmc->ErrorCode |= errorstate;
2181 else if(WideMode == SDMMC_BUS_WIDE_4B)
2183 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U);
2184 if(errorstate != HAL_MMC_ERROR_NONE)
2186 hmmc->ErrorCode |= errorstate;
2189 else if(WideMode == SDMMC_BUS_WIDE_1B)
2191 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70000U);
2192 if(errorstate != HAL_MMC_ERROR_NONE)
2194 hmmc->ErrorCode |= errorstate;
2197 else
2199 /* WideMode is not a valid argument*/
2200 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
2203 /* Check for switch error and violation of the trial number of sending CMD 13 */
2204 while(busy == 0U)
2206 if(count == SDMMC_MAX_TRIAL)
2208 hmmc->State = HAL_MMC_STATE_READY;
2209 hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
2210 return HAL_ERROR;
2212 count++;
2214 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2215 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2216 if(errorstate != HAL_MMC_ERROR_NONE)
2218 hmmc->ErrorCode |= errorstate;
2221 /* Get command response */
2222 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
2224 /* Get operating voltage*/
2225 busy = (((response >> 7U) == 1U) ? 0U : 1U);
2228 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2229 count = SDMMC_DATATIMEOUT;
2230 while((response & 0x00000100U) == 0U)
2232 if(count == 0U)
2234 hmmc->State = HAL_MMC_STATE_READY;
2235 hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
2236 return HAL_ERROR;
2238 count--;
2240 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2241 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2242 if(errorstate != HAL_MMC_ERROR_NONE)
2244 hmmc->ErrorCode |= errorstate;
2247 /* Get command response */
2248 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
2251 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2253 /* Clear all the static flags */
2254 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2255 hmmc->State = HAL_MMC_STATE_READY;
2256 return HAL_ERROR;
2258 else
2260 /* Configure the SDMMC peripheral */
2261 Init.ClockEdge = hmmc->Init.ClockEdge;
2262 Init.ClockPowerSave = hmmc->Init.ClockPowerSave;
2263 Init.BusWide = WideMode;
2264 Init.HardwareFlowControl = hmmc->Init.HardwareFlowControl;
2265 Init.ClockDiv = hmmc->Init.ClockDiv;
2266 (void)SDMMC_Init(hmmc->Instance, Init);
2269 /* Change State */
2270 hmmc->State = HAL_MMC_STATE_READY;
2272 return HAL_OK;
2276 * @brief Configure the speed bus mode
2277 * @param hmmc: Pointer to the MMC handle
2278 * @param SpeedMode: Specifies the MMC card speed bus mode
2279 * This parameter can be one of the following values:
2280 * @arg SDMMC_SPEED_MODE_AUTO: Max speed mode supported by the card
2281 * @arg SDMMC_SPEED_MODE_DEFAULT: Default Speed (MMC @ 26MHz)
2282 * @arg SDMMC_SPEED_MODE_HIGH: High Speed (MMC @ 52 MHz)
2283 * @arg SDMMC_SPEED_MODE_DDR: High Speed DDR (MMC DDR @ 52 MHz)
2284 * @retval HAL status
2287 HAL_StatusTypeDef HAL_MMC_ConfigSpeedBusOperation(MMC_HandleTypeDef *hmmc, uint32_t SpeedMode)
2289 uint32_t tickstart;
2290 HAL_StatusTypeDef status = HAL_OK;
2291 uint32_t device_type;
2292 uint32_t errorstate;
2294 /* Check the parameters */
2295 assert_param(IS_SDMMC_SPEED_MODE(SpeedMode));
2296 /* Change State */
2297 hmmc->State = HAL_MMC_STATE_BUSY;
2299 if(MMC_ReadExtCSD(hmmc, &device_type, 196, 0x0FFFFFFFU) != HAL_OK) /* Field DEVICE_TYPE [196] */
2301 return HAL_ERROR;
2304 switch (SpeedMode)
2306 case SDMMC_SPEED_MODE_AUTO:
2308 if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS) != 0U) && ((device_type & 0x04U) != 0U))
2310 /* High Speed DDR mode allowed */
2311 errorstate = MMC_HighSpeed(hmmc, ENABLE);
2312 if(errorstate != HAL_MMC_ERROR_NONE)
2314 hmmc->ErrorCode |= errorstate;
2316 else
2318 errorstate = MMC_DDR_Mode(hmmc, ENABLE);
2319 if(errorstate != HAL_MMC_ERROR_NONE)
2321 hmmc->ErrorCode |= errorstate;
2325 else if ((device_type & 0x02U) != 0U)
2327 /* High Speed mode allowed */
2328 errorstate = MMC_HighSpeed(hmmc, ENABLE);
2329 if(errorstate != HAL_MMC_ERROR_NONE)
2331 hmmc->ErrorCode |= errorstate;
2334 else
2336 /* Nothing to do : keep current speed */
2338 break;
2340 case SDMMC_SPEED_MODE_DDR:
2342 if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS) != 0U) && ((device_type & 0x04U) != 0U))
2344 /* High Speed DDR mode allowed */
2345 errorstate = MMC_HighSpeed(hmmc, ENABLE);
2346 if(errorstate != HAL_MMC_ERROR_NONE)
2348 hmmc->ErrorCode |= errorstate;
2350 else
2352 errorstate = MMC_DDR_Mode(hmmc, ENABLE);
2353 if(errorstate != HAL_MMC_ERROR_NONE)
2355 hmmc->ErrorCode |= errorstate;
2359 else
2361 /* High Speed DDR mode not allowed */
2362 hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2363 status = HAL_ERROR;
2365 break;
2367 case SDMMC_SPEED_MODE_HIGH:
2369 if ((device_type & 0x02U) != 0U)
2371 /* High Speed mode allowed */
2372 errorstate = MMC_HighSpeed(hmmc, ENABLE);
2373 if(errorstate != HAL_MMC_ERROR_NONE)
2375 hmmc->ErrorCode |= errorstate;
2378 else
2380 /* High Speed mode not allowed */
2381 hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2382 status = HAL_ERROR;
2384 break;
2386 case SDMMC_SPEED_MODE_DEFAULT:
2388 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) != 0U)
2390 /* High Speed DDR mode activated */
2391 errorstate = MMC_DDR_Mode(hmmc, DISABLE);
2392 if(errorstate != HAL_MMC_ERROR_NONE)
2394 hmmc->ErrorCode |= errorstate;
2397 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) != 0U)
2399 /* High Speed mode activated */
2400 errorstate = MMC_HighSpeed(hmmc, DISABLE);
2401 if(errorstate != HAL_MMC_ERROR_NONE)
2403 hmmc->ErrorCode |= errorstate;
2406 break;
2408 default:
2409 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
2410 status = HAL_ERROR;
2411 break;
2414 /* Verify that MMC card is ready to use after Speed mode switch*/
2415 tickstart = HAL_GetTick();
2416 while ((HAL_MMC_GetCardState(hmmc) != HAL_MMC_CARD_TRANSFER))
2418 if ((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT)
2420 hmmc->ErrorCode = HAL_MMC_ERROR_TIMEOUT;
2421 hmmc->State = HAL_MMC_STATE_READY;
2422 return HAL_TIMEOUT;
2426 /* Change State */
2427 hmmc->State = HAL_MMC_STATE_READY;
2428 return status;
2432 * @brief Gets the current mmc card data state.
2433 * @param hmmc: pointer to MMC handle
2434 * @retval Card state
2436 HAL_MMC_CardStateTypeDef HAL_MMC_GetCardState(MMC_HandleTypeDef *hmmc)
2438 uint32_t cardstate;
2439 uint32_t errorstate;
2440 uint32_t resp1 = 0U;
2442 errorstate = MMC_SendStatus(hmmc, &resp1);
2443 if(errorstate != HAL_MMC_ERROR_NONE)
2445 hmmc->ErrorCode |= errorstate;
2448 cardstate = ((resp1 >> 9U) & 0x0FU);
2450 return (HAL_MMC_CardStateTypeDef)cardstate;
2454 * @brief Abort the current transfer and disable the MMC.
2455 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2456 * the configuration information for MMC module.
2457 * @retval HAL status
2459 HAL_StatusTypeDef HAL_MMC_Abort(MMC_HandleTypeDef *hmmc)
2461 HAL_MMC_CardStateTypeDef CardState;
2463 /* DIsable All interrupts */
2464 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\
2465 SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR);
2467 /* Clear All flags */
2468 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2470 /* If IDMA Context, disable Internal DMA */
2471 hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA;
2473 hmmc->State = HAL_MMC_STATE_READY;
2475 /* Initialize the MMC operation */
2476 hmmc->Context = MMC_CONTEXT_NONE;
2478 CardState = HAL_MMC_GetCardState(hmmc);
2479 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2481 hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
2483 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2485 return HAL_ERROR;
2487 return HAL_OK;
2491 * @brief Abort the current transfer and disable the MMC (IT mode).
2492 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2493 * the configuration information for MMC module.
2494 * @retval HAL status
2496 HAL_StatusTypeDef HAL_MMC_Abort_IT(MMC_HandleTypeDef *hmmc)
2498 HAL_MMC_CardStateTypeDef CardState;
2500 /* DIsable All interrupts */
2501 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\
2502 SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR);
2504 /* If IDMA Context, disable Internal DMA */
2505 hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA;
2507 /* Clear All flags */
2508 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2510 CardState = HAL_MMC_GetCardState(hmmc);
2511 hmmc->State = HAL_MMC_STATE_READY;
2513 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2515 hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
2517 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2519 return HAL_ERROR;
2521 else
2523 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2524 hmmc->AbortCpltCallback(hmmc);
2525 #else
2526 HAL_MMC_AbortCallback(hmmc);
2527 #endif
2530 return HAL_OK;
2534 * @}
2538 * @}
2541 /* Private function ----------------------------------------------------------*/
2542 /** @addtogroup MMC_Private_Functions
2543 * @{
2548 * @brief Initializes the mmc card.
2549 * @param hmmc: Pointer to MMC handle
2550 * @retval MMC Card error state
2552 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc)
2554 HAL_MMC_CardCSDTypeDef CSD;
2555 uint32_t errorstate;
2556 uint16_t mmc_rca = 1U;
2557 MMC_InitTypeDef Init;
2559 /* Check the power State */
2560 if(SDMMC_GetPowerState(hmmc->Instance) == 0U)
2562 /* Power off */
2563 return HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
2566 /* Send CMD2 ALL_SEND_CID */
2567 errorstate = SDMMC_CmdSendCID(hmmc->Instance);
2568 if(errorstate != HAL_MMC_ERROR_NONE)
2570 return errorstate;
2572 else
2574 /* Get Card identification number data */
2575 hmmc->CID[0U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
2576 hmmc->CID[1U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2);
2577 hmmc->CID[2U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP3);
2578 hmmc->CID[3U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP4);
2581 /* Send CMD3 SET_REL_ADDR with argument 0 */
2582 /* MMC Card publishes its RCA. */
2583 errorstate = SDMMC_CmdSetRelAdd(hmmc->Instance, &mmc_rca);
2584 if(errorstate != HAL_MMC_ERROR_NONE)
2586 return errorstate;
2589 /* Get the MMC card RCA */
2590 hmmc->MmcCard.RelCardAdd = mmc_rca;
2592 /* Send CMD9 SEND_CSD with argument as card's RCA */
2593 errorstate = SDMMC_CmdSendCSD(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
2594 if(errorstate != HAL_MMC_ERROR_NONE)
2596 return errorstate;
2598 else
2600 /* Get Card Specific Data */
2601 hmmc->CSD[0U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
2602 hmmc->CSD[1U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2);
2603 hmmc->CSD[2U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP3);
2604 hmmc->CSD[3U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP4);
2607 /* Get the Card Class */
2608 hmmc->MmcCard.Class = (SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2) >> 20U);
2610 /* Select the Card */
2611 errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2612 if(errorstate != HAL_MMC_ERROR_NONE)
2614 return errorstate;
2617 /* Get CSD parameters */
2618 if (HAL_MMC_GetCardCSD(hmmc, &CSD) != HAL_OK)
2620 return hmmc->ErrorCode;
2623 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2624 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2625 if(errorstate != HAL_MMC_ERROR_NONE)
2627 hmmc->ErrorCode |= errorstate;
2630 /* Configure the SDMMC peripheral */
2631 Init.ClockEdge = hmmc->Init.ClockEdge;
2632 Init.ClockPowerSave = hmmc->Init.ClockPowerSave;
2633 Init.BusWide = SDMMC_BUS_WIDE_1B;
2634 Init.HardwareFlowControl = hmmc->Init.HardwareFlowControl;
2635 Init.ClockDiv = hmmc->Init.ClockDiv;
2636 (void)SDMMC_Init(hmmc->Instance, Init);
2638 /* All cards are initialized */
2639 return HAL_MMC_ERROR_NONE;
2643 * @brief Enquires cards about their operating voltage and configures clock
2644 * controls and stores MMC information that will be needed in future
2645 * in the MMC handle.
2646 * @param hmmc: Pointer to MMC handle
2647 * @retval error state
2649 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc)
2651 __IO uint32_t count = 0U;
2652 uint32_t response = 0U, validvoltage = 0U;
2653 uint32_t errorstate;
2655 /* CMD0: GO_IDLE_STATE */
2656 errorstate = SDMMC_CmdGoIdleState(hmmc->Instance);
2657 if(errorstate != HAL_MMC_ERROR_NONE)
2659 return errorstate;
2662 while(validvoltage == 0U)
2664 if(count++ == SDMMC_MAX_VOLT_TRIAL)
2666 return HAL_MMC_ERROR_INVALID_VOLTRANGE;
2669 /* SEND CMD1 APP_CMD with MMC_HIGH_VOLTAGE_RANGE(0xC0FF8000) as argument */
2670 errorstate = SDMMC_CmdOpCondition(hmmc->Instance, eMMC_HIGH_VOLTAGE_RANGE);
2671 if(errorstate != HAL_MMC_ERROR_NONE)
2673 return HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2676 /* Get command response */
2677 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
2679 /* Get operating voltage*/
2680 validvoltage = (((response >> 31U) == 1U) ? 1U : 0U);
2683 /* When power routine is finished and command returns valid voltage */
2684 if (((response & (0xFF000000U)) >> 24) == 0xC0U)
2686 hmmc->MmcCard.CardType = MMC_HIGH_CAPACITY_CARD;
2688 else
2690 hmmc->MmcCard.CardType = MMC_LOW_CAPACITY_CARD;
2693 return HAL_MMC_ERROR_NONE;
2697 * @brief Turns the SDMMC output signals off.
2698 * @param hmmc: Pointer to MMC handle
2699 * @retval None
2701 static void MMC_PowerOFF(MMC_HandleTypeDef *hmmc)
2703 /* Set Power State to OFF */
2704 (void)SDMMC_PowerState_OFF(hmmc->Instance);
2708 * @brief Returns the current card's status.
2709 * @param hmmc: Pointer to MMC handle
2710 * @param pCardStatus: pointer to the buffer that will contain the MMC card
2711 * status (Card Status register)
2712 * @retval error state
2714 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus)
2716 uint32_t errorstate;
2718 if(pCardStatus == NULL)
2720 return HAL_MMC_ERROR_PARAM;
2723 /* Send Status command */
2724 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
2725 if(errorstate != HAL_MMC_ERROR_NONE)
2727 return errorstate;
2730 /* Get MMC card status */
2731 *pCardStatus = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
2733 return HAL_MMC_ERROR_NONE;
2737 * @brief Reads extended CSD register to get the sectors number of the device
2738 * @param hmmc: Pointer to MMC handle
2739 * @param pFieldData: Pointer to the read buffer
2740 * @param FieldIndex: Index of the field to be read
2741 * @param Timeout: Specify timeout value
2742 * @retval HAL status
2744 HAL_StatusTypeDef MMC_ReadExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pFieldData, uint16_t FieldIndex, uint32_t Timeout)
2746 SDMMC_DataInitTypeDef config;
2747 uint32_t errorstate;
2748 uint32_t tickstart = HAL_GetTick();
2749 uint32_t count;
2750 uint32_t i = 0;
2751 uint32_t tmp_data;
2753 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
2755 /* Initialize data control register */
2756 hmmc->Instance->DCTRL = 0;
2758 /* Configure the MMC DPSM (Data Path State Machine) */
2759 config.DataTimeOut = SDMMC_DATATIMEOUT;
2760 config.DataLength = 0;
2761 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_1B;
2762 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
2763 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
2764 config.DPSM = SDMMC_DPSM_DISABLE;
2765 (void)SDMMC_ConfigData(hmmc->Instance, &config);
2767 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) == 0U)
2769 /* Set Block Size for Card */
2770 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, MMC_BLOCKSIZE);
2771 if(errorstate != HAL_MMC_ERROR_NONE)
2773 /* Clear all the static flags */
2774 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2775 hmmc->ErrorCode |= errorstate;
2776 hmmc->State = HAL_MMC_STATE_READY;
2777 return HAL_ERROR;
2781 /* Configure the MMC DPSM (Data Path State Machine) */
2782 config.DataTimeOut = SDMMC_DATATIMEOUT;
2783 config.DataLength = 512;
2784 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
2785 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
2786 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
2787 config.DPSM = SDMMC_DPSM_ENABLE;
2788 (void)SDMMC_ConfigData(hmmc->Instance, &config);
2790 /* Set Block Size for Card */
2791 errorstate = SDMMC_CmdSendEXTCSD(hmmc->Instance, 0);
2792 if(errorstate != HAL_MMC_ERROR_NONE)
2794 /* Clear all the static flags */
2795 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2796 hmmc->ErrorCode |= errorstate;
2797 hmmc->State = HAL_MMC_STATE_READY;
2798 return HAL_ERROR;
2801 /* Poll on SDMMC flags */
2802 while(!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
2804 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF))
2806 /* Read data from SDMMC Rx FIFO */
2807 for(count = 0U; count < 8U; count++)
2809 tmp_data = SDMMC_ReadFIFO(hmmc->Instance);
2810 /* eg : SEC_COUNT : FieldIndex = 212 => i+count = 53 */
2811 /* DEVICE_TYPE : FieldIndex = 196 => i+count = 49 */
2812 if ((i + count) == ((uint32_t)FieldIndex/4U))
2814 *pFieldData = tmp_data;
2817 i += 8U;
2820 if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U))
2822 /* Clear all the static flags */
2823 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2824 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
2825 hmmc->State= HAL_MMC_STATE_READY;
2826 return HAL_TIMEOUT;
2830 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2831 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16));
2832 if(errorstate != HAL_MMC_ERROR_NONE)
2834 hmmc->ErrorCode |= errorstate;
2837 /* Clear all the static flags */
2838 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS);
2840 hmmc->State = HAL_MMC_STATE_READY;
2842 return HAL_OK;
2846 * @brief Wrap up reading in non-blocking mode.
2847 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2848 * the configuration information.
2849 * @retval None
2851 static void MMC_Read_IT(MMC_HandleTypeDef *hmmc)
2853 uint32_t count, data;
2854 uint8_t* tmp;
2856 tmp = hmmc->pRxBuffPtr;
2858 if (hmmc->RxXferSize >= 32U)
2860 /* Read data from SDMMC Rx FIFO */
2861 for(count = 0U; count < 8U; count++)
2863 data = SDMMC_ReadFIFO(hmmc->Instance);
2864 *tmp = (uint8_t)(data & 0xFFU);
2865 tmp++;
2866 *tmp = (uint8_t)((data >> 8U) & 0xFFU);
2867 tmp++;
2868 *tmp = (uint8_t)((data >> 16U) & 0xFFU);
2869 tmp++;
2870 *tmp = (uint8_t)((data >> 24U) & 0xFFU);
2871 tmp++;
2874 hmmc->pRxBuffPtr = tmp;
2875 hmmc->RxXferSize -= 32U;
2880 * @brief Wrap up writing in non-blocking mode.
2881 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2882 * the configuration information.
2883 * @retval None
2885 static void MMC_Write_IT(MMC_HandleTypeDef *hmmc)
2887 uint32_t count, data;
2888 uint8_t* tmp;
2890 tmp = hmmc->pTxBuffPtr;
2892 if (hmmc->TxXferSize >= 32U)
2894 /* Write data to SDMMC Tx FIFO */
2895 for(count = 0U; count < 8U; count++)
2897 data = (uint32_t)(*tmp);
2898 tmp++;
2899 data |= ((uint32_t)(*tmp) << 8U);
2900 tmp++;
2901 data |= ((uint32_t)(*tmp) << 16U);
2902 tmp++;
2903 data |= ((uint32_t)(*tmp) << 24U);
2904 tmp++;
2905 (void)SDMMC_WriteFIFO(hmmc->Instance, &data);
2908 hmmc->pTxBuffPtr = tmp;
2909 hmmc->TxXferSize -= 32U;
2914 * @brief Switches the MMC card to high speed mode.
2915 * @param hmmc: MMC handle
2916 * @param state: State of high speed mode
2917 * @retval MMC Card error state
2919 static uint32_t MMC_HighSpeed(MMC_HandleTypeDef *hmmc, FunctionalState state)
2921 uint32_t errorstate = HAL_MMC_ERROR_NONE;
2922 uint32_t response, count;
2923 SDMMC_InitTypeDef Init;
2925 if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) != 0U) && (state == DISABLE))
2927 /* Index : 185 - Value : 0 */
2928 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B90000U);
2931 if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) == 0U) && (state != DISABLE))
2933 /* Index : 185 - Value : 1 */
2934 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B90100U);
2937 if(errorstate == HAL_MMC_ERROR_NONE)
2939 /* Check for switch error */
2940 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2941 if(errorstate == HAL_MMC_ERROR_NONE)
2943 /* Get command response */
2944 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
2945 if ((response & 0x80U) != 0U)
2947 errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
2949 else
2951 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2952 count = SDMMC_MAX_TRIAL;
2953 while(((response & 0x100U) == 0U) && (count != 0U))
2955 count--;
2957 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2958 if(errorstate != HAL_MMC_ERROR_NONE)
2960 break;
2963 /* Get command response */
2964 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
2967 /* Configure high speed */
2968 if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
2970 Init.ClockEdge = hmmc->Init.ClockEdge;
2971 Init.ClockPowerSave = hmmc->Init.ClockPowerSave;
2972 Init.BusWide = (hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS);
2973 Init.HardwareFlowControl = hmmc->Init.HardwareFlowControl;
2975 if (state == DISABLE)
2977 Init.ClockDiv = hmmc->Init.ClockDiv;
2978 (void)SDMMC_Init(hmmc->Instance, Init);
2980 CLEAR_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_BUSSPEED);
2982 else
2984 Init.ClockDiv = SDMMC_HSpeed_CLK_DIV;
2985 (void)SDMMC_Init(hmmc->Instance, Init);
2987 SET_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_BUSSPEED);
2994 return errorstate;
2998 * @brief Switches the MMC card to Double Data Rate (DDR) mode.
2999 * @param hmmc: MMC handle
3000 * @param state: State of DDR mode
3001 * @retval MMC Card error state
3003 static uint32_t MMC_DDR_Mode(MMC_HandleTypeDef *hmmc, FunctionalState state)
3005 uint32_t errorstate = HAL_MMC_ERROR_NONE;
3006 uint32_t response, count;
3008 if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) != 0U) && (state == DISABLE))
3010 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS_0) != 0U)
3012 /* Index : 183 - Value : 1 */
3013 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U);
3015 else
3017 /* Index : 183 - Value : 2 */
3018 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U);
3022 if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) == 0U) && (state != DISABLE))
3024 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS_0) != 0U)
3026 /* Index : 183 - Value : 5 */
3027 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70500U);
3029 else
3031 /* Index : 183 - Value : 6 */
3032 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70600U);
3036 if(errorstate == HAL_MMC_ERROR_NONE)
3038 /* Check for switch error */
3039 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3040 if(errorstate == HAL_MMC_ERROR_NONE)
3042 /* Get command response */
3043 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3044 if ((response & 0x80U) != 0U)
3046 errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE;
3048 else
3050 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3051 count = SDMMC_MAX_TRIAL;
3052 while(((response & 0x100U) == 0U) && (count != 0U))
3054 count--;
3056 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
3057 if(errorstate != HAL_MMC_ERROR_NONE)
3059 break;
3062 /* Get command response */
3063 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
3066 /* Configure DDR mode */
3067 if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE))
3069 if (state == DISABLE)
3071 CLEAR_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_DDR);
3073 else
3075 SET_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_DDR);
3082 return errorstate;
3086 * @brief Read DMA Buffer 0 Transfer completed callbacks
3087 * @param hmmc: MMC handle
3088 * @retval None
3090 __weak void HAL_MMCEx_Read_DMADoubleBuf0CpltCallback(MMC_HandleTypeDef *hmmc)
3092 /* Prevent unused argument(s) compilation warning */
3093 UNUSED(hmmc);
3095 /* NOTE : This function should not be modified, when the callback is needed,
3096 the HAL_MMCEx_Read_DMADoubleBuf0CpltCallback can be implemented in the user file
3101 * @brief Read DMA Buffer 1 Transfer completed callbacks
3102 * @param hmmc: MMC handle
3103 * @retval None
3105 __weak void HAL_MMCEx_Read_DMADoubleBuf1CpltCallback(MMC_HandleTypeDef *hmmc)
3107 /* Prevent unused argument(s) compilation warning */
3108 UNUSED(hmmc);
3110 /* NOTE : This function should not be modified, when the callback is needed,
3111 the HAL_MMCEx_Read_DMADoubleBuf1CpltCallback can be implemented in the user file
3116 * @brief Write DMA Buffer 0 Transfer completed callbacks
3117 * @param hmmc: MMC handle
3118 * @retval None
3120 __weak void HAL_MMCEx_Write_DMADoubleBuf0CpltCallback(MMC_HandleTypeDef *hmmc)
3122 /* Prevent unused argument(s) compilation warning */
3123 UNUSED(hmmc);
3125 /* NOTE : This function should not be modified, when the callback is needed,
3126 the HAL_MMCEx_Write_DMADoubleBuf0CpltCallback can be implemented in the user file
3131 * @brief Write DMA Buffer 1 Transfer completed callbacks
3132 * @param hmmc: MMC handle
3133 * @retval None
3135 __weak void HAL_MMCEx_Write_DMADoubleBuf1CpltCallback(MMC_HandleTypeDef *hmmc)
3137 /* Prevent unused argument(s) compilation warning */
3138 UNUSED(hmmc);
3140 /* NOTE : This function should not be modified, when the callback is needed,
3141 the HAL_MMCEx_Write_DMADoubleBuf1CpltCallback can be implemented in the user file
3146 * @}
3149 #endif /* HAL_MMC_MODULE_ENABLED */
3152 * @}
3156 * @}
3159 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/