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
14 ==============================================================================
15 ##### How to use this driver #####
16 ==============================================================================
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
23 You can easily tailor this configuration according to hardware resources.
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 ================================================
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
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 ==============================
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
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
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 ===============================
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
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 ===========================
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,
149 *** MMC card CSD register ***
150 ============================
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 ============================
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 ==================================
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
172 (@) You can refer to the MMC HAL driver header file for more useful macros
174 *** Callback registration ***
175 =============================================
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.
230 ******************************************************************************
233 * <h2><center>© 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
251 /** @defgroup MMC MMC
252 * @brief MMC HAL module driver
256 #ifdef HAL_MMC_MODULE_ENABLED
258 /* Private typedef -----------------------------------------------------------*/
259 /* Private define ------------------------------------------------------------*/
260 /** @addtogroup MMC_Private_Defines
268 /* Private macro -------------------------------------------------------------*/
269 /* Private variables ---------------------------------------------------------*/
270 /* Private function prototypes -----------------------------------------------*/
271 /* Private functions ---------------------------------------------------------*/
272 /** @defgroup MMC_Private_Functions MMC Private Functions
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
);
289 /* Exported functions --------------------------------------------------------*/
290 /** @addtogroup MMC_Exported_Functions
294 /** @addtogroup MMC_Exported_Functions_Group1
295 * @brief Initialization and de-initialization functions
298 ==============================================================================
299 ##### Initialization and de-initialization functions #####
300 ==============================================================================
302 This section provides functions allowing to initialize/de-initialize the MMC
303 card device to be ready for use.
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
315 HAL_StatusTypeDef
HAL_MMC_Init(MMC_HandleTypeDef
*hmmc
)
317 /* Check the MMC handle allocation */
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
);
354 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
355 HAL_MMC_MspInit(hmmc
);
359 hmmc
->State
= HAL_MMC_STATE_BUSY
;
361 /* Initialize the Card parameters */
362 if(HAL_MMC_InitCard(hmmc
) == 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
;
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.
386 HAL_StatusTypeDef
HAL_MMC_InitCard(MMC_HandleTypeDef
*hmmc
)
389 MMC_InitTypeDef Init
;
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
;
398 /* Init Clock should be less or equal to 400Khz*/
399 sdmmc_clk
= HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC
);
400 Init
.ClockDiv
= sdmmc_clk
/(2U*400000U);
402 /* Initialize SDMMC peripheral interface with default configuration */
403 (void)SDMMC_Init(hmmc
->Instance
, Init
);
405 /* Set Power State to ON */
406 (void)SDMMC_PowerState_ON(hmmc
->Instance
);
408 /* wait 74 Cycles: required power up waiting time before starting
409 the MMC initialization sequence */
410 sdmmc_clk
= sdmmc_clk
/(2U*Init
.ClockDiv
);
414 HAL_Delay(1U+ (74U*1000U/(sdmmc_clk
)));
421 /* Identify card operating voltage */
422 errorstate
= MMC_PowerON(hmmc
);
423 if(errorstate
!= HAL_MMC_ERROR_NONE
)
425 hmmc
->State
= HAL_MMC_STATE_READY
;
426 hmmc
->ErrorCode
|= errorstate
;
430 /* Card initialization */
431 errorstate
= MMC_InitCard(hmmc
);
432 if(errorstate
!= HAL_MMC_ERROR_NONE
)
434 hmmc
->State
= HAL_MMC_STATE_READY
;
435 hmmc
->ErrorCode
|= errorstate
;
439 /* Set Block Size for Card */
440 errorstate
= SDMMC_CmdBlockLength(hmmc
->Instance
, MMC_BLOCKSIZE
);
441 if(errorstate
!= HAL_MMC_ERROR_NONE
)
443 /* Clear all the static flags */
444 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
445 hmmc
->ErrorCode
|= errorstate
;
446 hmmc
->State
= HAL_MMC_STATE_READY
;
454 * @brief De-Initializes the MMC card.
455 * @param hmmc: Pointer to MMC handle
458 HAL_StatusTypeDef
HAL_MMC_DeInit(MMC_HandleTypeDef
*hmmc
)
460 /* Check the MMC handle allocation */
466 /* Check the parameters */
467 assert_param(IS_SDMMC_ALL_INSTANCE(hmmc
->Instance
));
469 hmmc
->State
= HAL_MMC_STATE_BUSY
;
471 /* Set MMC power state to off */
474 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
475 if(hmmc
->MspDeInitCallback
== NULL
)
477 hmmc
->MspDeInitCallback
= HAL_MMC_MspDeInit
;
480 /* DeInit the low level hardware */
481 hmmc
->MspDeInitCallback(hmmc
);
483 /* De-Initialize the MSP layer */
484 HAL_MMC_MspDeInit(hmmc
);
487 hmmc
->ErrorCode
= HAL_MMC_ERROR_NONE
;
488 hmmc
->State
= HAL_MMC_STATE_RESET
;
495 * @brief Initializes the MMC MSP.
496 * @param hmmc: Pointer to MMC handle
499 __weak
void HAL_MMC_MspInit(MMC_HandleTypeDef
*hmmc
)
501 /* Prevent unused argument(s) compilation warning */
504 /* NOTE : This function Should not be modified, when the callback is needed,
505 the HAL_MMC_MspInit could be implemented in the user file
510 * @brief De-Initialize MMC MSP.
511 * @param hmmc: Pointer to MMC handle
514 __weak
void HAL_MMC_MspDeInit(MMC_HandleTypeDef
*hmmc
)
516 /* Prevent unused argument(s) compilation warning */
519 /* NOTE : This function Should not be modified, when the callback is needed,
520 the HAL_MMC_MspDeInit could be implemented in the user file
528 /** @addtogroup MMC_Exported_Functions_Group2
529 * @brief Data transfer functions
532 ==============================================================================
533 ##### IO operation functions #####
534 ==============================================================================
536 This subsection provides a set of functions allowing to manage the data
537 transfer from/to MMC card.
544 * @brief Reads block(s) from a specified address in a card. The Data transfer
545 * is managed by polling mode.
546 * @note This API should be followed by a check on the card state through
547 * HAL_MMC_GetCardState().
548 * @param hmmc: Pointer to MMC handle
549 * @param pData: pointer to the buffer that will contain the received data
550 * @param BlockAdd: Block Address from where data is to be read
551 * @param NumberOfBlocks: Number of MMC blocks to read
552 * @param Timeout: Specify timeout value
555 HAL_StatusTypeDef
HAL_MMC_ReadBlocks(MMC_HandleTypeDef
*hmmc
, uint8_t *pData
, uint32_t BlockAdd
, uint32_t NumberOfBlocks
, uint32_t Timeout
)
557 SDMMC_DataInitTypeDef config
;
559 uint32_t tickstart
= HAL_GetTick();
560 uint32_t count
, data
, dataremaining
;
561 uint32_t add
= BlockAdd
;
562 uint8_t *tempbuff
= pData
;
566 hmmc
->ErrorCode
|= HAL_MMC_ERROR_PARAM
;
570 if(hmmc
->State
== HAL_MMC_STATE_READY
)
572 hmmc
->ErrorCode
= HAL_MMC_ERROR_NONE
;
574 if((BlockAdd
+ NumberOfBlocks
) > (hmmc
->MmcCard
.LogBlockNbr
))
576 hmmc
->ErrorCode
|= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE
;
580 hmmc
->State
= HAL_MMC_STATE_BUSY
;
582 /* Initialize data control register */
583 hmmc
->Instance
->DCTRL
= 0U;
585 if ((hmmc
->MmcCard
.CardType
) != MMC_HIGH_CAPACITY_CARD
)
590 /* Configure the MMC DPSM (Data Path State Machine) */
591 config
.DataTimeOut
= SDMMC_DATATIMEOUT
;
592 config
.DataLength
= NumberOfBlocks
* MMC_BLOCKSIZE
;
593 config
.DataBlockSize
= SDMMC_DATABLOCK_SIZE_512B
;
594 config
.TransferDir
= SDMMC_TRANSFER_DIR_TO_SDMMC
;
595 config
.TransferMode
= SDMMC_TRANSFER_MODE_BLOCK
;
596 config
.DPSM
= SDMMC_DPSM_DISABLE
;
597 (void)SDMMC_ConfigData(hmmc
->Instance
, &config
);
598 __SDMMC_CMDTRANS_ENABLE( hmmc
->Instance
);
600 /* Read block(s) in polling mode */
601 if(NumberOfBlocks
> 1U)
603 hmmc
->Context
= MMC_CONTEXT_READ_MULTIPLE_BLOCK
;
605 /* Read Multi Block command */
606 errorstate
= SDMMC_CmdReadMultiBlock(hmmc
->Instance
, add
);
610 hmmc
->Context
= MMC_CONTEXT_READ_SINGLE_BLOCK
;
612 /* Read Single Block command */
613 errorstate
= SDMMC_CmdReadSingleBlock(hmmc
->Instance
, add
);
615 if(errorstate
!= HAL_MMC_ERROR_NONE
)
617 /* Clear all the static flags */
618 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
619 hmmc
->ErrorCode
|= errorstate
;
620 hmmc
->State
= HAL_MMC_STATE_READY
;
624 /* Poll on SDMMC flags */
625 dataremaining
= config
.DataLength
;
626 while(!__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_RXOVERR
| SDMMC_FLAG_DCRCFAIL
| SDMMC_FLAG_DTIMEOUT
| SDMMC_FLAG_DATAEND
))
628 if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_RXFIFOHF
) && (dataremaining
>= 32U))
630 /* Read data from SDMMC Rx FIFO */
631 for(count
= 0U; count
< 8U; count
++)
633 data
= SDMMC_ReadFIFO(hmmc
->Instance
);
634 *tempbuff
= (uint8_t)(data
& 0xFFU
);
636 *tempbuff
= (uint8_t)((data
>> 8U) & 0xFFU
);
638 *tempbuff
= (uint8_t)((data
>> 16U) & 0xFFU
);
640 *tempbuff
= (uint8_t)((data
>> 24U) & 0xFFU
);
643 dataremaining
-= 32U;
646 if(((HAL_GetTick()-tickstart
) >= Timeout
) || (Timeout
== 0U))
648 /* Clear all the static flags */
649 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
650 hmmc
->ErrorCode
|= HAL_MMC_ERROR_TIMEOUT
;
651 hmmc
->State
= HAL_MMC_STATE_READY
;
655 __SDMMC_CMDTRANS_DISABLE( hmmc
->Instance
);
657 /* Send stop transmission command in case of multiblock read */
658 if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_DATAEND
) && (NumberOfBlocks
> 1U))
660 /* Send stop transmission command */
661 errorstate
= SDMMC_CmdStopTransfer(hmmc
->Instance
);
662 if(errorstate
!= HAL_MMC_ERROR_NONE
)
664 /* Clear all the static flags */
665 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
666 hmmc
->ErrorCode
|= errorstate
;
667 hmmc
->State
= HAL_MMC_STATE_READY
;
672 /* Get error state */
673 if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_DTIMEOUT
))
675 /* Clear all the static flags */
676 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
677 hmmc
->ErrorCode
|= HAL_MMC_ERROR_DATA_TIMEOUT
;
678 hmmc
->State
= HAL_MMC_STATE_READY
;
681 else if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_DCRCFAIL
))
683 /* Clear all the static flags */
684 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
685 hmmc
->ErrorCode
|= HAL_MMC_ERROR_DATA_CRC_FAIL
;
686 hmmc
->State
= HAL_MMC_STATE_READY
;
689 else if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_RXOVERR
))
691 /* Clear all the static flags */
692 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
693 hmmc
->ErrorCode
|= HAL_MMC_ERROR_RX_OVERRUN
;
694 hmmc
->State
= HAL_MMC_STATE_READY
;
702 /* Clear all the static flags */
703 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_DATA_FLAGS
);
705 hmmc
->State
= HAL_MMC_STATE_READY
;
711 hmmc
->ErrorCode
|= HAL_MMC_ERROR_BUSY
;
717 * @brief Allows to write block(s) to a specified address in a card. The Data
718 * transfer is managed by polling mode.
719 * @note This API should be followed by a check on the card state through
720 * HAL_MMC_GetCardState().
721 * @param hmmc: Pointer to MMC handle
722 * @param pData: pointer to the buffer that will contain the data to transmit
723 * @param BlockAdd: Block Address where data will be written
724 * @param NumberOfBlocks: Number of MMC blocks to write
725 * @param Timeout: Specify timeout value
728 HAL_StatusTypeDef
HAL_MMC_WriteBlocks(MMC_HandleTypeDef
*hmmc
, uint8_t *pData
, uint32_t BlockAdd
, uint32_t NumberOfBlocks
, uint32_t Timeout
)
730 SDMMC_DataInitTypeDef config
;
732 uint32_t tickstart
= HAL_GetTick();
733 uint32_t count
, data
, dataremaining
;
734 uint32_t add
= BlockAdd
;
735 uint8_t *tempbuff
= pData
;
739 hmmc
->ErrorCode
|= HAL_MMC_ERROR_PARAM
;
743 if(hmmc
->State
== HAL_MMC_STATE_READY
)
745 hmmc
->ErrorCode
= HAL_MMC_ERROR_NONE
;
747 if((BlockAdd
+ NumberOfBlocks
) > (hmmc
->MmcCard
.LogBlockNbr
))
749 hmmc
->ErrorCode
|= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE
;
753 hmmc
->State
= HAL_MMC_STATE_BUSY
;
755 /* Initialize data control register */
756 hmmc
->Instance
->DCTRL
= 0U;
758 if ((hmmc
->MmcCard
.CardType
) != MMC_HIGH_CAPACITY_CARD
)
763 /* Configure the MMC DPSM (Data Path State Machine) */
764 config
.DataTimeOut
= SDMMC_DATATIMEOUT
;
765 config
.DataLength
= NumberOfBlocks
* MMC_BLOCKSIZE
;
766 config
.DataBlockSize
= SDMMC_DATABLOCK_SIZE_512B
;
767 config
.TransferDir
= SDMMC_TRANSFER_DIR_TO_CARD
;
768 config
.TransferMode
= SDMMC_TRANSFER_MODE_BLOCK
;
769 config
.DPSM
= SDMMC_DPSM_DISABLE
;
770 (void)SDMMC_ConfigData(hmmc
->Instance
, &config
);
771 __SDMMC_CMDTRANS_ENABLE( hmmc
->Instance
);
773 /* Write Blocks in Polling mode */
774 if(NumberOfBlocks
> 1U)
776 hmmc
->Context
= MMC_CONTEXT_WRITE_MULTIPLE_BLOCK
;
778 /* Write Multi Block command */
779 errorstate
= SDMMC_CmdWriteMultiBlock(hmmc
->Instance
, add
);
783 hmmc
->Context
= MMC_CONTEXT_WRITE_SINGLE_BLOCK
;
785 /* Write Single Block command */
786 errorstate
= SDMMC_CmdWriteSingleBlock(hmmc
->Instance
, add
);
788 if(errorstate
!= HAL_MMC_ERROR_NONE
)
790 /* Clear all the static flags */
791 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
792 hmmc
->ErrorCode
|= errorstate
;
793 hmmc
->State
= HAL_MMC_STATE_READY
;
797 /* Write block(s) in polling mode */
798 dataremaining
= config
.DataLength
;
799 while(!__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_TXUNDERR
| SDMMC_FLAG_DCRCFAIL
| SDMMC_FLAG_DTIMEOUT
| SDMMC_FLAG_DATAEND
))
801 if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_TXFIFOHE
) && (dataremaining
>= 32U))
803 /* Write data to SDMMC Tx FIFO */
804 for(count
= 0U; count
< 8U; count
++)
806 data
= (uint32_t)(*tempbuff
);
808 data
|= ((uint32_t)(*tempbuff
) << 8U);
810 data
|= ((uint32_t)(*tempbuff
) << 16U);
812 data
|= ((uint32_t)(*tempbuff
) << 24U);
814 (void)SDMMC_WriteFIFO(hmmc
->Instance
, &data
);
816 dataremaining
-= 32U;
819 if(((HAL_GetTick()-tickstart
) >= Timeout
) || (Timeout
== 0U))
821 /* Clear all the static flags */
822 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
823 hmmc
->ErrorCode
|= errorstate
;
824 hmmc
->State
= HAL_MMC_STATE_READY
;
828 __SDMMC_CMDTRANS_DISABLE( hmmc
->Instance
);
830 /* Send stop transmission command in case of multiblock write */
831 if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_DATAEND
) && (NumberOfBlocks
> 1U))
833 /* Send stop transmission command */
834 errorstate
= SDMMC_CmdStopTransfer(hmmc
->Instance
);
835 if(errorstate
!= HAL_MMC_ERROR_NONE
)
837 /* Clear all the static flags */
838 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
839 hmmc
->ErrorCode
|= errorstate
;
840 hmmc
->State
= HAL_MMC_STATE_READY
;
845 /* Get error state */
846 if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_DTIMEOUT
))
848 /* Clear all the static flags */
849 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
850 hmmc
->ErrorCode
|= HAL_MMC_ERROR_DATA_TIMEOUT
;
851 hmmc
->State
= HAL_MMC_STATE_READY
;
854 else if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_DCRCFAIL
))
856 /* Clear all the static flags */
857 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
858 hmmc
->ErrorCode
|= HAL_MMC_ERROR_DATA_CRC_FAIL
;
859 hmmc
->State
= HAL_MMC_STATE_READY
;
862 else if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_TXUNDERR
))
864 /* Clear all the static flags */
865 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
866 hmmc
->ErrorCode
|= HAL_MMC_ERROR_TX_UNDERRUN
;
867 hmmc
->State
= HAL_MMC_STATE_READY
;
875 /* Clear all the static flags */
876 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_DATA_FLAGS
);
878 hmmc
->State
= HAL_MMC_STATE_READY
;
884 hmmc
->ErrorCode
|= HAL_MMC_ERROR_BUSY
;
890 * @brief Reads block(s) from a specified address in a card. The Data transfer
891 * is managed in interrupt mode.
892 * @note This API should be followed by a check on the card state through
893 * HAL_MMC_GetCardState().
894 * @note You could also check the IT transfer process through the MMC Rx
896 * @param hmmc: Pointer to MMC handle
897 * @param pData: Pointer to the buffer that will contain the received data
898 * @param BlockAdd: Block Address from where data is to be read
899 * @param NumberOfBlocks: Number of blocks to read.
902 HAL_StatusTypeDef
HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef
*hmmc
, uint8_t *pData
, uint32_t BlockAdd
, uint32_t NumberOfBlocks
)
904 SDMMC_DataInitTypeDef config
;
906 uint32_t add
= BlockAdd
;
910 hmmc
->ErrorCode
|= HAL_MMC_ERROR_PARAM
;
914 if(hmmc
->State
== HAL_MMC_STATE_READY
)
916 hmmc
->ErrorCode
= HAL_MMC_ERROR_NONE
;
918 if((BlockAdd
+ NumberOfBlocks
) > (hmmc
->MmcCard
.LogBlockNbr
))
920 hmmc
->ErrorCode
|= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE
;
924 hmmc
->State
= HAL_MMC_STATE_BUSY
;
926 /* Initialize data control register */
927 hmmc
->Instance
->DCTRL
= 0U;
929 hmmc
->pRxBuffPtr
= pData
;
930 hmmc
->RxXferSize
= MMC_BLOCKSIZE
* NumberOfBlocks
;
932 if ((hmmc
->MmcCard
.CardType
) != MMC_HIGH_CAPACITY_CARD
)
937 /* Configure the MMC DPSM (Data Path State Machine) */
938 config
.DataTimeOut
= SDMMC_DATATIMEOUT
;
939 config
.DataLength
= MMC_BLOCKSIZE
* NumberOfBlocks
;
940 config
.DataBlockSize
= SDMMC_DATABLOCK_SIZE_512B
;
941 config
.TransferDir
= SDMMC_TRANSFER_DIR_TO_SDMMC
;
942 config
.TransferMode
= SDMMC_TRANSFER_MODE_BLOCK
;
943 config
.DPSM
= SDMMC_DPSM_DISABLE
;
944 (void)SDMMC_ConfigData(hmmc
->Instance
, &config
);
945 __SDMMC_CMDTRANS_ENABLE( hmmc
->Instance
);
947 /* Read Blocks in IT mode */
948 if(NumberOfBlocks
> 1U)
950 hmmc
->Context
= (MMC_CONTEXT_READ_MULTIPLE_BLOCK
| MMC_CONTEXT_IT
);
952 /* Read Multi Block command */
953 errorstate
= SDMMC_CmdReadMultiBlock(hmmc
->Instance
, add
);
957 hmmc
->Context
= (MMC_CONTEXT_READ_SINGLE_BLOCK
| MMC_CONTEXT_IT
);
959 /* Read Single Block command */
960 errorstate
= SDMMC_CmdReadSingleBlock(hmmc
->Instance
, add
);
963 if(errorstate
!= HAL_MMC_ERROR_NONE
)
965 /* Clear all the static flags */
966 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
967 hmmc
->ErrorCode
|= errorstate
;
968 hmmc
->State
= HAL_MMC_STATE_READY
;
972 __HAL_MMC_ENABLE_IT(hmmc
, (SDMMC_IT_DCRCFAIL
| SDMMC_IT_DTIMEOUT
| SDMMC_IT_RXOVERR
| SDMMC_IT_DATAEND
| SDMMC_FLAG_RXFIFOHF
));
983 * @brief Writes block(s) to a specified address in a card. The Data transfer
984 * is managed in interrupt mode.
985 * @note This API should be followed by a check on the card state through
986 * HAL_MMC_GetCardState().
987 * @note You could also check the IT transfer process through the MMC Tx
989 * @param hmmc: Pointer to MMC handle
990 * @param pData: Pointer to the buffer that will contain the data to transmit
991 * @param BlockAdd: Block Address where data will be written
992 * @param NumberOfBlocks: Number of blocks to write
995 HAL_StatusTypeDef
HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef
*hmmc
, uint8_t *pData
, uint32_t BlockAdd
, uint32_t NumberOfBlocks
)
997 SDMMC_DataInitTypeDef config
;
999 uint32_t add
= BlockAdd
;
1003 hmmc
->ErrorCode
|= HAL_MMC_ERROR_PARAM
;
1007 if(hmmc
->State
== HAL_MMC_STATE_READY
)
1009 hmmc
->ErrorCode
= HAL_MMC_ERROR_NONE
;
1011 if((BlockAdd
+ NumberOfBlocks
) > (hmmc
->MmcCard
.LogBlockNbr
))
1013 hmmc
->ErrorCode
|= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE
;
1017 hmmc
->State
= HAL_MMC_STATE_BUSY
;
1019 /* Initialize data control register */
1020 hmmc
->Instance
->DCTRL
= 0U;
1022 hmmc
->pTxBuffPtr
= pData
;
1023 hmmc
->TxXferSize
= MMC_BLOCKSIZE
* NumberOfBlocks
;
1025 if ((hmmc
->MmcCard
.CardType
) != MMC_HIGH_CAPACITY_CARD
)
1030 /* Configure the MMC DPSM (Data Path State Machine) */
1031 config
.DataTimeOut
= SDMMC_DATATIMEOUT
;
1032 config
.DataLength
= MMC_BLOCKSIZE
* NumberOfBlocks
;
1033 config
.DataBlockSize
= SDMMC_DATABLOCK_SIZE_512B
;
1034 config
.TransferDir
= SDMMC_TRANSFER_DIR_TO_CARD
;
1035 config
.TransferMode
= SDMMC_TRANSFER_MODE_BLOCK
;
1036 config
.DPSM
= SDMMC_DPSM_DISABLE
;
1037 (void)SDMMC_ConfigData(hmmc
->Instance
, &config
);
1039 __SDMMC_CMDTRANS_ENABLE( hmmc
->Instance
);
1041 /* Write Blocks in Polling mode */
1042 if(NumberOfBlocks
> 1U)
1044 hmmc
->Context
= (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK
| MMC_CONTEXT_IT
);
1046 /* Write Multi Block command */
1047 errorstate
= SDMMC_CmdWriteMultiBlock(hmmc
->Instance
, add
);
1051 hmmc
->Context
= (MMC_CONTEXT_WRITE_SINGLE_BLOCK
| MMC_CONTEXT_IT
);
1053 /* Write Single Block command */
1054 errorstate
= SDMMC_CmdWriteSingleBlock(hmmc
->Instance
, add
);
1056 if(errorstate
!= HAL_MMC_ERROR_NONE
)
1058 /* Clear all the static flags */
1059 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
1060 hmmc
->ErrorCode
|= errorstate
;
1061 hmmc
->State
= HAL_MMC_STATE_READY
;
1065 /* Enable transfer interrupts */
1066 __HAL_MMC_ENABLE_IT(hmmc
, (SDMMC_IT_DCRCFAIL
| SDMMC_IT_DTIMEOUT
| SDMMC_IT_TXUNDERR
| SDMMC_IT_DATAEND
| SDMMC_FLAG_TXFIFOHE
));
1077 * @brief Reads block(s) from a specified address in a card. The Data transfer
1078 * is managed by DMA mode.
1079 * @note This API should be followed by a check on the card state through
1080 * HAL_MMC_GetCardState().
1081 * @note You could also check the DMA transfer process through the MMC Rx
1083 * @param hmmc: Pointer MMC handle
1084 * @param pData: Pointer to the buffer that will contain the received data
1085 * @param BlockAdd: Block Address from where data is to be read
1086 * @param NumberOfBlocks: Number of blocks to read.
1087 * @retval HAL status
1089 HAL_StatusTypeDef
HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef
*hmmc
, uint8_t *pData
, uint32_t BlockAdd
, uint32_t NumberOfBlocks
)
1091 SDMMC_DataInitTypeDef config
;
1092 uint32_t errorstate
;
1093 uint32_t add
= BlockAdd
;
1097 hmmc
->ErrorCode
|= HAL_MMC_ERROR_PARAM
;
1101 if(hmmc
->State
== HAL_MMC_STATE_READY
)
1103 hmmc
->ErrorCode
= HAL_DMA_ERROR_NONE
;
1105 if((BlockAdd
+ NumberOfBlocks
) > (hmmc
->MmcCard
.LogBlockNbr
))
1107 hmmc
->ErrorCode
|= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE
;
1111 hmmc
->State
= HAL_MMC_STATE_BUSY
;
1113 /* Initialize data control register */
1114 hmmc
->Instance
->DCTRL
= 0U;
1116 hmmc
->pRxBuffPtr
= pData
;
1117 hmmc
->RxXferSize
= MMC_BLOCKSIZE
* NumberOfBlocks
;
1119 if ((hmmc
->MmcCard
.CardType
) != MMC_HIGH_CAPACITY_CARD
)
1124 /* Configure the MMC DPSM (Data Path State Machine) */
1125 config
.DataTimeOut
= SDMMC_DATATIMEOUT
;
1126 config
.DataLength
= MMC_BLOCKSIZE
* NumberOfBlocks
;
1127 config
.DataBlockSize
= SDMMC_DATABLOCK_SIZE_512B
;
1128 config
.TransferDir
= SDMMC_TRANSFER_DIR_TO_SDMMC
;
1129 config
.TransferMode
= SDMMC_TRANSFER_MODE_BLOCK
;
1130 config
.DPSM
= SDMMC_DPSM_DISABLE
;
1131 (void)SDMMC_ConfigData(hmmc
->Instance
, &config
);
1133 __SDMMC_CMDTRANS_ENABLE( hmmc
->Instance
);
1134 hmmc
->Instance
->IDMABASE0
= (uint32_t) pData
;
1135 hmmc
->Instance
->IDMACTRL
= SDMMC_ENABLE_IDMA_SINGLE_BUFF
;
1137 /* Read Blocks in DMA mode */
1138 if(NumberOfBlocks
> 1U)
1140 hmmc
->Context
= (MMC_CONTEXT_READ_MULTIPLE_BLOCK
| MMC_CONTEXT_DMA
);
1142 /* Read Multi Block command */
1143 errorstate
= SDMMC_CmdReadMultiBlock(hmmc
->Instance
, add
);
1147 hmmc
->Context
= (MMC_CONTEXT_READ_SINGLE_BLOCK
| MMC_CONTEXT_DMA
);
1149 /* Read Single Block command */
1150 errorstate
= SDMMC_CmdReadSingleBlock(hmmc
->Instance
, add
);
1152 if(errorstate
!= HAL_MMC_ERROR_NONE
)
1154 /* Clear all the static flags */
1155 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
1156 hmmc
->ErrorCode
= errorstate
;
1157 hmmc
->State
= HAL_MMC_STATE_READY
;
1161 /* Enable transfer interrupts */
1162 __HAL_MMC_ENABLE_IT(hmmc
, (SDMMC_IT_DCRCFAIL
| SDMMC_IT_DTIMEOUT
| SDMMC_IT_RXOVERR
| SDMMC_IT_DATAEND
));
1173 * @brief Writes block(s) to a specified address in a card. The Data transfer
1174 * is managed by DMA mode.
1175 * @note This API should be followed by a check on the card state through
1176 * HAL_MMC_GetCardState().
1177 * @note You could also check the DMA transfer process through the MMC Tx
1179 * @param hmmc: Pointer to MMC handle
1180 * @param pData: Pointer to the buffer that will contain the data to transmit
1181 * @param BlockAdd: Block Address where data will be written
1182 * @param NumberOfBlocks: Number of blocks to write
1183 * @retval HAL status
1185 HAL_StatusTypeDef
HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef
*hmmc
, uint8_t *pData
, uint32_t BlockAdd
, uint32_t NumberOfBlocks
)
1187 SDMMC_DataInitTypeDef config
;
1188 uint32_t errorstate
;
1189 uint32_t add
= BlockAdd
;
1193 hmmc
->ErrorCode
|= HAL_MMC_ERROR_PARAM
;
1197 if(hmmc
->State
== HAL_MMC_STATE_READY
)
1199 hmmc
->ErrorCode
= HAL_MMC_ERROR_NONE
;
1201 if((BlockAdd
+ NumberOfBlocks
) > (hmmc
->MmcCard
.LogBlockNbr
))
1203 hmmc
->ErrorCode
|= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE
;
1207 hmmc
->State
= HAL_MMC_STATE_BUSY
;
1209 /* Initialize data control register */
1210 hmmc
->Instance
->DCTRL
= 0U;
1212 hmmc
->pTxBuffPtr
= pData
;
1213 hmmc
->TxXferSize
= MMC_BLOCKSIZE
* NumberOfBlocks
;
1215 if ((hmmc
->MmcCard
.CardType
) != MMC_HIGH_CAPACITY_CARD
)
1220 /* Configure the MMC DPSM (Data Path State Machine) */
1221 config
.DataTimeOut
= SDMMC_DATATIMEOUT
;
1222 config
.DataLength
= MMC_BLOCKSIZE
* NumberOfBlocks
;
1223 config
.DataBlockSize
= SDMMC_DATABLOCK_SIZE_512B
;
1224 config
.TransferDir
= SDMMC_TRANSFER_DIR_TO_CARD
;
1225 config
.TransferMode
= SDMMC_TRANSFER_MODE_BLOCK
;
1226 config
.DPSM
= SDMMC_DPSM_DISABLE
;
1227 (void)SDMMC_ConfigData(hmmc
->Instance
, &config
);
1229 __SDMMC_CMDTRANS_ENABLE( hmmc
->Instance
);
1231 hmmc
->Instance
->IDMABASE0
= (uint32_t) pData
;
1232 hmmc
->Instance
->IDMACTRL
= SDMMC_ENABLE_IDMA_SINGLE_BUFF
;
1234 /* Write Blocks in Polling mode */
1235 if(NumberOfBlocks
> 1U)
1237 hmmc
->Context
= (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK
| MMC_CONTEXT_DMA
);
1239 /* Write Multi Block command */
1240 errorstate
= SDMMC_CmdWriteMultiBlock(hmmc
->Instance
, add
);
1244 hmmc
->Context
= (MMC_CONTEXT_WRITE_SINGLE_BLOCK
| MMC_CONTEXT_DMA
);
1246 /* Write Single Block command */
1247 errorstate
= SDMMC_CmdWriteSingleBlock(hmmc
->Instance
, add
);
1249 if(errorstate
!= HAL_MMC_ERROR_NONE
)
1251 /* Clear all the static flags */
1252 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
1253 hmmc
->ErrorCode
|= errorstate
;
1254 hmmc
->State
= HAL_MMC_STATE_READY
;
1258 /* Enable transfer interrupts */
1259 __HAL_MMC_ENABLE_IT(hmmc
, (SDMMC_IT_DCRCFAIL
| SDMMC_IT_DTIMEOUT
| SDMMC_IT_TXUNDERR
| SDMMC_IT_DATAEND
));
1270 * @brief Erases the specified memory area of the given MMC card.
1271 * @note This API should be followed by a check on the card state through
1272 * HAL_MMC_GetCardState().
1273 * @param hmmc: Pointer to MMC handle
1274 * @param BlockStartAdd: Start Block address
1275 * @param BlockEndAdd: End Block address
1276 * @retval HAL status
1278 HAL_StatusTypeDef
HAL_MMC_Erase(MMC_HandleTypeDef
*hmmc
, uint32_t BlockStartAdd
, uint32_t BlockEndAdd
)
1280 uint32_t errorstate
;
1281 uint32_t start_add
= BlockStartAdd
;
1282 uint32_t end_add
= BlockEndAdd
;
1284 if(hmmc
->State
== HAL_MMC_STATE_READY
)
1286 hmmc
->ErrorCode
= HAL_MMC_ERROR_NONE
;
1288 if(end_add
< start_add
)
1290 hmmc
->ErrorCode
|= HAL_MMC_ERROR_PARAM
;
1294 if(end_add
> (hmmc
->MmcCard
.LogBlockNbr
))
1296 hmmc
->ErrorCode
|= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE
;
1300 hmmc
->State
= HAL_MMC_STATE_BUSY
;
1302 /* Check if the card command class supports erase command */
1303 if(((hmmc
->MmcCard
.Class
) & SDMMC_CCCC_ERASE
) == 0U)
1305 /* Clear all the static flags */
1306 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
1307 hmmc
->ErrorCode
|= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE
;
1308 hmmc
->State
= HAL_MMC_STATE_READY
;
1312 if((SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP1
) & SDMMC_CARD_LOCKED
) == SDMMC_CARD_LOCKED
)
1314 /* Clear all the static flags */
1315 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
1316 hmmc
->ErrorCode
|= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED
;
1317 hmmc
->State
= HAL_MMC_STATE_READY
;
1321 if ((hmmc
->MmcCard
.CardType
) != MMC_HIGH_CAPACITY_CARD
)
1327 /* Send CMD35 MMC_ERASE_GRP_START with argument as addr */
1328 errorstate
= SDMMC_CmdEraseStartAdd(hmmc
->Instance
, start_add
);
1329 if(errorstate
!= HAL_MMC_ERROR_NONE
)
1331 /* Clear all the static flags */
1332 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
1333 hmmc
->ErrorCode
|= errorstate
;
1334 hmmc
->State
= HAL_MMC_STATE_READY
;
1338 /* Send CMD36 MMC_ERASE_GRP_END with argument as addr */
1339 errorstate
= SDMMC_CmdEraseEndAdd(hmmc
->Instance
, end_add
);
1340 if(errorstate
!= HAL_MMC_ERROR_NONE
)
1342 /* Clear all the static flags */
1343 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
1344 hmmc
->ErrorCode
|= errorstate
;
1345 hmmc
->State
= HAL_MMC_STATE_READY
;
1349 /* Send CMD38 ERASE */
1350 errorstate
= SDMMC_CmdErase(hmmc
->Instance
, 0UL);
1351 if(errorstate
!= HAL_MMC_ERROR_NONE
)
1353 /* Clear all the static flags */
1354 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
1355 hmmc
->ErrorCode
|= errorstate
;
1356 hmmc
->State
= HAL_MMC_STATE_READY
;
1360 hmmc
->State
= HAL_MMC_STATE_READY
;
1371 * @brief This function handles MMC card interrupt request.
1372 * @param hmmc: Pointer to MMC handle
1375 void HAL_MMC_IRQHandler(MMC_HandleTypeDef
*hmmc
)
1377 uint32_t errorstate
;
1378 uint32_t context
= hmmc
->Context
;
1380 /* Check for SDMMC interrupt flags */
1381 if((__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_RXFIFOHF
) != RESET
) && ((context
& MMC_CONTEXT_IT
) != 0U))
1386 else if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_DATAEND
) != RESET
)
1388 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_FLAG_DATAEND
);
1390 __HAL_MMC_DISABLE_IT(hmmc
, SDMMC_IT_DATAEND
| SDMMC_IT_DCRCFAIL
| SDMMC_IT_DTIMEOUT
|\
1391 SDMMC_IT_TXUNDERR
| SDMMC_IT_RXOVERR
| SDMMC_IT_TXFIFOHE
|\
1394 __HAL_MMC_DISABLE_IT(hmmc
, SDMMC_IT_IDMABTC
);
1395 __SDMMC_CMDTRANS_DISABLE( hmmc
->Instance
);
1397 if((context
& MMC_CONTEXT_DMA
) != 0U)
1399 hmmc
->Instance
->DLEN
= 0;
1400 hmmc
->Instance
->DCTRL
= 0;
1401 hmmc
->Instance
->IDMACTRL
= SDMMC_DISABLE_IDMA
;
1403 /* Stop Transfer for Write Multi blocks or Read Multi blocks */
1404 if(((context
& MMC_CONTEXT_READ_MULTIPLE_BLOCK
) != 0U) || ((context
& MMC_CONTEXT_WRITE_MULTIPLE_BLOCK
) != 0U))
1406 errorstate
= SDMMC_CmdStopTransfer(hmmc
->Instance
);
1407 if(errorstate
!= HAL_MMC_ERROR_NONE
)
1409 hmmc
->ErrorCode
|= errorstate
;
1410 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1411 hmmc
->ErrorCallback(hmmc
);
1413 HAL_MMC_ErrorCallback(hmmc
);
1418 /* Clear all the static flags */
1419 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_DATA_FLAGS
);
1421 hmmc
->State
= HAL_MMC_STATE_READY
;
1422 if(((context
& MMC_CONTEXT_WRITE_SINGLE_BLOCK
) != 0U) || ((context
& MMC_CONTEXT_WRITE_MULTIPLE_BLOCK
) != 0U))
1424 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1425 hmmc
->TxCpltCallback(hmmc
);
1427 HAL_MMC_TxCpltCallback(hmmc
);
1430 if(((context
& MMC_CONTEXT_READ_SINGLE_BLOCK
) != 0U) || ((context
& MMC_CONTEXT_READ_MULTIPLE_BLOCK
) != 0U))
1432 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1433 hmmc
->RxCpltCallback(hmmc
);
1435 HAL_MMC_RxCpltCallback(hmmc
);
1439 else if((context
& MMC_CONTEXT_IT
) != 0U)
1441 /* Stop Transfer for Write Multi blocks or Read Multi blocks */
1442 if(((context
& MMC_CONTEXT_READ_MULTIPLE_BLOCK
) != 0U) || ((context
& MMC_CONTEXT_WRITE_MULTIPLE_BLOCK
) != 0U))
1444 errorstate
= SDMMC_CmdStopTransfer(hmmc
->Instance
);
1445 if(errorstate
!= HAL_MMC_ERROR_NONE
)
1447 hmmc
->ErrorCode
|= errorstate
;
1448 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1449 hmmc
->ErrorCallback(hmmc
);
1451 HAL_MMC_ErrorCallback(hmmc
);
1456 /* Clear all the static flags */
1457 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_DATA_FLAGS
);
1459 hmmc
->State
= HAL_MMC_STATE_READY
;
1460 if(((context
& MMC_CONTEXT_READ_SINGLE_BLOCK
) != 0U) || ((context
& MMC_CONTEXT_READ_MULTIPLE_BLOCK
) != 0U))
1462 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1463 hmmc
->RxCpltCallback(hmmc
);
1465 HAL_MMC_RxCpltCallback(hmmc
);
1470 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1471 hmmc
->TxCpltCallback(hmmc
);
1473 HAL_MMC_TxCpltCallback(hmmc
);
1483 else if((__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_TXFIFOHE
) != RESET
) && ((context
& MMC_CONTEXT_IT
) != 0U))
1488 else if (__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_DCRCFAIL
| SDMMC_FLAG_DTIMEOUT
| SDMMC_FLAG_RXOVERR
| SDMMC_FLAG_TXUNDERR
) != RESET
)
1490 /* Set Error code */
1491 if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_IT_DCRCFAIL
) != RESET
)
1493 hmmc
->ErrorCode
|= HAL_MMC_ERROR_DATA_CRC_FAIL
;
1495 if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_IT_DTIMEOUT
) != RESET
)
1497 hmmc
->ErrorCode
|= HAL_MMC_ERROR_DATA_TIMEOUT
;
1499 if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_IT_RXOVERR
) != RESET
)
1501 hmmc
->ErrorCode
|= HAL_MMC_ERROR_RX_OVERRUN
;
1503 if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_IT_TXUNDERR
) != RESET
)
1505 hmmc
->ErrorCode
|= HAL_MMC_ERROR_TX_UNDERRUN
;
1508 /* Clear All flags */
1509 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_DATA_FLAGS
);
1511 /* Disable all interrupts */
1512 __HAL_MMC_DISABLE_IT(hmmc
, SDMMC_IT_DATAEND
| SDMMC_IT_DCRCFAIL
| SDMMC_IT_DTIMEOUT
|\
1513 SDMMC_IT_TXUNDERR
| SDMMC_IT_RXOVERR
);
1515 __SDMMC_CMDTRANS_DISABLE( hmmc
->Instance
);
1516 hmmc
->Instance
->DCTRL
|= SDMMC_DCTRL_FIFORST
;
1517 hmmc
->Instance
->CMD
|= SDMMC_CMD_CMDSTOP
;
1518 hmmc
->ErrorCode
|= SDMMC_CmdStopTransfer(hmmc
->Instance
);
1519 hmmc
->Instance
->CMD
&= ~(SDMMC_CMD_CMDSTOP
);
1520 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_FLAG_DABORT
);
1522 if((context
& MMC_CONTEXT_IT
) != 0U)
1524 /* Set the MMC state to ready to be able to start again the process */
1525 hmmc
->State
= HAL_MMC_STATE_READY
;
1526 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1527 hmmc
->ErrorCallback(hmmc
);
1529 HAL_MMC_ErrorCallback(hmmc
);
1530 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1532 else if((context
& MMC_CONTEXT_DMA
) != 0U)
1534 if(hmmc
->ErrorCode
!= HAL_MMC_ERROR_NONE
)
1536 /* Disable Internal DMA */
1537 __HAL_MMC_DISABLE_IT(hmmc
, SDMMC_IT_IDMABTC
);
1538 hmmc
->Instance
->IDMACTRL
= SDMMC_DISABLE_IDMA
;
1540 /* Set the MMC state to ready to be able to start again the process */
1541 hmmc
->State
= HAL_MMC_STATE_READY
;
1542 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1543 hmmc
->ErrorCallback(hmmc
);
1545 HAL_MMC_ErrorCallback(hmmc
);
1546 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1555 else if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_IDMABTC
) != RESET
)
1557 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_IT_IDMABTC
);
1558 if(READ_BIT(hmmc
->Instance
->IDMACTRL
, SDMMC_IDMA_IDMABACT
) == 0U)
1560 /* Current buffer is buffer0, Transfer complete for buffer1 */
1561 if((context
& MMC_CONTEXT_WRITE_MULTIPLE_BLOCK
) != 0U)
1563 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1564 hmmc
->Write_DMADblBuf1CpltCallback(hmmc
);
1566 HAL_MMCEx_Write_DMADoubleBuf1CpltCallback(hmmc
);
1569 else /* MMC_CONTEXT_READ_MULTIPLE_BLOCK */
1571 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1572 hmmc
->Read_DMADblBuf1CpltCallback(hmmc
);
1574 HAL_MMCEx_Read_DMADoubleBuf1CpltCallback(hmmc
);
1578 else /* MMC_DMA_BUFFER1 */
1580 /* Current buffer is buffer1, Transfer complete for buffer0 */
1581 if((context
& MMC_CONTEXT_WRITE_MULTIPLE_BLOCK
) != 0U)
1583 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1584 hmmc
->Write_DMADblBuf0CpltCallback(hmmc
);
1586 HAL_MMCEx_Write_DMADoubleBuf0CpltCallback(hmmc
);
1589 else /* MMC_CONTEXT_READ_MULTIPLE_BLOCK */
1591 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1592 hmmc
->Read_DMADblBuf0CpltCallback(hmmc
);
1594 HAL_MMCEx_Read_DMADoubleBuf0CpltCallback(hmmc
);
1607 * @brief return the MMC state
1608 * @param hmmc: Pointer to mmc handle
1611 HAL_MMC_StateTypeDef
HAL_MMC_GetState(MMC_HandleTypeDef
*hmmc
)
1617 * @brief Return the MMC error code
1618 * @param hmmc : Pointer to a MMC_HandleTypeDef structure that contains
1619 * the configuration information.
1620 * @retval MMC Error Code
1622 uint32_t HAL_MMC_GetError(MMC_HandleTypeDef
*hmmc
)
1624 return hmmc
->ErrorCode
;
1628 * @brief Tx Transfer completed callbacks
1629 * @param hmmc: Pointer to MMC handle
1632 __weak
void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef
*hmmc
)
1634 /* Prevent unused argument(s) compilation warning */
1637 /* NOTE : This function should not be modified, when the callback is needed,
1638 the HAL_MMC_TxCpltCallback can be implemented in the user file
1643 * @brief Rx Transfer completed callbacks
1644 * @param hmmc: Pointer MMC handle
1647 __weak
void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef
*hmmc
)
1649 /* Prevent unused argument(s) compilation warning */
1652 /* NOTE : This function should not be modified, when the callback is needed,
1653 the HAL_MMC_RxCpltCallback can be implemented in the user file
1658 * @brief MMC error callbacks
1659 * @param hmmc: Pointer MMC handle
1662 __weak
void HAL_MMC_ErrorCallback(MMC_HandleTypeDef
*hmmc
)
1664 /* Prevent unused argument(s) compilation warning */
1667 /* NOTE : This function should not be modified, when the callback is needed,
1668 the HAL_MMC_ErrorCallback can be implemented in the user file
1673 * @brief MMC Abort callbacks
1674 * @param hmmc: Pointer MMC handle
1677 __weak
void HAL_MMC_AbortCallback(MMC_HandleTypeDef
*hmmc
)
1679 /* Prevent unused argument(s) compilation warning */
1682 /* NOTE : This function should not be modified, when the callback is needed,
1683 the HAL_MMC_AbortCallback can be implemented in the user file
1687 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1689 * @brief Register a User MMC Callback
1690 * To be used instead of the weak (surcharged) predefined callback
1691 * @param hmmc : MMC handle
1692 * @param CallbackId : ID of the callback to be registered
1693 * This parameter can be one of the following values:
1694 * @arg @ref HAL_MMC_TX_CPLT_CB_ID MMC Tx Complete Callback ID
1695 * @arg @ref HAL_MMC_RX_CPLT_CB_ID MMC Rx Complete Callback ID
1696 * @arg @ref HAL_MMC_ERROR_CB_ID MMC Error Callback ID
1697 * @arg @ref HAL_MMC_ABORT_CB_ID MMC Abort Callback ID
1698 * @arg @ref HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID MMC DMA Rx Double buffer 0 Callback ID
1699 * @arg @ref HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID MMC DMA Rx Double buffer 1 Callback ID
1700 * @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID MMC DMA Tx Double buffer 0 Callback ID
1701 * @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID MMC DMA Tx Double buffer 1 Callback ID
1702 * @arg @ref HAL_MMC_MSP_INIT_CB_ID MMC MspInit Callback ID
1703 * @arg @ref HAL_MMC_MSP_DEINIT_CB_ID MMC MspDeInit Callback ID
1704 * @param pCallback : pointer to the Callback function
1707 HAL_StatusTypeDef
HAL_MMC_RegisterCallback(MMC_HandleTypeDef
*hmmc
, HAL_MMC_CallbackIDTypeDef CallbackId
, pMMC_CallbackTypeDef pCallback
)
1709 HAL_StatusTypeDef status
= HAL_OK
;
1711 if(pCallback
== NULL
)
1713 /* Update the error code */
1714 hmmc
->ErrorCode
|= HAL_MMC_ERROR_INVALID_CALLBACK
;
1718 /* Process locked */
1721 if(hmmc
->State
== HAL_MMC_STATE_READY
)
1725 case HAL_MMC_TX_CPLT_CB_ID
:
1726 hmmc
->TxCpltCallback
= pCallback
;
1728 case HAL_MMC_RX_CPLT_CB_ID
:
1729 hmmc
->RxCpltCallback
= pCallback
;
1731 case HAL_MMC_ERROR_CB_ID
:
1732 hmmc
->ErrorCallback
= pCallback
;
1734 case HAL_MMC_ABORT_CB_ID
:
1735 hmmc
->AbortCpltCallback
= pCallback
;
1737 case HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID
:
1738 hmmc
->Read_DMADblBuf0CpltCallback
= pCallback
;
1740 case HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID
:
1741 hmmc
->Read_DMADblBuf1CpltCallback
= pCallback
;
1743 case HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID
:
1744 hmmc
->Write_DMADblBuf0CpltCallback
= pCallback
;
1746 case HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID
:
1747 hmmc
->Write_DMADblBuf1CpltCallback
= pCallback
;
1749 case HAL_MMC_MSP_INIT_CB_ID
:
1750 hmmc
->MspInitCallback
= pCallback
;
1752 case HAL_MMC_MSP_DEINIT_CB_ID
:
1753 hmmc
->MspDeInitCallback
= pCallback
;
1756 /* Update the error code */
1757 hmmc
->ErrorCode
|= HAL_MMC_ERROR_INVALID_CALLBACK
;
1758 /* update return status */
1763 else if (hmmc
->State
== HAL_MMC_STATE_RESET
)
1767 case HAL_MMC_MSP_INIT_CB_ID
:
1768 hmmc
->MspInitCallback
= pCallback
;
1770 case HAL_MMC_MSP_DEINIT_CB_ID
:
1771 hmmc
->MspDeInitCallback
= pCallback
;
1774 /* Update the error code */
1775 hmmc
->ErrorCode
|= HAL_MMC_ERROR_INVALID_CALLBACK
;
1776 /* update return status */
1783 /* Update the error code */
1784 hmmc
->ErrorCode
|= HAL_MMC_ERROR_INVALID_CALLBACK
;
1785 /* update return status */
1795 * @brief Unregister a User MMC Callback
1796 * MMC Callback is redirected to the weak (surcharged) predefined callback
1797 * @param hmmc : MMC handle
1798 * @param CallbackId : ID of the callback to be unregistered
1799 * This parameter can be one of the following values:
1800 * @arg @ref HAL_MMC_TX_CPLT_CB_ID MMC Tx Complete Callback ID
1801 * @arg @ref HAL_MMC_RX_CPLT_CB_ID MMC Rx Complete Callback ID
1802 * @arg @ref HAL_MMC_ERROR_CB_ID MMC Error Callback ID
1803 * @arg @ref HAL_MMC_ABORT_CB_ID MMC Abort Callback ID
1804 * @arg @ref HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID MMC DMA Rx Double buffer 0 Callback ID
1805 * @arg @ref HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID MMC DMA Rx Double buffer 1 Callback ID
1806 * @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID MMC DMA Tx Double buffer 0 Callback ID
1807 * @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID MMC DMA Tx Double buffer 1 Callback ID
1808 * @arg @ref HAL_MMC_MSP_INIT_CB_ID MMC MspInit Callback ID
1809 * @arg @ref HAL_MMC_MSP_DEINIT_CB_ID MMC MspDeInit Callback ID
1812 HAL_StatusTypeDef
HAL_MMC_UnRegisterCallback(MMC_HandleTypeDef
*hmmc
, HAL_MMC_CallbackIDTypeDef CallbackId
)
1814 HAL_StatusTypeDef status
= HAL_OK
;
1816 /* Process locked */
1819 if(hmmc
->State
== HAL_MMC_STATE_READY
)
1823 case HAL_MMC_TX_CPLT_CB_ID
:
1824 hmmc
->TxCpltCallback
= HAL_MMC_TxCpltCallback
;
1826 case HAL_MMC_RX_CPLT_CB_ID
:
1827 hmmc
->RxCpltCallback
= HAL_MMC_RxCpltCallback
;
1829 case HAL_MMC_ERROR_CB_ID
:
1830 hmmc
->ErrorCallback
= HAL_MMC_ErrorCallback
;
1832 case HAL_MMC_ABORT_CB_ID
:
1833 hmmc
->AbortCpltCallback
= HAL_MMC_AbortCallback
;
1835 case HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID
:
1836 hmmc
->Read_DMADblBuf0CpltCallback
= HAL_MMCEx_Read_DMADoubleBuf0CpltCallback
;
1838 case HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID
:
1839 hmmc
->Read_DMADblBuf1CpltCallback
= HAL_MMCEx_Read_DMADoubleBuf1CpltCallback
;
1841 case HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID
:
1842 hmmc
->Write_DMADblBuf0CpltCallback
= HAL_MMCEx_Write_DMADoubleBuf0CpltCallback
;
1844 case HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID
:
1845 hmmc
->Write_DMADblBuf1CpltCallback
= HAL_MMCEx_Write_DMADoubleBuf1CpltCallback
;
1847 case HAL_MMC_MSP_INIT_CB_ID
:
1848 hmmc
->MspInitCallback
= HAL_MMC_MspInit
;
1850 case HAL_MMC_MSP_DEINIT_CB_ID
:
1851 hmmc
->MspDeInitCallback
= HAL_MMC_MspDeInit
;
1854 /* Update the error code */
1855 hmmc
->ErrorCode
|= HAL_MMC_ERROR_INVALID_CALLBACK
;
1856 /* update return status */
1861 else if (hmmc
->State
== HAL_MMC_STATE_RESET
)
1865 case HAL_MMC_MSP_INIT_CB_ID
:
1866 hmmc
->MspInitCallback
= HAL_MMC_MspInit
;
1868 case HAL_MMC_MSP_DEINIT_CB_ID
:
1869 hmmc
->MspDeInitCallback
= HAL_MMC_MspDeInit
;
1872 /* Update the error code */
1873 hmmc
->ErrorCode
|= HAL_MMC_ERROR_INVALID_CALLBACK
;
1874 /* update return status */
1881 /* Update the error code */
1882 hmmc
->ErrorCode
|= HAL_MMC_ERROR_INVALID_CALLBACK
;
1883 /* update return status */
1897 /** @addtogroup MMC_Exported_Functions_Group3
1898 * @brief management functions
1901 ==============================================================================
1902 ##### Peripheral Control functions #####
1903 ==============================================================================
1905 This subsection provides a set of functions allowing to control the MMC card
1906 operations and get the related information
1913 * @brief Returns information the information of the card which are stored on
1915 * @param hmmc: Pointer to MMC handle
1916 * @param pCID: Pointer to a HAL_MMC_CIDTypedef structure that
1917 * contains all CID register parameters
1918 * @retval HAL status
1920 HAL_StatusTypeDef
HAL_MMC_GetCardCID(MMC_HandleTypeDef
*hmmc
, HAL_MMC_CardCIDTypeDef
*pCID
)
1922 pCID
->ManufacturerID
= (uint8_t)((hmmc
->CID
[0] & 0xFF000000U
) >> 24U);
1924 pCID
->OEM_AppliID
= (uint16_t)((hmmc
->CID
[0] & 0x00FFFF00U
) >> 8U);
1926 pCID
->ProdName1
= (((hmmc
->CID
[0] & 0x000000FFU
) << 24U) | ((hmmc
->CID
[1] & 0xFFFFFF00U
) >> 8U));
1928 pCID
->ProdName2
= (uint8_t)(hmmc
->CID
[1] & 0x000000FFU
);
1930 pCID
->ProdRev
= (uint8_t)((hmmc
->CID
[2] & 0xFF000000U
) >> 24U);
1932 pCID
->ProdSN
= (((hmmc
->CID
[2] & 0x00FFFFFFU
) << 8U) | ((hmmc
->CID
[3] & 0xFF000000U
) >> 24U));
1934 pCID
->Reserved1
= (uint8_t)((hmmc
->CID
[3] & 0x00F00000U
) >> 20U);
1936 pCID
->ManufactDate
= (uint16_t)((hmmc
->CID
[3] & 0x000FFF00U
) >> 8U);
1938 pCID
->CID_CRC
= (uint8_t)((hmmc
->CID
[3] & 0x000000FEU
) >> 1U);
1940 pCID
->Reserved2
= 1U;
1946 * @brief Returns information the information of the card which are stored on
1948 * @param hmmc: Pointer to MMC handle
1949 * @param pCSD: Pointer to a HAL_MMC_CardCSDTypeDef structure that
1950 * contains all CSD register parameters
1951 * @retval HAL status
1953 HAL_StatusTypeDef
HAL_MMC_GetCardCSD(MMC_HandleTypeDef
*hmmc
, HAL_MMC_CardCSDTypeDef
*pCSD
)
1955 uint32_t block_nbr
= 0;
1957 pCSD
->CSDStruct
= (uint8_t)((hmmc
->CSD
[0] & 0xC0000000U
) >> 30U);
1959 pCSD
->SysSpecVersion
= (uint8_t)((hmmc
->CSD
[0] & 0x3C000000U
) >> 26U);
1961 pCSD
->Reserved1
= (uint8_t)((hmmc
->CSD
[0] & 0x03000000U
) >> 24U);
1963 pCSD
->TAAC
= (uint8_t)((hmmc
->CSD
[0] & 0x00FF0000U
) >> 16U);
1965 pCSD
->NSAC
= (uint8_t)((hmmc
->CSD
[0] & 0x0000FF00U
) >> 8U);
1967 pCSD
->MaxBusClkFrec
= (uint8_t)(hmmc
->CSD
[0] & 0x000000FFU
);
1969 pCSD
->CardComdClasses
= (uint16_t)((hmmc
->CSD
[1] & 0xFFF00000U
) >> 20U);
1971 pCSD
->RdBlockLen
= (uint8_t)((hmmc
->CSD
[1] & 0x000F0000U
) >> 16U);
1973 pCSD
->PartBlockRead
= (uint8_t)((hmmc
->CSD
[1] & 0x00008000U
) >> 15U);
1975 pCSD
->WrBlockMisalign
= (uint8_t)((hmmc
->CSD
[1] & 0x00004000U
) >> 14U);
1977 pCSD
->RdBlockMisalign
= (uint8_t)((hmmc
->CSD
[1] & 0x00002000U
) >> 13U);
1979 pCSD
->DSRImpl
= (uint8_t)((hmmc
->CSD
[1] & 0x00001000U
) >> 12U);
1981 pCSD
->Reserved2
= 0U; /*!< Reserved */
1983 if(MMC_ReadExtCSD(hmmc
, &block_nbr
, 212, 0x0FFFFFFFU
) != HAL_OK
) /* Field SEC_COUNT [215:212] */
1988 if(hmmc
->MmcCard
.CardType
== MMC_LOW_CAPACITY_CARD
)
1990 pCSD
->DeviceSize
= (((hmmc
->CSD
[1] & 0x000003FFU
) << 2U) | ((hmmc
->CSD
[2] & 0xC0000000U
) >> 30U));
1992 pCSD
->MaxRdCurrentVDDMin
= (uint8_t)((hmmc
->CSD
[2] & 0x38000000U
) >> 27U);
1994 pCSD
->MaxRdCurrentVDDMax
= (uint8_t)((hmmc
->CSD
[2] & 0x07000000U
) >> 24U);
1996 pCSD
->MaxWrCurrentVDDMin
= (uint8_t)((hmmc
->CSD
[2] & 0x00E00000U
) >> 21U);
1998 pCSD
->MaxWrCurrentVDDMax
= (uint8_t)((hmmc
->CSD
[2] & 0x001C0000U
) >> 18U);
2000 pCSD
->DeviceSizeMul
= (uint8_t)((hmmc
->CSD
[2] & 0x00038000U
) >> 15U);
2002 hmmc
->MmcCard
.BlockNbr
= (pCSD
->DeviceSize
+ 1U) ;
2003 hmmc
->MmcCard
.BlockNbr
*= (1UL << ((pCSD
->DeviceSizeMul
& 0x07U
) + 2U));
2004 hmmc
->MmcCard
.BlockSize
= (1UL << (pCSD
->RdBlockLen
& 0x0FU
));
2006 hmmc
->MmcCard
.LogBlockNbr
= (hmmc
->MmcCard
.BlockNbr
) * ((hmmc
->MmcCard
.BlockSize
) / 512U);
2007 hmmc
->MmcCard
.LogBlockSize
= 512U;
2009 else if(hmmc
->MmcCard
.CardType
== MMC_HIGH_CAPACITY_CARD
)
2011 hmmc
->MmcCard
.BlockNbr
= block_nbr
;
2012 hmmc
->MmcCard
.LogBlockNbr
= hmmc
->MmcCard
.BlockNbr
;
2013 hmmc
->MmcCard
.BlockSize
= 512U;
2014 hmmc
->MmcCard
.LogBlockSize
= hmmc
->MmcCard
.BlockSize
;
2018 /* Clear all the static flags */
2019 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
2020 hmmc
->ErrorCode
|= HAL_MMC_ERROR_UNSUPPORTED_FEATURE
;
2021 hmmc
->State
= HAL_MMC_STATE_READY
;
2025 pCSD
->EraseGrSize
= (uint8_t)((hmmc
->CSD
[2] & 0x00004000U
) >> 14U);
2027 pCSD
->EraseGrMul
= (uint8_t)((hmmc
->CSD
[2] & 0x00003F80U
) >> 7U);
2029 pCSD
->WrProtectGrSize
= (uint8_t)(hmmc
->CSD
[2] & 0x0000007FU
);
2031 pCSD
->WrProtectGrEnable
= (uint8_t)((hmmc
->CSD
[3] & 0x80000000U
) >> 31U);
2033 pCSD
->ManDeflECC
= (uint8_t)((hmmc
->CSD
[3] & 0x60000000U
) >> 29U);
2035 pCSD
->WrSpeedFact
= (uint8_t)((hmmc
->CSD
[3] & 0x1C000000U
) >> 26U);
2037 pCSD
->MaxWrBlockLen
= (uint8_t)((hmmc
->CSD
[3] & 0x03C00000U
) >> 22U);
2039 pCSD
->WriteBlockPaPartial
= (uint8_t)((hmmc
->CSD
[3] & 0x00200000U
) >> 21U);
2041 pCSD
->Reserved3
= 0;
2043 pCSD
->ContentProtectAppli
= (uint8_t)((hmmc
->CSD
[3] & 0x00010000U
) >> 16U);
2045 pCSD
->FileFormatGroup
= (uint8_t)((hmmc
->CSD
[3] & 0x00008000U
) >> 15U);
2047 pCSD
->CopyFlag
= (uint8_t)((hmmc
->CSD
[3] & 0x00004000U
) >> 14U);
2049 pCSD
->PermWrProtect
= (uint8_t)((hmmc
->CSD
[3] & 0x00002000U
) >> 13U);
2051 pCSD
->TempWrProtect
= (uint8_t)((hmmc
->CSD
[3] & 0x00001000U
) >> 12U);
2053 pCSD
->FileFormat
= (uint8_t)((hmmc
->CSD
[3] & 0x00000C00U
) >> 10U);
2055 pCSD
->ECC
= (uint8_t)((hmmc
->CSD
[3] & 0x00000300U
) >> 8U);
2057 pCSD
->CSD_CRC
= (uint8_t)((hmmc
->CSD
[3] & 0x000000FEU
) >> 1U);
2059 pCSD
->Reserved4
= 1;
2065 * @brief Gets the MMC card info.
2066 * @param hmmc: Pointer to MMC handle
2067 * @param pCardInfo: Pointer to the HAL_MMC_CardInfoTypeDef structure that
2068 * will contain the MMC card status information
2069 * @retval HAL status
2071 HAL_StatusTypeDef
HAL_MMC_GetCardInfo(MMC_HandleTypeDef
*hmmc
, HAL_MMC_CardInfoTypeDef
*pCardInfo
)
2073 pCardInfo
->CardType
= (uint32_t)(hmmc
->MmcCard
.CardType
);
2074 pCardInfo
->Class
= (uint32_t)(hmmc
->MmcCard
.Class
);
2075 pCardInfo
->RelCardAdd
= (uint32_t)(hmmc
->MmcCard
.RelCardAdd
);
2076 pCardInfo
->BlockNbr
= (uint32_t)(hmmc
->MmcCard
.BlockNbr
);
2077 pCardInfo
->BlockSize
= (uint32_t)(hmmc
->MmcCard
.BlockSize
);
2078 pCardInfo
->LogBlockNbr
= (uint32_t)(hmmc
->MmcCard
.LogBlockNbr
);
2079 pCardInfo
->LogBlockSize
= (uint32_t)(hmmc
->MmcCard
.LogBlockSize
);
2085 * @brief Enables wide bus operation for the requested card if supported by
2087 * @param hmmc: Pointer to MMC handle
2088 * @param WideMode: Specifies the MMC card wide bus mode
2089 * This parameter can be one of the following values:
2090 * @arg SDMMC_BUS_WIDE_8B: 8-bit data transfer
2091 * @arg SDMMC_BUS_WIDE_4B: 4-bit data transfer
2092 * @arg SDMMC_BUS_WIDE_1B: 1-bit data transfer
2093 * @retval HAL status
2095 HAL_StatusTypeDef
HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef
*hmmc
, uint32_t WideMode
)
2098 SDMMC_InitTypeDef Init
;
2099 uint32_t errorstate
;
2100 uint32_t response
= 0U;
2102 /* Check the parameters */
2103 assert_param(IS_SDMMC_BUS_WIDE(WideMode
));
2106 hmmc
->State
= HAL_MMC_STATE_BUSY
;
2108 if(WideMode
== SDMMC_BUS_WIDE_8B
)
2110 errorstate
= SDMMC_CmdSwitch(hmmc
->Instance
, 0x03B70200U
);
2112 else if(WideMode
== SDMMC_BUS_WIDE_4B
)
2114 errorstate
= SDMMC_CmdSwitch(hmmc
->Instance
, 0x03B70100U
);
2116 else if(WideMode
== SDMMC_BUS_WIDE_1B
)
2118 errorstate
= SDMMC_CmdSwitch(hmmc
->Instance
, 0x03B70000U
);
2122 /* WideMode is not a valid argument*/
2123 errorstate
= HAL_MMC_ERROR_PARAM
;
2126 /* Check for switch error and violation of the trial number of sending CMD 13 */
2127 if(errorstate
== HAL_MMC_ERROR_NONE
)
2129 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2130 count
= SDMMC_MAX_TRIAL
;
2133 errorstate
= SDMMC_CmdSendStatus(hmmc
->Instance
, (uint32_t)(((uint32_t)hmmc
->MmcCard
.RelCardAdd
) << 16U));
2134 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2139 /* Get command response */
2140 response
= SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP1
);
2142 }while(((response
& 0x100U
) == 0U) && (count
!= 0U));
2144 /* Check the status after the switch command execution */
2145 if ((count
!= 0U) && (errorstate
== HAL_MMC_ERROR_NONE
))
2147 /* Check the bit SWITCH_ERROR of the device status */
2148 if ((response
& 0x80U
) != 0U)
2150 errorstate
= SDMMC_ERROR_GENERAL_UNKNOWN_ERR
;
2154 /* Configure the SDMMC peripheral */
2155 Init
.ClockEdge
= hmmc
->Init
.ClockEdge
;
2156 Init
.ClockPowerSave
= hmmc
->Init
.ClockPowerSave
;
2157 Init
.BusWide
= WideMode
;
2158 Init
.HardwareFlowControl
= hmmc
->Init
.HardwareFlowControl
;
2159 Init
.ClockDiv
= hmmc
->Init
.ClockDiv
;
2160 (void)SDMMC_Init(hmmc
->Instance
, Init
);
2163 else if (count
== 0U)
2165 errorstate
= SDMMC_ERROR_TIMEOUT
;
2174 hmmc
->State
= HAL_MMC_STATE_READY
;
2176 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2178 /* Clear all the static flags */
2179 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
2180 hmmc
->ErrorCode
|= errorstate
;
2188 * @brief Configure the speed bus mode
2189 * @param hmmc: Pointer to the MMC handle
2190 * @param SpeedMode: Specifies the MMC card speed bus mode
2191 * This parameter can be one of the following values:
2192 * @arg SDMMC_SPEED_MODE_AUTO: Max speed mode supported by the card
2193 * @arg SDMMC_SPEED_MODE_DEFAULT: Default Speed (MMC @ 26MHz)
2194 * @arg SDMMC_SPEED_MODE_HIGH: High Speed (MMC @ 52 MHz)
2195 * @arg SDMMC_SPEED_MODE_DDR: High Speed DDR (MMC DDR @ 52 MHz)
2196 * @retval HAL status
2199 HAL_StatusTypeDef
HAL_MMC_ConfigSpeedBusOperation(MMC_HandleTypeDef
*hmmc
, uint32_t SpeedMode
)
2202 HAL_StatusTypeDef status
= HAL_OK
;
2203 uint32_t device_type
;
2204 uint32_t errorstate
;
2206 /* Check the parameters */
2207 assert_param(IS_SDMMC_SPEED_MODE(SpeedMode
));
2209 hmmc
->State
= HAL_MMC_STATE_BUSY
;
2211 if(MMC_ReadExtCSD(hmmc
, &device_type
, 196, 0x0FFFFFFFU
) != HAL_OK
) /* Field DEVICE_TYPE [196] */
2218 case SDMMC_SPEED_MODE_AUTO
:
2220 if (((hmmc
->Instance
->CLKCR
& SDMMC_CLKCR_WIDBUS
) != 0U) && ((device_type
& 0x04U
) != 0U))
2222 /* High Speed DDR mode allowed */
2223 errorstate
= MMC_HighSpeed(hmmc
, ENABLE
);
2224 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2226 hmmc
->ErrorCode
|= errorstate
;
2230 errorstate
= MMC_DDR_Mode(hmmc
, ENABLE
);
2231 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2233 hmmc
->ErrorCode
|= errorstate
;
2237 else if ((device_type
& 0x02U
) != 0U)
2239 /* High Speed mode allowed */
2240 errorstate
= MMC_HighSpeed(hmmc
, ENABLE
);
2241 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2243 hmmc
->ErrorCode
|= errorstate
;
2248 /* Nothing to do : keep current speed */
2252 case SDMMC_SPEED_MODE_DDR
:
2254 if (((hmmc
->Instance
->CLKCR
& SDMMC_CLKCR_WIDBUS
) != 0U) && ((device_type
& 0x04U
) != 0U))
2256 /* High Speed DDR mode allowed */
2257 errorstate
= MMC_HighSpeed(hmmc
, ENABLE
);
2258 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2260 hmmc
->ErrorCode
|= errorstate
;
2264 errorstate
= MMC_DDR_Mode(hmmc
, ENABLE
);
2265 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2267 hmmc
->ErrorCode
|= errorstate
;
2273 /* High Speed DDR mode not allowed */
2274 hmmc
->ErrorCode
|= HAL_MMC_ERROR_UNSUPPORTED_FEATURE
;
2279 case SDMMC_SPEED_MODE_HIGH
:
2281 if ((device_type
& 0x02U
) != 0U)
2283 /* High Speed mode allowed */
2284 errorstate
= MMC_HighSpeed(hmmc
, ENABLE
);
2285 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2287 hmmc
->ErrorCode
|= errorstate
;
2292 /* High Speed mode not allowed */
2293 hmmc
->ErrorCode
|= HAL_MMC_ERROR_UNSUPPORTED_FEATURE
;
2298 case SDMMC_SPEED_MODE_DEFAULT
:
2300 if ((hmmc
->Instance
->CLKCR
& SDMMC_CLKCR_DDR
) != 0U)
2302 /* High Speed DDR mode activated */
2303 errorstate
= MMC_DDR_Mode(hmmc
, DISABLE
);
2304 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2306 hmmc
->ErrorCode
|= errorstate
;
2309 if ((hmmc
->Instance
->CLKCR
& SDMMC_CLKCR_BUSSPEED
) != 0U)
2311 /* High Speed mode activated */
2312 errorstate
= MMC_HighSpeed(hmmc
, DISABLE
);
2313 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2315 hmmc
->ErrorCode
|= errorstate
;
2321 hmmc
->ErrorCode
|= HAL_MMC_ERROR_PARAM
;
2326 /* Verify that MMC card is ready to use after Speed mode switch*/
2327 tickstart
= HAL_GetTick();
2328 while ((HAL_MMC_GetCardState(hmmc
) != HAL_MMC_CARD_TRANSFER
))
2330 if ((HAL_GetTick() - tickstart
) >= SDMMC_DATATIMEOUT
)
2332 hmmc
->ErrorCode
= HAL_MMC_ERROR_TIMEOUT
;
2333 hmmc
->State
= HAL_MMC_STATE_READY
;
2339 hmmc
->State
= HAL_MMC_STATE_READY
;
2344 * @brief Gets the current mmc card data state.
2345 * @param hmmc: pointer to MMC handle
2346 * @retval Card state
2348 HAL_MMC_CardStateTypeDef
HAL_MMC_GetCardState(MMC_HandleTypeDef
*hmmc
)
2351 uint32_t errorstate
;
2352 uint32_t resp1
= 0U;
2354 errorstate
= MMC_SendStatus(hmmc
, &resp1
);
2355 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2357 hmmc
->ErrorCode
|= errorstate
;
2360 cardstate
= ((resp1
>> 9U) & 0x0FU
);
2362 return (HAL_MMC_CardStateTypeDef
)cardstate
;
2366 * @brief Abort the current transfer and disable the MMC.
2367 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2368 * the configuration information for MMC module.
2369 * @retval HAL status
2371 HAL_StatusTypeDef
HAL_MMC_Abort(MMC_HandleTypeDef
*hmmc
)
2373 HAL_MMC_CardStateTypeDef CardState
;
2375 /* DIsable All interrupts */
2376 __HAL_MMC_DISABLE_IT(hmmc
, SDMMC_IT_DATAEND
| SDMMC_IT_DCRCFAIL
| SDMMC_IT_DTIMEOUT
|\
2377 SDMMC_IT_TXUNDERR
| SDMMC_IT_RXOVERR
);
2379 /* Clear All flags */
2380 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_DATA_FLAGS
);
2382 /* If IDMA Context, disable Internal DMA */
2383 hmmc
->Instance
->IDMACTRL
= SDMMC_DISABLE_IDMA
;
2385 hmmc
->State
= HAL_MMC_STATE_READY
;
2387 /* Initialize the MMC operation */
2388 hmmc
->Context
= MMC_CONTEXT_NONE
;
2390 CardState
= HAL_MMC_GetCardState(hmmc
);
2391 if((CardState
== HAL_MMC_CARD_RECEIVING
) || (CardState
== HAL_MMC_CARD_SENDING
))
2393 hmmc
->ErrorCode
= SDMMC_CmdStopTransfer(hmmc
->Instance
);
2395 if(hmmc
->ErrorCode
!= HAL_MMC_ERROR_NONE
)
2403 * @brief Abort the current transfer and disable the MMC (IT mode).
2404 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2405 * the configuration information for MMC module.
2406 * @retval HAL status
2408 HAL_StatusTypeDef
HAL_MMC_Abort_IT(MMC_HandleTypeDef
*hmmc
)
2410 HAL_MMC_CardStateTypeDef CardState
;
2412 /* DIsable All interrupts */
2413 __HAL_MMC_DISABLE_IT(hmmc
, SDMMC_IT_DATAEND
| SDMMC_IT_DCRCFAIL
| SDMMC_IT_DTIMEOUT
|\
2414 SDMMC_IT_TXUNDERR
| SDMMC_IT_RXOVERR
);
2416 /* If IDMA Context, disable Internal DMA */
2417 hmmc
->Instance
->IDMACTRL
= SDMMC_DISABLE_IDMA
;
2419 /* Clear All flags */
2420 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_DATA_FLAGS
);
2422 CardState
= HAL_MMC_GetCardState(hmmc
);
2423 hmmc
->State
= HAL_MMC_STATE_READY
;
2425 if((CardState
== HAL_MMC_CARD_RECEIVING
) || (CardState
== HAL_MMC_CARD_SENDING
))
2427 hmmc
->ErrorCode
= SDMMC_CmdStopTransfer(hmmc
->Instance
);
2429 if(hmmc
->ErrorCode
!= HAL_MMC_ERROR_NONE
)
2435 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2436 hmmc
->AbortCpltCallback(hmmc
);
2438 HAL_MMC_AbortCallback(hmmc
);
2446 * @brief Perform specific commands sequence for the different type of erase.
2447 * @note This API should be followed by a check on the card state through
2448 * HAL_MMC_GetCardState().
2449 * @param hmmc Pointer to MMC handle
2450 * @param EraseType Specifies the type of erase to be performed
2451 * This parameter can be one of the following values:
2452 * @arg HAL_MMC_ERASE Erase the erase groups identified by CMD35 & 36
2453 * @arg HAL_MMC_TRIM Erase the write blocks identified by CMD35 & 36
2454 * @arg HAL_MMC_DISCARD Discard the write blocks identified by CMD35 & 36
2455 * @arg HAL_MMC_SECURE_ERASE Perform a secure purge according SRT on the erase groups identified by CMD35 & 36
2456 * @arg HAL_MMC_SECURE_TRIM_STEP1 Mark the write blocks identified by CMD35 & 36 for secure erase
2457 * @arg HAL_MMC_SECURE_TRIM_STEP2 Perform a secure purge according SRT on the write blocks previously identified
2458 * @param BlockStartAdd Start Block address
2459 * @param BlockEndAdd End Block address
2460 * @retval HAL status
2462 HAL_StatusTypeDef
HAL_MMC_EraseSequence(MMC_HandleTypeDef
*hmmc
, uint32_t EraseType
, uint32_t BlockStartAdd
, uint32_t BlockEndAdd
)
2464 uint32_t errorstate
;
2465 uint32_t start_add
= BlockStartAdd
;
2466 uint32_t end_add
= BlockEndAdd
;
2467 uint32_t tickstart
= HAL_GetTick();
2469 /* Check the erase type value is correct */
2470 assert_param(IS_MMC_ERASE_TYPE(EraseType
));
2472 /* Check the coherence between start and end address */
2473 if(end_add
< start_add
)
2475 hmmc
->ErrorCode
|= HAL_MMC_ERROR_PARAM
;
2479 /* Check that the end address is not out of range of device memory */
2480 if(end_add
> (hmmc
->MmcCard
.LogBlockNbr
))
2482 hmmc
->ErrorCode
|= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE
;
2486 /* Check if the card command class supports erase command */
2487 if(((hmmc
->MmcCard
.Class
) & SDMMC_CCCC_ERASE
) == 0U)
2489 hmmc
->ErrorCode
|= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE
;
2493 /* Check the state of the driver */
2494 if(hmmc
->State
== HAL_MMC_STATE_READY
)
2497 hmmc
->State
= HAL_MMC_STATE_BUSY
;
2499 /* Check that the card is not locked */
2500 if((SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP1
) & SDMMC_CARD_LOCKED
) == SDMMC_CARD_LOCKED
)
2502 hmmc
->ErrorCode
|= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED
;
2503 hmmc
->State
= HAL_MMC_STATE_READY
;
2507 /* In case of low capacity card, the address is not block number but bytes */
2508 if ((hmmc
->MmcCard
.CardType
) != MMC_HIGH_CAPACITY_CARD
)
2514 /* Send CMD35 MMC_ERASE_GRP_START with start address as argument */
2515 errorstate
= SDMMC_CmdEraseStartAdd(hmmc
->Instance
, start_add
);
2516 if(errorstate
== HAL_MMC_ERROR_NONE
)
2518 /* Send CMD36 MMC_ERASE_GRP_END with end address as argument */
2519 errorstate
= SDMMC_CmdEraseEndAdd(hmmc
->Instance
, end_add
);
2520 if(errorstate
== HAL_MMC_ERROR_NONE
)
2522 /* Send CMD38 ERASE with erase type as argument */
2523 errorstate
= SDMMC_CmdErase(hmmc
->Instance
, EraseType
);
2524 if(errorstate
== HAL_MMC_ERROR_NONE
)
2526 if ((EraseType
== HAL_MMC_SECURE_ERASE
) || (EraseType
== HAL_MMC_SECURE_TRIM_STEP2
))
2528 /* Wait that the device is ready by checking the D0 line */
2529 while((!__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_BUSYD0END
)) && (errorstate
== HAL_MMC_ERROR_NONE
))
2531 if((HAL_GetTick()-tickstart
) >= SDMMC_MAXERASETIMEOUT
)
2533 errorstate
= HAL_MMC_ERROR_TIMEOUT
;
2537 /* Clear the flag corresponding to end D0 bus line */
2538 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_FLAG_BUSYD0END
);
2545 hmmc
->State
= HAL_MMC_STATE_READY
;
2548 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2550 /* Clear all the static flags */
2551 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
2552 hmmc
->ErrorCode
|= errorstate
;
2554 if(errorstate
!= HAL_MMC_ERROR_TIMEOUT
)
2575 * @brief Perform sanitize operation on the device.
2576 * @note This API should be followed by a check on the card state through
2577 * HAL_MMC_GetCardState().
2578 * @param hmmc Pointer to MMC handle
2579 * @retval HAL status
2581 HAL_StatusTypeDef
HAL_MMC_Sanitize(MMC_HandleTypeDef
*hmmc
)
2583 uint32_t errorstate
, response
= 0U, count
;
2584 uint32_t tickstart
= HAL_GetTick();
2586 /* Check the state of the driver */
2587 if(hmmc
->State
== HAL_MMC_STATE_READY
)
2590 hmmc
->State
= HAL_MMC_STATE_BUSY
;
2592 /* Index : 165 - Value : 0x01 */
2593 errorstate
= SDMMC_CmdSwitch(hmmc
->Instance
, 0x03A50100U
);
2594 if(errorstate
== HAL_MMC_ERROR_NONE
)
2596 /* Wait that the device is ready by checking the D0 line */
2597 while((!__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_BUSYD0END
)) && (errorstate
== HAL_MMC_ERROR_NONE
))
2599 if((HAL_GetTick()-tickstart
) >= SDMMC_MAXERASETIMEOUT
)
2601 errorstate
= HAL_MMC_ERROR_TIMEOUT
;
2605 /* Clear the flag corresponding to end D0 bus line */
2606 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_FLAG_BUSYD0END
);
2608 if(errorstate
== HAL_MMC_ERROR_NONE
)
2610 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2611 count
= SDMMC_MAX_TRIAL
;
2614 errorstate
= SDMMC_CmdSendStatus(hmmc
->Instance
, (uint32_t)(((uint32_t)hmmc
->MmcCard
.RelCardAdd
) << 16U));
2615 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2620 /* Get command response */
2621 response
= SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP1
);
2623 }while(((response
& 0x100U
) == 0U) && (count
!= 0U));
2625 /* Check the status after the switch command execution */
2626 if ((count
!= 0U) && (errorstate
== HAL_MMC_ERROR_NONE
))
2628 /* Check the bit SWITCH_ERROR of the device status */
2629 if ((response
& 0x80U
) != 0U)
2631 errorstate
= SDMMC_ERROR_GENERAL_UNKNOWN_ERR
;
2634 else if (count
== 0U)
2636 errorstate
= SDMMC_ERROR_TIMEOUT
;
2646 hmmc
->State
= HAL_MMC_STATE_READY
;
2649 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2651 /* Clear all the static flags */
2652 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
2653 hmmc
->ErrorCode
|= errorstate
;
2655 if(errorstate
!= HAL_MMC_ERROR_TIMEOUT
)
2676 * @brief Configure the Secure Removal Type (SRT) in the Extended CSD register.
2677 * @note This API should be followed by a check on the card state through
2678 * HAL_MMC_GetCardState().
2679 * @param hmmc Pointer to MMC handle
2680 * @param SRTMode Specifies the type of erase to be performed
2681 * This parameter can be one of the following values:
2682 * @arg HAL_MMC_SRT_ERASE Information removed by an erase
2683 * @arg HAL_MMC_SRT_WRITE_CHAR_ERASE Information removed by an overwriting with a character followed by an erase
2684 * @arg HAL_MMC_SRT_WRITE_CHAR_COMPL_RANDOM Information removed by an overwriting with a character, its complement then a random character
2685 * @arg HAL_MMC_SRT_VENDOR_DEFINED Information removed using a vendor defined
2686 * @retval HAL status
2688 HAL_StatusTypeDef
HAL_MMC_ConfigSecRemovalType(MMC_HandleTypeDef
*hmmc
, uint32_t SRTMode
)
2690 uint32_t srt
, errorstate
, response
= 0U, count
;
2692 /* Check the erase type value is correct */
2693 assert_param(IS_MMC_SRT_TYPE(SRTMode
));
2695 /* Check the state of the driver */
2696 if(hmmc
->State
== HAL_MMC_STATE_READY
)
2698 /* Get the supported values by the device */
2699 if(HAL_MMC_GetSupportedSecRemovalType(hmmc
, &srt
) == HAL_OK
)
2702 hmmc
->State
= HAL_MMC_STATE_BUSY
;
2704 /* Check the value passed as parameter is supported by the device */
2705 if((SRTMode
& srt
) != 0U)
2707 /* Index : 16 - Value : SRTMode */
2708 srt
|= ((POSITION_VAL(SRTMode
)) << 4U);
2709 errorstate
= SDMMC_CmdSwitch(hmmc
->Instance
, (0x03100000U
| (srt
<< 8U)));
2710 if(errorstate
== HAL_MMC_ERROR_NONE
)
2712 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2713 count
= SDMMC_MAX_TRIAL
;
2716 errorstate
= SDMMC_CmdSendStatus(hmmc
->Instance
, (uint32_t)(((uint32_t)hmmc
->MmcCard
.RelCardAdd
) << 16U));
2717 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2722 /* Get command response */
2723 response
= SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP1
);
2725 }while(((response
& 0x100U
) == 0U) && (count
!= 0U));
2727 /* Check the status after the switch command execution */
2728 if ((count
!= 0U) && (errorstate
== HAL_MMC_ERROR_NONE
))
2730 /* Check the bit SWITCH_ERROR of the device status */
2731 if ((response
& 0x80U
) != 0U)
2733 errorstate
= SDMMC_ERROR_GENERAL_UNKNOWN_ERR
;
2736 else if (count
== 0U)
2738 errorstate
= SDMMC_ERROR_TIMEOUT
;
2748 errorstate
= SDMMC_ERROR_UNSUPPORTED_FEATURE
;
2752 hmmc
->State
= HAL_MMC_STATE_READY
;
2756 errorstate
= SDMMC_ERROR_GENERAL_UNKNOWN_ERR
;
2760 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2762 /* Clear all the static flags */
2763 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
2764 hmmc
->ErrorCode
|= errorstate
;
2779 * @brief Gets the supported values of the the Secure Removal Type (SRT).
2780 * @param hmmc pointer to MMC handle
2781 * @param SupportedSRT pointer for supported SRT value
2782 * This parameter is a bit field of the following values:
2783 * @arg HAL_MMC_SRT_ERASE Information removed by an erase
2784 * @arg HAL_MMC_SRT_WRITE_CHAR_ERASE Information removed by an overwriting with a character followed by an erase
2785 * @arg HAL_MMC_SRT_WRITE_CHAR_COMPL_RANDOM Information removed by an overwriting with a character, its complement then a random character
2786 * @arg HAL_MMC_SRT_VENDOR_DEFINED Information removed using a vendor defined
2787 * @retval HAL status
2789 HAL_StatusTypeDef
HAL_MMC_GetSupportedSecRemovalType(MMC_HandleTypeDef
*hmmc
, uint32_t *SupportedSRT
)
2792 uint32_t errorstate
= SDMMC_ERROR_NONE
;
2794 /* Check the state of the driver */
2795 if(hmmc
->State
== HAL_MMC_STATE_READY
)
2798 hmmc
->State
= HAL_MMC_STATE_BUSY
;
2800 /* Read the Extended CSD register and get expected value */
2801 if(MMC_ReadExtCSD(hmmc
, &srt
, 16, 0x0FFFFFFFU
) == HAL_OK
) /* Field SECURE_REMOVAL_TYPE [16] */
2803 *SupportedSRT
= (srt
& 0x0000000FU
); /* Bits [3:0] of field 16 */
2807 errorstate
= SDMMC_ERROR_GENERAL_UNKNOWN_ERR
;
2811 hmmc
->State
= HAL_MMC_STATE_READY
;
2814 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2816 /* Clear all the static flags */
2817 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
2818 hmmc
->ErrorCode
|= errorstate
;
2840 /* Private function ----------------------------------------------------------*/
2841 /** @addtogroup MMC_Private_Functions
2847 * @brief Initializes the mmc card.
2848 * @param hmmc: Pointer to MMC handle
2849 * @retval MMC Card error state
2851 static uint32_t MMC_InitCard(MMC_HandleTypeDef
*hmmc
)
2853 HAL_MMC_CardCSDTypeDef CSD
;
2854 uint32_t errorstate
;
2855 uint16_t mmc_rca
= 1U;
2856 MMC_InitTypeDef Init
;
2858 /* Check the power State */
2859 if(SDMMC_GetPowerState(hmmc
->Instance
) == 0U)
2862 return HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE
;
2865 /* Send CMD2 ALL_SEND_CID */
2866 errorstate
= SDMMC_CmdSendCID(hmmc
->Instance
);
2867 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2873 /* Get Card identification number data */
2874 hmmc
->CID
[0U] = SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP1
);
2875 hmmc
->CID
[1U] = SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP2
);
2876 hmmc
->CID
[2U] = SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP3
);
2877 hmmc
->CID
[3U] = SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP4
);
2880 /* Send CMD3 SET_REL_ADDR with argument 0 */
2881 /* MMC Card publishes its RCA. */
2882 errorstate
= SDMMC_CmdSetRelAdd(hmmc
->Instance
, &mmc_rca
);
2883 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2888 /* Get the MMC card RCA */
2889 hmmc
->MmcCard
.RelCardAdd
= mmc_rca
;
2891 /* Send CMD9 SEND_CSD with argument as card's RCA */
2892 errorstate
= SDMMC_CmdSendCSD(hmmc
->Instance
, (uint32_t)(hmmc
->MmcCard
.RelCardAdd
<< 16U));
2893 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2899 /* Get Card Specific Data */
2900 hmmc
->CSD
[0U] = SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP1
);
2901 hmmc
->CSD
[1U] = SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP2
);
2902 hmmc
->CSD
[2U] = SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP3
);
2903 hmmc
->CSD
[3U] = SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP4
);
2906 /* Get the Card Class */
2907 hmmc
->MmcCard
.Class
= (SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP2
) >> 20U);
2909 /* Select the Card */
2910 errorstate
= SDMMC_CmdSelDesel(hmmc
->Instance
, (uint32_t)(((uint32_t)hmmc
->MmcCard
.RelCardAdd
) << 16U));
2911 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2916 /* Get CSD parameters */
2917 if (HAL_MMC_GetCardCSD(hmmc
, &CSD
) != HAL_OK
)
2919 return hmmc
->ErrorCode
;
2922 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2923 errorstate
= SDMMC_CmdSendStatus(hmmc
->Instance
, (uint32_t)(((uint32_t)hmmc
->MmcCard
.RelCardAdd
) << 16U));
2924 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2926 hmmc
->ErrorCode
|= errorstate
;
2929 /* Configure the SDMMC peripheral */
2930 Init
.ClockEdge
= hmmc
->Init
.ClockEdge
;
2931 Init
.ClockPowerSave
= hmmc
->Init
.ClockPowerSave
;
2932 Init
.BusWide
= SDMMC_BUS_WIDE_1B
;
2933 Init
.HardwareFlowControl
= hmmc
->Init
.HardwareFlowControl
;
2934 Init
.ClockDiv
= hmmc
->Init
.ClockDiv
;
2935 (void)SDMMC_Init(hmmc
->Instance
, Init
);
2937 /* All cards are initialized */
2938 return HAL_MMC_ERROR_NONE
;
2942 * @brief Enquires cards about their operating voltage and configures clock
2943 * controls and stores MMC information that will be needed in future
2944 * in the MMC handle.
2945 * @param hmmc: Pointer to MMC handle
2946 * @retval error state
2948 static uint32_t MMC_PowerON(MMC_HandleTypeDef
*hmmc
)
2950 __IO
uint32_t count
= 0U;
2951 uint32_t response
= 0U, validvoltage
= 0U;
2952 uint32_t errorstate
;
2954 /* CMD0: GO_IDLE_STATE */
2955 errorstate
= SDMMC_CmdGoIdleState(hmmc
->Instance
);
2956 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2961 while(validvoltage
== 0U)
2963 if(count
++ == SDMMC_MAX_VOLT_TRIAL
)
2965 return HAL_MMC_ERROR_INVALID_VOLTRANGE
;
2968 /* SEND CMD1 APP_CMD with MMC_HIGH_VOLTAGE_RANGE(0xC0FF8000) as argument */
2969 errorstate
= SDMMC_CmdOpCondition(hmmc
->Instance
, eMMC_HIGH_VOLTAGE_RANGE
);
2970 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2972 return HAL_MMC_ERROR_UNSUPPORTED_FEATURE
;
2975 /* Get command response */
2976 response
= SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP1
);
2978 /* Get operating voltage*/
2979 validvoltage
= (((response
>> 31U) == 1U) ? 1U : 0U);
2982 /* When power routine is finished and command returns valid voltage */
2983 if (((response
& (0xFF000000U
)) >> 24) == 0xC0U
)
2985 hmmc
->MmcCard
.CardType
= MMC_HIGH_CAPACITY_CARD
;
2989 hmmc
->MmcCard
.CardType
= MMC_LOW_CAPACITY_CARD
;
2992 return HAL_MMC_ERROR_NONE
;
2996 * @brief Turns the SDMMC output signals off.
2997 * @param hmmc: Pointer to MMC handle
3000 static void MMC_PowerOFF(MMC_HandleTypeDef
*hmmc
)
3002 /* Set Power State to OFF */
3003 (void)SDMMC_PowerState_OFF(hmmc
->Instance
);
3007 * @brief Returns the current card's status.
3008 * @param hmmc: Pointer to MMC handle
3009 * @param pCardStatus: pointer to the buffer that will contain the MMC card
3010 * status (Card Status register)
3011 * @retval error state
3013 static uint32_t MMC_SendStatus(MMC_HandleTypeDef
*hmmc
, uint32_t *pCardStatus
)
3015 uint32_t errorstate
;
3017 if(pCardStatus
== NULL
)
3019 return HAL_MMC_ERROR_PARAM
;
3022 /* Send Status command */
3023 errorstate
= SDMMC_CmdSendStatus(hmmc
->Instance
, (uint32_t)(hmmc
->MmcCard
.RelCardAdd
<< 16U));
3024 if(errorstate
!= HAL_MMC_ERROR_NONE
)
3029 /* Get MMC card status */
3030 *pCardStatus
= SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP1
);
3032 return HAL_MMC_ERROR_NONE
;
3036 * @brief Reads extended CSD register to get the sectors number of the device
3037 * @param hmmc: Pointer to MMC handle
3038 * @param pFieldData: Pointer to the read buffer
3039 * @param FieldIndex: Index of the field to be read
3040 * @param Timeout: Specify timeout value
3041 * @retval HAL status
3043 HAL_StatusTypeDef
MMC_ReadExtCSD(MMC_HandleTypeDef
*hmmc
, uint32_t *pFieldData
, uint16_t FieldIndex
, uint32_t Timeout
)
3045 SDMMC_DataInitTypeDef config
;
3046 uint32_t errorstate
;
3047 uint32_t tickstart
= HAL_GetTick();
3052 hmmc
->ErrorCode
= HAL_MMC_ERROR_NONE
;
3054 /* Initialize data control register */
3055 hmmc
->Instance
->DCTRL
= 0;
3057 /* Configure the MMC DPSM (Data Path State Machine) */
3058 config
.DataTimeOut
= SDMMC_DATATIMEOUT
;
3059 config
.DataLength
= 512;
3060 config
.DataBlockSize
= SDMMC_DATABLOCK_SIZE_512B
;
3061 config
.TransferDir
= SDMMC_TRANSFER_DIR_TO_SDMMC
;
3062 config
.TransferMode
= SDMMC_TRANSFER_MODE_BLOCK
;
3063 config
.DPSM
= SDMMC_DPSM_ENABLE
;
3064 (void)SDMMC_ConfigData(hmmc
->Instance
, &config
);
3066 /* Set Block Size for Card */
3067 errorstate
= SDMMC_CmdSendEXTCSD(hmmc
->Instance
, 0);
3068 if(errorstate
!= HAL_MMC_ERROR_NONE
)
3070 /* Clear all the static flags */
3071 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
3072 hmmc
->ErrorCode
|= errorstate
;
3073 hmmc
->State
= HAL_MMC_STATE_READY
;
3077 /* Poll on SDMMC flags */
3078 while(!__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_RXOVERR
| SDMMC_FLAG_DCRCFAIL
| SDMMC_FLAG_DTIMEOUT
| SDMMC_FLAG_DATAEND
))
3080 if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_RXFIFOHF
))
3082 /* Read data from SDMMC Rx FIFO */
3083 for(count
= 0U; count
< 8U; count
++)
3085 tmp_data
= SDMMC_ReadFIFO(hmmc
->Instance
);
3086 /* eg : SEC_COUNT : FieldIndex = 212 => i+count = 53 */
3087 /* DEVICE_TYPE : FieldIndex = 196 => i+count = 49 */
3088 if ((i
+ count
) == ((uint32_t)FieldIndex
/4U))
3090 *pFieldData
= tmp_data
;
3096 if(((HAL_GetTick()-tickstart
) >= Timeout
) || (Timeout
== 0U))
3098 /* Clear all the static flags */
3099 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
3100 hmmc
->ErrorCode
|= HAL_MMC_ERROR_TIMEOUT
;
3101 hmmc
->State
= HAL_MMC_STATE_READY
;
3106 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3107 errorstate
= SDMMC_CmdSendStatus(hmmc
->Instance
, (uint32_t)(((uint32_t)hmmc
->MmcCard
.RelCardAdd
) << 16));
3108 if(errorstate
!= HAL_MMC_ERROR_NONE
)
3110 hmmc
->ErrorCode
|= errorstate
;
3113 /* Clear all the static flags */
3114 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_DATA_FLAGS
);
3116 hmmc
->State
= HAL_MMC_STATE_READY
;
3122 * @brief Wrap up reading in non-blocking mode.
3123 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
3124 * the configuration information.
3127 static void MMC_Read_IT(MMC_HandleTypeDef
*hmmc
)
3129 uint32_t count
, data
;
3132 tmp
= hmmc
->pRxBuffPtr
;
3134 if (hmmc
->RxXferSize
>= 32U)
3136 /* Read data from SDMMC Rx FIFO */
3137 for(count
= 0U; count
< 8U; count
++)
3139 data
= SDMMC_ReadFIFO(hmmc
->Instance
);
3140 *tmp
= (uint8_t)(data
& 0xFFU
);
3142 *tmp
= (uint8_t)((data
>> 8U) & 0xFFU
);
3144 *tmp
= (uint8_t)((data
>> 16U) & 0xFFU
);
3146 *tmp
= (uint8_t)((data
>> 24U) & 0xFFU
);
3150 hmmc
->pRxBuffPtr
= tmp
;
3151 hmmc
->RxXferSize
-= 32U;
3156 * @brief Wrap up writing in non-blocking mode.
3157 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
3158 * the configuration information.
3161 static void MMC_Write_IT(MMC_HandleTypeDef
*hmmc
)
3163 uint32_t count
, data
;
3166 tmp
= hmmc
->pTxBuffPtr
;
3168 if (hmmc
->TxXferSize
>= 32U)
3170 /* Write data to SDMMC Tx FIFO */
3171 for(count
= 0U; count
< 8U; count
++)
3173 data
= (uint32_t)(*tmp
);
3175 data
|= ((uint32_t)(*tmp
) << 8U);
3177 data
|= ((uint32_t)(*tmp
) << 16U);
3179 data
|= ((uint32_t)(*tmp
) << 24U);
3181 (void)SDMMC_WriteFIFO(hmmc
->Instance
, &data
);
3184 hmmc
->pTxBuffPtr
= tmp
;
3185 hmmc
->TxXferSize
-= 32U;
3190 * @brief Switches the MMC card to high speed mode.
3191 * @param hmmc: MMC handle
3192 * @param state: State of high speed mode
3193 * @retval MMC Card error state
3195 static uint32_t MMC_HighSpeed(MMC_HandleTypeDef
*hmmc
, FunctionalState state
)
3197 uint32_t errorstate
= HAL_MMC_ERROR_NONE
;
3198 uint32_t response
= 0U, count
;
3199 SDMMC_InitTypeDef Init
;
3201 if (((hmmc
->Instance
->CLKCR
& SDMMC_CLKCR_BUSSPEED
) != 0U) && (state
== DISABLE
))
3203 /* Index : 185 - Value : 0 */
3204 errorstate
= SDMMC_CmdSwitch(hmmc
->Instance
, 0x03B90000U
);
3207 if (((hmmc
->Instance
->CLKCR
& SDMMC_CLKCR_BUSSPEED
) == 0U) && (state
!= DISABLE
))
3209 /* Index : 185 - Value : 1 */
3210 errorstate
= SDMMC_CmdSwitch(hmmc
->Instance
, 0x03B90100U
);
3213 if(errorstate
== HAL_MMC_ERROR_NONE
)
3215 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3216 count
= SDMMC_MAX_TRIAL
;
3219 errorstate
= SDMMC_CmdSendStatus(hmmc
->Instance
, (uint32_t)(((uint32_t)hmmc
->MmcCard
.RelCardAdd
) << 16U));
3220 if(errorstate
!= HAL_MMC_ERROR_NONE
)
3225 /* Get command response */
3226 response
= SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP1
);
3228 }while(((response
& 0x100U
) == 0U) && (count
!= 0U));
3230 /* Check the status after the switch command execution */
3231 if ((count
!= 0U) && (errorstate
== HAL_MMC_ERROR_NONE
))
3233 /* Check the bit SWITCH_ERROR of the device status */
3234 if ((response
& 0x80U
) != 0U)
3236 errorstate
= SDMMC_ERROR_UNSUPPORTED_FEATURE
;
3240 /* Configure high speed */
3241 Init
.ClockEdge
= hmmc
->Init
.ClockEdge
;
3242 Init
.ClockPowerSave
= hmmc
->Init
.ClockPowerSave
;
3243 Init
.BusWide
= (hmmc
->Instance
->CLKCR
& SDMMC_CLKCR_WIDBUS
);
3244 Init
.HardwareFlowControl
= hmmc
->Init
.HardwareFlowControl
;
3246 if (state
== DISABLE
)
3248 Init
.ClockDiv
= hmmc
->Init
.ClockDiv
;
3249 (void)SDMMC_Init(hmmc
->Instance
, Init
);
3251 CLEAR_BIT(hmmc
->Instance
->CLKCR
, SDMMC_CLKCR_BUSSPEED
);
3255 Init
.ClockDiv
= SDMMC_HSpeed_CLK_DIV
;
3256 (void)SDMMC_Init(hmmc
->Instance
, Init
);
3258 SET_BIT(hmmc
->Instance
->CLKCR
, SDMMC_CLKCR_BUSSPEED
);
3262 else if (count
== 0U)
3264 errorstate
= SDMMC_ERROR_TIMEOUT
;
3276 * @brief Switches the MMC card to Double Data Rate (DDR) mode.
3277 * @param hmmc: MMC handle
3278 * @param state: State of DDR mode
3279 * @retval MMC Card error state
3281 static uint32_t MMC_DDR_Mode(MMC_HandleTypeDef
*hmmc
, FunctionalState state
)
3283 uint32_t errorstate
= HAL_MMC_ERROR_NONE
;
3284 uint32_t response
= 0U, count
;
3286 if (((hmmc
->Instance
->CLKCR
& SDMMC_CLKCR_DDR
) != 0U) && (state
== DISABLE
))
3288 if ((hmmc
->Instance
->CLKCR
& SDMMC_CLKCR_WIDBUS_0
) != 0U)
3290 /* Index : 183 - Value : 1 */
3291 errorstate
= SDMMC_CmdSwitch(hmmc
->Instance
, 0x03B70100U
);
3295 /* Index : 183 - Value : 2 */
3296 errorstate
= SDMMC_CmdSwitch(hmmc
->Instance
, 0x03B70200U
);
3300 if (((hmmc
->Instance
->CLKCR
& SDMMC_CLKCR_DDR
) == 0U) && (state
!= DISABLE
))
3302 if ((hmmc
->Instance
->CLKCR
& SDMMC_CLKCR_WIDBUS_0
) != 0U)
3304 /* Index : 183 - Value : 5 */
3305 errorstate
= SDMMC_CmdSwitch(hmmc
->Instance
, 0x03B70500U
);
3309 /* Index : 183 - Value : 6 */
3310 errorstate
= SDMMC_CmdSwitch(hmmc
->Instance
, 0x03B70600U
);
3314 if(errorstate
== HAL_MMC_ERROR_NONE
)
3316 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3317 count
= SDMMC_MAX_TRIAL
;
3320 errorstate
= SDMMC_CmdSendStatus(hmmc
->Instance
, (uint32_t)(((uint32_t)hmmc
->MmcCard
.RelCardAdd
) << 16U));
3321 if(errorstate
!= HAL_MMC_ERROR_NONE
)
3326 /* Get command response */
3327 response
= SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP1
);
3329 }while(((response
& 0x100U
) == 0U) && (count
!= 0U));
3331 /* Check the status after the switch command execution */
3332 if ((count
!= 0U) && (errorstate
== HAL_MMC_ERROR_NONE
))
3334 /* Check the bit SWITCH_ERROR of the device status */
3335 if ((response
& 0x80U
) != 0U)
3337 errorstate
= SDMMC_ERROR_UNSUPPORTED_FEATURE
;
3341 /* Configure DDR mode */
3342 if (state
== DISABLE
)
3344 CLEAR_BIT(hmmc
->Instance
->CLKCR
, SDMMC_CLKCR_DDR
);
3348 SET_BIT(hmmc
->Instance
->CLKCR
, SDMMC_CLKCR_DDR
);
3352 else if (count
== 0U)
3354 errorstate
= SDMMC_ERROR_TIMEOUT
;
3366 * @brief Read DMA Buffer 0 Transfer completed callbacks
3367 * @param hmmc: MMC handle
3370 __weak
void HAL_MMCEx_Read_DMADoubleBuf0CpltCallback(MMC_HandleTypeDef
*hmmc
)
3372 /* Prevent unused argument(s) compilation warning */
3375 /* NOTE : This function should not be modified, when the callback is needed,
3376 the HAL_MMCEx_Read_DMADoubleBuf0CpltCallback can be implemented in the user file
3381 * @brief Read DMA Buffer 1 Transfer completed callbacks
3382 * @param hmmc: MMC handle
3385 __weak
void HAL_MMCEx_Read_DMADoubleBuf1CpltCallback(MMC_HandleTypeDef
*hmmc
)
3387 /* Prevent unused argument(s) compilation warning */
3390 /* NOTE : This function should not be modified, when the callback is needed,
3391 the HAL_MMCEx_Read_DMADoubleBuf1CpltCallback can be implemented in the user file
3396 * @brief Write DMA Buffer 0 Transfer completed callbacks
3397 * @param hmmc: MMC handle
3400 __weak
void HAL_MMCEx_Write_DMADoubleBuf0CpltCallback(MMC_HandleTypeDef
*hmmc
)
3402 /* Prevent unused argument(s) compilation warning */
3405 /* NOTE : This function should not be modified, when the callback is needed,
3406 the HAL_MMCEx_Write_DMADoubleBuf0CpltCallback can be implemented in the user file
3411 * @brief Write DMA Buffer 1 Transfer completed callbacks
3412 * @param hmmc: MMC handle
3415 __weak
void HAL_MMCEx_Write_DMADoubleBuf1CpltCallback(MMC_HandleTypeDef
*hmmc
)
3417 /* Prevent unused argument(s) compilation warning */
3420 /* NOTE : This function should not be modified, when the callback is needed,
3421 the HAL_MMCEx_Write_DMADoubleBuf1CpltCallback can be implemented in the user file
3429 #endif /* HAL_MMC_MODULE_ENABLED */
3439 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/