Update MixerProfile.md
[inav.git] / lib / main / STM32F4 / Drivers / STM32F4xx_HAL_Driver / Src / stm32f4xx_hal_mmc.c
blob04d269c6fb607f37886e2da2facda26f3e5ea6d4
1 /**
2 ******************************************************************************
3 * @file stm32f4xx_hal_mmc.c
4 * @author MCD Application Team
5 * @version V1.7.1
6 * @date 14-April-2017
7 * @brief MMC card HAL module driver.
8 * This file provides firmware functions to manage the following
9 * functionalities of the Secure Digital (MMC) peripheral:
10 * + Initialization and de-initialization functions
11 * + IO operation functions
12 * + Peripheral Control functions
13 * + MMC card Control functions
15 @verbatim
16 ==============================================================================
17 ##### How to use this driver #####
18 ==============================================================================
19 [..]
20 This driver implements a high level communication layer for read and write from/to
21 this memory. The needed STM32 hardware resources (SDMMC and GPIO) are performed by
22 the user in HAL_MMC_MspInit() function (MSP layer).
23 Basically, the MSP layer configuration should be the same as we provide in the
24 examples.
25 You can easily tailor this configuration according to hardware resources.
27 [..]
28 This driver is a generic layered driver for SDMMC memories which uses the HAL
29 SDMMC driver functions to interface with MMC and eMMC cards devices.
30 It is used as follows:
32 (#)Initialize the SDMMC low level resources by implement the HAL_MMC_MspInit() API:
33 (##) Enable the SDMMC interface clock using __HAL_RCC_SDMMC_CLK_ENABLE();
34 (##) SDMMC pins configuration for MMC card
35 (+++) Enable the clock for the SDMMC GPIOs using the functions __HAL_RCC_GPIOx_CLK_ENABLE();
36 (+++) Configure these SDMMC pins as alternate function pull-up using HAL_GPIO_Init()
37 and according to your pin assignment;
38 (##) DMA Configuration if you need to use DMA process (HAL_MMC_ReadBlocks_DMA()
39 and HAL_MMC_WriteBlocks_DMA() APIs).
40 (+++) Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE();
41 (+++) Configure the DMA using the function HAL_DMA_Init() with predeclared and filled.
42 (##) NVIC configuration if you need to use interrupt process when using DMA transfer.
43 (+++) Configure the SDMMC and DMA interrupt priorities using functions
44 HAL_NVIC_SetPriority(); DMA priority is superior to SDMMC's priority
45 (+++) Enable the NVIC DMA and SDMMC IRQs using function HAL_NVIC_EnableIRQ()
46 (+++) SDMMC interrupts are managed using the macros __HAL_MMC_ENABLE_IT()
47 and __HAL_MMC_DISABLE_IT() inside the communication process.
48 (+++) SDMMC interrupts pending bits are managed using the macros __HAL_MMC_GET_IT()
49 and __HAL_MMC_CLEAR_IT()
50 (##) NVIC configuration if you need to use interrupt process (HAL_MMC_ReadBlocks_IT()
51 and HAL_MMC_WriteBlocks_IT() APIs).
52 (+++) Configure the SDMMC interrupt priorities using function
53 HAL_NVIC_SetPriority();
54 (+++) Enable the NVIC SDMMC IRQs using function HAL_NVIC_EnableIRQ()
55 (+++) SDMMC interrupts are managed using the macros __HAL_MMC_ENABLE_IT()
56 and __HAL_MMC_DISABLE_IT() inside the communication process.
57 (+++) SDMMC interrupts pending bits are managed using the macros __HAL_MMC_GET_IT()
58 and __HAL_MMC_CLEAR_IT()
59 (#) At this stage, you can perform MMC read/write/erase operations after MMC card initialization
62 *** MMC Card Initialization and configuration ***
63 ================================================
64 [..]
65 To initialize the MMC Card, use the HAL_MMC_Init() function. It Initializes
66 SDMMC IP (STM32 side) and the MMC Card, and put it into StandBy State (Ready for data transfer).
67 This function provide the following operations:
69 (#) Initialize the SDMMC peripheral interface with defaullt configuration.
70 The initialization process is done at 400KHz. You can change or adapt
71 this frequency by adjusting the "ClockDiv" field.
72 The MMC Card frequency (SDMMC_CK) is computed as follows:
74 SDMMC_CK = SDMMCCLK / (ClockDiv + 2)
76 In initialization mode and according to the MMC Card standard,
77 make sure that the SDMMC_CK frequency doesn't exceed 400KHz.
79 This phase of initialization is done through SDMMC_Init() and
80 SDMMC_PowerState_ON() SDMMC low level APIs.
82 (#) Initialize the MMC card. The API used is HAL_MMC_InitCard().
83 This phase allows the card initialization and identification
84 and check the MMC Card type (Standard Capacity or High Capacity)
85 The initialization flow is compatible with MMC standard.
87 This API (HAL_MMC_InitCard()) could be used also to reinitialize the card in case
88 of plug-off plug-in.
90 (#) Configure the MMC Card Data transfer frequency. By Default, the card transfer
91 frequency is set to 24MHz. You can change or adapt this frequency by adjusting
92 the "ClockDiv" field.
93 In transfer mode and according to the MMC Card standard, make sure that the
94 SDMMC_CK frequency doesn't exceed 25MHz and 50MHz in High-speed mode switch.
95 To be able to use a frequency higher than 24MHz, you should use the SDMMC
96 peripheral in bypass mode. Refer to the corresponding reference manual
97 for more details.
99 (#) Select the corresponding MMC Card according to the address read with the step 2.
101 (#) Configure the MMC Card in wide bus mode: 4-bits data.
103 *** MMC Card Read operation ***
104 ==============================
105 [..]
106 (+) You can read from MMC card in polling mode by using function HAL_MMC_ReadBlocks().
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.
113 (+) You can read from MMC card in DMA mode by using function HAL_MMC_ReadBlocks_DMA().
114 This function allows the read of 512 bytes blocks.
115 You can choose either one block read operation or multiple block read operation
116 by adjusting the "NumberOfBlocks" parameter.
117 After this, you have to ensure that the transfer is done correctly. The check is done
118 through HAL_MMC_GetCardState() function for MMC card state.
119 You could also check the DMA transfer process through the MMC Rx interrupt event.
121 (+) You can read from MMC card in Interrupt mode by using function HAL_MMC_ReadBlocks_IT().
122 This function allows the read of 512 bytes blocks.
123 You can choose either one block read operation or multiple block read operation
124 by adjusting the "NumberOfBlocks" parameter.
125 After this, you have to ensure that the transfer is done correctly. The check is done
126 through HAL_MMC_GetCardState() function for MMC card state.
127 You could also check the IT transfer process through the MMC Rx interrupt event.
129 *** MMC Card Write operation ***
130 ===============================
131 [..]
132 (+) You can write to MMC card in polling mode by using function HAL_MMC_WriteBlocks().
133 This function allows the read of 512 bytes blocks.
134 You can choose either one block read operation or multiple block read operation
135 by adjusting the "NumberOfBlocks" parameter.
136 After this, you have to ensure that the transfer is done correctly. The check is done
137 through HAL_MMC_GetCardState() function for MMC card state.
139 (+) You can write to MMC card in DMA mode by using function HAL_MMC_WriteBlocks_DMA().
140 This function allows the read of 512 bytes blocks.
141 You can choose either one block read operation or multiple block read operation
142 by adjusting the "NumberOfBlocks" parameter.
143 After this, you have to ensure that the transfer is done correctly. The check is done
144 through HAL_MMC_GetCardState() function for MMC card state.
145 You could also check the DMA transfer process through the MMC Tx interrupt event.
147 (+) You can write to MMC card in Interrupt mode by using function HAL_MMC_WriteBlocks_IT().
148 This function allows the read of 512 bytes blocks.
149 You can choose either one block read operation or multiple block read operation
150 by adjusting the "NumberOfBlocks" parameter.
151 After this, you have to ensure that the transfer is done correctly. The check is done
152 through HAL_MMC_GetCardState() function for MMC card state.
153 You could also check the IT transfer process through the MMC Tx interrupt event.
155 *** MMC card status ***
156 ======================
157 [..]
158 (+) The MMC Status contains status bits that are related to the MMC Memory
159 Card proprietary features. To get MMC card status use the HAL_MMC_GetCardStatus().
161 *** MMC card information ***
162 ===========================
163 [..]
164 (+) To get MMC card information, you can use the function HAL_MMC_GetCardInfo().
165 It returns useful information about the MMC card such as block size, card type,
166 block number ...
168 *** MMC card CSD register ***
169 ============================
170 [..]
171 (+) The HAL_MMC_GetCardCSD() API allows to get the parameters of the CSD register.
172 Some of the CSD parameters are useful for card initialization and identification.
174 *** MMC card CID register ***
175 ============================
176 [..]
177 (+) The HAL_MMC_GetCardCID() API allows to get the parameters of the CID register.
178 Some of the CID parameters are useful for card initialization and identification.
180 *** MMC HAL driver macros list ***
181 ==================================
182 [..]
183 Below the list of most used macros in MMC HAL driver.
185 (+) __HAL_MMC_ENABLE : Enable the MMC device
186 (+) __HAL_MMC_DISABLE : Disable the MMC device
187 (+) __HAL_MMC_DMA_ENABLE: Enable the SDMMC DMA transfer
188 (+) __HAL_MMC_DMA_DISABLE: Disable the SDMMC DMA transfer
189 (+) __HAL_MMC_ENABLE_IT: Enable the MMC device interrupt
190 (+) __HAL_MMC_DISABLE_IT: Disable the MMC device interrupt
191 (+) __HAL_MMC_GET_FLAG:Check whether the specified MMC flag is set or not
192 (+) __HAL_MMC_CLEAR_FLAG: Clear the MMC's pending flags
194 [..]
195 (@) You can refer to the MMC HAL driver header file for more useful macros
197 @endverbatim
198 ******************************************************************************
199 * @attention
201 * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
203 * Redistribution and use in source and binary forms, with or without modification,
204 * are permitted provided that the following conditions are met:
205 * 1. Redistributions of source code must retain the above copyright notice,
206 * this list of conditions and the following disclaimer.
207 * 2. Redistributions in binary form must reproduce the above copyright notice,
208 * this list of conditions and the following disclaimer in the documentation
209 * and/or other materials provided with the distribution.
210 * 3. Neither the name of STMicroelectronics nor the names of its contributors
211 * may be used to endorse or promote products derived from this software
212 * without specific prior written permission.
214 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
215 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
216 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
217 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
218 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
219 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
220 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
221 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
222 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
223 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
225 ******************************************************************************
228 /* Includes ------------------------------------------------------------------*/
229 #include "stm32f4xx_hal.h"
231 /** @addtogroup STM32F4xx_HAL_Driver
232 * @{
235 /** @addtogroup MMC
236 * @{
239 #ifdef HAL_MMC_MODULE_ENABLED
241 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || \
242 defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || \
243 defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) || \
244 defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || \
245 defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
247 /* Private typedef -----------------------------------------------------------*/
248 /* Private define ------------------------------------------------------------*/
249 /** @addtogroup MMC_Private_Defines
250 * @{
254 * @}
257 /* Private macro -------------------------------------------------------------*/
258 /* Private variables ---------------------------------------------------------*/
259 /* Private function prototypes -----------------------------------------------*/
260 /* Private functions ---------------------------------------------------------*/
261 /** @defgroup MMC_Private_Functions MMC Private Functions
262 * @{
264 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc);
265 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc);
266 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus);
267 static HAL_StatusTypeDef MMC_PowerOFF(MMC_HandleTypeDef *hmmc);
268 static HAL_StatusTypeDef MMC_Write_IT(MMC_HandleTypeDef *hmmc);
269 static HAL_StatusTypeDef MMC_Read_IT(MMC_HandleTypeDef *hmmc);
270 static void MMC_DMATransmitCplt(DMA_HandleTypeDef *hdma);
271 static void MMC_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
272 static void MMC_DMAError(DMA_HandleTypeDef *hdma);
273 static void MMC_DMATxAbort(DMA_HandleTypeDef *hdma);
274 static void MMC_DMARxAbort(DMA_HandleTypeDef *hdma);
276 * @}
279 /* Exported functions --------------------------------------------------------*/
280 /** @addtogroup MMC_Exported_Functions
281 * @{
284 /** @addtogroup MMC_Exported_Functions_Group1
285 * @brief Initialization and de-initialization functions
287 @verbatim
288 ==============================================================================
289 ##### Initialization and de-initialization functions #####
290 ==============================================================================
291 [..]
292 This section provides functions allowing to initialize/de-initialize the MMC
293 card device to be ready for use.
295 @endverbatim
296 * @{
300 * @brief Initializes the MMC according to the specified parameters in the
301 MMC_HandleTypeDef and create the associated handle.
302 * @param hmmc: Pointer to the MMC handle
303 * @retval HAL status
305 HAL_StatusTypeDef HAL_MMC_Init(MMC_HandleTypeDef *hmmc)
307 /* Check the MMC handle allocation */
308 if(hmmc == NULL)
310 return HAL_ERROR;
313 /* Check the parameters */
314 assert_param(IS_SDIO_ALL_INSTANCE(hmmc->Instance));
315 assert_param(IS_SDIO_CLOCK_EDGE(hmmc->Init.ClockEdge));
316 assert_param(IS_SDIO_CLOCK_BYPASS(hmmc->Init.ClockBypass));
317 assert_param(IS_SDIO_CLOCK_POWER_SAVE(hmmc->Init.ClockPowerSave));
318 assert_param(IS_SDIO_BUS_WIDE(hmmc->Init.BusWide));
319 assert_param(IS_SDIO_HARDWARE_FLOW_CONTROL(hmmc->Init.HardwareFlowControl));
320 assert_param(IS_SDIO_CLKDIV(hmmc->Init.ClockDiv));
322 if(hmmc->State == HAL_MMC_STATE_RESET)
324 /* Allocate lock resource and initialize it */
325 hmmc->Lock = HAL_UNLOCKED;
326 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
327 HAL_MMC_MspInit(hmmc);
330 hmmc->State = HAL_MMC_STATE_BUSY;
332 /* Initialize the Card parameters */
333 HAL_MMC_InitCard(hmmc);
335 /* Initialize the error code */
336 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
338 /* Initialize the MMC operation */
339 hmmc->Context = MMC_CONTEXT_NONE;
341 /* Initialize the MMC state */
342 hmmc->State = HAL_MMC_STATE_READY;
344 return HAL_OK;
348 * @brief Initializes the MMC Card.
349 * @param hmmc: Pointer to MMC handle
350 * @note This function initializes the MMC card. It could be used when a card
351 re-initialization is needed.
352 * @retval HAL status
354 HAL_StatusTypeDef HAL_MMC_InitCard(MMC_HandleTypeDef *hmmc)
356 uint32_t errorstate = HAL_MMC_ERROR_NONE;
357 MMC_InitTypeDef Init;
359 /* Default SDMMC peripheral configuration for MMC card initialization */
360 Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
361 Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
362 Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
363 Init.BusWide = SDIO_BUS_WIDE_1B;
364 Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
365 Init.ClockDiv = SDIO_INIT_CLK_DIV;
367 /* Initialize SDMMC peripheral interface with default configuration */
368 SDIO_Init(hmmc->Instance, Init);
370 /* Disable SDMMC Clock */
371 __HAL_MMC_DISABLE(hmmc);
373 /* Set Power State to ON */
374 SDIO_PowerState_ON(hmmc->Instance);
376 /* Enable SDMMC Clock */
377 __HAL_MMC_ENABLE(hmmc);
379 /* Required power up waiting time before starting the SD initialization
380 sequence */
381 HAL_Delay(2U);
383 /* Identify card operating voltage */
384 errorstate = MMC_PowerON(hmmc);
385 if(errorstate != HAL_MMC_ERROR_NONE)
387 hmmc->State = HAL_MMC_STATE_READY;
388 hmmc->ErrorCode |= errorstate;
389 return HAL_ERROR;
392 /* Card initialization */
393 errorstate = MMC_InitCard(hmmc);
394 if(errorstate != HAL_MMC_ERROR_NONE)
396 hmmc->State = HAL_MMC_STATE_READY;
397 hmmc->ErrorCode |= errorstate;
398 return HAL_ERROR;
401 return HAL_OK;
405 * @brief De-Initializes the MMC card.
406 * @param hmmc: Pointer to MMC handle
407 * @retval HAL status
409 HAL_StatusTypeDef HAL_MMC_DeInit(MMC_HandleTypeDef *hmmc)
411 /* Check the MMC handle allocation */
412 if(hmmc == NULL)
414 return HAL_ERROR;
417 /* Check the parameters */
418 assert_param(IS_SDIO_ALL_INSTANCE(hmmc->Instance));
420 hmmc->State = HAL_MMC_STATE_BUSY;
422 /* Set SD power state to off */
423 MMC_PowerOFF(hmmc);
425 /* De-Initialize the MSP layer */
426 HAL_MMC_MspDeInit(hmmc);
428 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
429 hmmc->State = HAL_MMC_STATE_RESET;
431 return HAL_OK;
436 * @brief Initializes the MMC MSP.
437 * @param hmmc: Pointer to MMC handle
438 * @retval None
440 __weak void HAL_MMC_MspInit(MMC_HandleTypeDef *hmmc)
442 /* Prevent unused argument(s) compilation warning */
443 UNUSED(hmmc);
445 /* NOTE : This function Should not be modified, when the callback is needed,
446 the HAL_MMC_MspInit could be implemented in the user file
451 * @brief De-Initialize MMC MSP.
452 * @param hmmc: Pointer to MMC handle
453 * @retval None
455 __weak void HAL_MMC_MspDeInit(MMC_HandleTypeDef *hmmc)
457 /* Prevent unused argument(s) compilation warning */
458 UNUSED(hmmc);
460 /* NOTE : This function Should not be modified, when the callback is needed,
461 the HAL_MMC_MspDeInit could be implemented in the user file
466 * @}
469 /** @addtogroup MMC_Exported_Functions_Group2
470 * @brief Data transfer functions
472 @verbatim
473 ==============================================================================
474 ##### IO operation functions #####
475 ==============================================================================
476 [..]
477 This subsection provides a set of functions allowing to manage the data
478 transfer from/to MMC card.
480 @endverbatim
481 * @{
485 * @brief Reads block(s) from a specified address in a card. The Data transfer
486 * is managed by polling mode.
487 * @note This API should be followed by a check on the card state through
488 * HAL_MMC_GetCardState().
489 * @param hmmc: Pointer to MMC handle
490 * @param pData: pointer to the buffer that will contain the received data
491 * @param BlockAdd: Block Address from where data is to be read
492 * @param NumberOfBlocks: Number of MMC blocks to read
493 * @param Timeout: Specify timeout value
494 * @retval HAL status
496 HAL_StatusTypeDef HAL_MMC_ReadBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
498 SDIO_DataInitTypeDef config;
499 uint32_t errorstate = HAL_MMC_ERROR_NONE;
500 uint32_t tickstart = HAL_GetTick();
501 uint32_t count = 0U, *tempbuff = (uint32_t *)pData;
503 if(NULL == pData)
505 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
506 return HAL_ERROR;
509 if(hmmc->State == HAL_MMC_STATE_READY)
511 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
513 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
515 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
516 return HAL_ERROR;
519 hmmc->State = HAL_MMC_STATE_BUSY;
521 /* Initialize data control register */
522 hmmc->Instance->DCTRL = 0U;
524 /* Check the Card capacity in term of Logical number of blocks */
525 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
527 BlockAdd *= 512U;
530 /* Set Block Size for Card */
531 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
532 if(errorstate != HAL_MMC_ERROR_NONE)
534 /* Clear all the static flags */
535 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
536 hmmc->ErrorCode |= errorstate;
537 hmmc->State = HAL_MMC_STATE_READY;
538 return HAL_ERROR;
541 /* Configure the MMC DPSM (Data Path State Machine) */
542 config.DataTimeOut = SDMMC_DATATIMEOUT;
543 config.DataLength = NumberOfBlocks * BLOCKSIZE;
544 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
545 config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
546 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
547 config.DPSM = SDIO_DPSM_ENABLE;
548 SDIO_ConfigData(hmmc->Instance, &config);
550 /* Read block(s) in polling mode */
551 if(NumberOfBlocks > 1U)
553 hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
555 /* Read Multi Block command */
556 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, BlockAdd);
558 else
560 hmmc->Context = MMC_CONTEXT_READ_SINGLE_BLOCK;
562 /* Read Single Block command */
563 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, BlockAdd);
565 if(errorstate != HAL_MMC_ERROR_NONE)
567 /* Clear all the static flags */
568 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
569 hmmc->ErrorCode |= errorstate;
570 hmmc->State = HAL_MMC_STATE_READY;
571 return HAL_ERROR;
574 /* Poll on SDMMC flags */
575 #ifdef SDIO_STA_STBITERR
576 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_STA_STBITERR))
577 #else /* SDIO_STA_STBITERR not defined */
578 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND))
579 #endif /* SDIO_STA_STBITERR */
581 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXFIFOHF))
583 /* Read data from SDMMC Rx FIFO */
584 for(count = 0U; count < 8U; count++)
586 *(tempbuff + count) = SDIO_ReadFIFO(hmmc->Instance);
588 tempbuff += 8U;
591 if((Timeout == 0U)||((HAL_GetTick()-tickstart) >= Timeout))
593 /* Clear all the static flags */
594 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
595 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
596 hmmc->State= HAL_MMC_STATE_READY;
597 return HAL_TIMEOUT;
601 /* Send stop transmission command in case of multiblock read */
602 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1U))
604 /* Send stop transmission command */
605 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
606 if(errorstate != HAL_MMC_ERROR_NONE)
608 /* Clear all the static flags */
609 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
610 hmmc->ErrorCode |= errorstate;
611 hmmc->State = HAL_MMC_STATE_READY;
612 return HAL_ERROR;
616 /* Get error state */
617 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DTIMEOUT))
619 /* Clear all the static flags */
620 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
621 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
622 hmmc->State = HAL_MMC_STATE_READY;
623 return HAL_ERROR;
625 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL))
627 /* Clear all the static flags */
628 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
629 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
630 hmmc->State = HAL_MMC_STATE_READY;
631 return HAL_ERROR;
633 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR))
635 /* Clear all the static flags */
636 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
637 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
638 hmmc->State = HAL_MMC_STATE_READY;
639 return HAL_ERROR;
642 /* Empty FIFO if there is still any data */
643 while ((__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXDAVL)))
645 *tempbuff = SDIO_ReadFIFO(hmmc->Instance);
646 tempbuff++;
648 if((Timeout == 0U)||((HAL_GetTick()-tickstart) >= Timeout))
650 /* Clear all the static flags */
651 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
652 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
653 hmmc->State= HAL_MMC_STATE_READY;
654 return HAL_ERROR;
658 /* Clear all the static flags */
659 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
661 hmmc->State = HAL_MMC_STATE_READY;
663 return HAL_OK;
665 else
667 hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
668 return HAL_ERROR;
673 * @brief Allows to write block(s) to a specified address in a card. The Data
674 * transfer is managed by polling mode.
675 * @note This API should be followed by a check on the card state through
676 * HAL_MMC_GetCardState().
677 * @param hmmc: Pointer to MMC handle
678 * @param pData: pointer to the buffer that will contain the data to transmit
679 * @param BlockAdd: Block Address where data will be written
680 * @param NumberOfBlocks: Number of MMC blocks to write
681 * @param Timeout: Specify timeout value
682 * @retval HAL status
684 HAL_StatusTypeDef HAL_MMC_WriteBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
686 SDIO_DataInitTypeDef config;
687 uint32_t errorstate = HAL_MMC_ERROR_NONE;
688 uint32_t tickstart = HAL_GetTick();
689 uint32_t count = 0U;
690 uint32_t *tempbuff = (uint32_t *)pData;
692 if(NULL == pData)
694 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
695 return HAL_ERROR;
698 if(hmmc->State == HAL_MMC_STATE_READY)
700 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
702 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
704 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
705 return HAL_ERROR;
708 hmmc->State = HAL_MMC_STATE_BUSY;
710 /* Initialize data control register */
711 hmmc->Instance->DCTRL = 0U;
713 /* Check the Card capacity in term of Logical number of blocks */
714 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
716 BlockAdd *= 512U;
719 /* Set Block Size for Card */
720 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
721 if(errorstate != HAL_MMC_ERROR_NONE)
723 /* Clear all the static flags */
724 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
725 hmmc->ErrorCode |= errorstate;
726 hmmc->State = HAL_MMC_STATE_READY;
727 return HAL_ERROR;
730 /* Write Blocks in Polling mode */
731 if(NumberOfBlocks > 1U)
733 hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
735 /* Write Multi Block command */
736 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, BlockAdd);
738 else
740 hmmc->Context = MMC_CONTEXT_WRITE_SINGLE_BLOCK;
742 /* Write Single Block command */
743 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, BlockAdd);
745 if(errorstate != HAL_MMC_ERROR_NONE)
747 /* Clear all the static flags */
748 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
749 hmmc->ErrorCode |= errorstate;
750 hmmc->State = HAL_MMC_STATE_READY;
751 return HAL_ERROR;
754 /* Configure the MMC DPSM (Data Path State Machine) */
755 config.DataTimeOut = SDMMC_DATATIMEOUT;
756 config.DataLength = NumberOfBlocks * BLOCKSIZE;
757 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
758 config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
759 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
760 config.DPSM = SDIO_DPSM_ENABLE;
761 SDIO_ConfigData(hmmc->Instance, &config);
763 /* Write block(s) in polling mode */
764 #ifdef SDIO_STA_STBITERR
765 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_FLAG_STBITERR))
766 #else /* SDIO_STA_STBITERR not defined */
767 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND))
768 #endif /* SDIO_STA_STBITERR */
770 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXFIFOHE))
772 /* Write data to SDIO Tx FIFO */
773 for(count = 0U; count < 8U; count++)
775 SDIO_WriteFIFO(hmmc->Instance, (tempbuff + count));
777 tempbuff += 8U;
780 if((Timeout == 0U)||((HAL_GetTick()-tickstart) >= Timeout))
782 /* Clear all the static flags */
783 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
784 hmmc->ErrorCode |= errorstate;
785 hmmc->State = HAL_MMC_STATE_READY;
786 return HAL_TIMEOUT;
790 /* Send stop transmission command in case of multiblock write */
791 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1U))
793 /* Send stop transmission command */
794 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
795 if(errorstate != HAL_MMC_ERROR_NONE)
797 /* Clear all the static flags */
798 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
799 hmmc->ErrorCode |= errorstate;
800 hmmc->State = HAL_MMC_STATE_READY;
801 return HAL_ERROR;
805 /* Get error state */
806 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DTIMEOUT))
808 /* Clear all the static flags */
809 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
810 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
811 hmmc->State = HAL_MMC_STATE_READY;
812 return HAL_ERROR;
814 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL))
816 /* Clear all the static flags */
817 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
818 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
819 hmmc->State = HAL_MMC_STATE_READY;
820 return HAL_ERROR;
822 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR))
824 /* Clear all the static flags */
825 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
826 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
827 hmmc->State = HAL_MMC_STATE_READY;
828 return HAL_ERROR;
831 /* Clear all the static flags */
832 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
834 hmmc->State = HAL_MMC_STATE_READY;
836 return HAL_OK;
838 else
840 hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
841 return HAL_ERROR;
846 * @brief Reads block(s) from a specified address in a card. The Data transfer
847 * is managed in interrupt mode.
848 * @note This API should be followed by a check on the card state through
849 * HAL_MMC_GetCardState().
850 * @note You could also check the IT transfer process through the MMC Rx
851 * interrupt event.
852 * @param hmmc: Pointer to MMC handle
853 * @param pData: Pointer to the buffer that will contain the received data
854 * @param BlockAdd: Block Address from where data is to be read
855 * @param NumberOfBlocks: Number of blocks to read.
856 * @retval HAL status
858 HAL_StatusTypeDef HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
860 SDIO_DataInitTypeDef config;
861 uint32_t errorstate = HAL_MMC_ERROR_NONE;
863 if(NULL == pData)
865 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
866 return HAL_ERROR;
869 if(hmmc->State == HAL_MMC_STATE_READY)
871 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
873 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
875 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
876 return HAL_ERROR;
879 hmmc->State = HAL_MMC_STATE_BUSY;
881 /* Initialize data control register */
882 hmmc->Instance->DCTRL = 0U;
884 hmmc->pRxBuffPtr = (uint32_t *)pData;
885 hmmc->RxXferSize = BLOCKSIZE * NumberOfBlocks;
887 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_FLAG_RXFIFOHF));
889 /* Check the Card capacity in term of Logical number of blocks */
890 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
892 BlockAdd *= 512U;
895 /* Configure the MMC DPSM (Data Path State Machine) */
896 config.DataTimeOut = SDMMC_DATATIMEOUT;
897 config.DataLength = BLOCKSIZE * NumberOfBlocks;
898 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
899 config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
900 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
901 config.DPSM = SDIO_DPSM_ENABLE;
902 SDIO_ConfigData(hmmc->Instance, &config);
904 /* Set Block Size for Card */
905 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
906 if(errorstate != HAL_MMC_ERROR_NONE)
908 /* Clear all the static flags */
909 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
910 hmmc->ErrorCode |= errorstate;
911 hmmc->State = HAL_MMC_STATE_READY;
912 return HAL_ERROR;
915 /* Read Blocks in IT mode */
916 if(NumberOfBlocks > 1U)
918 hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_IT);
920 /* Read Multi Block command */
921 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, BlockAdd);
923 else
925 hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_IT);
927 /* Read Single Block command */
928 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, BlockAdd);
930 if(errorstate != HAL_MMC_ERROR_NONE)
932 /* Clear all the static flags */
933 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
934 hmmc->ErrorCode |= errorstate;
935 hmmc->State = HAL_MMC_STATE_READY;
936 return HAL_ERROR;
939 return HAL_OK;
941 else
943 return HAL_BUSY;
948 * @brief Writes block(s) to a specified address in a card. The Data transfer
949 * is managed in interrupt mode.
950 * @note This API should be followed by a check on the card state through
951 * HAL_MMC_GetCardState().
952 * @note You could also check the IT transfer process through the MMC Tx
953 * interrupt event.
954 * @param hmmc: Pointer to MMC handle
955 * @param pData: Pointer to the buffer that will contain the data to transmit
956 * @param BlockAdd: Block Address where data will be written
957 * @param NumberOfBlocks: Number of blocks to write
958 * @retval HAL status
960 HAL_StatusTypeDef HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
962 SDIO_DataInitTypeDef config;
963 uint32_t errorstate = HAL_MMC_ERROR_NONE;
965 if(NULL == pData)
967 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
968 return HAL_ERROR;
971 if(hmmc->State == HAL_MMC_STATE_READY)
973 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
975 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
977 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
978 return HAL_ERROR;
981 hmmc->State = HAL_MMC_STATE_BUSY;
983 /* Initialize data control register */
984 hmmc->Instance->DCTRL = 0U;
986 hmmc->pTxBuffPtr = (uint32_t *)pData;
987 hmmc->TxXferSize = BLOCKSIZE * NumberOfBlocks;
989 /* Enable transfer interrupts */
990 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_DATAEND | SDIO_FLAG_TXFIFOHE));
992 /* Check the Card capacity in term of Logical number of blocks */
993 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
995 BlockAdd *= 512U;
998 /* Set Block Size for Card */
999 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
1000 if(errorstate != HAL_MMC_ERROR_NONE)
1002 /* Clear all the static flags */
1003 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1004 hmmc->ErrorCode |= errorstate;
1005 hmmc->State = HAL_MMC_STATE_READY;
1006 return HAL_ERROR;
1009 /* Write Blocks in Polling mode */
1010 if(NumberOfBlocks > 1U)
1012 hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK| MMC_CONTEXT_IT);
1014 /* Write Multi Block command */
1015 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, BlockAdd);
1017 else
1019 hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_IT);
1021 /* Write Single Block command */
1022 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, BlockAdd);
1024 if(errorstate != HAL_MMC_ERROR_NONE)
1026 /* Clear all the static flags */
1027 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1028 hmmc->ErrorCode |= errorstate;
1029 hmmc->State = HAL_MMC_STATE_READY;
1030 return HAL_ERROR;
1033 /* Configure the MMC DPSM (Data Path State Machine) */
1034 config.DataTimeOut = SDMMC_DATATIMEOUT;
1035 config.DataLength = BLOCKSIZE * NumberOfBlocks;
1036 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
1037 config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
1038 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
1039 config.DPSM = SDIO_DPSM_ENABLE;
1040 SDIO_ConfigData(hmmc->Instance, &config);
1042 return HAL_OK;
1044 else
1046 return HAL_BUSY;
1051 * @brief Reads block(s) from a specified address in a card. The Data transfer
1052 * is managed by DMA mode.
1053 * @note This API should be followed by a check on the card state through
1054 * HAL_MMC_GetCardState().
1055 * @note You could also check the DMA transfer process through the MMC Rx
1056 * interrupt event.
1057 * @param hmmc: Pointer MMC handle
1058 * @param pData: Pointer to the buffer that will contain the received data
1059 * @param BlockAdd: Block Address from where data is to be read
1060 * @param NumberOfBlocks: Number of blocks to read.
1061 * @retval HAL status
1063 HAL_StatusTypeDef HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
1065 SDIO_DataInitTypeDef config;
1066 uint32_t errorstate = HAL_MMC_ERROR_NONE;
1068 if(NULL == pData)
1070 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1071 return HAL_ERROR;
1074 if(hmmc->State == HAL_MMC_STATE_READY)
1076 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
1078 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1080 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1081 return HAL_ERROR;
1084 hmmc->State = HAL_MMC_STATE_BUSY;
1086 /* Initialize data control register */
1087 hmmc->Instance->DCTRL = 0U;
1089 #ifdef SDIO_STA_STBITER
1090 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_IT_STBITERR));
1091 #else /* SDIO_STA_STBITERR not defined */
1092 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND));
1093 #endif /* SDIO_STA_STBITERR */
1095 /* Set the DMA transfer complete callback */
1096 hmmc->hdmarx->XferCpltCallback = MMC_DMAReceiveCplt;
1098 /* Set the DMA error callback */
1099 hmmc->hdmarx->XferErrorCallback = MMC_DMAError;
1101 /* Set the DMA Abort callback */
1102 hmmc->hdmarx->XferAbortCallback = NULL;
1104 /* Enable the DMA Channel */
1105 HAL_DMA_Start_IT(hmmc->hdmarx, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)pData, (uint32_t)(BLOCKSIZE * NumberOfBlocks)/4);
1107 /* Enable MMC DMA transfer */
1108 __HAL_MMC_DMA_ENABLE(hmmc);
1110 /* Check the Card capacity in term of Logical number of blocks */
1111 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
1113 BlockAdd *= 512U;
1116 /* Configure the MMC DPSM (Data Path State Machine) */
1117 config.DataTimeOut = SDMMC_DATATIMEOUT;
1118 config.DataLength = BLOCKSIZE * NumberOfBlocks;
1119 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
1120 config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
1121 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
1122 config.DPSM = SDIO_DPSM_ENABLE;
1123 SDIO_ConfigData(hmmc->Instance, &config);
1125 /* Set Block Size for Card */
1126 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
1127 if(errorstate != HAL_MMC_ERROR_NONE)
1129 /* Clear all the static flags */
1130 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1131 hmmc->ErrorCode |= errorstate;
1132 hmmc->State = HAL_MMC_STATE_READY;
1133 return HAL_ERROR;
1136 /* Read Blocks in DMA mode */
1137 if(NumberOfBlocks > 1U)
1139 hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
1141 /* Read Multi Block command */
1142 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, BlockAdd);
1144 else
1146 hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_DMA);
1148 /* Read Single Block command */
1149 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, BlockAdd);
1151 if(errorstate != HAL_MMC_ERROR_NONE)
1153 /* Clear all the static flags */
1154 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1155 hmmc->ErrorCode |= errorstate;
1156 hmmc->State = HAL_MMC_STATE_READY;
1157 return HAL_ERROR;
1160 return HAL_OK;
1162 else
1164 return HAL_BUSY;
1169 * @brief Writes block(s) to a specified address in a card. The Data transfer
1170 * is managed by DMA mode.
1171 * @note This API should be followed by a check on the card state through
1172 * HAL_MMC_GetCardState().
1173 * @note You could also check the DMA transfer process through the MMC Tx
1174 * interrupt event.
1175 * @param hmmc: Pointer to MMC handle
1176 * @param pData: Pointer to the buffer that will contain the data to transmit
1177 * @param BlockAdd: Block Address where data will be written
1178 * @param NumberOfBlocks: Number of blocks to write
1179 * @retval HAL status
1181 HAL_StatusTypeDef HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
1183 SDIO_DataInitTypeDef config;
1184 uint32_t errorstate = HAL_MMC_ERROR_NONE;
1186 if(NULL == pData)
1188 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1189 return HAL_ERROR;
1192 if(hmmc->State == HAL_MMC_STATE_READY)
1194 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
1196 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1198 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1199 return HAL_ERROR;
1202 hmmc->State = HAL_MMC_STATE_BUSY;
1204 /* Initialize data control register */
1205 hmmc->Instance->DCTRL = 0U;
1207 /* Enable MMC Error interrupts */
1208 #ifdef SDIO_STA_STBITER
1209 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR));
1210 #else /* SDIO_STA_STBITERR not defined */
1211 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR));
1212 #endif /* SDIO_STA_STBITERR */
1214 /* Set the DMA transfer complete callback */
1215 hmmc->hdmatx->XferCpltCallback = MMC_DMATransmitCplt;
1217 /* Set the DMA error callback */
1218 hmmc->hdmatx->XferErrorCallback = MMC_DMAError;
1220 /* Set the DMA Abort callback */
1221 hmmc->hdmatx->XferAbortCallback = NULL;
1223 /* Check the Card capacity in term of Logical number of blocks */
1224 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
1226 BlockAdd *= 512U;
1229 /* Set Block Size for Card */
1230 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
1231 if(errorstate != HAL_MMC_ERROR_NONE)
1233 /* Clear all the static flags */
1234 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1235 hmmc->ErrorCode |= errorstate;
1236 hmmc->State = HAL_MMC_STATE_READY;
1237 return HAL_ERROR;
1240 /* Write Blocks in Polling mode */
1241 if(NumberOfBlocks > 1U)
1243 hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
1245 /* Write Multi Block command */
1246 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, BlockAdd);
1248 else
1250 hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_DMA);
1252 /* Write Single Block command */
1253 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, BlockAdd);
1255 if(errorstate != HAL_MMC_ERROR_NONE)
1257 /* Clear all the static flags */
1258 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1259 hmmc->ErrorCode |= errorstate;
1260 hmmc->State = HAL_MMC_STATE_READY;
1261 return HAL_ERROR;
1264 /* Enable SDIO DMA transfer */
1265 __HAL_MMC_DMA_ENABLE(hmmc);
1267 /* Enable the DMA Channel */
1268 HAL_DMA_Start_IT(hmmc->hdmatx, (uint32_t)pData, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)(BLOCKSIZE * NumberOfBlocks)/4);
1270 /* Configure the MMC DPSM (Data Path State Machine) */
1271 config.DataTimeOut = SDMMC_DATATIMEOUT;
1272 config.DataLength = BLOCKSIZE * NumberOfBlocks;
1273 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
1274 config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
1275 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
1276 config.DPSM = SDIO_DPSM_ENABLE;
1277 SDIO_ConfigData(hmmc->Instance, &config);
1279 return HAL_OK;
1281 else
1283 return HAL_BUSY;
1288 * @brief Erases the specified memory area of the given MMC card.
1289 * @note This API should be followed by a check on the card state through
1290 * HAL_MMC_GetCardState().
1291 * @param hmmc: Pointer to MMC handle
1292 * @param BlockStartAdd: Start Block address
1293 * @param BlockEndAdd: End Block address
1294 * @retval HAL status
1296 HAL_StatusTypeDef HAL_MMC_Erase(MMC_HandleTypeDef *hmmc, uint32_t BlockStartAdd, uint32_t BlockEndAdd)
1298 uint32_t errorstate = HAL_MMC_ERROR_NONE;
1300 if(hmmc->State == HAL_MMC_STATE_READY)
1302 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
1304 if(BlockEndAdd < BlockStartAdd)
1306 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1307 return HAL_ERROR;
1310 if(BlockEndAdd > (hmmc->MmcCard.LogBlockNbr))
1312 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1313 return HAL_ERROR;
1316 hmmc->State = HAL_MMC_STATE_BUSY;
1318 /* Check if the card command class supports erase command */
1319 if((hmmc->MmcCard.Class) & SDIO_CCCC_ERASE == 0U)
1321 /* Clear all the static flags */
1322 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1323 hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
1324 hmmc->State = HAL_MMC_STATE_READY;
1325 return HAL_ERROR;
1328 if((SDIO_GetResponse(hmmc->Instance, SDIO_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
1330 /* Clear all the static flags */
1331 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1332 hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED;
1333 hmmc->State = HAL_MMC_STATE_READY;
1334 return HAL_ERROR;
1337 /* Check the Card capacity in term of Logical number of blocks */
1338 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
1340 BlockStartAdd *= 512U;
1341 BlockEndAdd *= 512U;
1344 /* Send CMD35 MMC_ERASE_GRP_START with argument as addr */
1345 errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, BlockStartAdd);
1346 if(errorstate != HAL_MMC_ERROR_NONE)
1348 /* Clear all the static flags */
1349 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1350 hmmc->ErrorCode |= errorstate;
1351 hmmc->State = HAL_MMC_STATE_READY;
1352 return HAL_ERROR;
1355 /* Send CMD36 MMC_ERASE_GRP_END with argument as addr */
1356 errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, BlockEndAdd);
1357 if(errorstate != HAL_MMC_ERROR_NONE)
1359 /* Clear all the static flags */
1360 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1361 hmmc->ErrorCode |= errorstate;
1362 hmmc->State = HAL_MMC_STATE_READY;
1363 return HAL_ERROR;
1366 /* Send CMD38 ERASE */
1367 errorstate = SDMMC_CmdErase(hmmc->Instance);
1368 if(errorstate != HAL_MMC_ERROR_NONE)
1370 /* Clear all the static flags */
1371 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1372 hmmc->ErrorCode |= errorstate;
1373 hmmc->State = HAL_MMC_STATE_READY;
1374 return HAL_ERROR;
1377 hmmc->State = HAL_MMC_STATE_READY;
1379 return HAL_OK;
1381 else
1383 return HAL_BUSY;
1388 * @brief This function handles MMC card interrupt request.
1389 * @param hmmc: Pointer to MMC handle
1390 * @retval None
1392 void HAL_MMC_IRQHandler(MMC_HandleTypeDef *hmmc)
1394 uint32_t errorstate = HAL_MMC_ERROR_NONE;
1396 /* Check for SDIO interrupt flags */
1397 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DATAEND) != RESET)
1399 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_FLAG_DATAEND);
1401 #ifdef SDIO_STA_STBITERR
1402 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
1403 SDIO_IT_TXUNDERR | SDIO_IT_RXOVERR | SDIO_IT_STBITERR);
1404 #else /* SDIO_STA_STBITERR not defined */
1405 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
1406 SDIO_IT_TXUNDERR | SDIO_IT_RXOVERR);
1407 #endif
1409 if((hmmc->Context & MMC_CONTEXT_IT) != RESET)
1411 if(((hmmc->Context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != RESET) || ((hmmc->Context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != RESET))
1413 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
1414 if(errorstate != HAL_MMC_ERROR_NONE)
1416 hmmc->ErrorCode |= errorstate;
1417 HAL_MMC_ErrorCallback(hmmc);
1421 /* Clear all the static flags */
1422 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1424 hmmc->State = HAL_MMC_STATE_READY;
1425 if(((hmmc->Context & MMC_CONTEXT_READ_SINGLE_BLOCK) != RESET) || ((hmmc->Context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != RESET))
1427 HAL_MMC_RxCpltCallback(hmmc);
1429 else
1431 HAL_MMC_TxCpltCallback(hmmc);
1434 else if((hmmc->Context & MMC_CONTEXT_DMA) != RESET)
1436 if((hmmc->Context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != RESET)
1438 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
1439 if(errorstate != HAL_MMC_ERROR_NONE)
1441 hmmc->ErrorCode |= errorstate;
1442 HAL_MMC_ErrorCallback(hmmc);
1445 if(((hmmc->Context & MMC_CONTEXT_READ_SINGLE_BLOCK) == RESET) && ((hmmc->Context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) == RESET))
1447 /* Disable the DMA transfer for transmit request by setting the DMAEN bit
1448 in the MMC DCTRL register */
1449 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
1451 hmmc->State = HAL_MMC_STATE_READY;
1453 HAL_MMC_TxCpltCallback(hmmc);
1458 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_TXFIFOHE) != RESET)
1460 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_FLAG_TXFIFOHE);
1462 MMC_Write_IT(hmmc);
1465 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_RXFIFOHF) != RESET)
1467 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_FLAG_RXFIFOHF);
1469 MMC_Read_IT(hmmc);
1472 #ifdef SDIO_STA_STBITERR
1473 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR) != RESET)
1475 /* Set Error code */
1476 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DCRCFAIL) != RESET)
1478 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
1480 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DTIMEOUT) != RESET)
1482 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
1484 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_RXOVERR) != RESET)
1486 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
1488 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_TXUNDERR) != RESET)
1490 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
1492 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_STBITERR) != RESET)
1494 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
1497 /* Clear All flags */
1498 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS | SDIO_FLAG_STBITERR);
1500 /* Disable all interrupts */
1501 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
1502 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR |SDIO_IT_STBITERR);
1504 if((hmmc->Context & MMC_CONTEXT_DMA) != RESET)
1506 /* Abort the MMC DMA Streams */
1507 if(hmmc->hdmatx != NULL)
1509 /* Set the DMA Tx abort callback */
1510 hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort;
1511 /* Abort DMA in IT mode */
1512 if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
1514 MMC_DMATxAbort(hmmc->hdmatx);
1517 else if(hmmc->hdmarx != NULL)
1519 /* Set the DMA Rx abort callback */
1520 hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort;
1521 /* Abort DMA in IT mode */
1522 if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
1524 MMC_DMARxAbort(hmmc->hdmarx);
1527 else
1529 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1530 hmmc->State = HAL_MMC_STATE_READY;
1531 HAL_MMC_AbortCallback(hmmc);
1534 else if((hmmc->Context & MMC_CONTEXT_IT) != RESET)
1536 /* Set the MMC state to ready to be able to start again the process */
1537 hmmc->State = HAL_MMC_STATE_READY;
1538 HAL_MMC_ErrorCallback(hmmc);
1541 #else /* SDIO_STA_STBITERR not defined */
1542 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_TXUNDERR) != RESET)
1544 /* Set Error code */
1545 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DCRCFAIL) != RESET)
1547 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
1549 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DTIMEOUT) != RESET)
1551 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
1553 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_RXOVERR) != RESET)
1555 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
1557 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_TXUNDERR) != RESET)
1559 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
1562 /* Clear All flags */
1563 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1565 /* Disable all interrupts */
1566 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
1567 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
1569 if((hmmc->Context & MMC_CONTEXT_DMA) != RESET)
1571 /* Abort the MMC DMA Streams */
1572 if(hmmc->hdmatx != NULL)
1574 /* Set the DMA Tx abort callback */
1575 hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort;
1576 /* Abort DMA in IT mode */
1577 if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
1579 MMC_DMATxAbort(hmmc->hdmatx);
1582 else if(hmmc->hdmarx != NULL)
1584 /* Set the DMA Rx abort callback */
1585 hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort;
1586 /* Abort DMA in IT mode */
1587 if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
1589 MMC_DMARxAbort(hmmc->hdmarx);
1592 else
1594 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1595 hmmc->State = HAL_MMC_STATE_READY;
1596 HAL_MMC_AbortCallback(hmmc);
1599 else if((hmmc->Context & MMC_CONTEXT_IT) != RESET)
1601 /* Set the MMC state to ready to be able to start again the process */
1602 hmmc->State = HAL_MMC_STATE_READY;
1603 HAL_MMC_ErrorCallback(hmmc);
1606 #endif /* SDIO_STA_STBITERR */
1610 * @brief return the MMC state
1611 * @param hmmc: Pointer to mmc handle
1612 * @retval HAL state
1614 HAL_MMC_StateTypeDef HAL_MMC_GetState(MMC_HandleTypeDef *hmmc)
1616 return hmmc->State;
1620 * @brief Return the MMC error code
1621 * @param hmmc : Pointer to a MMC_HandleTypeDef structure that contains
1622 * the configuration information.
1623 * @retval MMC Error Code
1625 uint32_t HAL_MMC_GetError(MMC_HandleTypeDef *hmmc)
1627 return hmmc->ErrorCode;
1631 * @brief Tx Transfer completed callbacks
1632 * @param hmmc: Pointer to MMC handle
1633 * @retval None
1635 __weak void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef *hmmc)
1637 /* Prevent unused argument(s) compilation warning */
1638 UNUSED(hmmc);
1640 /* NOTE : This function should not be modified, when the callback is needed,
1641 the HAL_MMC_TxCpltCallback can be implemented in the user file
1646 * @brief Rx Transfer completed callbacks
1647 * @param hmmc: Pointer MMC handle
1648 * @retval None
1650 __weak void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef *hmmc)
1652 /* Prevent unused argument(s) compilation warning */
1653 UNUSED(hmmc);
1655 /* NOTE : This function should not be modified, when the callback is needed,
1656 the HAL_MMC_RxCpltCallback can be implemented in the user file
1661 * @brief MMC error callbacks
1662 * @param hmmc: Pointer MMC handle
1663 * @retval None
1665 __weak void HAL_MMC_ErrorCallback(MMC_HandleTypeDef *hmmc)
1667 /* Prevent unused argument(s) compilation warning */
1668 UNUSED(hmmc);
1670 /* NOTE : This function should not be modified, when the callback is needed,
1671 the HAL_MMC_ErrorCallback can be implemented in the user file
1676 * @brief MMC Abort callbacks
1677 * @param hmmc: Pointer MMC handle
1678 * @retval None
1680 __weak void HAL_MMC_AbortCallback(MMC_HandleTypeDef *hmmc)
1682 /* Prevent unused argument(s) compilation warning */
1683 UNUSED(hmmc);
1685 /* NOTE : This function should not be modified, when the callback is needed,
1686 the HAL_MMC_ErrorCallback can be implemented in the user file
1692 * @}
1695 /** @addtogroup MMC_Exported_Functions_Group3
1696 * @brief management functions
1698 @verbatim
1699 ==============================================================================
1700 ##### Peripheral Control functions #####
1701 ==============================================================================
1702 [..]
1703 This subsection provides a set of functions allowing to control the MMC card
1704 operations and get the related information
1706 @endverbatim
1707 * @{
1711 * @brief Returns information the information of the card which are stored on
1712 * the CID register.
1713 * @param hmmc: Pointer to MMC handle
1714 * @param pCID: Pointer to a HAL_MMC_CIDTypedef structure that
1715 * contains all CID register parameters
1716 * @retval HAL status
1718 HAL_StatusTypeDef HAL_MMC_GetCardCID(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCIDTypeDef *pCID)
1720 uint32_t tmp = 0U;
1722 /* Byte 0 */
1723 tmp = (uint8_t)((hmmc->CID[0U] & 0xFF000000U) >> 24U);
1724 pCID->ManufacturerID = tmp;
1726 /* Byte 1 */
1727 tmp = (uint8_t)((hmmc->CID[0U] & 0x00FF0000U) >> 16U);
1728 pCID->OEM_AppliID = tmp << 8U;
1730 /* Byte 2 */
1731 tmp = (uint8_t)((hmmc->CID[0U] & 0x000000FF00U) >> 8U);
1732 pCID->OEM_AppliID |= tmp;
1734 /* Byte 3 */
1735 tmp = (uint8_t)(hmmc->CID[0U] & 0x000000FFU);
1736 pCID->ProdName1 = tmp << 24U;
1738 /* Byte 4 */
1739 tmp = (uint8_t)((hmmc->CID[1U] & 0xFF000000U) >> 24U);
1740 pCID->ProdName1 |= tmp << 16U;
1742 /* Byte 5 */
1743 tmp = (uint8_t)((hmmc->CID[1U] & 0x00FF0000U) >> 16U);
1744 pCID->ProdName1 |= tmp << 8U;
1746 /* Byte 6 */
1747 tmp = (uint8_t)((hmmc->CID[1U] & 0x0000FF00U) >> 8U);
1748 pCID->ProdName1 |= tmp;
1750 /* Byte 7 */
1751 tmp = (uint8_t)(hmmc->CID[1U] & 0x000000FFU);
1752 pCID->ProdName2 = tmp;
1754 /* Byte 8 */
1755 tmp = (uint8_t)((hmmc->CID[2U] & 0xFF000000U) >> 24U);
1756 pCID->ProdRev = tmp;
1758 /* Byte 9 */
1759 tmp = (uint8_t)((hmmc->CID[2U] & 0x00FF0000U) >> 16U);
1760 pCID->ProdSN = tmp << 24U;
1762 /* Byte 10 */
1763 tmp = (uint8_t)((hmmc->CID[2U] & 0x0000FF00U) >> 8U);
1764 pCID->ProdSN |= tmp << 16U;
1766 /* Byte 11 */
1767 tmp = (uint8_t)(hmmc->CID[2U] & 0x000000FFU);
1768 pCID->ProdSN |= tmp << 8U;
1770 /* Byte 12 */
1771 tmp = (uint8_t)((hmmc->CID[3U] & 0xFF000000U) >> 24U);
1772 pCID->ProdSN |= tmp;
1774 /* Byte 13 */
1775 tmp = (uint8_t)((hmmc->CID[3U] & 0x00FF0000U) >> 16U);
1776 pCID->Reserved1 |= (tmp & 0xF0U) >> 4U;
1777 pCID->ManufactDate = (tmp & 0x0FU) << 8U;
1779 /* Byte 14 */
1780 tmp = (uint8_t)((hmmc->CID[3U] & 0x0000FF00U) >> 8U);
1781 pCID->ManufactDate |= tmp;
1783 /* Byte 15 */
1784 tmp = (uint8_t)(hmmc->CID[3U] & 0x000000FFU);
1785 pCID->CID_CRC = (tmp & 0xFEU) >> 1U;
1786 pCID->Reserved2 = 1U;
1788 return HAL_OK;
1792 * @brief Returns information the information of the card which are stored on
1793 * the CSD register.
1794 * @param hmmc: Pointer to MMC handle
1795 * @param pCSD: Pointer to a HAL_MMC_CardInfoTypeDef structure that
1796 * contains all CSD register parameters
1797 * @retval HAL status
1799 HAL_StatusTypeDef HAL_MMC_GetCardCSD(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCSDTypeDef *pCSD)
1801 uint32_t tmp = 0U;
1803 /* Byte 0 */
1804 tmp = (hmmc->CSD[0U] & 0xFF000000U) >> 24U;
1805 pCSD->CSDStruct = (uint8_t)((tmp & 0xC0U) >> 6U);
1806 pCSD->SysSpecVersion = (uint8_t)((tmp & 0x3CU) >> 2U);
1807 pCSD->Reserved1 = tmp & 0x03U;
1809 /* Byte 1 */
1810 tmp = (hmmc->CSD[0U] & 0x00FF0000U) >> 16U;
1811 pCSD->TAAC = (uint8_t)tmp;
1813 /* Byte 2 */
1814 tmp = (hmmc->CSD[0U] & 0x0000FF00U) >> 8U;
1815 pCSD->NSAC = (uint8_t)tmp;
1817 /* Byte 3 */
1818 tmp = hmmc->CSD[0U] & 0x000000FFU;
1819 pCSD->MaxBusClkFrec = (uint8_t)tmp;
1821 /* Byte 4 */
1822 tmp = (hmmc->CSD[1U] & 0xFF000000U) >> 24U;
1823 pCSD->CardComdClasses = (uint16_t)(tmp << 4U);
1825 /* Byte 5 */
1826 tmp = (hmmc->CSD[1U] & 0x00FF0000U) >> 16U;
1827 pCSD->CardComdClasses |= (uint16_t)((tmp & 0xF0U) >> 4U);
1828 pCSD->RdBlockLen = (uint8_t)(tmp & 0x0FU);
1830 /* Byte 6 */
1831 tmp = (hmmc->CSD[1U] & 0x0000FF00U) >> 8U;
1832 pCSD->PartBlockRead = (uint8_t)((tmp & 0x80U) >> 7U);
1833 pCSD->WrBlockMisalign = (uint8_t)((tmp & 0x40U) >> 6U);
1834 pCSD->RdBlockMisalign = (uint8_t)((tmp & 0x20U) >> 5U);
1835 pCSD->DSRImpl = (uint8_t)((tmp & 0x10U) >> 4U);
1836 pCSD->Reserved2 = 0; /*!< Reserved */
1838 pCSD->DeviceSize = (tmp & 0x03U) << 10U;
1840 /* Byte 7 */
1841 tmp = (uint8_t)(hmmc->CSD[1U] & 0x000000FFU);
1842 pCSD->DeviceSize |= (tmp) << 2U;
1844 /* Byte 8 */
1845 tmp = (uint8_t)((hmmc->CSD[2U] & 0xFF000000U) >> 24U);
1846 pCSD->DeviceSize |= (tmp & 0xC0U) >> 6U;
1848 pCSD->MaxRdCurrentVDDMin = (tmp & 0x38U) >> 3U;
1849 pCSD->MaxRdCurrentVDDMax = (tmp & 0x07U);
1851 /* Byte 9 */
1852 tmp = (uint8_t)((hmmc->CSD[2U] & 0x00FF0000U) >> 16U);
1853 pCSD->MaxWrCurrentVDDMin = (tmp & 0xE0U) >> 5U;
1854 pCSD->MaxWrCurrentVDDMax = (tmp & 0x1CU) >> 2U;
1855 pCSD->DeviceSizeMul = (tmp & 0x03U) << 1U;
1856 /* Byte 10 */
1857 tmp = (uint8_t)((hmmc->CSD[2] & 0x0000FF00U) >> 8U);
1858 pCSD->DeviceSizeMul |= (tmp & 0x80U) >> 7U;
1860 hmmc->MmcCard.BlockNbr = (pCSD->DeviceSize + 1U) ;
1861 hmmc->MmcCard.BlockNbr *= (1U << (pCSD->DeviceSizeMul + 2U));
1862 hmmc->MmcCard.BlockSize = 1U << (pCSD->RdBlockLen);
1864 hmmc->MmcCard.LogBlockNbr = (hmmc->MmcCard.BlockNbr) * ((hmmc->MmcCard.BlockSize) / 512U);
1865 hmmc->MmcCard.LogBlockSize = 512U;
1867 pCSD->EraseGrSize = (tmp & 0x40U) >> 6U;
1868 pCSD->EraseGrMul = (tmp & 0x3FU) << 1U;
1870 /* Byte 11 */
1871 tmp = (uint8_t)(hmmc->CSD[2U] & 0x000000FFU);
1872 pCSD->EraseGrMul |= (tmp & 0x80U) >> 7U;
1873 pCSD->WrProtectGrSize = (tmp & 0x7FU);
1875 /* Byte 12 */
1876 tmp = (uint8_t)((hmmc->CSD[3U] & 0xFF000000U) >> 24U);
1877 pCSD->WrProtectGrEnable = (tmp & 0x80U) >> 7U;
1878 pCSD->ManDeflECC = (tmp & 0x60U) >> 5U;
1879 pCSD->WrSpeedFact = (tmp & 0x1CU) >> 2U;
1880 pCSD->MaxWrBlockLen = (tmp & 0x03U) << 2U;
1882 /* Byte 13 */
1883 tmp = (uint8_t)((hmmc->CSD[3U] & 0x00FF0000U) >> 16U);
1884 pCSD->MaxWrBlockLen |= (tmp & 0xC0U) >> 6U;
1885 pCSD->WriteBlockPaPartial = (tmp & 0x20U) >> 5U;
1886 pCSD->Reserved3 = 0U;
1887 pCSD->ContentProtectAppli = (tmp & 0x01U);
1889 /* Byte 14 */
1890 tmp = (uint8_t)((hmmc->CSD[3U] & 0x0000FF00U) >> 8U);
1891 pCSD->FileFormatGrouop = (tmp & 0x80U) >> 7U;
1892 pCSD->CopyFlag = (tmp & 0x40U) >> 6U;
1893 pCSD->PermWrProtect = (tmp & 0x20U) >> 5U;
1894 pCSD->TempWrProtect = (tmp & 0x10U) >> 4U;
1895 pCSD->FileFormat = (tmp & 0x0CU) >> 2U;
1896 pCSD->ECC = (tmp & 0x03U);
1898 /* Byte 15 */
1899 tmp = (uint8_t)(hmmc->CSD[3U] & 0x000000FFU);
1900 pCSD->CSD_CRC = (tmp & 0xFEU) >> 1U;
1901 pCSD->Reserved4 = 1U;
1903 return HAL_OK;
1907 * @brief Gets the MMC card info.
1908 * @param hmmc: Pointer to MMC handle
1909 * @param pCardInfo: Pointer to the HAL_MMC_CardInfoTypeDef structure that
1910 * will contain the MMC card status information
1911 * @retval HAL status
1913 HAL_StatusTypeDef HAL_MMC_GetCardInfo(MMC_HandleTypeDef *hmmc, HAL_MMC_CardInfoTypeDef *pCardInfo)
1915 pCardInfo->CardType = (uint32_t)(hmmc->MmcCard.CardType);
1916 pCardInfo->Class = (uint32_t)(hmmc->MmcCard.Class);
1917 pCardInfo->RelCardAdd = (uint32_t)(hmmc->MmcCard.RelCardAdd);
1918 pCardInfo->BlockNbr = (uint32_t)(hmmc->MmcCard.BlockNbr);
1919 pCardInfo->BlockSize = (uint32_t)(hmmc->MmcCard.BlockSize);
1920 pCardInfo->LogBlockNbr = (uint32_t)(hmmc->MmcCard.LogBlockNbr);
1921 pCardInfo->LogBlockSize = (uint32_t)(hmmc->MmcCard.LogBlockSize);
1923 return HAL_OK;
1927 * @brief Enables wide bus operation for the requested card if supported by
1928 * card.
1929 * @param hmmc: Pointer to MMC handle
1930 * @param WideMode: Specifies the MMC card wide bus mode
1931 * This parameter can be one of the following values:
1932 * @arg SDIO_BUS_WIDE_8B: 8-bit data transfer
1933 * @arg SDIO_BUS_WIDE_4B: 4-bit data transfer
1934 * @arg SDIO_BUS_WIDE_1B: 1-bit data transfer
1935 * @retval HAL status
1937 HAL_StatusTypeDef HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef *hmmc, uint32_t WideMode)
1939 __IO uint32_t count = 0U;
1940 SDIO_InitTypeDef Init;
1941 uint32_t errorstate = HAL_MMC_ERROR_NONE;
1942 uint32_t response = 0U, busy = 0U;
1944 /* Check the parameters */
1945 assert_param(IS_SDIO_BUS_WIDE(WideMode));
1947 /* Chnage Satte */
1948 hmmc->State = HAL_MMC_STATE_BUSY;
1950 /* Update Clock for Bus mode update */
1951 Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
1952 Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
1953 Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
1954 Init.BusWide = WideMode;
1955 Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
1956 Init.ClockDiv = SDIO_INIT_CLK_DIV;
1957 /* Initialize SDIO*/
1958 SDIO_Init(hmmc->Instance, Init);
1960 if(WideMode == SDIO_BUS_WIDE_8B)
1962 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U);
1963 if(errorstate != HAL_MMC_ERROR_NONE)
1965 hmmc->ErrorCode |= errorstate;
1968 else if(WideMode == SDIO_BUS_WIDE_4B)
1970 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U);
1971 if(errorstate != HAL_MMC_ERROR_NONE)
1973 hmmc->ErrorCode |= errorstate;
1976 else if(WideMode == SDIO_BUS_WIDE_1B)
1978 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70000U);
1979 if(errorstate != HAL_MMC_ERROR_NONE)
1981 hmmc->ErrorCode |= errorstate;
1984 else
1986 /* WideMode is not a valid argument*/
1987 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1990 /* Check for switch error and violation of the trial number of sending CMD 13 */
1991 while(busy == 0U)
1993 if(count++ == SDMMC_MAX_TRIAL)
1995 hmmc->State = HAL_MMC_STATE_READY;
1996 hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
1997 return HAL_ERROR;
2000 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2001 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2002 if(errorstate != HAL_MMC_ERROR_NONE)
2004 hmmc->ErrorCode |= errorstate;
2007 /* Get command response */
2008 response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
2010 /* Get operating voltage*/
2011 busy = (((response >> 7U) == 1U) ? 0U : 1U);
2014 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2015 count = SDMMC_DATATIMEOUT;
2016 while((response & 0x00000100U) == 0U)
2018 if(count-- == 0U)
2020 hmmc->State = HAL_MMC_STATE_READY;
2021 hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
2022 return HAL_ERROR;
2025 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2026 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2027 if(errorstate != HAL_MMC_ERROR_NONE)
2029 hmmc->ErrorCode |= errorstate;
2032 /* Get command response */
2033 response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
2036 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2038 /* Clear all the static flags */
2039 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
2040 hmmc->State = HAL_MMC_STATE_READY;
2041 return HAL_ERROR;
2043 else
2045 /* Configure the SDIO peripheral */
2046 Init.ClockEdge = hmmc->Init.ClockEdge;
2047 Init.ClockBypass = hmmc->Init.ClockBypass;
2048 Init.ClockPowerSave = hmmc->Init.ClockPowerSave;
2049 Init.BusWide = WideMode;
2050 Init.HardwareFlowControl = hmmc->Init.HardwareFlowControl;
2051 Init.ClockDiv = hmmc->Init.ClockDiv;
2052 SDIO_Init(hmmc->Instance, Init);
2055 /* Change State */
2056 hmmc->State = HAL_MMC_STATE_READY;
2058 return HAL_OK;
2063 * @brief Gets the current mmc card data state.
2064 * @param hmmc: pointer to MMC handle
2065 * @retval Card state
2067 HAL_MMC_CardStateTypeDef HAL_MMC_GetCardState(MMC_HandleTypeDef *hmmc)
2069 HAL_MMC_CardStateTypeDef cardstate = HAL_MMC_CARD_TRANSFER;
2070 uint32_t errorstate = HAL_MMC_ERROR_NONE;
2071 uint32_t resp1 = 0U;
2073 errorstate = MMC_SendStatus(hmmc, &resp1);
2074 if(errorstate != HAL_OK)
2076 hmmc->ErrorCode |= errorstate;
2079 cardstate = (HAL_MMC_CardStateTypeDef)((resp1 >> 9U) & 0x0FU);
2081 return cardstate;
2085 * @brief Abort the current transfer and disable the MMC.
2086 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2087 * the configuration information for MMC module.
2088 * @retval HAL status
2090 HAL_StatusTypeDef HAL_MMC_Abort(MMC_HandleTypeDef *hmmc)
2092 HAL_MMC_CardStateTypeDef CardState;
2094 /* DIsable All interrupts */
2095 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
2096 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
2098 /* Clear All flags */
2099 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
2101 if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL))
2103 /* Disable the MMC DMA request */
2104 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
2106 /* Abort the MMC DMA Tx Stream */
2107 if(hmmc->hdmatx != NULL)
2109 HAL_DMA_Abort(hmmc->hdmatx);
2111 /* Abort the MMC DMA Rx Stream */
2112 if(hmmc->hdmarx != NULL)
2114 HAL_DMA_Abort(hmmc->hdmarx);
2118 hmmc->State = HAL_MMC_STATE_READY;
2119 CardState = HAL_MMC_GetCardState(hmmc);
2120 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2122 hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
2124 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2126 return HAL_ERROR;
2128 return HAL_OK;
2132 * @brief Abort the current transfer and disable the MMC (IT mode).
2133 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2134 * the configuration information for MMC module.
2135 * @retval HAL status
2137 HAL_StatusTypeDef HAL_MMC_Abort_IT(MMC_HandleTypeDef *hmmc)
2139 HAL_MMC_CardStateTypeDef CardState;
2141 /* DIsable All interrupts */
2142 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
2143 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
2145 /* Clear All flags */
2146 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
2148 if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL))
2150 /* Disable the MMC DMA request */
2151 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
2153 /* Abort the MMC DMA Tx Stream */
2154 if(hmmc->hdmatx != NULL)
2156 hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort;
2157 if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
2159 hmmc->hdmatx = NULL;
2162 /* Abort the MMC DMA Rx Stream */
2163 if(hmmc->hdmarx != NULL)
2165 hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort;
2166 if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
2168 hmmc->hdmarx = NULL;
2173 /* No transfer ongoing on both DMA channels*/
2174 if((hmmc->hdmatx == NULL) && (hmmc->hdmarx == NULL))
2176 CardState = HAL_MMC_GetCardState(hmmc);
2177 hmmc->State = HAL_MMC_STATE_READY;
2178 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2180 hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
2182 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2184 return HAL_ERROR;
2186 else
2188 HAL_MMC_AbortCallback(hmmc);
2192 return HAL_OK;
2196 * @}
2200 * @}
2203 /* Private function ----------------------------------------------------------*/
2204 /** @addtogroup MMC_Private_Functions
2205 * @{
2209 * @brief DMA MMC transmit process complete callback
2210 * @param hdma: DMA handle
2211 * @retval None
2213 static void MMC_DMATransmitCplt(DMA_HandleTypeDef *hdma)
2215 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2217 /* Enable DATAEND Interrupt */
2218 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DATAEND));
2222 * @brief DMA MMC receive process complete callback
2223 * @param hdma: DMA handle
2224 * @retval None
2226 static void MMC_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
2228 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2229 uint32_t errorstate = HAL_MMC_ERROR_NONE;
2231 /* Send stop command in multiblock write */
2232 if(hmmc->Context == (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA))
2234 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
2235 if(errorstate != HAL_MMC_ERROR_NONE)
2237 hmmc->ErrorCode |= errorstate;
2238 HAL_MMC_ErrorCallback(hmmc);
2242 /* Disable the DMA transfer for transmit request by setting the DMAEN bit
2243 in the MMC DCTRL register */
2244 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
2246 /* Clear all the static flags */
2247 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
2249 hmmc->State = HAL_MMC_STATE_READY;
2251 HAL_MMC_RxCpltCallback(hmmc);
2255 * @brief DMA MMC communication error callback
2256 * @param hdma: DMA handle
2257 * @retval None
2259 static void MMC_DMAError(DMA_HandleTypeDef *hdma)
2261 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2262 HAL_MMC_CardStateTypeDef CardState;
2264 if((hmmc->hdmarx->ErrorCode == HAL_DMA_ERROR_TE) || (hmmc->hdmatx->ErrorCode == HAL_DMA_ERROR_TE))
2266 /* Clear All flags */
2267 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
2269 /* Disable All interrupts */
2270 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
2271 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
2273 hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
2274 CardState = HAL_MMC_GetCardState(hmmc);
2275 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2277 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
2280 hmmc->State= HAL_MMC_STATE_READY;
2283 HAL_MMC_ErrorCallback(hmmc);
2287 * @brief DMA MMC Tx Abort callback
2288 * @param hdma: DMA handle
2289 * @retval None
2291 static void MMC_DMATxAbort(DMA_HandleTypeDef *hdma)
2293 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2294 HAL_MMC_CardStateTypeDef CardState;
2296 if(hmmc->hdmatx != NULL)
2298 hmmc->hdmatx = NULL;
2301 /* All DMA channels are aborted */
2302 if(hmmc->hdmarx == NULL)
2304 CardState = HAL_MMC_GetCardState(hmmc);
2305 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
2306 hmmc->State = HAL_MMC_STATE_READY;
2307 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2309 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
2311 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2313 HAL_MMC_AbortCallback(hmmc);
2315 else
2317 HAL_MMC_ErrorCallback(hmmc);
2324 * @brief DMA MMC Rx Abort callback
2325 * @param hdma: DMA handle
2326 * @retval None
2328 static void MMC_DMARxAbort(DMA_HandleTypeDef *hdma)
2330 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2331 HAL_MMC_CardStateTypeDef CardState;
2333 if(hmmc->hdmarx != NULL)
2335 hmmc->hdmarx = NULL;
2338 /* All DMA channels are aborted */
2339 if(hmmc->hdmatx == NULL)
2341 CardState = HAL_MMC_GetCardState(hmmc);
2342 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
2343 hmmc->State = HAL_MMC_STATE_READY;
2344 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2346 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
2348 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2350 HAL_MMC_AbortCallback(hmmc);
2352 else
2354 HAL_MMC_ErrorCallback(hmmc);
2362 * @brief Initializes the mmc card.
2363 * @param hmmc: Pointer to MMC handle
2364 * @retval MMC Card error state
2366 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc)
2368 HAL_MMC_CardCSDTypeDef CSD;
2369 uint32_t errorstate = HAL_MMC_ERROR_NONE;
2370 uint16_t mmc_rca = 1;
2372 /* Check the power State */
2373 if(SDIO_GetPowerState(hmmc->Instance) == 0U)
2375 /* Power off */
2376 return HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
2379 /* Send CMD2 ALL_SEND_CID */
2380 errorstate = SDMMC_CmdSendCID(hmmc->Instance);
2381 if(errorstate != HAL_MMC_ERROR_NONE)
2383 return errorstate;
2385 else
2387 /* Get Card identification number data */
2388 hmmc->CID[0U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
2389 hmmc->CID[1U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP2);
2390 hmmc->CID[2U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP3);
2391 hmmc->CID[3U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP4);
2394 /* Send CMD3 SET_REL_ADDR with argument 0 */
2395 /* MMC Card publishes its RCA. */
2396 errorstate = SDMMC_CmdSetRelAdd(hmmc->Instance, &mmc_rca);
2397 if(errorstate != HAL_MMC_ERROR_NONE)
2399 return errorstate;
2402 /* Get the MMC card RCA */
2403 hmmc->MmcCard.RelCardAdd = mmc_rca;
2405 /* Send CMD9 SEND_CSD with argument as card's RCA */
2406 errorstate = SDMMC_CmdSendCSD(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
2407 if(errorstate != HAL_MMC_ERROR_NONE)
2409 return errorstate;
2411 else
2413 /* Get Card Specific Data */
2414 hmmc->CSD[0U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
2415 hmmc->CSD[1U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP2);
2416 hmmc->CSD[2U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP3);
2417 hmmc->CSD[3U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP4);
2420 /* Get the Card Class */
2421 hmmc->MmcCard.Class = (SDIO_GetResponse(hmmc->Instance, SDIO_RESP2) >> 20U);
2423 /* Get CSD parameters */
2424 HAL_MMC_GetCardCSD(hmmc, &CSD);
2426 /* Select the Card */
2427 errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2428 if(errorstate != HAL_MMC_ERROR_NONE)
2430 return errorstate;
2433 /* Configure SDIO peripheral interface */
2434 SDIO_Init(hmmc->Instance, hmmc->Init);
2436 /* All cards are initialized */
2437 return HAL_MMC_ERROR_NONE;
2441 * @brief Enquires cards about their operating voltage and configures clock
2442 * controls and stores MMC information that will be needed in future
2443 * in the MMC handle.
2444 * @param hmmc: Pointer to MMC handle
2445 * @retval error state
2447 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc)
2449 __IO uint32_t count = 0U;
2450 uint32_t response = 0U, validvoltage = 0U;
2451 uint32_t errorstate = HAL_MMC_ERROR_NONE;
2453 /* CMD0: GO_IDLE_STATE */
2454 errorstate = SDMMC_CmdGoIdleState(hmmc->Instance);
2455 if(errorstate != HAL_MMC_ERROR_NONE)
2457 return errorstate;
2460 while(validvoltage == 0U)
2462 if(count++ == SDMMC_MAX_VOLT_TRIAL)
2464 return HAL_MMC_ERROR_INVALID_VOLTRANGE;
2467 /* SEND CMD1 APP_CMD with MMC_HIGH_VOLTAGE_RANGE(0xC0FF8000) as argument */
2468 errorstate = SDMMC_CmdOpCondition(hmmc->Instance, eMMC_HIGH_VOLTAGE_RANGE);
2469 if(errorstate != HAL_MMC_ERROR_NONE)
2471 return HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2474 /* Get command response */
2475 response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
2477 /* Get operating voltage*/
2478 validvoltage = (((response >> 31U) == 1U) ? 1U : 0U);
2481 /* When power routine is finished and command returns valid voltage */
2482 if ((response & eMMC_HIGH_VOLTAGE_RANGE) == MMC_HIGH_VOLTAGE_RANGE)
2484 /* When voltage range of the card is within 2.7V and 3.6V */
2485 hmmc->MmcCard.CardType = MMC_HIGH_VOLTAGE_CARD;
2487 else
2489 /* When voltage range of the card is within 1.65V and 1.95V or 2.7V and 3.6V */
2490 hmmc->MmcCard.CardType = MMC_DUAL_VOLTAGE_CARD;
2493 return HAL_MMC_ERROR_NONE;
2497 * @brief Turns the SDIO output signals off.
2498 * @param hmmc: Pointer to MMC handle
2499 * @retval HAL status
2501 static HAL_StatusTypeDef MMC_PowerOFF(MMC_HandleTypeDef *hmmc)
2503 /* Set Power State to OFF */
2504 SDIO_PowerState_OFF(hmmc->Instance);
2506 return HAL_OK;
2510 * @brief Returns the current card's status.
2511 * @param hmmc: Pointer to MMC handle
2512 * @param pCardStatus: pointer to the buffer that will contain the MMC card
2513 * status (Card Status register)
2514 * @retval error state
2516 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus)
2518 uint32_t errorstate = HAL_MMC_ERROR_NONE;
2520 if(pCardStatus == NULL)
2522 return HAL_MMC_ERROR_PARAM;
2525 /* Send Status command */
2526 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
2527 if(errorstate != HAL_OK)
2529 return errorstate;
2532 /* Get MMC card status */
2533 *pCardStatus = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
2535 return HAL_MMC_ERROR_NONE;
2539 * @brief Wrap up reading in non-blocking mode.
2540 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2541 * the configuration information.
2542 * @retval HAL status
2544 static HAL_StatusTypeDef MMC_Read_IT(MMC_HandleTypeDef *hmmc)
2546 uint32_t count = 0U;
2547 uint32_t* tmp;
2549 tmp = (uint32_t*)hmmc->pRxBuffPtr;
2551 /* Read data from SDMMC Rx FIFO */
2552 for(count = 0U; count < 8U; count++)
2554 *(tmp + count) = SDIO_ReadFIFO(hmmc->Instance);
2557 hmmc->pRxBuffPtr += 8U;
2559 return HAL_OK;
2563 * @brief Wrap up writing in non-blocking mode.
2564 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2565 * the configuration information.
2566 * @retval HAL status
2568 static HAL_StatusTypeDef MMC_Write_IT(MMC_HandleTypeDef *hmmc)
2570 uint32_t count = 0U;
2571 uint32_t* tmp;
2573 tmp = (uint32_t*)hmmc->pTxBuffPtr;
2575 /* Write data to SDMMC Tx FIFO */
2576 for(count = 0U; count < 8U; count++)
2578 SDIO_WriteFIFO(hmmc->Instance, (tmp + count));
2581 hmmc->pTxBuffPtr += 8U;
2583 return HAL_OK;
2587 * @}
2590 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx ||
2591 STM32F401xC || STM32F401xE || STM32F411xE || STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx ||
2592 STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */
2594 #endif /* HAL_MMC_MODULE_ENABLED */
2597 * @}
2601 * @}
2604 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/