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
;
390 HAL_StatusTypeDef status
;
392 /* Default SDMMC peripheral configuration for MMC card initialization */
393 Init
.ClockEdge
= SDMMC_CLOCK_EDGE_RISING
;
394 Init
.ClockPowerSave
= SDMMC_CLOCK_POWER_SAVE_DISABLE
;
395 Init
.BusWide
= SDMMC_BUS_WIDE_1B
;
396 Init
.HardwareFlowControl
= SDMMC_HARDWARE_FLOW_CONTROL_DISABLE
;
397 Init
.ClockDiv
= SDMMC_INIT_CLK_DIV
;
399 /* Initialize SDMMC peripheral interface with default configuration */
400 status
= SDMMC_Init(hmmc
->Instance
, Init
);
401 if(status
== HAL_ERROR
)
406 /* Set Power State to ON */
407 status
= SDMMC_PowerState_ON(hmmc
->Instance
);
408 if(status
== HAL_ERROR
)
413 /* Identify card operating voltage */
414 errorstate
= MMC_PowerON(hmmc
);
415 if(errorstate
!= HAL_MMC_ERROR_NONE
)
417 hmmc
->State
= HAL_MMC_STATE_READY
;
418 hmmc
->ErrorCode
|= errorstate
;
422 /* Card initialization */
423 errorstate
= MMC_InitCard(hmmc
);
424 if(errorstate
!= HAL_MMC_ERROR_NONE
)
426 hmmc
->State
= HAL_MMC_STATE_READY
;
427 hmmc
->ErrorCode
|= errorstate
;
435 * @brief De-Initializes the MMC card.
436 * @param hmmc: Pointer to MMC handle
439 HAL_StatusTypeDef
HAL_MMC_DeInit(MMC_HandleTypeDef
*hmmc
)
441 /* Check the MMC handle allocation */
447 /* Check the parameters */
448 assert_param(IS_SDMMC_ALL_INSTANCE(hmmc
->Instance
));
450 hmmc
->State
= HAL_MMC_STATE_BUSY
;
452 /* Set MMC power state to off */
455 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
456 if(hmmc
->MspDeInitCallback
== NULL
)
458 hmmc
->MspDeInitCallback
= HAL_MMC_MspDeInit
;
461 /* DeInit the low level hardware */
462 hmmc
->MspDeInitCallback(hmmc
);
464 /* De-Initialize the MSP layer */
465 HAL_MMC_MspDeInit(hmmc
);
468 hmmc
->ErrorCode
= HAL_MMC_ERROR_NONE
;
469 hmmc
->State
= HAL_MMC_STATE_RESET
;
476 * @brief Initializes the MMC MSP.
477 * @param hmmc: Pointer to MMC handle
480 __weak
void HAL_MMC_MspInit(MMC_HandleTypeDef
*hmmc
)
482 /* Prevent unused argument(s) compilation warning */
485 /* NOTE : This function Should not be modified, when the callback is needed,
486 the HAL_MMC_MspInit could be implemented in the user file
491 * @brief De-Initialize MMC MSP.
492 * @param hmmc: Pointer to MMC handle
495 __weak
void HAL_MMC_MspDeInit(MMC_HandleTypeDef
*hmmc
)
497 /* Prevent unused argument(s) compilation warning */
500 /* NOTE : This function Should not be modified, when the callback is needed,
501 the HAL_MMC_MspDeInit could be implemented in the user file
509 /** @addtogroup MMC_Exported_Functions_Group2
510 * @brief Data transfer functions
513 ==============================================================================
514 ##### IO operation functions #####
515 ==============================================================================
517 This subsection provides a set of functions allowing to manage the data
518 transfer from/to MMC card.
525 * @brief Reads block(s) from a specified address in a card. The Data transfer
526 * is managed by polling mode.
527 * @note This API should be followed by a check on the card state through
528 * HAL_MMC_GetCardState().
529 * @param hmmc: Pointer to MMC handle
530 * @param pData: pointer to the buffer that will contain the received data
531 * @param BlockAdd: Block Address from where data is to be read
532 * @param NumberOfBlocks: Number of MMC blocks to read
533 * @param Timeout: Specify timeout value
536 HAL_StatusTypeDef
HAL_MMC_ReadBlocks(MMC_HandleTypeDef
*hmmc
, uint8_t *pData
, uint32_t BlockAdd
, uint32_t NumberOfBlocks
, uint32_t Timeout
)
538 SDMMC_DataInitTypeDef config
;
540 uint32_t tickstart
= HAL_GetTick();
541 uint32_t count
, data
, dataremaining
;
542 uint32_t add
= BlockAdd
;
543 uint8_t *tempbuff
= pData
;
547 hmmc
->ErrorCode
|= HAL_MMC_ERROR_PARAM
;
551 if(hmmc
->State
== HAL_MMC_STATE_READY
)
553 hmmc
->ErrorCode
= HAL_MMC_ERROR_NONE
;
555 if((BlockAdd
+ NumberOfBlocks
) > (hmmc
->MmcCard
.LogBlockNbr
))
557 hmmc
->ErrorCode
|= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE
;
561 hmmc
->State
= HAL_MMC_STATE_BUSY
;
563 /* Initialize data control register */
564 hmmc
->Instance
->DCTRL
= 0U;
566 if ((hmmc
->MmcCard
.CardType
) != MMC_HIGH_CAPACITY_CARD
)
571 if ((hmmc
->Instance
->CLKCR
& SDMMC_CLKCR_DDR
) == 0U)
573 /* Set Block Size for Card */
574 errorstate
= SDMMC_CmdBlockLength(hmmc
->Instance
, MMC_BLOCKSIZE
);
575 if(errorstate
!= HAL_MMC_ERROR_NONE
)
577 /* Clear all the static flags */
578 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
579 hmmc
->ErrorCode
|= errorstate
;
580 hmmc
->State
= HAL_MMC_STATE_READY
;
585 /* Configure the MMC DPSM (Data Path State Machine) */
586 config
.DataTimeOut
= SDMMC_DATATIMEOUT
;
587 config
.DataLength
= NumberOfBlocks
* MMC_BLOCKSIZE
;
588 config
.DataBlockSize
= SDMMC_DATABLOCK_SIZE_512B
;
589 config
.TransferDir
= SDMMC_TRANSFER_DIR_TO_SDMMC
;
590 config
.TransferMode
= SDMMC_TRANSFER_MODE_BLOCK
;
591 config
.DPSM
= SDMMC_DPSM_DISABLE
;
592 (void)SDMMC_ConfigData(hmmc
->Instance
, &config
);
593 __SDMMC_CMDTRANS_ENABLE( hmmc
->Instance
);
595 /* Read block(s) in polling mode */
596 if(NumberOfBlocks
> 1U)
598 hmmc
->Context
= MMC_CONTEXT_READ_MULTIPLE_BLOCK
;
600 /* Read Multi Block command */
601 errorstate
= SDMMC_CmdReadMultiBlock(hmmc
->Instance
, add
);
605 hmmc
->Context
= MMC_CONTEXT_READ_SINGLE_BLOCK
;
607 /* Read Single Block command */
608 errorstate
= SDMMC_CmdReadSingleBlock(hmmc
->Instance
, add
);
610 if(errorstate
!= HAL_MMC_ERROR_NONE
)
612 /* Clear all the static flags */
613 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
614 hmmc
->ErrorCode
|= errorstate
;
615 hmmc
->State
= HAL_MMC_STATE_READY
;
619 /* Poll on SDMMC flags */
620 dataremaining
= config
.DataLength
;
621 while(!__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_RXOVERR
| SDMMC_FLAG_DCRCFAIL
| SDMMC_FLAG_DTIMEOUT
| SDMMC_FLAG_DATAEND
))
623 if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_RXFIFOHF
) && (dataremaining
>= 32U))
625 /* Read data from SDMMC Rx FIFO */
626 for(count
= 0U; count
< 8U; count
++)
628 data
= SDMMC_ReadFIFO(hmmc
->Instance
);
629 *tempbuff
= (uint8_t)(data
& 0xFFU
);
631 *tempbuff
= (uint8_t)((data
>> 8U) & 0xFFU
);
633 *tempbuff
= (uint8_t)((data
>> 16U) & 0xFFU
);
635 *tempbuff
= (uint8_t)((data
>> 24U) & 0xFFU
);
638 dataremaining
-= 32U;
641 if(((HAL_GetTick()-tickstart
) >= Timeout
) || (Timeout
== 0U))
643 /* Clear all the static flags */
644 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
645 hmmc
->ErrorCode
|= HAL_MMC_ERROR_TIMEOUT
;
646 hmmc
->State
= HAL_MMC_STATE_READY
;
650 __SDMMC_CMDTRANS_DISABLE( hmmc
->Instance
);
652 /* Send stop transmission command in case of multiblock read */
653 if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_DATAEND
) && (NumberOfBlocks
> 1U))
655 /* Send stop transmission command */
656 errorstate
= SDMMC_CmdStopTransfer(hmmc
->Instance
);
657 if(errorstate
!= HAL_MMC_ERROR_NONE
)
659 /* Clear all the static flags */
660 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
661 hmmc
->ErrorCode
|= errorstate
;
662 hmmc
->State
= HAL_MMC_STATE_READY
;
667 /* Get error state */
668 if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_DTIMEOUT
))
670 /* Clear all the static flags */
671 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
672 hmmc
->ErrorCode
|= HAL_MMC_ERROR_DATA_TIMEOUT
;
673 hmmc
->State
= HAL_MMC_STATE_READY
;
676 else if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_DCRCFAIL
))
678 /* Clear all the static flags */
679 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
680 hmmc
->ErrorCode
|= HAL_MMC_ERROR_DATA_CRC_FAIL
;
681 hmmc
->State
= HAL_MMC_STATE_READY
;
684 else if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_RXOVERR
))
686 /* Clear all the static flags */
687 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
688 hmmc
->ErrorCode
|= HAL_MMC_ERROR_RX_OVERRUN
;
689 hmmc
->State
= HAL_MMC_STATE_READY
;
697 /* Clear all the static flags */
698 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_DATA_FLAGS
);
700 hmmc
->State
= HAL_MMC_STATE_READY
;
706 hmmc
->ErrorCode
|= HAL_MMC_ERROR_BUSY
;
712 * @brief Allows to write block(s) to a specified address in a card. The Data
713 * transfer is managed by polling mode.
714 * @note This API should be followed by a check on the card state through
715 * HAL_MMC_GetCardState().
716 * @param hmmc: Pointer to MMC handle
717 * @param pData: pointer to the buffer that will contain the data to transmit
718 * @param BlockAdd: Block Address where data will be written
719 * @param NumberOfBlocks: Number of MMC blocks to write
720 * @param Timeout: Specify timeout value
723 HAL_StatusTypeDef
HAL_MMC_WriteBlocks(MMC_HandleTypeDef
*hmmc
, uint8_t *pData
, uint32_t BlockAdd
, uint32_t NumberOfBlocks
, uint32_t Timeout
)
725 SDMMC_DataInitTypeDef config
;
727 uint32_t tickstart
= HAL_GetTick();
728 uint32_t count
, data
, dataremaining
;
729 uint32_t add
= BlockAdd
;
730 uint8_t *tempbuff
= pData
;
734 hmmc
->ErrorCode
|= HAL_MMC_ERROR_PARAM
;
738 if(hmmc
->State
== HAL_MMC_STATE_READY
)
740 hmmc
->ErrorCode
= HAL_MMC_ERROR_NONE
;
742 if((BlockAdd
+ NumberOfBlocks
) > (hmmc
->MmcCard
.LogBlockNbr
))
744 hmmc
->ErrorCode
|= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE
;
748 hmmc
->State
= HAL_MMC_STATE_BUSY
;
750 /* Initialize data control register */
751 hmmc
->Instance
->DCTRL
= 0U;
753 if ((hmmc
->MmcCard
.CardType
) != MMC_HIGH_CAPACITY_CARD
)
758 if ((hmmc
->Instance
->CLKCR
& SDMMC_CLKCR_DDR
) == 0U)
760 /* Set Block Size for Card */
761 errorstate
= SDMMC_CmdBlockLength(hmmc
->Instance
, MMC_BLOCKSIZE
);
762 if(errorstate
!= HAL_MMC_ERROR_NONE
)
764 /* Clear all the static flags */
765 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
766 hmmc
->ErrorCode
|= errorstate
;
767 hmmc
->State
= HAL_MMC_STATE_READY
;
772 /* Configure the MMC DPSM (Data Path State Machine) */
773 config
.DataTimeOut
= SDMMC_DATATIMEOUT
;
774 config
.DataLength
= NumberOfBlocks
* MMC_BLOCKSIZE
;
775 config
.DataBlockSize
= SDMMC_DATABLOCK_SIZE_512B
;
776 config
.TransferDir
= SDMMC_TRANSFER_DIR_TO_CARD
;
777 config
.TransferMode
= SDMMC_TRANSFER_MODE_BLOCK
;
778 config
.DPSM
= SDMMC_DPSM_DISABLE
;
779 (void)SDMMC_ConfigData(hmmc
->Instance
, &config
);
780 __SDMMC_CMDTRANS_ENABLE( hmmc
->Instance
);
782 /* Write Blocks in Polling mode */
783 if(NumberOfBlocks
> 1U)
785 hmmc
->Context
= MMC_CONTEXT_WRITE_MULTIPLE_BLOCK
;
787 /* Write Multi Block command */
788 errorstate
= SDMMC_CmdWriteMultiBlock(hmmc
->Instance
, add
);
792 hmmc
->Context
= MMC_CONTEXT_WRITE_SINGLE_BLOCK
;
794 /* Write Single Block command */
795 errorstate
= SDMMC_CmdWriteSingleBlock(hmmc
->Instance
, add
);
797 if(errorstate
!= HAL_MMC_ERROR_NONE
)
799 /* Clear all the static flags */
800 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
801 hmmc
->ErrorCode
|= errorstate
;
802 hmmc
->State
= HAL_MMC_STATE_READY
;
806 /* Write block(s) in polling mode */
807 dataremaining
= config
.DataLength
;
808 while(!__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_TXUNDERR
| SDMMC_FLAG_DCRCFAIL
| SDMMC_FLAG_DTIMEOUT
| SDMMC_FLAG_DATAEND
))
810 if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_TXFIFOHE
) && (dataremaining
>= 32U))
812 /* Write data to SDMMC Tx FIFO */
813 for(count
= 0U; count
< 8U; count
++)
815 data
= (uint32_t)(*tempbuff
);
817 data
|= ((uint32_t)(*tempbuff
) << 8U);
819 data
|= ((uint32_t)(*tempbuff
) << 16U);
821 data
|= ((uint32_t)(*tempbuff
) << 24U);
823 (void)SDMMC_WriteFIFO(hmmc
->Instance
, &data
);
825 dataremaining
-= 32U;
828 if(((HAL_GetTick()-tickstart
) >= Timeout
) || (Timeout
== 0U))
830 /* Clear all the static flags */
831 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
832 hmmc
->ErrorCode
|= errorstate
;
833 hmmc
->State
= HAL_MMC_STATE_READY
;
837 __SDMMC_CMDTRANS_DISABLE( hmmc
->Instance
);
839 /* Send stop transmission command in case of multiblock write */
840 if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_DATAEND
) && (NumberOfBlocks
> 1U))
842 /* Send stop transmission command */
843 errorstate
= SDMMC_CmdStopTransfer(hmmc
->Instance
);
844 if(errorstate
!= HAL_MMC_ERROR_NONE
)
846 /* Clear all the static flags */
847 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
848 hmmc
->ErrorCode
|= errorstate
;
849 hmmc
->State
= HAL_MMC_STATE_READY
;
854 /* Get error state */
855 if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_DTIMEOUT
))
857 /* Clear all the static flags */
858 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
859 hmmc
->ErrorCode
|= HAL_MMC_ERROR_DATA_TIMEOUT
;
860 hmmc
->State
= HAL_MMC_STATE_READY
;
863 else if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_DCRCFAIL
))
865 /* Clear all the static flags */
866 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
867 hmmc
->ErrorCode
|= HAL_MMC_ERROR_DATA_CRC_FAIL
;
868 hmmc
->State
= HAL_MMC_STATE_READY
;
871 else if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_TXUNDERR
))
873 /* Clear all the static flags */
874 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
875 hmmc
->ErrorCode
|= HAL_MMC_ERROR_TX_UNDERRUN
;
876 hmmc
->State
= HAL_MMC_STATE_READY
;
884 /* Clear all the static flags */
885 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_DATA_FLAGS
);
887 hmmc
->State
= HAL_MMC_STATE_READY
;
893 hmmc
->ErrorCode
|= HAL_MMC_ERROR_BUSY
;
899 * @brief Reads block(s) from a specified address in a card. The Data transfer
900 * is managed in interrupt mode.
901 * @note This API should be followed by a check on the card state through
902 * HAL_MMC_GetCardState().
903 * @note You could also check the IT transfer process through the MMC Rx
905 * @param hmmc: Pointer to MMC handle
906 * @param pData: Pointer to the buffer that will contain the received data
907 * @param BlockAdd: Block Address from where data is to be read
908 * @param NumberOfBlocks: Number of blocks to read.
911 HAL_StatusTypeDef
HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef
*hmmc
, uint8_t *pData
, uint32_t BlockAdd
, uint32_t NumberOfBlocks
)
913 SDMMC_DataInitTypeDef config
;
915 uint32_t add
= BlockAdd
;
919 hmmc
->ErrorCode
|= HAL_MMC_ERROR_PARAM
;
923 if(hmmc
->State
== HAL_MMC_STATE_READY
)
925 hmmc
->ErrorCode
= HAL_MMC_ERROR_NONE
;
927 if((BlockAdd
+ NumberOfBlocks
) > (hmmc
->MmcCard
.LogBlockNbr
))
929 hmmc
->ErrorCode
|= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE
;
933 hmmc
->State
= HAL_MMC_STATE_BUSY
;
935 /* Initialize data control register */
936 hmmc
->Instance
->DCTRL
= 0U;
938 hmmc
->pRxBuffPtr
= pData
;
939 hmmc
->RxXferSize
= MMC_BLOCKSIZE
* NumberOfBlocks
;
941 if ((hmmc
->MmcCard
.CardType
) != MMC_HIGH_CAPACITY_CARD
)
946 if ((hmmc
->Instance
->CLKCR
& SDMMC_CLKCR_DDR
) == 0U)
948 /* Set Block Size for Card */
949 errorstate
= SDMMC_CmdBlockLength(hmmc
->Instance
, MMC_BLOCKSIZE
);
950 if(errorstate
!= HAL_MMC_ERROR_NONE
)
952 /* Clear all the static flags */
953 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
954 hmmc
->ErrorCode
|= errorstate
;
955 hmmc
->State
= HAL_MMC_STATE_READY
;
960 /* Configure the MMC DPSM (Data Path State Machine) */
961 config
.DataTimeOut
= SDMMC_DATATIMEOUT
;
962 config
.DataLength
= MMC_BLOCKSIZE
* NumberOfBlocks
;
963 config
.DataBlockSize
= SDMMC_DATABLOCK_SIZE_512B
;
964 config
.TransferDir
= SDMMC_TRANSFER_DIR_TO_SDMMC
;
965 config
.TransferMode
= SDMMC_TRANSFER_MODE_BLOCK
;
966 config
.DPSM
= SDMMC_DPSM_DISABLE
;
967 (void)SDMMC_ConfigData(hmmc
->Instance
, &config
);
968 __SDMMC_CMDTRANS_ENABLE( hmmc
->Instance
);
970 /* Read Blocks in IT mode */
971 if(NumberOfBlocks
> 1U)
973 hmmc
->Context
= (MMC_CONTEXT_READ_MULTIPLE_BLOCK
| MMC_CONTEXT_IT
);
975 /* Read Multi Block command */
976 errorstate
= SDMMC_CmdReadMultiBlock(hmmc
->Instance
, add
);
980 hmmc
->Context
= (MMC_CONTEXT_READ_SINGLE_BLOCK
| MMC_CONTEXT_IT
);
982 /* Read Single Block command */
983 errorstate
= SDMMC_CmdReadSingleBlock(hmmc
->Instance
, add
);
986 if(errorstate
!= HAL_MMC_ERROR_NONE
)
988 /* Clear all the static flags */
989 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
990 hmmc
->ErrorCode
|= errorstate
;
991 hmmc
->State
= HAL_MMC_STATE_READY
;
995 __HAL_MMC_ENABLE_IT(hmmc
, (SDMMC_IT_DCRCFAIL
| SDMMC_IT_DTIMEOUT
| SDMMC_IT_RXOVERR
| SDMMC_IT_DATAEND
| SDMMC_FLAG_RXFIFOHF
));
1006 * @brief Writes block(s) to a specified address in a card. The Data transfer
1007 * is managed in interrupt mode.
1008 * @note This API should be followed by a check on the card state through
1009 * HAL_MMC_GetCardState().
1010 * @note You could also check the IT transfer process through the MMC Tx
1012 * @param hmmc: Pointer to MMC handle
1013 * @param pData: Pointer to the buffer that will contain the data to transmit
1014 * @param BlockAdd: Block Address where data will be written
1015 * @param NumberOfBlocks: Number of blocks to write
1016 * @retval HAL status
1018 HAL_StatusTypeDef
HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef
*hmmc
, uint8_t *pData
, uint32_t BlockAdd
, uint32_t NumberOfBlocks
)
1020 SDMMC_DataInitTypeDef config
;
1021 uint32_t errorstate
;
1022 uint32_t add
= BlockAdd
;
1026 hmmc
->ErrorCode
|= HAL_MMC_ERROR_PARAM
;
1030 if(hmmc
->State
== HAL_MMC_STATE_READY
)
1032 hmmc
->ErrorCode
= HAL_MMC_ERROR_NONE
;
1034 if((BlockAdd
+ NumberOfBlocks
) > (hmmc
->MmcCard
.LogBlockNbr
))
1036 hmmc
->ErrorCode
|= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE
;
1040 hmmc
->State
= HAL_MMC_STATE_BUSY
;
1042 /* Initialize data control register */
1043 hmmc
->Instance
->DCTRL
= 0U;
1045 hmmc
->pTxBuffPtr
= pData
;
1046 hmmc
->TxXferSize
= MMC_BLOCKSIZE
* NumberOfBlocks
;
1048 if ((hmmc
->MmcCard
.CardType
) != MMC_HIGH_CAPACITY_CARD
)
1053 if ((hmmc
->Instance
->CLKCR
& SDMMC_CLKCR_DDR
) == 0U)
1055 /* Set Block Size for Card */
1056 errorstate
= SDMMC_CmdBlockLength(hmmc
->Instance
, MMC_BLOCKSIZE
);
1057 if(errorstate
!= HAL_MMC_ERROR_NONE
)
1059 /* Clear all the static flags */
1060 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
1061 hmmc
->ErrorCode
|= errorstate
;
1062 hmmc
->State
= HAL_MMC_STATE_READY
;
1067 /* Configure the MMC DPSM (Data Path State Machine) */
1068 config
.DataTimeOut
= SDMMC_DATATIMEOUT
;
1069 config
.DataLength
= MMC_BLOCKSIZE
* NumberOfBlocks
;
1070 config
.DataBlockSize
= SDMMC_DATABLOCK_SIZE_512B
;
1071 config
.TransferDir
= SDMMC_TRANSFER_DIR_TO_CARD
;
1072 config
.TransferMode
= SDMMC_TRANSFER_MODE_BLOCK
;
1073 config
.DPSM
= SDMMC_DPSM_DISABLE
;
1074 (void)SDMMC_ConfigData(hmmc
->Instance
, &config
);
1076 __SDMMC_CMDTRANS_ENABLE( hmmc
->Instance
);
1078 /* Write Blocks in Polling mode */
1079 if(NumberOfBlocks
> 1U)
1081 hmmc
->Context
= (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK
| MMC_CONTEXT_IT
);
1083 /* Write Multi Block command */
1084 errorstate
= SDMMC_CmdWriteMultiBlock(hmmc
->Instance
, add
);
1088 hmmc
->Context
= (MMC_CONTEXT_WRITE_SINGLE_BLOCK
| MMC_CONTEXT_IT
);
1090 /* Write Single Block command */
1091 errorstate
= SDMMC_CmdWriteSingleBlock(hmmc
->Instance
, add
);
1093 if(errorstate
!= HAL_MMC_ERROR_NONE
)
1095 /* Clear all the static flags */
1096 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
1097 hmmc
->ErrorCode
|= errorstate
;
1098 hmmc
->State
= HAL_MMC_STATE_READY
;
1102 /* Enable transfer interrupts */
1103 __HAL_MMC_ENABLE_IT(hmmc
, (SDMMC_IT_DCRCFAIL
| SDMMC_IT_DTIMEOUT
| SDMMC_IT_TXUNDERR
| SDMMC_IT_DATAEND
| SDMMC_FLAG_TXFIFOHE
));
1114 * @brief Reads block(s) from a specified address in a card. The Data transfer
1115 * is managed by DMA mode.
1116 * @note This API should be followed by a check on the card state through
1117 * HAL_MMC_GetCardState().
1118 * @note You could also check the DMA transfer process through the MMC Rx
1120 * @param hmmc: Pointer MMC handle
1121 * @param pData: Pointer to the buffer that will contain the received data
1122 * @param BlockAdd: Block Address from where data is to be read
1123 * @param NumberOfBlocks: Number of blocks to read.
1124 * @retval HAL status
1126 HAL_StatusTypeDef
HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef
*hmmc
, uint8_t *pData
, uint32_t BlockAdd
, uint32_t NumberOfBlocks
)
1128 SDMMC_DataInitTypeDef config
;
1129 uint32_t errorstate
;
1130 uint32_t add
= BlockAdd
;
1134 hmmc
->ErrorCode
|= HAL_MMC_ERROR_PARAM
;
1138 if(hmmc
->State
== HAL_MMC_STATE_READY
)
1140 hmmc
->ErrorCode
= HAL_DMA_ERROR_NONE
;
1142 if((BlockAdd
+ NumberOfBlocks
) > (hmmc
->MmcCard
.LogBlockNbr
))
1144 hmmc
->ErrorCode
|= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE
;
1148 hmmc
->State
= HAL_MMC_STATE_BUSY
;
1150 /* Initialize data control register */
1151 hmmc
->Instance
->DCTRL
= 0U;
1153 hmmc
->pRxBuffPtr
= pData
;
1154 hmmc
->RxXferSize
= MMC_BLOCKSIZE
* NumberOfBlocks
;
1156 if ((hmmc
->MmcCard
.CardType
) != MMC_HIGH_CAPACITY_CARD
)
1161 if ((hmmc
->Instance
->CLKCR
& SDMMC_CLKCR_DDR
) == 0U)
1163 /* Set Block Size for Card */
1164 errorstate
= SDMMC_CmdBlockLength(hmmc
->Instance
, MMC_BLOCKSIZE
);
1165 if(errorstate
!= HAL_MMC_ERROR_NONE
)
1167 /* Clear all the static flags */
1168 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
1169 hmmc
->ErrorCode
= errorstate
;
1170 hmmc
->State
= HAL_MMC_STATE_READY
;
1175 /* Configure the MMC DPSM (Data Path State Machine) */
1176 config
.DataTimeOut
= SDMMC_DATATIMEOUT
;
1177 config
.DataLength
= MMC_BLOCKSIZE
* NumberOfBlocks
;
1178 config
.DataBlockSize
= SDMMC_DATABLOCK_SIZE_512B
;
1179 config
.TransferDir
= SDMMC_TRANSFER_DIR_TO_SDMMC
;
1180 config
.TransferMode
= SDMMC_TRANSFER_MODE_BLOCK
;
1181 config
.DPSM
= SDMMC_DPSM_DISABLE
;
1182 (void)SDMMC_ConfigData(hmmc
->Instance
, &config
);
1184 __SDMMC_CMDTRANS_ENABLE( hmmc
->Instance
);
1185 hmmc
->Instance
->IDMABASE0
= (uint32_t) pData
;
1186 hmmc
->Instance
->IDMACTRL
= SDMMC_ENABLE_IDMA_SINGLE_BUFF
;
1188 /* Read Blocks in DMA mode */
1189 if(NumberOfBlocks
> 1U)
1191 hmmc
->Context
= (MMC_CONTEXT_READ_MULTIPLE_BLOCK
| MMC_CONTEXT_DMA
);
1193 /* Read Multi Block command */
1194 errorstate
= SDMMC_CmdReadMultiBlock(hmmc
->Instance
, add
);
1198 hmmc
->Context
= (MMC_CONTEXT_READ_SINGLE_BLOCK
| MMC_CONTEXT_DMA
);
1200 /* Read Single Block command */
1201 errorstate
= SDMMC_CmdReadSingleBlock(hmmc
->Instance
, add
);
1203 if(errorstate
!= HAL_MMC_ERROR_NONE
)
1205 /* Clear all the static flags */
1206 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
1207 hmmc
->ErrorCode
= errorstate
;
1208 hmmc
->State
= HAL_MMC_STATE_READY
;
1212 /* Enable transfer interrupts */
1213 __HAL_MMC_ENABLE_IT(hmmc
, (SDMMC_IT_DCRCFAIL
| SDMMC_IT_DTIMEOUT
| SDMMC_IT_RXOVERR
| SDMMC_IT_DATAEND
));
1224 * @brief Writes block(s) to a specified address in a card. The Data transfer
1225 * is managed by DMA mode.
1226 * @note This API should be followed by a check on the card state through
1227 * HAL_MMC_GetCardState().
1228 * @note You could also check the DMA transfer process through the MMC Tx
1230 * @param hmmc: Pointer to MMC handle
1231 * @param pData: Pointer to the buffer that will contain the data to transmit
1232 * @param BlockAdd: Block Address where data will be written
1233 * @param NumberOfBlocks: Number of blocks to write
1234 * @retval HAL status
1236 HAL_StatusTypeDef
HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef
*hmmc
, uint8_t *pData
, uint32_t BlockAdd
, uint32_t NumberOfBlocks
)
1238 SDMMC_DataInitTypeDef config
;
1239 uint32_t errorstate
;
1240 uint32_t add
= BlockAdd
;
1244 hmmc
->ErrorCode
|= HAL_MMC_ERROR_PARAM
;
1248 if(hmmc
->State
== HAL_MMC_STATE_READY
)
1250 hmmc
->ErrorCode
= HAL_MMC_ERROR_NONE
;
1252 if((BlockAdd
+ NumberOfBlocks
) > (hmmc
->MmcCard
.LogBlockNbr
))
1254 hmmc
->ErrorCode
|= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE
;
1258 hmmc
->State
= HAL_MMC_STATE_BUSY
;
1260 /* Initialize data control register */
1261 hmmc
->Instance
->DCTRL
= 0U;
1263 hmmc
->pTxBuffPtr
= pData
;
1264 hmmc
->TxXferSize
= MMC_BLOCKSIZE
* NumberOfBlocks
;
1266 if ((hmmc
->MmcCard
.CardType
) != MMC_HIGH_CAPACITY_CARD
)
1271 if ((hmmc
->Instance
->CLKCR
& SDMMC_CLKCR_DDR
) == 0U)
1273 /* Set Block Size for Card */
1274 errorstate
= SDMMC_CmdBlockLength(hmmc
->Instance
, MMC_BLOCKSIZE
);
1275 if(errorstate
!= HAL_MMC_ERROR_NONE
)
1277 /* Clear all the static flags */
1278 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
1279 hmmc
->ErrorCode
|= errorstate
;
1280 hmmc
->State
= HAL_MMC_STATE_READY
;
1285 /* Configure the MMC DPSM (Data Path State Machine) */
1286 config
.DataTimeOut
= SDMMC_DATATIMEOUT
;
1287 config
.DataLength
= MMC_BLOCKSIZE
* NumberOfBlocks
;
1288 config
.DataBlockSize
= SDMMC_DATABLOCK_SIZE_512B
;
1289 config
.TransferDir
= SDMMC_TRANSFER_DIR_TO_CARD
;
1290 config
.TransferMode
= SDMMC_TRANSFER_MODE_BLOCK
;
1291 config
.DPSM
= SDMMC_DPSM_DISABLE
;
1292 (void)SDMMC_ConfigData(hmmc
->Instance
, &config
);
1294 __SDMMC_CMDTRANS_ENABLE( hmmc
->Instance
);
1296 hmmc
->Instance
->IDMABASE0
= (uint32_t) pData
;
1297 hmmc
->Instance
->IDMACTRL
= SDMMC_ENABLE_IDMA_SINGLE_BUFF
;
1299 /* Write Blocks in Polling mode */
1300 if(NumberOfBlocks
> 1U)
1302 hmmc
->Context
= (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK
| MMC_CONTEXT_DMA
);
1304 /* Write Multi Block command */
1305 errorstate
= SDMMC_CmdWriteMultiBlock(hmmc
->Instance
, add
);
1309 hmmc
->Context
= (MMC_CONTEXT_WRITE_SINGLE_BLOCK
| MMC_CONTEXT_DMA
);
1311 /* Write Single Block command */
1312 errorstate
= SDMMC_CmdWriteSingleBlock(hmmc
->Instance
, add
);
1314 if(errorstate
!= HAL_MMC_ERROR_NONE
)
1316 /* Clear all the static flags */
1317 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
1318 hmmc
->ErrorCode
|= errorstate
;
1319 hmmc
->State
= HAL_MMC_STATE_READY
;
1323 /* Enable transfer interrupts */
1324 __HAL_MMC_ENABLE_IT(hmmc
, (SDMMC_IT_DCRCFAIL
| SDMMC_IT_DTIMEOUT
| SDMMC_IT_TXUNDERR
| SDMMC_IT_DATAEND
));
1335 * @brief Erases the specified memory area of the given MMC card.
1336 * @note This API should be followed by a check on the card state through
1337 * HAL_MMC_GetCardState().
1338 * @param hmmc: Pointer to MMC handle
1339 * @param BlockStartAdd: Start Block address
1340 * @param BlockEndAdd: End Block address
1341 * @retval HAL status
1343 HAL_StatusTypeDef
HAL_MMC_Erase(MMC_HandleTypeDef
*hmmc
, uint32_t BlockStartAdd
, uint32_t BlockEndAdd
)
1345 uint32_t errorstate
;
1346 uint32_t start_add
= BlockStartAdd
;
1347 uint32_t end_add
= BlockEndAdd
;
1349 if(hmmc
->State
== HAL_MMC_STATE_READY
)
1351 hmmc
->ErrorCode
= HAL_MMC_ERROR_NONE
;
1353 if(end_add
< start_add
)
1355 hmmc
->ErrorCode
|= HAL_MMC_ERROR_PARAM
;
1359 if(end_add
> (hmmc
->MmcCard
.LogBlockNbr
))
1361 hmmc
->ErrorCode
|= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE
;
1365 hmmc
->State
= HAL_MMC_STATE_BUSY
;
1367 /* Check if the card command class supports erase command */
1368 if(((hmmc
->MmcCard
.Class
) & SDMMC_CCCC_ERASE
) == 0U)
1370 /* Clear all the static flags */
1371 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
1372 hmmc
->ErrorCode
|= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE
;
1373 hmmc
->State
= HAL_MMC_STATE_READY
;
1377 if((SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP1
) & SDMMC_CARD_LOCKED
) == SDMMC_CARD_LOCKED
)
1379 /* Clear all the static flags */
1380 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
1381 hmmc
->ErrorCode
|= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED
;
1382 hmmc
->State
= HAL_MMC_STATE_READY
;
1386 if ((hmmc
->MmcCard
.CardType
) != MMC_HIGH_CAPACITY_CARD
)
1392 /* Send CMD35 MMC_ERASE_GRP_START with argument as addr */
1393 errorstate
= SDMMC_CmdEraseStartAdd(hmmc
->Instance
, start_add
);
1394 if(errorstate
!= HAL_MMC_ERROR_NONE
)
1396 /* Clear all the static flags */
1397 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
1398 hmmc
->ErrorCode
|= errorstate
;
1399 hmmc
->State
= HAL_MMC_STATE_READY
;
1403 /* Send CMD36 MMC_ERASE_GRP_END with argument as addr */
1404 errorstate
= SDMMC_CmdEraseEndAdd(hmmc
->Instance
, end_add
);
1405 if(errorstate
!= HAL_MMC_ERROR_NONE
)
1407 /* Clear all the static flags */
1408 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
1409 hmmc
->ErrorCode
|= errorstate
;
1410 hmmc
->State
= HAL_MMC_STATE_READY
;
1414 /* Send CMD38 ERASE */
1415 errorstate
= SDMMC_CmdErase(hmmc
->Instance
);
1416 if(errorstate
!= HAL_MMC_ERROR_NONE
)
1418 /* Clear all the static flags */
1419 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
1420 hmmc
->ErrorCode
|= errorstate
;
1421 hmmc
->State
= HAL_MMC_STATE_READY
;
1425 hmmc
->State
= HAL_MMC_STATE_READY
;
1436 * @brief This function handles MMC card interrupt request.
1437 * @param hmmc: Pointer to MMC handle
1440 void HAL_MMC_IRQHandler(MMC_HandleTypeDef
*hmmc
)
1442 uint32_t errorstate
;
1443 uint32_t context
= hmmc
->Context
;
1445 /* Check for SDMMC interrupt flags */
1446 if((__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_RXFIFOHF
) != RESET
) && ((context
& MMC_CONTEXT_IT
) != 0U))
1451 else if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_DATAEND
) != RESET
)
1453 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_FLAG_DATAEND
);
1455 __HAL_MMC_DISABLE_IT(hmmc
, SDMMC_IT_DATAEND
| SDMMC_IT_DCRCFAIL
| SDMMC_IT_DTIMEOUT
|\
1456 SDMMC_IT_TXUNDERR
| SDMMC_IT_RXOVERR
| SDMMC_IT_TXFIFOHE
|\
1459 __HAL_MMC_DISABLE_IT(hmmc
, SDMMC_IT_IDMABTC
);
1460 __SDMMC_CMDTRANS_DISABLE( hmmc
->Instance
);
1462 if((context
& MMC_CONTEXT_DMA
) != 0U)
1464 hmmc
->Instance
->DLEN
= 0;
1465 hmmc
->Instance
->DCTRL
= 0;
1466 hmmc
->Instance
->IDMACTRL
= SDMMC_DISABLE_IDMA
;
1468 /* Stop Transfer for Write Multi blocks or Read Multi blocks */
1469 if(((context
& MMC_CONTEXT_READ_MULTIPLE_BLOCK
) != 0U) || ((context
& MMC_CONTEXT_WRITE_MULTIPLE_BLOCK
) != 0U))
1471 errorstate
= SDMMC_CmdStopTransfer(hmmc
->Instance
);
1472 if(errorstate
!= HAL_MMC_ERROR_NONE
)
1474 hmmc
->ErrorCode
|= errorstate
;
1475 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1476 hmmc
->ErrorCallback(hmmc
);
1478 HAL_MMC_ErrorCallback(hmmc
);
1483 /* Clear all the static flags */
1484 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_DATA_FLAGS
);
1486 hmmc
->State
= HAL_MMC_STATE_READY
;
1487 if(((context
& MMC_CONTEXT_WRITE_SINGLE_BLOCK
) != 0U) || ((context
& MMC_CONTEXT_WRITE_MULTIPLE_BLOCK
) != 0U))
1489 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1490 hmmc
->TxCpltCallback(hmmc
);
1492 HAL_MMC_TxCpltCallback(hmmc
);
1495 if(((context
& MMC_CONTEXT_READ_SINGLE_BLOCK
) != 0U) || ((context
& MMC_CONTEXT_READ_MULTIPLE_BLOCK
) != 0U))
1497 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1498 hmmc
->RxCpltCallback(hmmc
);
1500 HAL_MMC_RxCpltCallback(hmmc
);
1504 else if((context
& MMC_CONTEXT_IT
) != 0U)
1506 /* Stop Transfer for Write Multi blocks or Read Multi blocks */
1507 if(((context
& MMC_CONTEXT_READ_MULTIPLE_BLOCK
) != 0U) || ((context
& MMC_CONTEXT_WRITE_MULTIPLE_BLOCK
) != 0U))
1509 errorstate
= SDMMC_CmdStopTransfer(hmmc
->Instance
);
1510 if(errorstate
!= HAL_MMC_ERROR_NONE
)
1512 hmmc
->ErrorCode
|= errorstate
;
1513 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1514 hmmc
->ErrorCallback(hmmc
);
1516 HAL_MMC_ErrorCallback(hmmc
);
1521 /* Clear all the static flags */
1522 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_DATA_FLAGS
);
1524 hmmc
->State
= HAL_MMC_STATE_READY
;
1525 if(((context
& MMC_CONTEXT_READ_SINGLE_BLOCK
) != 0U) || ((context
& MMC_CONTEXT_READ_MULTIPLE_BLOCK
) != 0U))
1527 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1528 hmmc
->RxCpltCallback(hmmc
);
1530 HAL_MMC_RxCpltCallback(hmmc
);
1535 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1536 hmmc
->TxCpltCallback(hmmc
);
1538 HAL_MMC_TxCpltCallback(hmmc
);
1548 else if((__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_TXFIFOHE
) != RESET
) && ((context
& MMC_CONTEXT_IT
) != 0U))
1553 else if (__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_DCRCFAIL
| SDMMC_FLAG_DTIMEOUT
| SDMMC_FLAG_RXOVERR
| SDMMC_FLAG_TXUNDERR
) != RESET
)
1555 /* Set Error code */
1556 if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_IT_DCRCFAIL
) != RESET
)
1558 hmmc
->ErrorCode
|= HAL_MMC_ERROR_DATA_CRC_FAIL
;
1560 if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_IT_DTIMEOUT
) != RESET
)
1562 hmmc
->ErrorCode
|= HAL_MMC_ERROR_DATA_TIMEOUT
;
1564 if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_IT_RXOVERR
) != RESET
)
1566 hmmc
->ErrorCode
|= HAL_MMC_ERROR_RX_OVERRUN
;
1568 if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_IT_TXUNDERR
) != RESET
)
1570 hmmc
->ErrorCode
|= HAL_MMC_ERROR_TX_UNDERRUN
;
1573 /* Clear All flags */
1574 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_DATA_FLAGS
);
1576 /* Disable all interrupts */
1577 __HAL_MMC_DISABLE_IT(hmmc
, SDMMC_IT_DATAEND
| SDMMC_IT_DCRCFAIL
| SDMMC_IT_DTIMEOUT
|\
1578 SDMMC_IT_TXUNDERR
| SDMMC_IT_RXOVERR
);
1580 __SDMMC_CMDTRANS_DISABLE( hmmc
->Instance
);
1581 hmmc
->Instance
->DCTRL
|= SDMMC_DCTRL_FIFORST
;
1582 hmmc
->Instance
->CMD
|= SDMMC_CMD_CMDSTOP
;
1583 hmmc
->ErrorCode
|= SDMMC_CmdStopTransfer(hmmc
->Instance
);
1584 hmmc
->Instance
->CMD
&= ~(SDMMC_CMD_CMDSTOP
);
1585 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_FLAG_DABORT
);
1587 if((context
& MMC_CONTEXT_IT
) != 0U)
1589 /* Set the MMC state to ready to be able to start again the process */
1590 hmmc
->State
= HAL_MMC_STATE_READY
;
1591 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1592 hmmc
->ErrorCallback(hmmc
);
1594 HAL_MMC_ErrorCallback(hmmc
);
1595 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1597 else if((context
& MMC_CONTEXT_DMA
) != 0U)
1599 if(hmmc
->ErrorCode
!= HAL_MMC_ERROR_NONE
)
1601 /* Disable Internal DMA */
1602 __HAL_MMC_DISABLE_IT(hmmc
, SDMMC_IT_IDMABTC
);
1603 hmmc
->Instance
->IDMACTRL
= SDMMC_DISABLE_IDMA
;
1605 /* Set the MMC state to ready to be able to start again the process */
1606 hmmc
->State
= HAL_MMC_STATE_READY
;
1607 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1608 hmmc
->ErrorCallback(hmmc
);
1610 HAL_MMC_ErrorCallback(hmmc
);
1611 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */
1620 else if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_IDMABTC
) != RESET
)
1622 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_IT_IDMABTC
);
1623 if(READ_BIT(hmmc
->Instance
->IDMACTRL
, SDMMC_IDMA_IDMABACT
) == 0U)
1625 /* Current buffer is buffer0, Transfer complete for buffer1 */
1626 if((context
& MMC_CONTEXT_WRITE_MULTIPLE_BLOCK
) != 0U)
1628 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1629 hmmc
->Write_DMADblBuf1CpltCallback(hmmc
);
1631 HAL_MMCEx_Write_DMADoubleBuf1CpltCallback(hmmc
);
1634 else /* MMC_CONTEXT_READ_MULTIPLE_BLOCK */
1636 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1637 hmmc
->Read_DMADblBuf1CpltCallback(hmmc
);
1639 HAL_MMCEx_Read_DMADoubleBuf1CpltCallback(hmmc
);
1643 else /* MMC_DMA_BUFFER1 */
1645 /* Current buffer is buffer1, Transfer complete for buffer0 */
1646 if((context
& MMC_CONTEXT_WRITE_MULTIPLE_BLOCK
) != 0U)
1648 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1649 hmmc
->Write_DMADblBuf0CpltCallback(hmmc
);
1651 HAL_MMCEx_Write_DMADoubleBuf0CpltCallback(hmmc
);
1654 else /* MMC_CONTEXT_READ_MULTIPLE_BLOCK */
1656 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1657 hmmc
->Read_DMADblBuf0CpltCallback(hmmc
);
1659 HAL_MMCEx_Read_DMADoubleBuf0CpltCallback(hmmc
);
1672 * @brief return the MMC state
1673 * @param hmmc: Pointer to mmc handle
1676 HAL_MMC_StateTypeDef
HAL_MMC_GetState(MMC_HandleTypeDef
*hmmc
)
1682 * @brief Return the MMC error code
1683 * @param hmmc : Pointer to a MMC_HandleTypeDef structure that contains
1684 * the configuration information.
1685 * @retval MMC Error Code
1687 uint32_t HAL_MMC_GetError(MMC_HandleTypeDef
*hmmc
)
1689 return hmmc
->ErrorCode
;
1693 * @brief Tx Transfer completed callbacks
1694 * @param hmmc: Pointer to MMC handle
1697 __weak
void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef
*hmmc
)
1699 /* Prevent unused argument(s) compilation warning */
1702 /* NOTE : This function should not be modified, when the callback is needed,
1703 the HAL_MMC_TxCpltCallback can be implemented in the user file
1708 * @brief Rx Transfer completed callbacks
1709 * @param hmmc: Pointer MMC handle
1712 __weak
void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef
*hmmc
)
1714 /* Prevent unused argument(s) compilation warning */
1717 /* NOTE : This function should not be modified, when the callback is needed,
1718 the HAL_MMC_RxCpltCallback can be implemented in the user file
1723 * @brief MMC error callbacks
1724 * @param hmmc: Pointer MMC handle
1727 __weak
void HAL_MMC_ErrorCallback(MMC_HandleTypeDef
*hmmc
)
1729 /* Prevent unused argument(s) compilation warning */
1732 /* NOTE : This function should not be modified, when the callback is needed,
1733 the HAL_MMC_ErrorCallback can be implemented in the user file
1738 * @brief MMC Abort callbacks
1739 * @param hmmc: Pointer MMC handle
1742 __weak
void HAL_MMC_AbortCallback(MMC_HandleTypeDef
*hmmc
)
1744 /* Prevent unused argument(s) compilation warning */
1747 /* NOTE : This function should not be modified, when the callback is needed,
1748 the HAL_MMC_AbortCallback can be implemented in the user file
1752 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
1754 * @brief Register a User MMC Callback
1755 * To be used instead of the weak (surcharged) predefined callback
1756 * @param hmmc : MMC handle
1757 * @param CallbackId : ID of the callback to be registered
1758 * This parameter can be one of the following values:
1759 * @arg @ref HAL_MMC_TX_CPLT_CB_ID MMC Tx Complete Callback ID
1760 * @arg @ref HAL_MMC_RX_CPLT_CB_ID MMC Rx Complete Callback ID
1761 * @arg @ref HAL_MMC_ERROR_CB_ID MMC Error Callback ID
1762 * @arg @ref HAL_MMC_ABORT_CB_ID MMC Abort Callback ID
1763 * @arg @ref HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID MMC DMA Rx Double buffer 0 Callback ID
1764 * @arg @ref HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID MMC DMA Rx Double buffer 1 Callback ID
1765 * @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID MMC DMA Tx Double buffer 0 Callback ID
1766 * @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID MMC DMA Tx Double buffer 1 Callback ID
1767 * @arg @ref HAL_MMC_MSP_INIT_CB_ID MMC MspInit Callback ID
1768 * @arg @ref HAL_MMC_MSP_DEINIT_CB_ID MMC MspDeInit Callback ID
1769 * @param pCallback : pointer to the Callback function
1772 HAL_StatusTypeDef
HAL_MMC_RegisterCallback(MMC_HandleTypeDef
*hmmc
, HAL_MMC_CallbackIDTypeDef CallbackId
, pMMC_CallbackTypeDef pCallback
)
1774 HAL_StatusTypeDef status
= HAL_OK
;
1776 if(pCallback
== NULL
)
1778 /* Update the error code */
1779 hmmc
->ErrorCode
|= HAL_MMC_ERROR_INVALID_CALLBACK
;
1783 /* Process locked */
1786 if(hmmc
->State
== HAL_MMC_STATE_READY
)
1790 case HAL_MMC_TX_CPLT_CB_ID
:
1791 hmmc
->TxCpltCallback
= pCallback
;
1793 case HAL_MMC_RX_CPLT_CB_ID
:
1794 hmmc
->RxCpltCallback
= pCallback
;
1796 case HAL_MMC_ERROR_CB_ID
:
1797 hmmc
->ErrorCallback
= pCallback
;
1799 case HAL_MMC_ABORT_CB_ID
:
1800 hmmc
->AbortCpltCallback
= pCallback
;
1802 case HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID
:
1803 hmmc
->Read_DMADblBuf0CpltCallback
= pCallback
;
1805 case HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID
:
1806 hmmc
->Read_DMADblBuf1CpltCallback
= pCallback
;
1808 case HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID
:
1809 hmmc
->Write_DMADblBuf0CpltCallback
= pCallback
;
1811 case HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID
:
1812 hmmc
->Write_DMADblBuf1CpltCallback
= pCallback
;
1814 case HAL_MMC_MSP_INIT_CB_ID
:
1815 hmmc
->MspInitCallback
= pCallback
;
1817 case HAL_MMC_MSP_DEINIT_CB_ID
:
1818 hmmc
->MspDeInitCallback
= pCallback
;
1821 /* Update the error code */
1822 hmmc
->ErrorCode
|= HAL_MMC_ERROR_INVALID_CALLBACK
;
1823 /* update return status */
1828 else if (hmmc
->State
== HAL_MMC_STATE_RESET
)
1832 case HAL_MMC_MSP_INIT_CB_ID
:
1833 hmmc
->MspInitCallback
= pCallback
;
1835 case HAL_MMC_MSP_DEINIT_CB_ID
:
1836 hmmc
->MspDeInitCallback
= pCallback
;
1839 /* Update the error code */
1840 hmmc
->ErrorCode
|= HAL_MMC_ERROR_INVALID_CALLBACK
;
1841 /* update return status */
1848 /* Update the error code */
1849 hmmc
->ErrorCode
|= HAL_MMC_ERROR_INVALID_CALLBACK
;
1850 /* update return status */
1860 * @brief Unregister a User MMC Callback
1861 * MMC Callback is redirected to the weak (surcharged) predefined callback
1862 * @param hmmc : MMC handle
1863 * @param CallbackId : ID of the callback to be unregistered
1864 * This parameter can be one of the following values:
1865 * @arg @ref HAL_MMC_TX_CPLT_CB_ID MMC Tx Complete Callback ID
1866 * @arg @ref HAL_MMC_RX_CPLT_CB_ID MMC Rx Complete Callback ID
1867 * @arg @ref HAL_MMC_ERROR_CB_ID MMC Error Callback ID
1868 * @arg @ref HAL_MMC_ABORT_CB_ID MMC Abort Callback ID
1869 * @arg @ref HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID MMC DMA Rx Double buffer 0 Callback ID
1870 * @arg @ref HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID MMC DMA Rx Double buffer 1 Callback ID
1871 * @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID MMC DMA Tx Double buffer 0 Callback ID
1872 * @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID MMC DMA Tx Double buffer 1 Callback ID
1873 * @arg @ref HAL_MMC_MSP_INIT_CB_ID MMC MspInit Callback ID
1874 * @arg @ref HAL_MMC_MSP_DEINIT_CB_ID MMC MspDeInit Callback ID
1877 HAL_StatusTypeDef
HAL_MMC_UnRegisterCallback(MMC_HandleTypeDef
*hmmc
, HAL_MMC_CallbackIDTypeDef CallbackId
)
1879 HAL_StatusTypeDef status
= HAL_OK
;
1881 /* Process locked */
1884 if(hmmc
->State
== HAL_MMC_STATE_READY
)
1888 case HAL_MMC_TX_CPLT_CB_ID
:
1889 hmmc
->TxCpltCallback
= HAL_MMC_TxCpltCallback
;
1891 case HAL_MMC_RX_CPLT_CB_ID
:
1892 hmmc
->RxCpltCallback
= HAL_MMC_RxCpltCallback
;
1894 case HAL_MMC_ERROR_CB_ID
:
1895 hmmc
->ErrorCallback
= HAL_MMC_ErrorCallback
;
1897 case HAL_MMC_ABORT_CB_ID
:
1898 hmmc
->AbortCpltCallback
= HAL_MMC_AbortCallback
;
1900 case HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID
:
1901 hmmc
->Read_DMADblBuf0CpltCallback
= HAL_MMCEx_Read_DMADoubleBuf0CpltCallback
;
1903 case HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID
:
1904 hmmc
->Read_DMADblBuf1CpltCallback
= HAL_MMCEx_Read_DMADoubleBuf1CpltCallback
;
1906 case HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID
:
1907 hmmc
->Write_DMADblBuf0CpltCallback
= HAL_MMCEx_Write_DMADoubleBuf0CpltCallback
;
1909 case HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID
:
1910 hmmc
->Write_DMADblBuf1CpltCallback
= HAL_MMCEx_Write_DMADoubleBuf1CpltCallback
;
1912 case HAL_MMC_MSP_INIT_CB_ID
:
1913 hmmc
->MspInitCallback
= HAL_MMC_MspInit
;
1915 case HAL_MMC_MSP_DEINIT_CB_ID
:
1916 hmmc
->MspDeInitCallback
= HAL_MMC_MspDeInit
;
1919 /* Update the error code */
1920 hmmc
->ErrorCode
|= HAL_MMC_ERROR_INVALID_CALLBACK
;
1921 /* update return status */
1926 else if (hmmc
->State
== HAL_MMC_STATE_RESET
)
1930 case HAL_MMC_MSP_INIT_CB_ID
:
1931 hmmc
->MspInitCallback
= HAL_MMC_MspInit
;
1933 case HAL_MMC_MSP_DEINIT_CB_ID
:
1934 hmmc
->MspDeInitCallback
= HAL_MMC_MspDeInit
;
1937 /* Update the error code */
1938 hmmc
->ErrorCode
|= HAL_MMC_ERROR_INVALID_CALLBACK
;
1939 /* update return status */
1946 /* Update the error code */
1947 hmmc
->ErrorCode
|= HAL_MMC_ERROR_INVALID_CALLBACK
;
1948 /* update return status */
1962 /** @addtogroup MMC_Exported_Functions_Group3
1963 * @brief management functions
1966 ==============================================================================
1967 ##### Peripheral Control functions #####
1968 ==============================================================================
1970 This subsection provides a set of functions allowing to control the MMC card
1971 operations and get the related information
1978 * @brief Returns information the information of the card which are stored on
1980 * @param hmmc: Pointer to MMC handle
1981 * @param pCID: Pointer to a HAL_MMC_CIDTypedef structure that
1982 * contains all CID register parameters
1983 * @retval HAL status
1985 HAL_StatusTypeDef
HAL_MMC_GetCardCID(MMC_HandleTypeDef
*hmmc
, HAL_MMC_CardCIDTypeDef
*pCID
)
1987 pCID
->ManufacturerID
= (uint8_t)((hmmc
->CID
[0] & 0xFF000000U
) >> 24U);
1989 pCID
->OEM_AppliID
= (uint16_t)((hmmc
->CID
[0] & 0x00FFFF00U
) >> 8U);
1991 pCID
->ProdName1
= (((hmmc
->CID
[0] & 0x000000FFU
) << 24U) | ((hmmc
->CID
[1] & 0xFFFFFF00U
) >> 8U));
1993 pCID
->ProdName2
= (uint8_t)(hmmc
->CID
[1] & 0x000000FFU
);
1995 pCID
->ProdRev
= (uint8_t)((hmmc
->CID
[2] & 0xFF000000U
) >> 24U);
1997 pCID
->ProdSN
= (((hmmc
->CID
[2] & 0x00FFFFFFU
) << 8U) | ((hmmc
->CID
[3] & 0xFF000000U
) >> 24U));
1999 pCID
->Reserved1
= (uint8_t)((hmmc
->CID
[3] & 0x00F00000U
) >> 20U);
2001 pCID
->ManufactDate
= (uint16_t)((hmmc
->CID
[3] & 0x000FFF00U
) >> 8U);
2003 pCID
->CID_CRC
= (uint8_t)((hmmc
->CID
[3] & 0x000000FEU
) >> 1U);
2005 pCID
->Reserved2
= 1U;
2011 * @brief Returns information the information of the card which are stored on
2013 * @param hmmc: Pointer to MMC handle
2014 * @param pCSD: Pointer to a HAL_MMC_CardCSDTypeDef structure that
2015 * contains all CSD register parameters
2016 * @retval HAL status
2018 HAL_StatusTypeDef
HAL_MMC_GetCardCSD(MMC_HandleTypeDef
*hmmc
, HAL_MMC_CardCSDTypeDef
*pCSD
)
2020 uint32_t block_nbr
= 0;
2022 pCSD
->CSDStruct
= (uint8_t)((hmmc
->CSD
[0] & 0xC0000000U
) >> 30U);
2024 pCSD
->SysSpecVersion
= (uint8_t)((hmmc
->CSD
[0] & 0x3C000000U
) >> 26U);
2026 pCSD
->Reserved1
= (uint8_t)((hmmc
->CSD
[0] & 0x03000000U
) >> 24U);
2028 pCSD
->TAAC
= (uint8_t)((hmmc
->CSD
[0] & 0x00FF0000U
) >> 16U);
2030 pCSD
->NSAC
= (uint8_t)((hmmc
->CSD
[0] & 0x0000FF00U
) >> 8U);
2032 pCSD
->MaxBusClkFrec
= (uint8_t)(hmmc
->CSD
[0] & 0x000000FFU
);
2034 pCSD
->CardComdClasses
= (uint16_t)((hmmc
->CSD
[1] & 0xFFF00000U
) >> 20U);
2036 pCSD
->RdBlockLen
= (uint8_t)((hmmc
->CSD
[1] & 0x000F0000U
) >> 16U);
2038 pCSD
->PartBlockRead
= (uint8_t)((hmmc
->CSD
[1] & 0x00008000U
) >> 15U);
2040 pCSD
->WrBlockMisalign
= (uint8_t)((hmmc
->CSD
[1] & 0x00004000U
) >> 14U);
2042 pCSD
->RdBlockMisalign
= (uint8_t)((hmmc
->CSD
[1] & 0x00002000U
) >> 13U);
2044 pCSD
->DSRImpl
= (uint8_t)((hmmc
->CSD
[1] & 0x00001000U
) >> 12U);
2046 pCSD
->Reserved2
= 0U; /*!< Reserved */
2048 if(MMC_ReadExtCSD(hmmc
, &block_nbr
, 212, 0x0FFFFFFFU
) != HAL_OK
) /* Field SEC_COUNT [215:212] */
2053 if(hmmc
->MmcCard
.CardType
== MMC_LOW_CAPACITY_CARD
)
2055 pCSD
->DeviceSize
= (((hmmc
->CSD
[1] & 0x000003FFU
) << 2U) | ((hmmc
->CSD
[2] & 0xC0000000U
) >> 30U));
2057 pCSD
->MaxRdCurrentVDDMin
= (uint8_t)((hmmc
->CSD
[2] & 0x38000000U
) >> 27U);
2059 pCSD
->MaxRdCurrentVDDMax
= (uint8_t)((hmmc
->CSD
[2] & 0x07000000U
) >> 24U);
2061 pCSD
->MaxWrCurrentVDDMin
= (uint8_t)((hmmc
->CSD
[2] & 0x00E00000U
) >> 21U);
2063 pCSD
->MaxWrCurrentVDDMax
= (uint8_t)((hmmc
->CSD
[2] & 0x001C0000U
) >> 18U);
2065 pCSD
->DeviceSizeMul
= (uint8_t)((hmmc
->CSD
[2] & 0x00038000U
) >> 15U);
2067 hmmc
->MmcCard
.BlockNbr
= (pCSD
->DeviceSize
+ 1U) ;
2068 hmmc
->MmcCard
.BlockNbr
*= (1UL << ((pCSD
->DeviceSizeMul
& 0x07U
) + 2U));
2069 hmmc
->MmcCard
.BlockSize
= (1UL << (pCSD
->RdBlockLen
& 0x0FU
));
2071 hmmc
->MmcCard
.LogBlockNbr
= (hmmc
->MmcCard
.BlockNbr
) * ((hmmc
->MmcCard
.BlockSize
) / 512U);
2072 hmmc
->MmcCard
.LogBlockSize
= 512U;
2074 else if(hmmc
->MmcCard
.CardType
== MMC_HIGH_CAPACITY_CARD
)
2076 hmmc
->MmcCard
.BlockNbr
= block_nbr
;
2077 hmmc
->MmcCard
.LogBlockNbr
= hmmc
->MmcCard
.BlockNbr
;
2078 hmmc
->MmcCard
.BlockSize
= 512U;
2079 hmmc
->MmcCard
.LogBlockSize
= hmmc
->MmcCard
.BlockSize
;
2083 /* Clear all the static flags */
2084 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
2085 hmmc
->ErrorCode
|= HAL_MMC_ERROR_UNSUPPORTED_FEATURE
;
2086 hmmc
->State
= HAL_MMC_STATE_READY
;
2090 pCSD
->EraseGrSize
= (uint8_t)((hmmc
->CSD
[2] & 0x00004000U
) >> 14U);
2092 pCSD
->EraseGrMul
= (uint8_t)((hmmc
->CSD
[2] & 0x00003F80U
) >> 7U);
2094 pCSD
->WrProtectGrSize
= (uint8_t)(hmmc
->CSD
[2] & 0x0000007FU
);
2096 pCSD
->WrProtectGrEnable
= (uint8_t)((hmmc
->CSD
[3] & 0x80000000U
) >> 31U);
2098 pCSD
->ManDeflECC
= (uint8_t)((hmmc
->CSD
[3] & 0x60000000U
) >> 29U);
2100 pCSD
->WrSpeedFact
= (uint8_t)((hmmc
->CSD
[3] & 0x1C000000U
) >> 26U);
2102 pCSD
->MaxWrBlockLen
= (uint8_t)((hmmc
->CSD
[3] & 0x03C00000U
) >> 22U);
2104 pCSD
->WriteBlockPaPartial
= (uint8_t)((hmmc
->CSD
[3] & 0x00200000U
) >> 21U);
2106 pCSD
->Reserved3
= 0;
2108 pCSD
->ContentProtectAppli
= (uint8_t)((hmmc
->CSD
[3] & 0x00010000U
) >> 16U);
2110 pCSD
->FileFormatGroup
= (uint8_t)((hmmc
->CSD
[3] & 0x00008000U
) >> 15U);
2112 pCSD
->CopyFlag
= (uint8_t)((hmmc
->CSD
[3] & 0x00004000U
) >> 14U);
2114 pCSD
->PermWrProtect
= (uint8_t)((hmmc
->CSD
[3] & 0x00002000U
) >> 13U);
2116 pCSD
->TempWrProtect
= (uint8_t)((hmmc
->CSD
[3] & 0x00001000U
) >> 12U);
2118 pCSD
->FileFormat
= (uint8_t)((hmmc
->CSD
[3] & 0x00000C00U
) >> 10U);
2120 pCSD
->ECC
= (uint8_t)((hmmc
->CSD
[3] & 0x00000300U
) >> 8U);
2122 pCSD
->CSD_CRC
= (uint8_t)((hmmc
->CSD
[3] & 0x000000FEU
) >> 1U);
2124 pCSD
->Reserved4
= 1;
2130 * @brief Gets the MMC card info.
2131 * @param hmmc: Pointer to MMC handle
2132 * @param pCardInfo: Pointer to the HAL_MMC_CardInfoTypeDef structure that
2133 * will contain the MMC card status information
2134 * @retval HAL status
2136 HAL_StatusTypeDef
HAL_MMC_GetCardInfo(MMC_HandleTypeDef
*hmmc
, HAL_MMC_CardInfoTypeDef
*pCardInfo
)
2138 pCardInfo
->CardType
= (uint32_t)(hmmc
->MmcCard
.CardType
);
2139 pCardInfo
->Class
= (uint32_t)(hmmc
->MmcCard
.Class
);
2140 pCardInfo
->RelCardAdd
= (uint32_t)(hmmc
->MmcCard
.RelCardAdd
);
2141 pCardInfo
->BlockNbr
= (uint32_t)(hmmc
->MmcCard
.BlockNbr
);
2142 pCardInfo
->BlockSize
= (uint32_t)(hmmc
->MmcCard
.BlockSize
);
2143 pCardInfo
->LogBlockNbr
= (uint32_t)(hmmc
->MmcCard
.LogBlockNbr
);
2144 pCardInfo
->LogBlockSize
= (uint32_t)(hmmc
->MmcCard
.LogBlockSize
);
2150 * @brief Enables wide bus operation for the requested card if supported by
2152 * @param hmmc: Pointer to MMC handle
2153 * @param WideMode: Specifies the MMC card wide bus mode
2154 * This parameter can be one of the following values:
2155 * @arg SDMMC_BUS_WIDE_8B: 8-bit data transfer
2156 * @arg SDMMC_BUS_WIDE_4B: 4-bit data transfer
2157 * @arg SDMMC_BUS_WIDE_1B: 1-bit data transfer
2158 * @retval HAL status
2160 HAL_StatusTypeDef
HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef
*hmmc
, uint32_t WideMode
)
2162 __IO
uint32_t count
= 0U;
2163 SDMMC_InitTypeDef Init
;
2164 uint32_t errorstate
;
2165 uint32_t response
= 0U, busy
= 0U;
2167 /* Check the parameters */
2168 assert_param(IS_SDMMC_BUS_WIDE(WideMode
));
2171 hmmc
->State
= HAL_MMC_STATE_BUSY
;
2173 if(WideMode
== SDMMC_BUS_WIDE_8B
)
2175 errorstate
= SDMMC_CmdSwitch(hmmc
->Instance
, 0x03B70200U
);
2176 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2178 hmmc
->ErrorCode
|= errorstate
;
2181 else if(WideMode
== SDMMC_BUS_WIDE_4B
)
2183 errorstate
= SDMMC_CmdSwitch(hmmc
->Instance
, 0x03B70100U
);
2184 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2186 hmmc
->ErrorCode
|= errorstate
;
2189 else if(WideMode
== SDMMC_BUS_WIDE_1B
)
2191 errorstate
= SDMMC_CmdSwitch(hmmc
->Instance
, 0x03B70000U
);
2192 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2194 hmmc
->ErrorCode
|= errorstate
;
2199 /* WideMode is not a valid argument*/
2200 hmmc
->ErrorCode
|= HAL_MMC_ERROR_PARAM
;
2203 /* Check for switch error and violation of the trial number of sending CMD 13 */
2206 if(count
== SDMMC_MAX_TRIAL
)
2208 hmmc
->State
= HAL_MMC_STATE_READY
;
2209 hmmc
->ErrorCode
|= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE
;
2214 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2215 errorstate
= SDMMC_CmdSendStatus(hmmc
->Instance
, (uint32_t)(((uint32_t)hmmc
->MmcCard
.RelCardAdd
) << 16U));
2216 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2218 hmmc
->ErrorCode
|= errorstate
;
2221 /* Get command response */
2222 response
= SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP1
);
2224 /* Get operating voltage*/
2225 busy
= (((response
>> 7U) == 1U) ? 0U : 1U);
2228 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2229 count
= SDMMC_DATATIMEOUT
;
2230 while((response
& 0x00000100U
) == 0U)
2234 hmmc
->State
= HAL_MMC_STATE_READY
;
2235 hmmc
->ErrorCode
|= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE
;
2240 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2241 errorstate
= SDMMC_CmdSendStatus(hmmc
->Instance
, (uint32_t)(((uint32_t)hmmc
->MmcCard
.RelCardAdd
) << 16U));
2242 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2244 hmmc
->ErrorCode
|= errorstate
;
2247 /* Get command response */
2248 response
= SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP1
);
2251 if(hmmc
->ErrorCode
!= HAL_MMC_ERROR_NONE
)
2253 /* Clear all the static flags */
2254 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
2255 hmmc
->State
= HAL_MMC_STATE_READY
;
2260 /* Configure the SDMMC peripheral */
2261 Init
.ClockEdge
= hmmc
->Init
.ClockEdge
;
2262 Init
.ClockPowerSave
= hmmc
->Init
.ClockPowerSave
;
2263 Init
.BusWide
= WideMode
;
2264 Init
.HardwareFlowControl
= hmmc
->Init
.HardwareFlowControl
;
2265 Init
.ClockDiv
= hmmc
->Init
.ClockDiv
;
2266 (void)SDMMC_Init(hmmc
->Instance
, Init
);
2270 hmmc
->State
= HAL_MMC_STATE_READY
;
2276 * @brief Configure the speed bus mode
2277 * @param hmmc: Pointer to the MMC handle
2278 * @param SpeedMode: Specifies the MMC card speed bus mode
2279 * This parameter can be one of the following values:
2280 * @arg SDMMC_SPEED_MODE_AUTO: Max speed mode supported by the card
2281 * @arg SDMMC_SPEED_MODE_DEFAULT: Default Speed (MMC @ 26MHz)
2282 * @arg SDMMC_SPEED_MODE_HIGH: High Speed (MMC @ 52 MHz)
2283 * @arg SDMMC_SPEED_MODE_DDR: High Speed DDR (MMC DDR @ 52 MHz)
2284 * @retval HAL status
2287 HAL_StatusTypeDef
HAL_MMC_ConfigSpeedBusOperation(MMC_HandleTypeDef
*hmmc
, uint32_t SpeedMode
)
2290 HAL_StatusTypeDef status
= HAL_OK
;
2291 uint32_t device_type
;
2292 uint32_t errorstate
;
2294 /* Check the parameters */
2295 assert_param(IS_SDMMC_SPEED_MODE(SpeedMode
));
2297 hmmc
->State
= HAL_MMC_STATE_BUSY
;
2299 if(MMC_ReadExtCSD(hmmc
, &device_type
, 196, 0x0FFFFFFFU
) != HAL_OK
) /* Field DEVICE_TYPE [196] */
2306 case SDMMC_SPEED_MODE_AUTO
:
2308 if (((hmmc
->Instance
->CLKCR
& SDMMC_CLKCR_WIDBUS
) != 0U) && ((device_type
& 0x04U
) != 0U))
2310 /* High Speed DDR mode allowed */
2311 errorstate
= MMC_HighSpeed(hmmc
, ENABLE
);
2312 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2314 hmmc
->ErrorCode
|= errorstate
;
2318 errorstate
= MMC_DDR_Mode(hmmc
, ENABLE
);
2319 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2321 hmmc
->ErrorCode
|= errorstate
;
2325 else if ((device_type
& 0x02U
) != 0U)
2327 /* High Speed mode allowed */
2328 errorstate
= MMC_HighSpeed(hmmc
, ENABLE
);
2329 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2331 hmmc
->ErrorCode
|= errorstate
;
2336 /* Nothing to do : keep current speed */
2340 case SDMMC_SPEED_MODE_DDR
:
2342 if (((hmmc
->Instance
->CLKCR
& SDMMC_CLKCR_WIDBUS
) != 0U) && ((device_type
& 0x04U
) != 0U))
2344 /* High Speed DDR mode allowed */
2345 errorstate
= MMC_HighSpeed(hmmc
, ENABLE
);
2346 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2348 hmmc
->ErrorCode
|= errorstate
;
2352 errorstate
= MMC_DDR_Mode(hmmc
, ENABLE
);
2353 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2355 hmmc
->ErrorCode
|= errorstate
;
2361 /* High Speed DDR mode not allowed */
2362 hmmc
->ErrorCode
|= HAL_MMC_ERROR_UNSUPPORTED_FEATURE
;
2367 case SDMMC_SPEED_MODE_HIGH
:
2369 if ((device_type
& 0x02U
) != 0U)
2371 /* High Speed mode allowed */
2372 errorstate
= MMC_HighSpeed(hmmc
, ENABLE
);
2373 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2375 hmmc
->ErrorCode
|= errorstate
;
2380 /* High Speed mode not allowed */
2381 hmmc
->ErrorCode
|= HAL_MMC_ERROR_UNSUPPORTED_FEATURE
;
2386 case SDMMC_SPEED_MODE_DEFAULT
:
2388 if ((hmmc
->Instance
->CLKCR
& SDMMC_CLKCR_DDR
) != 0U)
2390 /* High Speed DDR mode activated */
2391 errorstate
= MMC_DDR_Mode(hmmc
, DISABLE
);
2392 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2394 hmmc
->ErrorCode
|= errorstate
;
2397 if ((hmmc
->Instance
->CLKCR
& SDMMC_CLKCR_BUSSPEED
) != 0U)
2399 /* High Speed mode activated */
2400 errorstate
= MMC_HighSpeed(hmmc
, DISABLE
);
2401 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2403 hmmc
->ErrorCode
|= errorstate
;
2409 hmmc
->ErrorCode
|= HAL_MMC_ERROR_PARAM
;
2414 /* Verify that MMC card is ready to use after Speed mode switch*/
2415 tickstart
= HAL_GetTick();
2416 while ((HAL_MMC_GetCardState(hmmc
) != HAL_MMC_CARD_TRANSFER
))
2418 if ((HAL_GetTick() - tickstart
) >= SDMMC_DATATIMEOUT
)
2420 hmmc
->ErrorCode
= HAL_MMC_ERROR_TIMEOUT
;
2421 hmmc
->State
= HAL_MMC_STATE_READY
;
2427 hmmc
->State
= HAL_MMC_STATE_READY
;
2432 * @brief Gets the current mmc card data state.
2433 * @param hmmc: pointer to MMC handle
2434 * @retval Card state
2436 HAL_MMC_CardStateTypeDef
HAL_MMC_GetCardState(MMC_HandleTypeDef
*hmmc
)
2439 uint32_t errorstate
;
2440 uint32_t resp1
= 0U;
2442 errorstate
= MMC_SendStatus(hmmc
, &resp1
);
2443 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2445 hmmc
->ErrorCode
|= errorstate
;
2448 cardstate
= ((resp1
>> 9U) & 0x0FU
);
2450 return (HAL_MMC_CardStateTypeDef
)cardstate
;
2454 * @brief Abort the current transfer and disable the MMC.
2455 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2456 * the configuration information for MMC module.
2457 * @retval HAL status
2459 HAL_StatusTypeDef
HAL_MMC_Abort(MMC_HandleTypeDef
*hmmc
)
2461 HAL_MMC_CardStateTypeDef CardState
;
2463 /* DIsable All interrupts */
2464 __HAL_MMC_DISABLE_IT(hmmc
, SDMMC_IT_DATAEND
| SDMMC_IT_DCRCFAIL
| SDMMC_IT_DTIMEOUT
|\
2465 SDMMC_IT_TXUNDERR
| SDMMC_IT_RXOVERR
);
2467 /* Clear All flags */
2468 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_DATA_FLAGS
);
2470 /* If IDMA Context, disable Internal DMA */
2471 hmmc
->Instance
->IDMACTRL
= SDMMC_DISABLE_IDMA
;
2473 hmmc
->State
= HAL_MMC_STATE_READY
;
2475 /* Initialize the MMC operation */
2476 hmmc
->Context
= MMC_CONTEXT_NONE
;
2478 CardState
= HAL_MMC_GetCardState(hmmc
);
2479 if((CardState
== HAL_MMC_CARD_RECEIVING
) || (CardState
== HAL_MMC_CARD_SENDING
))
2481 hmmc
->ErrorCode
= SDMMC_CmdStopTransfer(hmmc
->Instance
);
2483 if(hmmc
->ErrorCode
!= HAL_MMC_ERROR_NONE
)
2491 * @brief Abort the current transfer and disable the MMC (IT mode).
2492 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2493 * the configuration information for MMC module.
2494 * @retval HAL status
2496 HAL_StatusTypeDef
HAL_MMC_Abort_IT(MMC_HandleTypeDef
*hmmc
)
2498 HAL_MMC_CardStateTypeDef CardState
;
2500 /* DIsable All interrupts */
2501 __HAL_MMC_DISABLE_IT(hmmc
, SDMMC_IT_DATAEND
| SDMMC_IT_DCRCFAIL
| SDMMC_IT_DTIMEOUT
|\
2502 SDMMC_IT_TXUNDERR
| SDMMC_IT_RXOVERR
);
2504 /* If IDMA Context, disable Internal DMA */
2505 hmmc
->Instance
->IDMACTRL
= SDMMC_DISABLE_IDMA
;
2507 /* Clear All flags */
2508 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_DATA_FLAGS
);
2510 CardState
= HAL_MMC_GetCardState(hmmc
);
2511 hmmc
->State
= HAL_MMC_STATE_READY
;
2513 if((CardState
== HAL_MMC_CARD_RECEIVING
) || (CardState
== HAL_MMC_CARD_SENDING
))
2515 hmmc
->ErrorCode
= SDMMC_CmdStopTransfer(hmmc
->Instance
);
2517 if(hmmc
->ErrorCode
!= HAL_MMC_ERROR_NONE
)
2523 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U)
2524 hmmc
->AbortCpltCallback(hmmc
);
2526 HAL_MMC_AbortCallback(hmmc
);
2541 /* Private function ----------------------------------------------------------*/
2542 /** @addtogroup MMC_Private_Functions
2548 * @brief Initializes the mmc card.
2549 * @param hmmc: Pointer to MMC handle
2550 * @retval MMC Card error state
2552 static uint32_t MMC_InitCard(MMC_HandleTypeDef
*hmmc
)
2554 HAL_MMC_CardCSDTypeDef CSD
;
2555 uint32_t errorstate
;
2556 uint16_t mmc_rca
= 1U;
2557 MMC_InitTypeDef Init
;
2559 /* Check the power State */
2560 if(SDMMC_GetPowerState(hmmc
->Instance
) == 0U)
2563 return HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE
;
2566 /* Send CMD2 ALL_SEND_CID */
2567 errorstate
= SDMMC_CmdSendCID(hmmc
->Instance
);
2568 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2574 /* Get Card identification number data */
2575 hmmc
->CID
[0U] = SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP1
);
2576 hmmc
->CID
[1U] = SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP2
);
2577 hmmc
->CID
[2U] = SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP3
);
2578 hmmc
->CID
[3U] = SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP4
);
2581 /* Send CMD3 SET_REL_ADDR with argument 0 */
2582 /* MMC Card publishes its RCA. */
2583 errorstate
= SDMMC_CmdSetRelAdd(hmmc
->Instance
, &mmc_rca
);
2584 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2589 /* Get the MMC card RCA */
2590 hmmc
->MmcCard
.RelCardAdd
= mmc_rca
;
2592 /* Send CMD9 SEND_CSD with argument as card's RCA */
2593 errorstate
= SDMMC_CmdSendCSD(hmmc
->Instance
, (uint32_t)(hmmc
->MmcCard
.RelCardAdd
<< 16U));
2594 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2600 /* Get Card Specific Data */
2601 hmmc
->CSD
[0U] = SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP1
);
2602 hmmc
->CSD
[1U] = SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP2
);
2603 hmmc
->CSD
[2U] = SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP3
);
2604 hmmc
->CSD
[3U] = SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP4
);
2607 /* Get the Card Class */
2608 hmmc
->MmcCard
.Class
= (SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP2
) >> 20U);
2610 /* Select the Card */
2611 errorstate
= SDMMC_CmdSelDesel(hmmc
->Instance
, (uint32_t)(((uint32_t)hmmc
->MmcCard
.RelCardAdd
) << 16U));
2612 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2617 /* Get CSD parameters */
2618 if (HAL_MMC_GetCardCSD(hmmc
, &CSD
) != HAL_OK
)
2620 return hmmc
->ErrorCode
;
2623 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2624 errorstate
= SDMMC_CmdSendStatus(hmmc
->Instance
, (uint32_t)(((uint32_t)hmmc
->MmcCard
.RelCardAdd
) << 16U));
2625 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2627 hmmc
->ErrorCode
|= errorstate
;
2630 /* Configure the SDMMC peripheral */
2631 Init
.ClockEdge
= hmmc
->Init
.ClockEdge
;
2632 Init
.ClockPowerSave
= hmmc
->Init
.ClockPowerSave
;
2633 Init
.BusWide
= SDMMC_BUS_WIDE_1B
;
2634 Init
.HardwareFlowControl
= hmmc
->Init
.HardwareFlowControl
;
2635 Init
.ClockDiv
= hmmc
->Init
.ClockDiv
;
2636 (void)SDMMC_Init(hmmc
->Instance
, Init
);
2638 /* All cards are initialized */
2639 return HAL_MMC_ERROR_NONE
;
2643 * @brief Enquires cards about their operating voltage and configures clock
2644 * controls and stores MMC information that will be needed in future
2645 * in the MMC handle.
2646 * @param hmmc: Pointer to MMC handle
2647 * @retval error state
2649 static uint32_t MMC_PowerON(MMC_HandleTypeDef
*hmmc
)
2651 __IO
uint32_t count
= 0U;
2652 uint32_t response
= 0U, validvoltage
= 0U;
2653 uint32_t errorstate
;
2655 /* CMD0: GO_IDLE_STATE */
2656 errorstate
= SDMMC_CmdGoIdleState(hmmc
->Instance
);
2657 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2662 while(validvoltage
== 0U)
2664 if(count
++ == SDMMC_MAX_VOLT_TRIAL
)
2666 return HAL_MMC_ERROR_INVALID_VOLTRANGE
;
2669 /* SEND CMD1 APP_CMD with MMC_HIGH_VOLTAGE_RANGE(0xC0FF8000) as argument */
2670 errorstate
= SDMMC_CmdOpCondition(hmmc
->Instance
, eMMC_HIGH_VOLTAGE_RANGE
);
2671 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2673 return HAL_MMC_ERROR_UNSUPPORTED_FEATURE
;
2676 /* Get command response */
2677 response
= SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP1
);
2679 /* Get operating voltage*/
2680 validvoltage
= (((response
>> 31U) == 1U) ? 1U : 0U);
2683 /* When power routine is finished and command returns valid voltage */
2684 if (((response
& (0xFF000000U
)) >> 24) == 0xC0U
)
2686 hmmc
->MmcCard
.CardType
= MMC_HIGH_CAPACITY_CARD
;
2690 hmmc
->MmcCard
.CardType
= MMC_LOW_CAPACITY_CARD
;
2693 return HAL_MMC_ERROR_NONE
;
2697 * @brief Turns the SDMMC output signals off.
2698 * @param hmmc: Pointer to MMC handle
2701 static void MMC_PowerOFF(MMC_HandleTypeDef
*hmmc
)
2703 /* Set Power State to OFF */
2704 (void)SDMMC_PowerState_OFF(hmmc
->Instance
);
2708 * @brief Returns the current card's status.
2709 * @param hmmc: Pointer to MMC handle
2710 * @param pCardStatus: pointer to the buffer that will contain the MMC card
2711 * status (Card Status register)
2712 * @retval error state
2714 static uint32_t MMC_SendStatus(MMC_HandleTypeDef
*hmmc
, uint32_t *pCardStatus
)
2716 uint32_t errorstate
;
2718 if(pCardStatus
== NULL
)
2720 return HAL_MMC_ERROR_PARAM
;
2723 /* Send Status command */
2724 errorstate
= SDMMC_CmdSendStatus(hmmc
->Instance
, (uint32_t)(hmmc
->MmcCard
.RelCardAdd
<< 16U));
2725 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2730 /* Get MMC card status */
2731 *pCardStatus
= SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP1
);
2733 return HAL_MMC_ERROR_NONE
;
2737 * @brief Reads extended CSD register to get the sectors number of the device
2738 * @param hmmc: Pointer to MMC handle
2739 * @param pFieldData: Pointer to the read buffer
2740 * @param FieldIndex: Index of the field to be read
2741 * @param Timeout: Specify timeout value
2742 * @retval HAL status
2744 HAL_StatusTypeDef
MMC_ReadExtCSD(MMC_HandleTypeDef
*hmmc
, uint32_t *pFieldData
, uint16_t FieldIndex
, uint32_t Timeout
)
2746 SDMMC_DataInitTypeDef config
;
2747 uint32_t errorstate
;
2748 uint32_t tickstart
= HAL_GetTick();
2753 hmmc
->ErrorCode
= HAL_MMC_ERROR_NONE
;
2755 /* Initialize data control register */
2756 hmmc
->Instance
->DCTRL
= 0;
2758 /* Configure the MMC DPSM (Data Path State Machine) */
2759 config
.DataTimeOut
= SDMMC_DATATIMEOUT
;
2760 config
.DataLength
= 0;
2761 config
.DataBlockSize
= SDMMC_DATABLOCK_SIZE_1B
;
2762 config
.TransferDir
= SDMMC_TRANSFER_DIR_TO_SDMMC
;
2763 config
.TransferMode
= SDMMC_TRANSFER_MODE_BLOCK
;
2764 config
.DPSM
= SDMMC_DPSM_DISABLE
;
2765 (void)SDMMC_ConfigData(hmmc
->Instance
, &config
);
2767 if ((hmmc
->Instance
->CLKCR
& SDMMC_CLKCR_DDR
) == 0U)
2769 /* Set Block Size for Card */
2770 errorstate
= SDMMC_CmdBlockLength(hmmc
->Instance
, MMC_BLOCKSIZE
);
2771 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2773 /* Clear all the static flags */
2774 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
2775 hmmc
->ErrorCode
|= errorstate
;
2776 hmmc
->State
= HAL_MMC_STATE_READY
;
2781 /* Configure the MMC DPSM (Data Path State Machine) */
2782 config
.DataTimeOut
= SDMMC_DATATIMEOUT
;
2783 config
.DataLength
= 512;
2784 config
.DataBlockSize
= SDMMC_DATABLOCK_SIZE_512B
;
2785 config
.TransferDir
= SDMMC_TRANSFER_DIR_TO_SDMMC
;
2786 config
.TransferMode
= SDMMC_TRANSFER_MODE_BLOCK
;
2787 config
.DPSM
= SDMMC_DPSM_ENABLE
;
2788 (void)SDMMC_ConfigData(hmmc
->Instance
, &config
);
2790 /* Set Block Size for Card */
2791 errorstate
= SDMMC_CmdSendEXTCSD(hmmc
->Instance
, 0);
2792 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2794 /* Clear all the static flags */
2795 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
2796 hmmc
->ErrorCode
|= errorstate
;
2797 hmmc
->State
= HAL_MMC_STATE_READY
;
2801 /* Poll on SDMMC flags */
2802 while(!__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_RXOVERR
| SDMMC_FLAG_DCRCFAIL
| SDMMC_FLAG_DTIMEOUT
| SDMMC_FLAG_DATAEND
))
2804 if(__HAL_MMC_GET_FLAG(hmmc
, SDMMC_FLAG_RXFIFOHF
))
2806 /* Read data from SDMMC Rx FIFO */
2807 for(count
= 0U; count
< 8U; count
++)
2809 tmp_data
= SDMMC_ReadFIFO(hmmc
->Instance
);
2810 /* eg : SEC_COUNT : FieldIndex = 212 => i+count = 53 */
2811 /* DEVICE_TYPE : FieldIndex = 196 => i+count = 49 */
2812 if ((i
+ count
) == ((uint32_t)FieldIndex
/4U))
2814 *pFieldData
= tmp_data
;
2820 if(((HAL_GetTick()-tickstart
) >= Timeout
) || (Timeout
== 0U))
2822 /* Clear all the static flags */
2823 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_FLAGS
);
2824 hmmc
->ErrorCode
|= HAL_MMC_ERROR_TIMEOUT
;
2825 hmmc
->State
= HAL_MMC_STATE_READY
;
2830 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2831 errorstate
= SDMMC_CmdSendStatus(hmmc
->Instance
, (uint32_t)(((uint32_t)hmmc
->MmcCard
.RelCardAdd
) << 16));
2832 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2834 hmmc
->ErrorCode
|= errorstate
;
2837 /* Clear all the static flags */
2838 __HAL_MMC_CLEAR_FLAG(hmmc
, SDMMC_STATIC_DATA_FLAGS
);
2840 hmmc
->State
= HAL_MMC_STATE_READY
;
2846 * @brief Wrap up reading in non-blocking mode.
2847 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2848 * the configuration information.
2851 static void MMC_Read_IT(MMC_HandleTypeDef
*hmmc
)
2853 uint32_t count
, data
;
2856 tmp
= hmmc
->pRxBuffPtr
;
2858 if (hmmc
->RxXferSize
>= 32U)
2860 /* Read data from SDMMC Rx FIFO */
2861 for(count
= 0U; count
< 8U; count
++)
2863 data
= SDMMC_ReadFIFO(hmmc
->Instance
);
2864 *tmp
= (uint8_t)(data
& 0xFFU
);
2866 *tmp
= (uint8_t)((data
>> 8U) & 0xFFU
);
2868 *tmp
= (uint8_t)((data
>> 16U) & 0xFFU
);
2870 *tmp
= (uint8_t)((data
>> 24U) & 0xFFU
);
2874 hmmc
->pRxBuffPtr
= tmp
;
2875 hmmc
->RxXferSize
-= 32U;
2880 * @brief Wrap up writing in non-blocking mode.
2881 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2882 * the configuration information.
2885 static void MMC_Write_IT(MMC_HandleTypeDef
*hmmc
)
2887 uint32_t count
, data
;
2890 tmp
= hmmc
->pTxBuffPtr
;
2892 if (hmmc
->TxXferSize
>= 32U)
2894 /* Write data to SDMMC Tx FIFO */
2895 for(count
= 0U; count
< 8U; count
++)
2897 data
= (uint32_t)(*tmp
);
2899 data
|= ((uint32_t)(*tmp
) << 8U);
2901 data
|= ((uint32_t)(*tmp
) << 16U);
2903 data
|= ((uint32_t)(*tmp
) << 24U);
2905 (void)SDMMC_WriteFIFO(hmmc
->Instance
, &data
);
2908 hmmc
->pTxBuffPtr
= tmp
;
2909 hmmc
->TxXferSize
-= 32U;
2914 * @brief Switches the MMC card to high speed mode.
2915 * @param hmmc: MMC handle
2916 * @param state: State of high speed mode
2917 * @retval MMC Card error state
2919 static uint32_t MMC_HighSpeed(MMC_HandleTypeDef
*hmmc
, FunctionalState state
)
2921 uint32_t errorstate
= HAL_MMC_ERROR_NONE
;
2922 uint32_t response
, count
;
2923 SDMMC_InitTypeDef Init
;
2925 if (((hmmc
->Instance
->CLKCR
& SDMMC_CLKCR_BUSSPEED
) != 0U) && (state
== DISABLE
))
2927 /* Index : 185 - Value : 0 */
2928 errorstate
= SDMMC_CmdSwitch(hmmc
->Instance
, 0x03B90000U
);
2931 if (((hmmc
->Instance
->CLKCR
& SDMMC_CLKCR_BUSSPEED
) == 0U) && (state
!= DISABLE
))
2933 /* Index : 185 - Value : 1 */
2934 errorstate
= SDMMC_CmdSwitch(hmmc
->Instance
, 0x03B90100U
);
2937 if(errorstate
== HAL_MMC_ERROR_NONE
)
2939 /* Check for switch error */
2940 errorstate
= SDMMC_CmdSendStatus(hmmc
->Instance
, (uint32_t)(((uint32_t)hmmc
->MmcCard
.RelCardAdd
) << 16U));
2941 if(errorstate
== HAL_MMC_ERROR_NONE
)
2943 /* Get command response */
2944 response
= SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP1
);
2945 if ((response
& 0x80U
) != 0U)
2947 errorstate
= SDMMC_ERROR_UNSUPPORTED_FEATURE
;
2951 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2952 count
= SDMMC_MAX_TRIAL
;
2953 while(((response
& 0x100U
) == 0U) && (count
!= 0U))
2957 errorstate
= SDMMC_CmdSendStatus(hmmc
->Instance
, (uint32_t)(((uint32_t)hmmc
->MmcCard
.RelCardAdd
) << 16U));
2958 if(errorstate
!= HAL_MMC_ERROR_NONE
)
2963 /* Get command response */
2964 response
= SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP1
);
2967 /* Configure high speed */
2968 if ((count
!= 0U) && (errorstate
== HAL_MMC_ERROR_NONE
))
2970 Init
.ClockEdge
= hmmc
->Init
.ClockEdge
;
2971 Init
.ClockPowerSave
= hmmc
->Init
.ClockPowerSave
;
2972 Init
.BusWide
= (hmmc
->Instance
->CLKCR
& SDMMC_CLKCR_WIDBUS
);
2973 Init
.HardwareFlowControl
= hmmc
->Init
.HardwareFlowControl
;
2975 if (state
== DISABLE
)
2977 Init
.ClockDiv
= hmmc
->Init
.ClockDiv
;
2978 (void)SDMMC_Init(hmmc
->Instance
, Init
);
2980 CLEAR_BIT(hmmc
->Instance
->CLKCR
, SDMMC_CLKCR_BUSSPEED
);
2984 Init
.ClockDiv
= SDMMC_HSpeed_CLK_DIV
;
2985 (void)SDMMC_Init(hmmc
->Instance
, Init
);
2987 SET_BIT(hmmc
->Instance
->CLKCR
, SDMMC_CLKCR_BUSSPEED
);
2998 * @brief Switches the MMC card to Double Data Rate (DDR) mode.
2999 * @param hmmc: MMC handle
3000 * @param state: State of DDR mode
3001 * @retval MMC Card error state
3003 static uint32_t MMC_DDR_Mode(MMC_HandleTypeDef
*hmmc
, FunctionalState state
)
3005 uint32_t errorstate
= HAL_MMC_ERROR_NONE
;
3006 uint32_t response
, count
;
3008 if (((hmmc
->Instance
->CLKCR
& SDMMC_CLKCR_DDR
) != 0U) && (state
== DISABLE
))
3010 if ((hmmc
->Instance
->CLKCR
& SDMMC_CLKCR_WIDBUS_0
) != 0U)
3012 /* Index : 183 - Value : 1 */
3013 errorstate
= SDMMC_CmdSwitch(hmmc
->Instance
, 0x03B70100U
);
3017 /* Index : 183 - Value : 2 */
3018 errorstate
= SDMMC_CmdSwitch(hmmc
->Instance
, 0x03B70200U
);
3022 if (((hmmc
->Instance
->CLKCR
& SDMMC_CLKCR_DDR
) == 0U) && (state
!= DISABLE
))
3024 if ((hmmc
->Instance
->CLKCR
& SDMMC_CLKCR_WIDBUS_0
) != 0U)
3026 /* Index : 183 - Value : 5 */
3027 errorstate
= SDMMC_CmdSwitch(hmmc
->Instance
, 0x03B70500U
);
3031 /* Index : 183 - Value : 6 */
3032 errorstate
= SDMMC_CmdSwitch(hmmc
->Instance
, 0x03B70600U
);
3036 if(errorstate
== HAL_MMC_ERROR_NONE
)
3038 /* Check for switch error */
3039 errorstate
= SDMMC_CmdSendStatus(hmmc
->Instance
, (uint32_t)(((uint32_t)hmmc
->MmcCard
.RelCardAdd
) << 16U));
3040 if(errorstate
== HAL_MMC_ERROR_NONE
)
3042 /* Get command response */
3043 response
= SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP1
);
3044 if ((response
& 0x80U
) != 0U)
3046 errorstate
= SDMMC_ERROR_UNSUPPORTED_FEATURE
;
3050 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
3051 count
= SDMMC_MAX_TRIAL
;
3052 while(((response
& 0x100U
) == 0U) && (count
!= 0U))
3056 errorstate
= SDMMC_CmdSendStatus(hmmc
->Instance
, (uint32_t)(((uint32_t)hmmc
->MmcCard
.RelCardAdd
) << 16U));
3057 if(errorstate
!= HAL_MMC_ERROR_NONE
)
3062 /* Get command response */
3063 response
= SDMMC_GetResponse(hmmc
->Instance
, SDMMC_RESP1
);
3066 /* Configure DDR mode */
3067 if ((count
!= 0U) && (errorstate
== HAL_MMC_ERROR_NONE
))
3069 if (state
== DISABLE
)
3071 CLEAR_BIT(hmmc
->Instance
->CLKCR
, SDMMC_CLKCR_DDR
);
3075 SET_BIT(hmmc
->Instance
->CLKCR
, SDMMC_CLKCR_DDR
);
3086 * @brief Read DMA Buffer 0 Transfer completed callbacks
3087 * @param hmmc: MMC handle
3090 __weak
void HAL_MMCEx_Read_DMADoubleBuf0CpltCallback(MMC_HandleTypeDef
*hmmc
)
3092 /* Prevent unused argument(s) compilation warning */
3095 /* NOTE : This function should not be modified, when the callback is needed,
3096 the HAL_MMCEx_Read_DMADoubleBuf0CpltCallback can be implemented in the user file
3101 * @brief Read DMA Buffer 1 Transfer completed callbacks
3102 * @param hmmc: MMC handle
3105 __weak
void HAL_MMCEx_Read_DMADoubleBuf1CpltCallback(MMC_HandleTypeDef
*hmmc
)
3107 /* Prevent unused argument(s) compilation warning */
3110 /* NOTE : This function should not be modified, when the callback is needed,
3111 the HAL_MMCEx_Read_DMADoubleBuf1CpltCallback can be implemented in the user file
3116 * @brief Write DMA Buffer 0 Transfer completed callbacks
3117 * @param hmmc: MMC handle
3120 __weak
void HAL_MMCEx_Write_DMADoubleBuf0CpltCallback(MMC_HandleTypeDef
*hmmc
)
3122 /* Prevent unused argument(s) compilation warning */
3125 /* NOTE : This function should not be modified, when the callback is needed,
3126 the HAL_MMCEx_Write_DMADoubleBuf0CpltCallback can be implemented in the user file
3131 * @brief Write DMA Buffer 1 Transfer completed callbacks
3132 * @param hmmc: MMC handle
3135 __weak
void HAL_MMCEx_Write_DMADoubleBuf1CpltCallback(MMC_HandleTypeDef
*hmmc
)
3137 /* Prevent unused argument(s) compilation warning */
3140 /* NOTE : This function should not be modified, when the callback is needed,
3141 the HAL_MMCEx_Write_DMADoubleBuf1CpltCallback can be implemented in the user file
3149 #endif /* HAL_MMC_MODULE_ENABLED */
3159 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/