before merging master
[inav.git] / lib / main / STM32F7 / Drivers / STM32F7xx_HAL_Driver / Src / stm32f7xx_hal_mmc.c
blob3ddb9f85eab4c43370d8e1836655c9985e81a141
1 /**
2 ******************************************************************************
3 * @file stm32f7xx_hal_mmc.c
4 * @author MCD Application Team
5 * @version V1.2.2
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 information ***
156 ===========================
157 [..]
158 (+) To get MMC card information, you can use the function HAL_MMC_GetCardInfo().
159 It returns useful information about the MMC card such as block size, card type,
160 block number ...
162 *** MMC card CSD register ***
163 ============================
164 [..]
165 (+) The HAL_MMC_GetCardCSD() API allows to get the parameters of the CSD register.
166 Some of the CSD parameters are useful for card initialization and identification.
168 *** MMC card CID register ***
169 ============================
170 [..]
171 (+) The HAL_MMC_GetCardCID() API allows to get the parameters of the CID register.
172 Some of the CID parameters are useful for card initialization and identification.
174 *** MMC HAL driver macros list ***
175 ==================================
176 [..]
177 Below the list of most used macros in MMC HAL driver.
179 (+) __HAL_MMC_ENABLE : Enable the MMC device
180 (+) __HAL_MMC_DISABLE : Disable the MMC device
181 (+) __HAL_MMC_DMA_ENABLE: Enable the SDMMC DMA transfer
182 (+) __HAL_MMC_DMA_DISABLE: Disable the SDMMC DMA transfer
183 (+) __HAL_MMC_ENABLE_IT: Enable the MMC device interrupt
184 (+) __HAL_MMC_DISABLE_IT: Disable the MMC device interrupt
185 (+) __HAL_MMC_GET_FLAG:Check whether the specified MMC flag is set or not
186 (+) __HAL_MMC_CLEAR_FLAG: Clear the MMC's pending flags
188 [..]
189 (@) You can refer to the MMC HAL driver header file for more useful macros
191 @endverbatim
192 ******************************************************************************
193 * @attention
195 * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
197 * Redistribution and use in source and binary forms, with or without modification,
198 * are permitted provided that the following conditions are met:
199 * 1. Redistributions of source code must retain the above copyright notice,
200 * this list of conditions and the following disclaimer.
201 * 2. Redistributions in binary form must reproduce the above copyright notice,
202 * this list of conditions and the following disclaimer in the documentation
203 * and/or other materials provided with the distribution.
204 * 3. Neither the name of STMicroelectronics nor the names of its contributors
205 * may be used to endorse or promote products derived from this software
206 * without specific prior written permission.
208 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
209 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
210 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
211 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
212 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
213 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
214 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
215 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
216 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
217 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
219 ******************************************************************************
222 /* Includes ------------------------------------------------------------------*/
223 #include "stm32f7xx_hal.h"
225 /** @addtogroup STM32F7xx_HAL_Driver
226 * @{
229 /** @defgroup MMC MMC
230 * @brief MMC HAL module driver
231 * @{
234 #ifdef HAL_MMC_MODULE_ENABLED
236 /* Private typedef -----------------------------------------------------------*/
237 /* Private define ------------------------------------------------------------*/
238 /** @addtogroup MMC_Private_Defines
239 * @{
243 * @}
246 /* Private macro -------------------------------------------------------------*/
247 /* Private variables ---------------------------------------------------------*/
248 /* Private function prototypes -----------------------------------------------*/
249 /* Private functions ---------------------------------------------------------*/
250 /** @defgroup MMC_Private_Functions MMC Private Functions
251 * @{
253 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc);
254 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc);
255 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus);
256 static HAL_StatusTypeDef MMC_PowerOFF(MMC_HandleTypeDef *hmmc);
257 static HAL_StatusTypeDef MMC_Write_IT(MMC_HandleTypeDef *hmmc);
258 static HAL_StatusTypeDef MMC_Read_IT(MMC_HandleTypeDef *hmmc);
259 static void MMC_DMATransmitCplt(DMA_HandleTypeDef *hdma);
260 static void MMC_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
261 static void MMC_DMAError(DMA_HandleTypeDef *hdma);
262 static void MMC_DMATxAbort(DMA_HandleTypeDef *hdma);
263 static void MMC_DMARxAbort(DMA_HandleTypeDef *hdma);
265 * @}
268 /* Exported functions --------------------------------------------------------*/
269 /** @addtogroup MMC_Exported_Functions
270 * @{
273 /** @addtogroup MMC_Exported_Functions_Group1
274 * @brief Initialization and de-initialization functions
276 @verbatim
277 ==============================================================================
278 ##### Initialization and de-initialization functions #####
279 ==============================================================================
280 [..]
281 This section provides functions allowing to initialize/de-initialize the MMC
282 card device to be ready for use.
284 @endverbatim
285 * @{
289 * @brief Initializes the MMC according to the specified parameters in the
290 MMC_HandleTypeDef and create the associated handle.
291 * @param hmmc: Pointer to the MMC handle
292 * @retval HAL status
294 HAL_StatusTypeDef HAL_MMC_Init(MMC_HandleTypeDef *hmmc)
296 /* Check the MMC handle allocation */
297 if(hmmc == NULL)
299 return HAL_ERROR;
302 /* Check the parameters */
303 assert_param(IS_SDMMC_ALL_INSTANCE(hmmc->Instance));
304 assert_param(IS_SDMMC_CLOCK_EDGE(hmmc->Init.ClockEdge));
305 assert_param(IS_SDMMC_CLOCK_BYPASS(hmmc->Init.ClockBypass));
306 assert_param(IS_SDMMC_CLOCK_POWER_SAVE(hmmc->Init.ClockPowerSave));
307 assert_param(IS_SDMMC_BUS_WIDE(hmmc->Init.BusWide));
308 assert_param(IS_SDMMC_HARDWARE_FLOW_CONTROL(hmmc->Init.HardwareFlowControl));
309 assert_param(IS_SDMMC_CLKDIV(hmmc->Init.ClockDiv));
311 if(hmmc->State == HAL_MMC_STATE_RESET)
313 /* Allocate lock resource and initialize it */
314 hmmc->Lock = HAL_UNLOCKED;
315 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
316 HAL_MMC_MspInit(hmmc);
319 hmmc->State = HAL_MMC_STATE_BUSY;
321 /* Initialize the Card parameters */
322 HAL_MMC_InitCard(hmmc);
324 /* Initialize the error code */
325 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
327 /* Initialize the MMC operation */
328 hmmc->Context = MMC_CONTEXT_NONE;
330 /* Initialize the MMC state */
331 hmmc->State = HAL_MMC_STATE_READY;
333 return HAL_OK;
337 * @brief Initializes the MMC Card.
338 * @param hmmc: Pointer to MMC handle
339 * @note This function initializes the MMC card. It could be used when a card
340 re-initialization is needed.
341 * @retval HAL status
343 HAL_StatusTypeDef HAL_MMC_InitCard(MMC_HandleTypeDef *hmmc)
345 uint32_t errorstate = HAL_MMC_ERROR_NONE;
346 MMC_InitTypeDef Init;
348 /* Default SDMMC peripheral configuration for MMC card initialization */
349 Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
350 Init.ClockBypass = SDMMC_CLOCK_BYPASS_DISABLE;
351 Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
352 Init.BusWide = SDMMC_BUS_WIDE_1B;
353 Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
354 Init.ClockDiv = SDMMC_INIT_CLK_DIV;
356 /* Initialize SDMMC peripheral interface with default configuration */
357 SDMMC_Init(hmmc->Instance, Init);
359 /* Disable SDMMC Clock */
360 __HAL_MMC_DISABLE(hmmc);
362 /* Set Power State to ON */
363 SDMMC_PowerState_ON(hmmc->Instance);
365 /* Enable MMC Clock */
366 __HAL_MMC_ENABLE(hmmc);
368 /* Required power up waiting time before starting the SD initialization sequence */
369 HAL_Delay(2);
371 /* Identify card operating voltage */
372 errorstate = MMC_PowerON(hmmc);
373 if(errorstate != HAL_MMC_ERROR_NONE)
375 hmmc->State = HAL_MMC_STATE_READY;
376 hmmc->ErrorCode |= errorstate;
377 return HAL_ERROR;
380 /* Card initialization */
381 errorstate = MMC_InitCard(hmmc);
382 if(errorstate != HAL_MMC_ERROR_NONE)
384 hmmc->State = HAL_MMC_STATE_READY;
385 hmmc->ErrorCode |= errorstate;
386 return HAL_ERROR;
389 return HAL_OK;
393 * @brief De-Initializes the MMC card.
394 * @param hmmc: Pointer to MMC handle
395 * @retval HAL status
397 HAL_StatusTypeDef HAL_MMC_DeInit(MMC_HandleTypeDef *hmmc)
399 /* Check the MMC handle allocation */
400 if(hmmc == NULL)
402 return HAL_ERROR;
405 /* Check the parameters */
406 assert_param(IS_SDMMC_ALL_INSTANCE(hmmc->Instance));
408 hmmc->State = HAL_MMC_STATE_BUSY;
410 /* Set MMC power state to off */
411 MMC_PowerOFF(hmmc);
413 /* De-Initialize the MSP layer */
414 HAL_MMC_MspDeInit(hmmc);
416 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
417 hmmc->State = HAL_MMC_STATE_RESET;
419 return HAL_OK;
424 * @brief Initializes the MMC MSP.
425 * @param hmmc: Pointer to MMC handle
426 * @retval None
428 __weak void HAL_MMC_MspInit(MMC_HandleTypeDef *hmmc)
430 /* Prevent unused argument(s) compilation warning */
431 UNUSED(hmmc);
433 /* NOTE : This function Should not be modified, when the callback is needed,
434 the HAL_MMC_MspInit could be implemented in the user file
439 * @brief De-Initialize MMC MSP.
440 * @param hmmc: Pointer to MMC handle
441 * @retval None
443 __weak void HAL_MMC_MspDeInit(MMC_HandleTypeDef *hmmc)
445 /* Prevent unused argument(s) compilation warning */
446 UNUSED(hmmc);
448 /* NOTE : This function Should not be modified, when the callback is needed,
449 the HAL_MMC_MspDeInit could be implemented in the user file
454 * @}
457 /** @addtogroup MMC_Exported_Functions_Group2
458 * @brief Data transfer functions
460 @verbatim
461 ==============================================================================
462 ##### IO operation functions #####
463 ==============================================================================
464 [..]
465 This subsection provides a set of functions allowing to manage the data
466 transfer from/to MMC card.
468 @endverbatim
469 * @{
473 * @brief Reads block(s) from a specified address in a card. The Data transfer
474 * is managed by polling mode.
475 * @note This API should be followed by a check on the card state through
476 * HAL_MMC_GetCardState().
477 * @param hmmc: Pointer to MMC handle
478 * @param pData: pointer to the buffer that will contain the received data
479 * @param BlockAdd: Block Address from where data is to be read
480 * @param NumberOfBlocks: Number of MMC blocks to read
481 * @param Timeout: Specify timeout value
482 * @retval HAL status
484 HAL_StatusTypeDef HAL_MMC_ReadBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
486 SDMMC_DataInitTypeDef config;
487 uint32_t errorstate = HAL_MMC_ERROR_NONE;
488 uint32_t tickstart = HAL_GetTick();
489 uint32_t count = 0, *tempbuff = (uint32_t *)pData;
491 if(NULL == pData)
493 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
494 return HAL_ERROR;
497 if(hmmc->State == HAL_MMC_STATE_READY)
499 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
501 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
503 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
504 return HAL_ERROR;
507 hmmc->State = HAL_MMC_STATE_BUSY;
509 /* Initialize data control register */
510 hmmc->Instance->DCTRL = 0;
512 /* Check the Card capacity in term of Logical number of blocks */
513 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
515 BlockAdd *= 512;
518 /* Set Block Size for Card */
519 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
520 if(errorstate != HAL_MMC_ERROR_NONE)
522 /* Clear all the static flags */
523 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
524 hmmc->ErrorCode |= errorstate;
525 hmmc->State = HAL_MMC_STATE_READY;
526 return HAL_ERROR;
529 /* Configure the MMC DPSM (Data Path State Machine) */
530 config.DataTimeOut = SDMMC_DATATIMEOUT;
531 config.DataLength = NumberOfBlocks * BLOCKSIZE;
532 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
533 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
534 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
535 config.DPSM = SDMMC_DPSM_ENABLE;
536 SDMMC_ConfigData(hmmc->Instance, &config);
538 /* Read block(s) in polling mode */
539 if(NumberOfBlocks > 1)
541 hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
543 /* Read Multi Block command */
544 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, BlockAdd);
546 else
548 hmmc->Context = MMC_CONTEXT_READ_SINGLE_BLOCK;
550 /* Read Single Block command */
551 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, BlockAdd);
553 if(errorstate != HAL_MMC_ERROR_NONE)
555 /* Clear all the static flags */
556 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
557 hmmc->ErrorCode |= errorstate;
558 hmmc->State = HAL_MMC_STATE_READY;
559 return HAL_ERROR;
562 /* Poll on SDMMC flags */
563 while(!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
565 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF))
567 /* Read data from SDMMC Rx FIFO */
568 for(count = 0U; count < 8U; count++)
570 *(tempbuff + count) = SDMMC_ReadFIFO(hmmc->Instance);
572 tempbuff += 8U;
575 if((Timeout == 0U)||((HAL_GetTick()-tickstart) >= Timeout))
577 /* Clear all the static flags */
578 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
579 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
580 hmmc->State= HAL_MMC_STATE_READY;
581 return HAL_TIMEOUT;
585 /* Send stop transmission command in case of multiblock read */
586 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U))
588 /* Send stop transmission command */
589 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
590 if(errorstate != HAL_MMC_ERROR_NONE)
592 /* Clear all the static flags */
593 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
594 hmmc->ErrorCode |= errorstate;
595 hmmc->State = HAL_MMC_STATE_READY;
596 return HAL_ERROR;
600 /* Get error state */
601 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
603 /* Clear all the static flags */
604 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
605 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
606 hmmc->State = HAL_MMC_STATE_READY;
607 return HAL_ERROR;
609 else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
611 /* Clear all the static flags */
612 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
613 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
614 hmmc->State = HAL_MMC_STATE_READY;
615 return HAL_ERROR;
617 else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR))
619 /* Clear all the static flags */
620 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
621 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
622 hmmc->State = HAL_MMC_STATE_READY;
623 return HAL_ERROR;
626 /* Empty FIFO if there is still any data */
627 while ((__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXDAVL)))
629 *tempbuff = SDMMC_ReadFIFO(hmmc->Instance);
630 tempbuff++;
632 if((Timeout == 0U)||((HAL_GetTick()-tickstart) >= Timeout))
634 /* Clear all the static flags */
635 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
636 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
637 hmmc->State= HAL_MMC_STATE_READY;
638 return HAL_ERROR;
642 /* Clear all the static flags */
643 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
645 hmmc->State = HAL_MMC_STATE_READY;
647 return HAL_OK;
649 else
651 hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
652 return HAL_ERROR;
657 * @brief Allows to write block(s) to a specified address in a card. The Data
658 * transfer is managed by polling mode.
659 * @note This API should be followed by a check on the card state through
660 * HAL_MMC_GetCardState().
661 * @param hmmc: Pointer to MMC handle
662 * @param pData: pointer to the buffer that will contain the data to transmit
663 * @param BlockAdd: Block Address where data will be written
664 * @param NumberOfBlocks: Number of MMC blocks to write
665 * @param Timeout: Specify timeout value
666 * @retval HAL status
668 HAL_StatusTypeDef HAL_MMC_WriteBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
670 SDMMC_DataInitTypeDef config;
671 uint32_t errorstate = HAL_MMC_ERROR_NONE;
672 uint32_t tickstart = HAL_GetTick();
673 uint32_t count = 0;
674 uint32_t *tempbuff = (uint32_t *)pData;
676 if(NULL == pData)
678 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
679 return HAL_ERROR;
682 if(hmmc->State == HAL_MMC_STATE_READY)
684 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
686 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
688 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
689 return HAL_ERROR;
692 hmmc->State = HAL_MMC_STATE_BUSY;
694 /* Initialize data control register */
695 hmmc->Instance->DCTRL = 0;
697 /* Check the Card capacity in term of Logical number of blocks */
698 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
700 BlockAdd *= 512;
703 /* Set Block Size for Card */
704 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
705 if(errorstate != HAL_MMC_ERROR_NONE)
707 /* Clear all the static flags */
708 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
709 hmmc->ErrorCode |= errorstate;
710 hmmc->State = HAL_MMC_STATE_READY;
711 return HAL_ERROR;
714 /* Write Blocks in Polling mode */
715 if(NumberOfBlocks > 1U)
717 hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
719 /* Write Multi Block command */
720 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, BlockAdd);
722 else
724 hmmc->Context = MMC_CONTEXT_WRITE_SINGLE_BLOCK;
726 /* Write Single Block command */
727 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, BlockAdd);
729 if(errorstate != HAL_MMC_ERROR_NONE)
731 /* Clear all the static flags */
732 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
733 hmmc->ErrorCode |= errorstate;
734 hmmc->State = HAL_MMC_STATE_READY;
735 return HAL_ERROR;
738 /* Configure the MMC DPSM (Data Path State Machine) */
739 config.DataTimeOut = SDMMC_DATATIMEOUT;
740 config.DataLength = NumberOfBlocks * BLOCKSIZE;
741 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
742 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
743 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
744 config.DPSM = SDMMC_DPSM_ENABLE;
745 SDMMC_ConfigData(hmmc->Instance, &config);
747 /* Write block(s) in polling mode */
748 while(!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND))
750 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE))
752 /* Write data to SDMMC Tx FIFO */
753 for(count = 0U; count < 8U; count++)
755 SDMMC_WriteFIFO(hmmc->Instance, (tempbuff + count));
757 tempbuff += 8U;
760 if((Timeout == 0U)||((HAL_GetTick()-tickstart) >= Timeout))
762 /* Clear all the static flags */
763 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
764 hmmc->ErrorCode |= errorstate;
765 hmmc->State = HAL_MMC_STATE_READY;
766 return HAL_TIMEOUT;
770 /* Send stop transmission command in case of multiblock write */
771 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U))
773 /* Send stop transmission command */
774 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
775 if(errorstate != HAL_MMC_ERROR_NONE)
777 /* Clear all the static flags */
778 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
779 hmmc->ErrorCode |= errorstate;
780 hmmc->State = HAL_MMC_STATE_READY;
781 return HAL_ERROR;
785 /* Get error state */
786 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT))
788 /* Clear all the static flags */
789 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
790 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
791 hmmc->State = HAL_MMC_STATE_READY;
792 return HAL_ERROR;
794 else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL))
796 /* Clear all the static flags */
797 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
798 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
799 hmmc->State = HAL_MMC_STATE_READY;
800 return HAL_ERROR;
802 else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR))
804 /* Clear all the static flags */
805 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
806 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
807 hmmc->State = HAL_MMC_STATE_READY;
808 return HAL_ERROR;
811 /* Clear all the static flags */
812 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
814 hmmc->State = HAL_MMC_STATE_READY;
816 return HAL_OK;
818 else
820 hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
821 return HAL_ERROR;
826 * @brief Reads block(s) from a specified address in a card. The Data transfer
827 * is managed in interrupt mode.
828 * @note This API should be followed by a check on the card state through
829 * HAL_MMC_GetCardState().
830 * @note You could also check the IT transfer process through the MMC Rx
831 * interrupt event.
832 * @param hmmc: Pointer to MMC handle
833 * @param pData: Pointer to the buffer that will contain the received data
834 * @param BlockAdd: Block Address from where data is to be read
835 * @param NumberOfBlocks: Number of blocks to read.
836 * @retval HAL status
838 HAL_StatusTypeDef HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
840 SDMMC_DataInitTypeDef config;
841 uint32_t errorstate = HAL_MMC_ERROR_NONE;
843 if(NULL == pData)
845 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
846 return HAL_ERROR;
849 if(hmmc->State == HAL_MMC_STATE_READY)
851 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
853 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
855 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
856 return HAL_ERROR;
859 hmmc->State = HAL_MMC_STATE_BUSY;
861 /* Initialize data control register */
862 hmmc->Instance->DCTRL = 0U;
864 hmmc->pRxBuffPtr = (uint32_t *)pData;
865 hmmc->RxXferSize = BLOCKSIZE * NumberOfBlocks;
867 __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND | SDMMC_FLAG_RXFIFOHF));
869 /* Check the Card capacity in term of Logical number of blocks */
870 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
872 BlockAdd *= 512;
875 /* Configure the MMC DPSM (Data Path State Machine) */
876 config.DataTimeOut = SDMMC_DATATIMEOUT;
877 config.DataLength = BLOCKSIZE * NumberOfBlocks;
878 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
879 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
880 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
881 config.DPSM = SDMMC_DPSM_ENABLE;
882 SDMMC_ConfigData(hmmc->Instance, &config);
884 /* Set Block Size for Card */
885 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
886 if(errorstate != HAL_MMC_ERROR_NONE)
888 /* Clear all the static flags */
889 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
890 hmmc->ErrorCode |= errorstate;
891 hmmc->State = HAL_MMC_STATE_READY;
892 return HAL_ERROR;
895 /* Read Blocks in IT mode */
896 if(NumberOfBlocks > 1U)
898 hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_IT);
900 /* Read Multi Block command */
901 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, BlockAdd);
903 else
905 hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_IT);
907 /* Read Single Block command */
908 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, BlockAdd);
910 if(errorstate != HAL_MMC_ERROR_NONE)
912 /* Clear all the static flags */
913 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
914 hmmc->ErrorCode |= errorstate;
915 hmmc->State = HAL_MMC_STATE_READY;
916 return HAL_ERROR;
919 return HAL_OK;
921 else
923 return HAL_BUSY;
928 * @brief Writes block(s) to a specified address in a card. The Data transfer
929 * is managed in interrupt mode.
930 * @note This API should be followed by a check on the card state through
931 * HAL_MMC_GetCardState().
932 * @note You could also check the IT transfer process through the MMC Tx
933 * interrupt event.
934 * @param hmmc: Pointer to MMC handle
935 * @param pData: Pointer to the buffer that will contain the data to transmit
936 * @param BlockAdd: Block Address where data will be written
937 * @param NumberOfBlocks: Number of blocks to write
938 * @retval HAL status
940 HAL_StatusTypeDef HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
942 SDMMC_DataInitTypeDef config;
943 uint32_t errorstate = HAL_MMC_ERROR_NONE;
945 if(NULL == pData)
947 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
948 return HAL_ERROR;
951 if(hmmc->State == HAL_MMC_STATE_READY)
953 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
955 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
957 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
958 return HAL_ERROR;
961 hmmc->State = HAL_MMC_STATE_BUSY;
963 /* Initialize data control register */
964 hmmc->Instance->DCTRL = 0U;
966 hmmc->pTxBuffPtr = (uint32_t *)pData;
967 hmmc->TxXferSize = BLOCKSIZE * NumberOfBlocks;
969 /* Enable transfer interrupts */
970 __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND | SDMMC_FLAG_TXFIFOHE));
972 /* Check the Card capacity in term of Logical number of blocks */
973 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
975 BlockAdd *= 512;
978 /* Set Block Size for Card */
979 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
980 if(errorstate != HAL_MMC_ERROR_NONE)
982 /* Clear all the static flags */
983 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
984 hmmc->ErrorCode |= errorstate;
985 hmmc->State = HAL_MMC_STATE_READY;
986 return HAL_ERROR;
989 /* Write Blocks in Polling mode */
990 if(NumberOfBlocks > 1U)
992 hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK| MMC_CONTEXT_IT);
994 /* Write Multi Block command */
995 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, BlockAdd);
997 else
999 hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_IT);
1001 /* Write Single Block command */
1002 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, BlockAdd);
1004 if(errorstate != HAL_MMC_ERROR_NONE)
1006 /* Clear all the static flags */
1007 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1008 hmmc->ErrorCode |= errorstate;
1009 hmmc->State = HAL_MMC_STATE_READY;
1010 return HAL_ERROR;
1013 /* Configure the MMC DPSM (Data Path State Machine) */
1014 config.DataTimeOut = SDMMC_DATATIMEOUT;
1015 config.DataLength = BLOCKSIZE * NumberOfBlocks;
1016 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1017 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
1018 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
1019 config.DPSM = SDMMC_DPSM_ENABLE;
1020 SDMMC_ConfigData(hmmc->Instance, &config);
1022 return HAL_OK;
1024 else
1026 return HAL_BUSY;
1031 * @brief Reads block(s) from a specified address in a card. The Data transfer
1032 * is managed by DMA mode.
1033 * @note This API should be followed by a check on the card state through
1034 * HAL_MMC_GetCardState().
1035 * @note You could also check the DMA transfer process through the MMC Rx
1036 * interrupt event.
1037 * @param hmmc: Pointer MMC handle
1038 * @param pData: Pointer to the buffer that will contain the received data
1039 * @param BlockAdd: Block Address from where data is to be read
1040 * @param NumberOfBlocks: Number of blocks to read.
1041 * @retval HAL status
1043 HAL_StatusTypeDef HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
1045 SDMMC_DataInitTypeDef config;
1046 uint32_t errorstate = HAL_MMC_ERROR_NONE;
1048 if(NULL == pData)
1050 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1051 return HAL_ERROR;
1054 if(hmmc->State == HAL_MMC_STATE_READY)
1056 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
1058 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1060 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1061 return HAL_ERROR;
1064 hmmc->State = HAL_MMC_STATE_BUSY;
1066 /* Initialize data control register */
1067 hmmc->Instance->DCTRL = 0U;
1069 __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND));
1071 /* Set the DMA transfer complete callback */
1072 hmmc->hdmarx->XferCpltCallback = MMC_DMAReceiveCplt;
1074 /* Set the DMA error callback */
1075 hmmc->hdmarx->XferErrorCallback = MMC_DMAError;
1077 /* Set the DMA Abort callback */
1078 hmmc->hdmarx->XferAbortCallback = NULL;
1080 /* Enable the DMA Channel */
1081 HAL_DMA_Start_IT(hmmc->hdmarx, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)pData, (uint32_t)(BLOCKSIZE * NumberOfBlocks)/4);
1083 /* Enable MMC DMA transfer */
1084 __HAL_MMC_DMA_ENABLE(hmmc);
1086 /* Check the Card capacity in term of Logical number of blocks */
1087 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
1089 BlockAdd *= 512;
1092 /* Configure the MMC DPSM (Data Path State Machine) */
1093 config.DataTimeOut = SDMMC_DATATIMEOUT;
1094 config.DataLength = BLOCKSIZE * NumberOfBlocks;
1095 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1096 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC;
1097 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
1098 config.DPSM = SDMMC_DPSM_ENABLE;
1099 SDMMC_ConfigData(hmmc->Instance, &config);
1101 /* Set Block Size for Card */
1102 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
1103 if(errorstate != HAL_MMC_ERROR_NONE)
1105 /* Clear all the static flags */
1106 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1107 hmmc->ErrorCode |= errorstate;
1108 hmmc->State = HAL_MMC_STATE_READY;
1109 return HAL_ERROR;
1112 /* Read Blocks in DMA mode */
1113 if(NumberOfBlocks > 1U)
1115 hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
1117 /* Read Multi Block command */
1118 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, BlockAdd);
1120 else
1122 hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_DMA);
1124 /* Read Single Block command */
1125 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, BlockAdd);
1127 if(errorstate != HAL_MMC_ERROR_NONE)
1129 /* Clear all the static flags */
1130 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1131 hmmc->ErrorCode |= errorstate;
1132 hmmc->State = HAL_MMC_STATE_READY;
1133 return HAL_ERROR;
1136 return HAL_OK;
1138 else
1140 return HAL_BUSY;
1145 * @brief Writes block(s) to a specified address in a card. The Data transfer
1146 * is managed by DMA mode.
1147 * @note This API should be followed by a check on the card state through
1148 * HAL_MMC_GetCardState().
1149 * @note You could also check the DMA transfer process through the MMC Tx
1150 * interrupt event.
1151 * @param hmmc: Pointer to MMC handle
1152 * @param pData: Pointer to the buffer that will contain the data to transmit
1153 * @param BlockAdd: Block Address where data will be written
1154 * @param NumberOfBlocks: Number of blocks to write
1155 * @retval HAL status
1157 HAL_StatusTypeDef HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
1159 SDMMC_DataInitTypeDef config;
1160 uint32_t errorstate = HAL_MMC_ERROR_NONE;
1162 if(NULL == pData)
1164 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1165 return HAL_ERROR;
1168 if(hmmc->State == HAL_MMC_STATE_READY)
1170 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
1172 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1174 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1175 return HAL_ERROR;
1178 hmmc->State = HAL_MMC_STATE_BUSY;
1180 /* Initialize data control register */
1181 hmmc->Instance->DCTRL = 0U;
1183 /* Enable MMC Error interrupts */
1184 __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR));
1186 /* Set the DMA transfer complete callback */
1187 hmmc->hdmatx->XferCpltCallback = MMC_DMATransmitCplt;
1189 /* Set the DMA error callback */
1190 hmmc->hdmatx->XferErrorCallback = MMC_DMAError;
1192 /* Set the DMA Abort callback */
1193 hmmc->hdmatx->XferAbortCallback = NULL;
1195 /* Check the Card capacity in term of Logical number of blocks */
1196 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
1198 BlockAdd *= 512;
1201 /* Set Block Size for Card */
1202 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
1203 if(errorstate != HAL_MMC_ERROR_NONE)
1205 /* Clear all the static flags */
1206 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1207 hmmc->ErrorCode |= errorstate;
1208 hmmc->State = HAL_MMC_STATE_READY;
1209 return HAL_ERROR;
1212 /* Write Blocks in Polling mode */
1213 if(NumberOfBlocks > 1U)
1215 hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
1217 /* Write Multi Block command */
1218 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, BlockAdd);
1220 else
1222 hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_DMA);
1224 /* Write Single Block command */
1225 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, BlockAdd);
1227 if(errorstate != HAL_MMC_ERROR_NONE)
1229 /* Clear all the static flags */
1230 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1231 hmmc->ErrorCode |= errorstate;
1232 hmmc->State = HAL_MMC_STATE_READY;
1233 return HAL_ERROR;
1236 /* Enable SDMMC DMA transfer */
1237 __HAL_MMC_DMA_ENABLE(hmmc);
1239 /* Enable the DMA Channel */
1240 HAL_DMA_Start_IT(hmmc->hdmatx, (uint32_t)pData, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)(BLOCKSIZE * NumberOfBlocks)/4);
1242 /* Configure the MMC DPSM (Data Path State Machine) */
1243 config.DataTimeOut = SDMMC_DATATIMEOUT;
1244 config.DataLength = BLOCKSIZE * NumberOfBlocks;
1245 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B;
1246 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD;
1247 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK;
1248 config.DPSM = SDMMC_DPSM_ENABLE;
1249 SDMMC_ConfigData(hmmc->Instance, &config);
1251 return HAL_OK;
1253 else
1255 return HAL_BUSY;
1260 * @brief Erases the specified memory area of the given MMC card.
1261 * @note This API should be followed by a check on the card state through
1262 * HAL_MMC_GetCardState().
1263 * @param hmmc: Pointer to MMC handle
1264 * @param BlockStartAdd: Start Block address
1265 * @param BlockEndAdd: End Block address
1266 * @retval HAL status
1268 HAL_StatusTypeDef HAL_MMC_Erase(MMC_HandleTypeDef *hmmc, uint32_t BlockStartAdd, uint32_t BlockEndAdd)
1270 uint32_t errorstate = HAL_MMC_ERROR_NONE;
1272 if(hmmc->State == HAL_MMC_STATE_READY)
1274 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
1276 if(BlockEndAdd < BlockStartAdd)
1278 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1279 return HAL_ERROR;
1282 if(BlockEndAdd > (hmmc->MmcCard.LogBlockNbr))
1284 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1285 return HAL_ERROR;
1288 hmmc->State = HAL_MMC_STATE_BUSY;
1290 /* Check if the card command class supports erase command */
1291 if(((hmmc->MmcCard.Class) & SDMMC_CCCC_ERASE) == 0U)
1293 /* Clear all the static flags */
1294 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1295 hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
1296 hmmc->State = HAL_MMC_STATE_READY;
1297 return HAL_ERROR;
1300 if((SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
1302 /* Clear all the static flags */
1303 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1304 hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED;
1305 hmmc->State = HAL_MMC_STATE_READY;
1306 return HAL_ERROR;
1309 /* Check the Card capacity in term of Logical number of blocks */
1310 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
1312 BlockStartAdd *= 512U;
1313 BlockEndAdd *= 512U;
1316 /* Send CMD35 MMC_ERASE_GRP_START with argument as addr */
1317 errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, BlockStartAdd);
1318 if(errorstate != HAL_MMC_ERROR_NONE)
1320 /* Clear all the static flags */
1321 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1322 hmmc->ErrorCode |= errorstate;
1323 hmmc->State = HAL_MMC_STATE_READY;
1324 return HAL_ERROR;
1327 /* Send CMD36 MMC_ERASE_GRP_END with argument as addr */
1328 errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, BlockEndAdd);
1329 if(errorstate != HAL_MMC_ERROR_NONE)
1331 /* Clear all the static flags */
1332 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1333 hmmc->ErrorCode |= errorstate;
1334 hmmc->State = HAL_MMC_STATE_READY;
1335 return HAL_ERROR;
1338 /* Send CMD38 ERASE */
1339 errorstate = SDMMC_CmdErase(hmmc->Instance);
1340 if(errorstate != HAL_MMC_ERROR_NONE)
1342 /* Clear all the static flags */
1343 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1344 hmmc->ErrorCode |= errorstate;
1345 hmmc->State = HAL_MMC_STATE_READY;
1346 return HAL_ERROR;
1349 hmmc->State = HAL_MMC_STATE_READY;
1351 return HAL_OK;
1353 else
1355 return HAL_BUSY;
1360 * @brief This function handles MMC card interrupt request.
1361 * @param hmmc: Pointer to MMC handle
1362 * @retval None
1364 void HAL_MMC_IRQHandler(MMC_HandleTypeDef *hmmc)
1366 uint32_t errorstate = HAL_MMC_ERROR_NONE;
1368 /* Check for SDMMC interrupt flags */
1369 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_DATAEND) != RESET)
1371 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_DATAEND);
1373 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\
1374 SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR);
1376 if((hmmc->Context & MMC_CONTEXT_IT) != RESET)
1378 if(((hmmc->Context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != RESET) || ((hmmc->Context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != RESET))
1380 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
1381 if(errorstate != HAL_MMC_ERROR_NONE)
1383 hmmc->ErrorCode |= errorstate;
1384 HAL_MMC_ErrorCallback(hmmc);
1388 /* Clear all the static flags */
1389 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1391 hmmc->State = HAL_MMC_STATE_READY;
1392 if(((hmmc->Context & MMC_CONTEXT_READ_SINGLE_BLOCK) != RESET) || ((hmmc->Context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != RESET))
1394 HAL_MMC_RxCpltCallback(hmmc);
1396 else
1398 HAL_MMC_TxCpltCallback(hmmc);
1401 else if((hmmc->Context & MMC_CONTEXT_DMA) != RESET)
1403 if((hmmc->Context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != RESET)
1405 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
1406 if(errorstate != HAL_MMC_ERROR_NONE)
1408 hmmc->ErrorCode |= errorstate;
1409 HAL_MMC_ErrorCallback(hmmc);
1412 if(((hmmc->Context & MMC_CONTEXT_READ_SINGLE_BLOCK) == RESET) && ((hmmc->Context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) == RESET))
1414 /* Disable the DMA transfer for transmit request by setting the DMAEN bit
1415 in the MMC DCTRL register */
1416 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN);
1418 hmmc->State = HAL_MMC_STATE_READY;
1420 HAL_MMC_TxCpltCallback(hmmc);
1425 else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_TXFIFOHE) != RESET)
1427 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE);
1429 MMC_Write_IT(hmmc);
1432 else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_RXFIFOHF) != RESET)
1434 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF);
1436 MMC_Read_IT(hmmc);
1439 else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_TXUNDERR) != RESET)
1441 /* Set Error code */
1442 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_DCRCFAIL) != RESET)
1444 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
1446 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_DTIMEOUT) != RESET)
1448 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
1450 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_RXOVERR) != RESET)
1452 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
1454 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_TXUNDERR) != RESET)
1456 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
1459 /* Clear All flags */
1460 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1462 /* Disable all interrupts */
1463 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\
1464 SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR);
1466 if((hmmc->Context & MMC_CONTEXT_DMA) != RESET)
1468 /* Abort the MMC DMA Streams */
1469 if(hmmc->hdmatx != NULL)
1471 /* Set the DMA Tx abort callback */
1472 hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort;
1473 /* Abort DMA in IT mode */
1474 if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
1476 MMC_DMATxAbort(hmmc->hdmatx);
1479 else if(hmmc->hdmarx != NULL)
1481 /* Set the DMA Rx abort callback */
1482 hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort;
1483 /* Abort DMA in IT mode */
1484 if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
1486 MMC_DMARxAbort(hmmc->hdmarx);
1489 else
1491 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1492 hmmc->State = HAL_MMC_STATE_READY;
1493 HAL_MMC_AbortCallback(hmmc);
1496 else if((hmmc->Context & MMC_CONTEXT_IT) != RESET)
1498 /* Set the MMC state to ready to be able to start again the process */
1499 hmmc->State = HAL_MMC_STATE_READY;
1500 HAL_MMC_ErrorCallback(hmmc);
1506 * @brief return the MMC state
1507 * @param hmmc: Pointer to mmc handle
1508 * @retval HAL state
1510 HAL_MMC_StateTypeDef HAL_MMC_GetState(MMC_HandleTypeDef *hmmc)
1512 return hmmc->State;
1516 * @brief Return the MMC error code
1517 * @param hmmc : Pointer to a MMC_HandleTypeDef structure that contains
1518 * the configuration information.
1519 * @retval MMC Error Code
1521 uint32_t HAL_MMC_GetError(MMC_HandleTypeDef *hmmc)
1523 return hmmc->ErrorCode;
1527 * @brief Tx Transfer completed callbacks
1528 * @param hmmc: Pointer to MMC handle
1529 * @retval None
1531 __weak void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef *hmmc)
1533 /* Prevent unused argument(s) compilation warning */
1534 UNUSED(hmmc);
1536 /* NOTE : This function should not be modified, when the callback is needed,
1537 the HAL_MMC_TxCpltCallback can be implemented in the user file
1542 * @brief Rx Transfer completed callbacks
1543 * @param hmmc: Pointer MMC handle
1544 * @retval None
1546 __weak void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef *hmmc)
1548 /* Prevent unused argument(s) compilation warning */
1549 UNUSED(hmmc);
1551 /* NOTE : This function should not be modified, when the callback is needed,
1552 the HAL_MMC_ErrorCallback can be implemented in the user file
1557 * @brief MMC error callbacks
1558 * @param hmmc: Pointer MMC handle
1559 * @retval None
1561 __weak void HAL_MMC_ErrorCallback(MMC_HandleTypeDef *hmmc)
1563 /* Prevent unused argument(s) compilation warning */
1564 UNUSED(hmmc);
1566 /* NOTE : This function should not be modified, when the callback is needed,
1567 the HAL_MMC_ErrorCallback can be implemented in the user file
1572 * @brief MMC Abort callbacks
1573 * @param hmmc: Pointer MMC handle
1574 * @retval None
1576 __weak void HAL_MMC_AbortCallback(MMC_HandleTypeDef *hmmc)
1578 /* Prevent unused argument(s) compilation warning */
1579 UNUSED(hmmc);
1581 /* NOTE : This function should not be modified, when the callback is needed,
1582 the HAL_MMC_ErrorCallback can be implemented in the user file
1588 * @}
1591 /** @addtogroup MMC_Exported_Functions_Group3
1592 * @brief management functions
1594 @verbatim
1595 ==============================================================================
1596 ##### Peripheral Control functions #####
1597 ==============================================================================
1598 [..]
1599 This subsection provides a set of functions allowing to control the MMC card
1600 operations and get the related information
1602 @endverbatim
1603 * @{
1607 * @brief Returns information the information of the card which are stored on
1608 * the CID register.
1609 * @param hmmc: Pointer to MMC handle
1610 * @param pCID: Pointer to a HAL_MMC_CIDTypedef structure that
1611 * contains all CID register parameters
1612 * @retval HAL status
1614 HAL_StatusTypeDef HAL_MMC_GetCardCID(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCIDTypeDef *pCID)
1616 uint32_t tmp = 0;
1618 /* Byte 0 */
1619 tmp = (uint8_t)((hmmc->CID[0] & 0xFF000000U) >> 24);
1620 pCID->ManufacturerID = tmp;
1622 /* Byte 1 */
1623 tmp = (uint8_t)((hmmc->CID[0] & 0x00FF0000) >> 16);
1624 pCID->OEM_AppliID = tmp << 8;
1626 /* Byte 2 */
1627 tmp = (uint8_t)((hmmc->CID[0] & 0x000000FF00) >> 8);
1628 pCID->OEM_AppliID |= tmp;
1630 /* Byte 3 */
1631 tmp = (uint8_t)(hmmc->CID[0] & 0x000000FF);
1632 pCID->ProdName1 = tmp << 24;
1634 /* Byte 4 */
1635 tmp = (uint8_t)((hmmc->CID[1] & 0xFF000000U) >> 24);
1636 pCID->ProdName1 |= tmp << 16;
1638 /* Byte 5 */
1639 tmp = (uint8_t)((hmmc->CID[1] & 0x00FF0000) >> 16);
1640 pCID->ProdName1 |= tmp << 8;
1642 /* Byte 6 */
1643 tmp = (uint8_t)((hmmc->CID[1] & 0x0000FF00) >> 8);
1644 pCID->ProdName1 |= tmp;
1646 /* Byte 7 */
1647 tmp = (uint8_t)(hmmc->CID[1] & 0x000000FF);
1648 pCID->ProdName2 = tmp;
1650 /* Byte 8 */
1651 tmp = (uint8_t)((hmmc->CID[2] & 0xFF000000U) >> 24);
1652 pCID->ProdRev = tmp;
1654 /* Byte 9 */
1655 tmp = (uint8_t)((hmmc->CID[2] & 0x00FF0000) >> 16);
1656 pCID->ProdSN = tmp << 24;
1658 /* Byte 10 */
1659 tmp = (uint8_t)((hmmc->CID[2] & 0x0000FF00) >> 8);
1660 pCID->ProdSN |= tmp << 16;
1662 /* Byte 11 */
1663 tmp = (uint8_t)(hmmc->CID[2] & 0x000000FF);
1664 pCID->ProdSN |= tmp << 8;
1666 /* Byte 12 */
1667 tmp = (uint8_t)((hmmc->CID[3] & 0xFF000000U) >> 24);
1668 pCID->ProdSN |= tmp;
1670 /* Byte 13 */
1671 tmp = (uint8_t)((hmmc->CID[3] & 0x00FF0000) >> 16);
1672 pCID->Reserved1 |= (tmp & 0xF0) >> 4;
1673 pCID->ManufactDate = (tmp & 0x0F) << 8;
1675 /* Byte 14 */
1676 tmp = (uint8_t)((hmmc->CID[3] & 0x0000FF00) >> 8);
1677 pCID->ManufactDate |= tmp;
1679 /* Byte 15 */
1680 tmp = (uint8_t)(hmmc->CID[3] & 0x000000FF);
1681 pCID->CID_CRC = (tmp & 0xFE) >> 1;
1682 pCID->Reserved2 = 1;
1684 return HAL_OK;
1688 * @brief Returns information the information of the card which are stored on
1689 * the CSD register.
1690 * @param hmmc: Pointer to MMC handle
1691 * @param pCSD: Pointer to a HAL_MMC_CardInfoTypeDef structure that
1692 * contains all CSD register parameters
1693 * @retval HAL status
1695 HAL_StatusTypeDef HAL_MMC_GetCardCSD(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCSDTypeDef *pCSD)
1697 uint32_t tmp = 0;
1699 /* Byte 0 */
1700 tmp = (hmmc->CSD[0] & 0xFF000000U) >> 24;
1701 pCSD->CSDStruct = (uint8_t)((tmp & 0xC0) >> 6);
1702 pCSD->SysSpecVersion = (uint8_t)((tmp & 0x3C) >> 2);
1703 pCSD->Reserved1 = tmp & 0x03;
1705 /* Byte 1 */
1706 tmp = (hmmc->CSD[0] & 0x00FF0000) >> 16;
1707 pCSD->TAAC = (uint8_t)tmp;
1709 /* Byte 2 */
1710 tmp = (hmmc->CSD[0] & 0x0000FF00) >> 8;
1711 pCSD->NSAC = (uint8_t)tmp;
1713 /* Byte 3 */
1714 tmp = hmmc->CSD[0] & 0x000000FF;
1715 pCSD->MaxBusClkFrec = (uint8_t)tmp;
1717 /* Byte 4 */
1718 tmp = (hmmc->CSD[1] & 0xFF000000U) >> 24;
1719 pCSD->CardComdClasses = (uint16_t)(tmp << 4);
1721 /* Byte 5 */
1722 tmp = (hmmc->CSD[1] & 0x00FF0000U) >> 16;
1723 pCSD->CardComdClasses |= (uint16_t)((tmp & 0xF0) >> 4);
1724 pCSD->RdBlockLen = (uint8_t)(tmp & 0x0F);
1726 /* Byte 6 */
1727 tmp = (hmmc->CSD[1] & 0x0000FF00U) >> 8;
1728 pCSD->PartBlockRead = (uint8_t)((tmp & 0x80) >> 7);
1729 pCSD->WrBlockMisalign = (uint8_t)((tmp & 0x40) >> 6);
1730 pCSD->RdBlockMisalign = (uint8_t)((tmp & 0x20) >> 5);
1731 pCSD->DSRImpl = (uint8_t)((tmp & 0x10) >> 4);
1732 pCSD->Reserved2 = 0; /*!< Reserved */
1734 pCSD->DeviceSize = (tmp & 0x03) << 10;
1736 /* Byte 7 */
1737 tmp = (uint8_t)(hmmc->CSD[1] & 0x000000FFU);
1738 pCSD->DeviceSize |= (tmp) << 2;
1740 /* Byte 8 */
1741 tmp = (uint8_t)((hmmc->CSD[2] & 0xFF000000U) >> 24);
1742 pCSD->DeviceSize |= (tmp & 0xC0) >> 6;
1744 pCSD->MaxRdCurrentVDDMin = (tmp & 0x38) >> 3;
1745 pCSD->MaxRdCurrentVDDMax = (tmp & 0x07);
1747 /* Byte 9 */
1748 tmp = (uint8_t)((hmmc->CSD[2] & 0x00FF0000U) >> 16);
1749 pCSD->MaxWrCurrentVDDMin = (tmp & 0xE0) >> 5;
1750 pCSD->MaxWrCurrentVDDMax = (tmp & 0x1C) >> 2;
1751 pCSD->DeviceSizeMul = (tmp & 0x03) << 1;
1752 /* Byte 10 */
1753 tmp = (uint8_t)((hmmc->CSD[2] & 0x0000FF00U) >> 8);
1754 pCSD->DeviceSizeMul |= (tmp & 0x80) >> 7;
1756 hmmc->MmcCard.BlockNbr = (pCSD->DeviceSize + 1) ;
1757 hmmc->MmcCard.BlockNbr *= (1 << (pCSD->DeviceSizeMul + 2));
1758 hmmc->MmcCard.BlockSize = 1 << (pCSD->RdBlockLen);
1760 hmmc->MmcCard.LogBlockNbr = (hmmc->MmcCard.BlockNbr) * ((hmmc->MmcCard.BlockSize) / 512);
1761 hmmc->MmcCard.LogBlockSize = 512;
1763 pCSD->EraseGrSize = (tmp & 0x40) >> 6;
1764 pCSD->EraseGrMul = (tmp & 0x3F) << 1;
1766 /* Byte 11 */
1767 tmp = (uint8_t)(hmmc->CSD[2] & 0x000000FF);
1768 pCSD->EraseGrMul |= (tmp & 0x80) >> 7;
1769 pCSD->WrProtectGrSize = (tmp & 0x7F);
1771 /* Byte 12 */
1772 tmp = (uint8_t)((hmmc->CSD[3] & 0xFF000000U) >> 24);
1773 pCSD->WrProtectGrEnable = (tmp & 0x80) >> 7;
1774 pCSD->ManDeflECC = (tmp & 0x60) >> 5;
1775 pCSD->WrSpeedFact = (tmp & 0x1C) >> 2;
1776 pCSD->MaxWrBlockLen = (tmp & 0x03) << 2;
1778 /* Byte 13 */
1779 tmp = (uint8_t)((hmmc->CSD[3] & 0x00FF0000) >> 16);
1780 pCSD->MaxWrBlockLen |= (tmp & 0xC0) >> 6;
1781 pCSD->WriteBlockPaPartial = (tmp & 0x20) >> 5;
1782 pCSD->Reserved3 = 0;
1783 pCSD->ContentProtectAppli = (tmp & 0x01);
1785 /* Byte 14 */
1786 tmp = (uint8_t)((hmmc->CSD[3] & 0x0000FF00) >> 8);
1787 pCSD->FileFormatGrouop = (tmp & 0x80) >> 7;
1788 pCSD->CopyFlag = (tmp & 0x40) >> 6;
1789 pCSD->PermWrProtect = (tmp & 0x20) >> 5;
1790 pCSD->TempWrProtect = (tmp & 0x10) >> 4;
1791 pCSD->FileFormat = (tmp & 0x0C) >> 2;
1792 pCSD->ECC = (tmp & 0x03);
1794 /* Byte 15 */
1795 tmp = (uint8_t)(hmmc->CSD[3] & 0x000000FF);
1796 pCSD->CSD_CRC = (tmp & 0xFE) >> 1;
1797 pCSD->Reserved4 = 1;
1799 return HAL_OK;
1803 * @brief Gets the MMC card info.
1804 * @param hmmc: Pointer to MMC handle
1805 * @param pCardInfo: Pointer to the HAL_MMC_CardInfoTypeDef structure that
1806 * will contain the MMC card status information
1807 * @retval HAL status
1809 HAL_StatusTypeDef HAL_MMC_GetCardInfo(MMC_HandleTypeDef *hmmc, HAL_MMC_CardInfoTypeDef *pCardInfo)
1811 pCardInfo->CardType = (uint32_t)(hmmc->MmcCard.CardType);
1812 pCardInfo->Class = (uint32_t)(hmmc->MmcCard.Class);
1813 pCardInfo->RelCardAdd = (uint32_t)(hmmc->MmcCard.RelCardAdd);
1814 pCardInfo->BlockNbr = (uint32_t)(hmmc->MmcCard.BlockNbr);
1815 pCardInfo->BlockSize = (uint32_t)(hmmc->MmcCard.BlockSize);
1816 pCardInfo->LogBlockNbr = (uint32_t)(hmmc->MmcCard.LogBlockNbr);
1817 pCardInfo->LogBlockSize = (uint32_t)(hmmc->MmcCard.LogBlockSize);
1819 return HAL_OK;
1823 * @brief Enables wide bus operation for the requested card if supported by
1824 * card.
1825 * @param hmmc: Pointer to MMC handle
1826 * @param WideMode: Specifies the MMC card wide bus mode
1827 * This parameter can be one of the following values:
1828 * @arg SDMMC_BUS_WIDE_8B: 8-bit data transfer
1829 * @arg SDMMC_BUS_WIDE_4B: 4-bit data transfer
1830 * @arg SDMMC_BUS_WIDE_1B: 1-bit data transfer
1831 * @retval HAL status
1833 HAL_StatusTypeDef HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef *hmmc, uint32_t WideMode)
1835 __IO uint32_t count = 0;
1836 SDMMC_InitTypeDef Init;
1837 uint32_t errorstate = HAL_MMC_ERROR_NONE;
1838 uint32_t response = 0, busy = 0;
1840 /* Check the parameters */
1841 assert_param(IS_SDMMC_BUS_WIDE(WideMode));
1843 /* Chnage Satte */
1844 hmmc->State = HAL_MMC_STATE_BUSY;
1846 /* Update Clock for Bus mode update */
1847 Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
1848 Init.ClockBypass = SDMMC_CLOCK_BYPASS_DISABLE;
1849 Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
1850 Init.BusWide = WideMode;
1851 Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
1852 Init.ClockDiv = SDMMC_INIT_CLK_DIV;
1853 /* Initialize SDMMC*/
1854 SDMMC_Init(hmmc->Instance, Init);
1856 if(WideMode == SDMMC_BUS_WIDE_8B)
1858 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200);
1859 if(errorstate != HAL_MMC_ERROR_NONE)
1861 hmmc->ErrorCode |= errorstate;
1864 else if(WideMode == SDMMC_BUS_WIDE_4B)
1866 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100);
1867 if(errorstate != HAL_MMC_ERROR_NONE)
1869 hmmc->ErrorCode |= errorstate;
1872 else if(WideMode == SDMMC_BUS_WIDE_1B)
1874 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70000);
1875 if(errorstate != HAL_MMC_ERROR_NONE)
1877 hmmc->ErrorCode |= errorstate;
1880 else
1882 /* WideMode is not a valid argument*/
1883 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1886 /* Check for switch error and violation of the trial number of sending CMD 13 */
1887 while(busy == 0)
1889 if(count++ == SDMMC_MAX_TRIAL)
1891 hmmc->State = HAL_MMC_STATE_READY;
1892 hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
1893 return HAL_ERROR;
1896 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
1897 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16));
1898 if(errorstate != HAL_MMC_ERROR_NONE)
1900 hmmc->ErrorCode |= errorstate;
1903 /* Get command response */
1904 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
1906 /* Get operating voltage*/
1907 busy = (((response >> 7) == 1) ? 0 : 1);
1910 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
1911 count = SDMMC_DATATIMEOUT;
1912 while((response & 0x00000100) == 0)
1914 if(count-- == 0)
1916 hmmc->State = HAL_MMC_STATE_READY;
1917 hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
1918 return HAL_ERROR;
1921 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
1922 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16));
1923 if(errorstate != HAL_MMC_ERROR_NONE)
1925 hmmc->ErrorCode |= errorstate;
1928 /* Get command response */
1929 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
1932 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
1934 /* Clear all the static flags */
1935 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1936 hmmc->State = HAL_MMC_STATE_READY;
1937 return HAL_ERROR;
1939 else
1941 /* Configure the SDMMC peripheral */
1942 Init.ClockEdge = hmmc->Init.ClockEdge;
1943 Init.ClockBypass = hmmc->Init.ClockBypass;
1944 Init.ClockPowerSave = hmmc->Init.ClockPowerSave;
1945 Init.BusWide = WideMode;
1946 Init.HardwareFlowControl = hmmc->Init.HardwareFlowControl;
1947 Init.ClockDiv = hmmc->Init.ClockDiv;
1948 SDMMC_Init(hmmc->Instance, Init);
1951 /* Change State */
1952 hmmc->State = HAL_MMC_STATE_READY;
1954 return HAL_OK;
1959 * @brief Gets the current mmc card data state.
1960 * @param hmmc: pointer to MMC handle
1961 * @retval Card state
1963 HAL_MMC_CardStateTypeDef HAL_MMC_GetCardState(MMC_HandleTypeDef *hmmc)
1965 HAL_MMC_CardStateTypeDef cardstate = HAL_MMC_CARD_TRANSFER;
1966 uint32_t errorstate = HAL_MMC_ERROR_NONE;
1967 uint32_t resp1 = 0;
1969 errorstate = MMC_SendStatus(hmmc, &resp1);
1970 if(errorstate != HAL_OK)
1972 hmmc->ErrorCode |= errorstate;
1975 cardstate = (HAL_MMC_CardStateTypeDef)((resp1 >> 9) & 0x0F);
1977 return cardstate;
1981 * @brief Abort the current transfer and disable the MMC.
1982 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
1983 * the configuration information for MMC module.
1984 * @retval HAL status
1986 HAL_StatusTypeDef HAL_MMC_Abort(MMC_HandleTypeDef *hmmc)
1988 HAL_MMC_CardStateTypeDef CardState;
1990 /* DIsable All interrupts */
1991 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\
1992 SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR);
1994 /* Clear All flags */
1995 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
1997 if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL))
1999 /* Disable the MMC DMA request */
2000 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN);
2002 /* Abort the MMC DMA Tx Stream */
2003 if(hmmc->hdmatx != NULL)
2005 HAL_DMA_Abort(hmmc->hdmatx);
2007 /* Abort the MMC DMA Rx Stream */
2008 if(hmmc->hdmarx != NULL)
2010 HAL_DMA_Abort(hmmc->hdmarx);
2014 hmmc->State = HAL_MMC_STATE_READY;
2015 CardState = HAL_MMC_GetCardState(hmmc);
2016 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2018 hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
2020 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2022 return HAL_ERROR;
2024 return HAL_OK;
2028 * @brief Abort the current transfer and disable the MMC (IT mode).
2029 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2030 * the configuration information for MMC module.
2031 * @retval HAL status
2033 HAL_StatusTypeDef HAL_MMC_Abort_IT(MMC_HandleTypeDef *hmmc)
2035 HAL_MMC_CardStateTypeDef CardState;
2037 /* DIsable All interrupts */
2038 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\
2039 SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR);
2041 /* Clear All flags */
2042 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2044 if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL))
2046 /* Disable the MMC DMA request */
2047 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN);
2049 /* Abort the MMC DMA Tx Stream */
2050 if(hmmc->hdmatx != NULL)
2052 hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort;
2053 if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
2055 hmmc->hdmatx = NULL;
2058 /* Abort the MMC DMA Rx Stream */
2059 if(hmmc->hdmarx != NULL)
2061 hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort;
2062 if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
2064 hmmc->hdmarx = NULL;
2069 /* No transfer ongoing on both DMA channels*/
2070 if((hmmc->hdmatx == NULL) && (hmmc->hdmarx == NULL))
2072 CardState = HAL_MMC_GetCardState(hmmc);
2073 hmmc->State = HAL_MMC_STATE_READY;
2074 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2076 hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
2078 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2080 return HAL_ERROR;
2082 else
2084 HAL_MMC_AbortCallback(hmmc);
2088 return HAL_OK;
2092 * @}
2096 * @}
2099 /* Private function ----------------------------------------------------------*/
2100 /** @addtogroup MMC_Private_Functions
2101 * @{
2105 * @brief DMA MMC transmit process complete callback
2106 * @param hdma: DMA handle
2107 * @retval None
2109 static void MMC_DMATransmitCplt(DMA_HandleTypeDef *hdma)
2111 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2113 /* Enable DATAEND Interrupt */
2114 __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DATAEND));
2118 * @brief DMA MMC receive process complete callback
2119 * @param hdma: DMA handle
2120 * @retval None
2122 static void MMC_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
2124 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2125 uint32_t errorstate = HAL_MMC_ERROR_NONE;
2127 /* Send stop command in multiblock write */
2128 if(hmmc->Context == (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA))
2130 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
2131 if(errorstate != HAL_MMC_ERROR_NONE)
2133 hmmc->ErrorCode |= errorstate;
2134 HAL_MMC_ErrorCallback(hmmc);
2138 /* Disable the DMA transfer for transmit request by setting the DMAEN bit
2139 in the MMC DCTRL register */
2140 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN);
2142 /* Clear all the static flags */
2143 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2145 hmmc->State = HAL_MMC_STATE_READY;
2147 HAL_MMC_RxCpltCallback(hmmc);
2151 * @brief DMA MMC communication error callback
2152 * @param hdma: DMA handle
2153 * @retval None
2155 static void MMC_DMAError(DMA_HandleTypeDef *hdma)
2157 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2158 HAL_MMC_CardStateTypeDef CardState;
2160 /* if DMA error is FIFO error ignore it */
2161 if(HAL_DMA_GetError(hdma) != HAL_DMA_ERROR_FE)
2163 if((hmmc->hdmarx->ErrorCode == HAL_DMA_ERROR_TE) || (hmmc->hdmatx->ErrorCode == HAL_DMA_ERROR_TE))
2165 /* Clear All flags */
2166 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS);
2168 /* Disable All interrupts */
2169 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\
2170 SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR);
2172 hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
2173 CardState = HAL_MMC_GetCardState(hmmc);
2174 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2176 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
2179 hmmc->State= HAL_MMC_STATE_READY;
2182 HAL_MMC_ErrorCallback(hmmc);
2187 * @brief DMA MMC Tx Abort callback
2188 * @param hdma: DMA handle
2189 * @retval None
2191 static void MMC_DMATxAbort(DMA_HandleTypeDef *hdma)
2193 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2194 HAL_MMC_CardStateTypeDef CardState;
2196 if(hmmc->hdmatx != NULL)
2198 hmmc->hdmatx = NULL;
2201 /* All DMA channels are aborted */
2202 if(hmmc->hdmarx == NULL)
2204 CardState = HAL_MMC_GetCardState(hmmc);
2205 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
2206 hmmc->State = HAL_MMC_STATE_READY;
2207 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2209 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
2211 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2213 HAL_MMC_AbortCallback(hmmc);
2215 else
2217 HAL_MMC_ErrorCallback(hmmc);
2224 * @brief DMA MMC Rx Abort callback
2225 * @param hdma: DMA handle
2226 * @retval None
2228 static void MMC_DMARxAbort(DMA_HandleTypeDef *hdma)
2230 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2231 HAL_MMC_CardStateTypeDef CardState;
2233 if(hmmc->hdmarx != NULL)
2235 hmmc->hdmarx = NULL;
2238 /* All DMA channels are aborted */
2239 if(hmmc->hdmatx == NULL)
2241 CardState = HAL_MMC_GetCardState(hmmc);
2242 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
2243 hmmc->State = HAL_MMC_STATE_READY;
2244 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2246 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
2248 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2250 HAL_MMC_AbortCallback(hmmc);
2252 else
2254 HAL_MMC_ErrorCallback(hmmc);
2262 * @brief Initializes the mmc card.
2263 * @param hmmc: Pointer to MMC handle
2264 * @retval MMC Card error state
2266 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc)
2268 HAL_MMC_CardCSDTypeDef CSD;
2269 uint32_t errorstate = HAL_MMC_ERROR_NONE;
2270 uint16_t mmc_rca = 1;
2272 /* Check the power State */
2273 if(SDMMC_GetPowerState(hmmc->Instance) == 0)
2275 /* Power off */
2276 return HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
2279 /* Send CMD2 ALL_SEND_CID */
2280 errorstate = SDMMC_CmdSendCID(hmmc->Instance);
2281 if(errorstate != HAL_MMC_ERROR_NONE)
2283 return errorstate;
2285 else
2287 /* Get Card identification number data */
2288 hmmc->CID[0] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
2289 hmmc->CID[1] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2);
2290 hmmc->CID[2] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP3);
2291 hmmc->CID[3] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP4);
2294 /* Send CMD3 SET_REL_ADDR with argument 0 */
2295 /* MMC Card publishes its RCA. */
2296 errorstate = SDMMC_CmdSetRelAdd(hmmc->Instance, &mmc_rca);
2297 if(errorstate != HAL_MMC_ERROR_NONE)
2299 return errorstate;
2302 /* Get the MMC card RCA */
2303 hmmc->MmcCard.RelCardAdd = mmc_rca;
2305 /* Send CMD9 SEND_CSD with argument as card's RCA */
2306 errorstate = SDMMC_CmdSendCSD(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
2307 if(errorstate != HAL_MMC_ERROR_NONE)
2309 return errorstate;
2311 else
2313 /* Get Card Specific Data */
2314 hmmc->CSD[0U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
2315 hmmc->CSD[1U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2);
2316 hmmc->CSD[2U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP3);
2317 hmmc->CSD[3U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP4);
2320 /* Get the Card Class */
2321 hmmc->MmcCard.Class = (SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2) >> 20);
2323 /* Get CSD parameters */
2324 HAL_MMC_GetCardCSD(hmmc, &CSD);
2326 /* Select the Card */
2327 errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16));
2328 if(errorstate != HAL_MMC_ERROR_NONE)
2330 return errorstate;
2333 /* Configure SDMMC peripheral interface */
2334 SDMMC_Init(hmmc->Instance, hmmc->Init);
2336 /* All cards are initialized */
2337 return HAL_MMC_ERROR_NONE;
2341 * @brief Enquires cards about their operating voltage and configures clock
2342 * controls and stores MMC information that will be needed in future
2343 * in the MMC handle.
2344 * @param hmmc: Pointer to MMC handle
2345 * @retval error state
2347 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc)
2349 __IO uint32_t count = 0;
2350 uint32_t response = 0, validvoltage = 0;
2351 uint32_t errorstate = HAL_MMC_ERROR_NONE;
2353 /* CMD0: GO_IDLE_STATE */
2354 errorstate = SDMMC_CmdGoIdleState(hmmc->Instance);
2355 if(errorstate != HAL_MMC_ERROR_NONE)
2357 return errorstate;
2360 while(validvoltage == 0)
2362 if(count++ == SDMMC_MAX_VOLT_TRIAL)
2364 return HAL_MMC_ERROR_INVALID_VOLTRANGE;
2367 /* SEND CMD1 APP_CMD with MMC_HIGH_VOLTAGE_RANGE(0xC0FF8000) as argument */
2368 errorstate = SDMMC_CmdOpCondition(hmmc->Instance, eMMC_HIGH_VOLTAGE_RANGE);
2369 if(errorstate != HAL_MMC_ERROR_NONE)
2371 return HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2374 /* Get command response */
2375 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
2377 /* Get operating voltage*/
2378 validvoltage = (((response >> 31) == 1) ? 1 : 0);
2381 /* When power routine is finished and command returns valid voltage */
2382 if ((response & MMC_HIGH_VOLTAGE_RANGE) == MMC_HIGH_VOLTAGE_RANGE)
2384 /* When voltage range of the card is within 2.7V and 3.6V */
2385 hmmc->MmcCard.CardType = MMC_HIGH_VOLTAGE_CARD;
2387 else
2389 /* When voltage range of the card is within 1.65V and 1.95V or 2.7V and 3.6V */
2390 hmmc->MmcCard.CardType = MMC_DUAL_VOLTAGE_CARD;
2393 return HAL_MMC_ERROR_NONE;
2397 * @brief Turns the SDMMC output signals off.
2398 * @param hmmc: Pointer to MMC handle
2399 * @retval HAL status
2401 static HAL_StatusTypeDef MMC_PowerOFF(MMC_HandleTypeDef *hmmc)
2403 /* Set Power State to OFF */
2404 SDMMC_PowerState_OFF(hmmc->Instance);
2406 return HAL_OK;
2410 * @brief Returns the current card's status.
2411 * @param hmmc: Pointer to MMC handle
2412 * @param pCardStatus: pointer to the buffer that will contain the MMC card
2413 * status (Card Status register)
2414 * @retval error state
2416 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus)
2418 uint32_t errorstate = HAL_MMC_ERROR_NONE;
2420 if(pCardStatus == NULL)
2422 return HAL_MMC_ERROR_PARAM;
2425 /* Send Status command */
2426 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16));
2427 if(errorstate != HAL_OK)
2429 return errorstate;
2432 /* Get MMC card status */
2433 *pCardStatus = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1);
2435 return HAL_MMC_ERROR_NONE;
2439 * @brief Wrap up reading in non-blocking mode.
2440 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2441 * the configuration information.
2442 * @retval HAL status
2444 static HAL_StatusTypeDef MMC_Read_IT(MMC_HandleTypeDef *hmmc)
2446 uint32_t count = 0;
2447 uint32_t* tmp;
2449 tmp = (uint32_t*)hmmc->pRxBuffPtr;
2451 /* Read data from SDMMC Rx FIFO */
2452 for(count = 0; count < 8; count++)
2454 *(tmp + count) = SDMMC_ReadFIFO(hmmc->Instance);
2457 hmmc->pRxBuffPtr += 8;
2459 return HAL_OK;
2463 * @brief Wrap up writing in non-blocking mode.
2464 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2465 * the configuration information.
2466 * @retval HAL status
2468 static HAL_StatusTypeDef MMC_Write_IT(MMC_HandleTypeDef *hmmc)
2470 uint32_t count = 0;
2471 uint32_t* tmp;
2473 tmp = (uint32_t*)hmmc->pTxBuffPtr;
2475 /* Write data to SDMMC Tx FIFO */
2476 for(count = 0; count < 8; count++)
2478 SDMMC_WriteFIFO(hmmc->Instance, (tmp + count));
2481 hmmc->pTxBuffPtr += 8;
2483 return HAL_OK;
2487 * @}
2490 #endif /* HAL_SD_MODULE_ENABLED */
2493 * @}
2497 * @}
2500 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/