Merge pull request #11494 from haslinghuis/dshot_gpio
[betaflight.git] / lib / main / STM32F1 / Drivers / STM32F1xx_HAL_Driver / Src / stm32f1xx_hal_mmc.c
blobd39a9fca6b635db7a88f220746c30a7fd9369f7b
1 /**
2 ******************************************************************************
3 * @file stm32f1xx_hal_mmc.c
4 * @author MCD Application Team
5 * @version V1.1.1
6 * @date 12-May-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 "stm32f1xx_hal.h"
231 /** @addtogroup STM32F1xx_HAL_Driver
232 * @{
235 /** @addtogroup MMC
236 * @{
239 #ifdef HAL_MMC_MODULE_ENABLED
241 #if defined(STM32F103xE) || defined(STM32F103xG)
243 /* Private typedef -----------------------------------------------------------*/
244 /* Private define ------------------------------------------------------------*/
245 /** @addtogroup MMC_Private_Defines
246 * @{
250 * @}
253 /* Private macro -------------------------------------------------------------*/
254 /* Private variables ---------------------------------------------------------*/
255 /* Private function prototypes -----------------------------------------------*/
256 /* Private functions ---------------------------------------------------------*/
257 /** @defgroup MMC_Private_Functions MMC Private Functions
258 * @{
260 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc);
261 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc);
262 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus);
263 static HAL_StatusTypeDef MMC_PowerOFF(MMC_HandleTypeDef *hmmc);
264 static HAL_StatusTypeDef MMC_Write_IT(MMC_HandleTypeDef *hmmc);
265 static HAL_StatusTypeDef MMC_Read_IT(MMC_HandleTypeDef *hmmc);
266 static void MMC_DMATransmitCplt(DMA_HandleTypeDef *hdma);
267 static void MMC_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
268 static void MMC_DMAError(DMA_HandleTypeDef *hdma);
269 static void MMC_DMATxAbort(DMA_HandleTypeDef *hdma);
270 static void MMC_DMARxAbort(DMA_HandleTypeDef *hdma);
272 * @}
275 /* Exported functions --------------------------------------------------------*/
276 /** @addtogroup MMC_Exported_Functions
277 * @{
280 /** @addtogroup MMC_Exported_Functions_Group1
281 * @brief Initialization and de-initialization functions
283 @verbatim
284 ==============================================================================
285 ##### Initialization and de-initialization functions #####
286 ==============================================================================
287 [..]
288 This section provides functions allowing to initialize/de-initialize the MMC
289 card device to be ready for use.
291 @endverbatim
292 * @{
296 * @brief Initializes the MMC according to the specified parameters in the
297 MMC_HandleTypeDef and create the associated handle.
298 * @param hmmc: Pointer to the MMC handle
299 * @retval HAL status
301 HAL_StatusTypeDef HAL_MMC_Init(MMC_HandleTypeDef *hmmc)
303 /* Check the MMC handle allocation */
304 if(hmmc == NULL)
306 return HAL_ERROR;
309 /* Check the parameters */
310 assert_param(IS_SDIO_ALL_INSTANCE(hmmc->Instance));
311 assert_param(IS_SDIO_CLOCK_EDGE(hmmc->Init.ClockEdge));
312 assert_param(IS_SDIO_CLOCK_BYPASS(hmmc->Init.ClockBypass));
313 assert_param(IS_SDIO_CLOCK_POWER_SAVE(hmmc->Init.ClockPowerSave));
314 assert_param(IS_SDIO_BUS_WIDE(hmmc->Init.BusWide));
315 assert_param(IS_SDIO_HARDWARE_FLOW_CONTROL(hmmc->Init.HardwareFlowControl));
316 assert_param(IS_SDIO_CLKDIV(hmmc->Init.ClockDiv));
318 if(hmmc->State == HAL_MMC_STATE_RESET)
320 /* Allocate lock resource and initialize it */
321 hmmc->Lock = HAL_UNLOCKED;
322 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
323 HAL_MMC_MspInit(hmmc);
326 hmmc->State = HAL_MMC_STATE_BUSY;
328 /* Initialize the Card parameters */
329 HAL_MMC_InitCard(hmmc);
331 /* Initialize the error code */
332 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
334 /* Initialize the MMC operation */
335 hmmc->Context = MMC_CONTEXT_NONE;
337 /* Initialize the MMC state */
338 hmmc->State = HAL_MMC_STATE_READY;
340 return HAL_OK;
344 * @brief Initializes the MMC Card.
345 * @param hmmc: Pointer to MMC handle
346 * @note This function initializes the MMC card. It could be used when a card
347 re-initialization is needed.
348 * @retval HAL status
350 HAL_StatusTypeDef HAL_MMC_InitCard(MMC_HandleTypeDef *hmmc)
352 uint32_t errorstate = HAL_MMC_ERROR_NONE;
353 MMC_InitTypeDef Init;
355 /* Default SDMMC peripheral configuration for MMC card initialization */
356 Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
357 Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
358 Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
359 Init.BusWide = SDIO_BUS_WIDE_1B;
360 Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
361 Init.ClockDiv = SDIO_INIT_CLK_DIV;
363 /* Initialize SDMMC peripheral interface with default configuration */
364 SDIO_Init(hmmc->Instance, Init);
366 /* Disable SDMMC Clock */
367 __HAL_MMC_DISABLE(hmmc);
369 /* Set Power State to ON */
370 SDIO_PowerState_ON(hmmc->Instance);
372 /* Enable SDMMC Clock */
373 __HAL_MMC_ENABLE(hmmc);
375 /* Required power up waiting time before starting the SD initialization
376 sequence */
377 HAL_Delay(2U);
379 /* Identify card operating voltage */
380 errorstate = MMC_PowerON(hmmc);
381 if(errorstate != HAL_MMC_ERROR_NONE)
383 hmmc->State = HAL_MMC_STATE_READY;
384 hmmc->ErrorCode |= errorstate;
385 return HAL_ERROR;
388 /* Card initialization */
389 errorstate = MMC_InitCard(hmmc);
390 if(errorstate != HAL_MMC_ERROR_NONE)
392 hmmc->State = HAL_MMC_STATE_READY;
393 hmmc->ErrorCode |= errorstate;
394 return HAL_ERROR;
397 return HAL_OK;
401 * @brief De-Initializes the MMC card.
402 * @param hmmc: Pointer to MMC handle
403 * @retval HAL status
405 HAL_StatusTypeDef HAL_MMC_DeInit(MMC_HandleTypeDef *hmmc)
407 /* Check the MMC handle allocation */
408 if(hmmc == NULL)
410 return HAL_ERROR;
413 /* Check the parameters */
414 assert_param(IS_SDIO_ALL_INSTANCE(hmmc->Instance));
416 hmmc->State = HAL_MMC_STATE_BUSY;
418 /* Set SD power state to off */
419 MMC_PowerOFF(hmmc);
421 /* De-Initialize the MSP layer */
422 HAL_MMC_MspDeInit(hmmc);
424 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
425 hmmc->State = HAL_MMC_STATE_RESET;
427 return HAL_OK;
432 * @brief Initializes the MMC MSP.
433 * @param hmmc: Pointer to MMC handle
434 * @retval None
436 __weak void HAL_MMC_MspInit(MMC_HandleTypeDef *hmmc)
438 /* Prevent unused argument(s) compilation warning */
439 UNUSED(hmmc);
441 /* NOTE : This function Should not be modified, when the callback is needed,
442 the HAL_MMC_MspInit could be implemented in the user file
447 * @brief De-Initialize MMC MSP.
448 * @param hmmc: Pointer to MMC handle
449 * @retval None
451 __weak void HAL_MMC_MspDeInit(MMC_HandleTypeDef *hmmc)
453 /* Prevent unused argument(s) compilation warning */
454 UNUSED(hmmc);
456 /* NOTE : This function Should not be modified, when the callback is needed,
457 the HAL_MMC_MspDeInit could be implemented in the user file
462 * @}
465 /** @addtogroup MMC_Exported_Functions_Group2
466 * @brief Data transfer functions
468 @verbatim
469 ==============================================================================
470 ##### IO operation functions #####
471 ==============================================================================
472 [..]
473 This subsection provides a set of functions allowing to manage the data
474 transfer from/to MMC card.
476 @endverbatim
477 * @{
481 * @brief Reads block(s) from a specified address in a card. The Data transfer
482 * is managed by polling mode.
483 * @note This API should be followed by a check on the card state through
484 * HAL_MMC_GetCardState().
485 * @param hmmc: Pointer to MMC handle
486 * @param pData: pointer to the buffer that will contain the received data
487 * @param BlockAdd: Block Address from where data is to be read
488 * @param NumberOfBlocks: Number of MMC blocks to read
489 * @param Timeout: Specify timeout value
490 * @retval HAL status
492 HAL_StatusTypeDef HAL_MMC_ReadBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
494 SDIO_DataInitTypeDef config;
495 uint32_t errorstate = HAL_MMC_ERROR_NONE;
496 uint32_t tickstart = HAL_GetTick();
497 uint32_t count = 0U, *tempbuff = (uint32_t *)pData;
499 if(NULL == pData)
501 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
502 return HAL_ERROR;
505 if(hmmc->State == HAL_MMC_STATE_READY)
507 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
509 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
511 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
512 return HAL_ERROR;
515 hmmc->State = HAL_MMC_STATE_BUSY;
517 /* Initialize data control register */
518 hmmc->Instance->DCTRL = 0U;
520 /* Check the Card capacity in term of Logical number of blocks */
521 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
523 BlockAdd *= 512U;
526 /* Set Block Size for Card */
527 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
528 if(errorstate != HAL_MMC_ERROR_NONE)
530 /* Clear all the static flags */
531 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
532 hmmc->ErrorCode |= errorstate;
533 hmmc->State = HAL_MMC_STATE_READY;
534 return HAL_ERROR;
537 /* Configure the MMC DPSM (Data Path State Machine) */
538 config.DataTimeOut = SDMMC_DATATIMEOUT;
539 config.DataLength = NumberOfBlocks * BLOCKSIZE;
540 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
541 config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
542 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
543 config.DPSM = SDIO_DPSM_ENABLE;
544 SDIO_ConfigData(hmmc->Instance, &config);
546 /* Read block(s) in polling mode */
547 if(NumberOfBlocks > 1U)
549 hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK;
551 /* Read Multi Block command */
552 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, BlockAdd);
554 else
556 hmmc->Context = MMC_CONTEXT_READ_SINGLE_BLOCK;
558 /* Read Single Block command */
559 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, BlockAdd);
561 if(errorstate != HAL_MMC_ERROR_NONE)
563 /* Clear all the static flags */
564 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
565 hmmc->ErrorCode |= errorstate;
566 hmmc->State = HAL_MMC_STATE_READY;
567 return HAL_ERROR;
570 /* Poll on SDMMC flags */
571 #ifdef SDIO_STA_STBITERR
572 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_STA_STBITERR))
573 #else /* SDIO_STA_STBITERR not defined */
574 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND))
575 #endif /* SDIO_STA_STBITERR */
577 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXFIFOHF))
579 /* Read data from SDMMC Rx FIFO */
580 for(count = 0U; count < 8U; count++)
582 *(tempbuff + count) = SDIO_ReadFIFO(hmmc->Instance);
584 tempbuff += 8U;
587 if((Timeout == 0U)||((HAL_GetTick()-tickstart) >= Timeout))
589 /* Clear all the static flags */
590 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
591 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
592 hmmc->State= HAL_MMC_STATE_READY;
593 return HAL_TIMEOUT;
597 /* Send stop transmission command in case of multiblock read */
598 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1U))
600 /* Send stop transmission command */
601 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
602 if(errorstate != HAL_MMC_ERROR_NONE)
604 /* Clear all the static flags */
605 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
606 hmmc->ErrorCode |= errorstate;
607 hmmc->State = HAL_MMC_STATE_READY;
608 return HAL_ERROR;
612 /* Get error state */
613 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DTIMEOUT))
615 /* Clear all the static flags */
616 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
617 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
618 hmmc->State = HAL_MMC_STATE_READY;
619 return HAL_ERROR;
621 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL))
623 /* Clear all the static flags */
624 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
625 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
626 hmmc->State = HAL_MMC_STATE_READY;
627 return HAL_ERROR;
629 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR))
631 /* Clear all the static flags */
632 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
633 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
634 hmmc->State = HAL_MMC_STATE_READY;
635 return HAL_ERROR;
638 /* Empty FIFO if there is still any data */
639 while ((__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXDAVL)))
641 *tempbuff = SDIO_ReadFIFO(hmmc->Instance);
642 tempbuff++;
644 if((Timeout == 0U)||((HAL_GetTick()-tickstart) >= Timeout))
646 /* Clear all the static flags */
647 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
648 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT;
649 hmmc->State= HAL_MMC_STATE_READY;
650 return HAL_ERROR;
654 /* Clear all the static flags */
655 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
657 hmmc->State = HAL_MMC_STATE_READY;
659 return HAL_OK;
661 else
663 hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
664 return HAL_ERROR;
669 * @brief Allows to write block(s) to a specified address in a card. The Data
670 * transfer is managed by polling mode.
671 * @note This API should be followed by a check on the card state through
672 * HAL_MMC_GetCardState().
673 * @param hmmc: Pointer to MMC handle
674 * @param pData: pointer to the buffer that will contain the data to transmit
675 * @param BlockAdd: Block Address where data will be written
676 * @param NumberOfBlocks: Number of MMC blocks to write
677 * @param Timeout: Specify timeout value
678 * @retval HAL status
680 HAL_StatusTypeDef HAL_MMC_WriteBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout)
682 SDIO_DataInitTypeDef config;
683 uint32_t errorstate = HAL_MMC_ERROR_NONE;
684 uint32_t tickstart = HAL_GetTick();
685 uint32_t count = 0U;
686 uint32_t *tempbuff = (uint32_t *)pData;
688 if(NULL == pData)
690 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
691 return HAL_ERROR;
694 if(hmmc->State == HAL_MMC_STATE_READY)
696 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
698 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
700 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
701 return HAL_ERROR;
704 hmmc->State = HAL_MMC_STATE_BUSY;
706 /* Initialize data control register */
707 hmmc->Instance->DCTRL = 0U;
709 /* Check the Card capacity in term of Logical number of blocks */
710 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
712 BlockAdd *= 512U;
715 /* Set Block Size for Card */
716 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
717 if(errorstate != HAL_MMC_ERROR_NONE)
719 /* Clear all the static flags */
720 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
721 hmmc->ErrorCode |= errorstate;
722 hmmc->State = HAL_MMC_STATE_READY;
723 return HAL_ERROR;
726 /* Write Blocks in Polling mode */
727 if(NumberOfBlocks > 1U)
729 hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK;
731 /* Write Multi Block command */
732 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, BlockAdd);
734 else
736 hmmc->Context = MMC_CONTEXT_WRITE_SINGLE_BLOCK;
738 /* Write Single Block command */
739 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, BlockAdd);
741 if(errorstate != HAL_MMC_ERROR_NONE)
743 /* Clear all the static flags */
744 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
745 hmmc->ErrorCode |= errorstate;
746 hmmc->State = HAL_MMC_STATE_READY;
747 return HAL_ERROR;
750 /* Configure the MMC DPSM (Data Path State Machine) */
751 config.DataTimeOut = SDMMC_DATATIMEOUT;
752 config.DataLength = NumberOfBlocks * BLOCKSIZE;
753 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
754 config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
755 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
756 config.DPSM = SDIO_DPSM_ENABLE;
757 SDIO_ConfigData(hmmc->Instance, &config);
759 /* Write block(s) in polling mode */
760 #ifdef SDIO_STA_STBITERR
761 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_FLAG_STBITERR))
762 #else /* SDIO_STA_STBITERR not defined */
763 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND))
764 #endif /* SDIO_STA_STBITERR */
766 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXFIFOHE))
768 /* Write data to SDIO Tx FIFO */
769 for(count = 0U; count < 8U; count++)
771 SDIO_WriteFIFO(hmmc->Instance, (tempbuff + count));
773 tempbuff += 8U;
776 if((Timeout == 0U)||((HAL_GetTick()-tickstart) >= Timeout))
778 /* Clear all the static flags */
779 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
780 hmmc->ErrorCode |= errorstate;
781 hmmc->State = HAL_MMC_STATE_READY;
782 return HAL_TIMEOUT;
786 /* Send stop transmission command in case of multiblock write */
787 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1U))
789 /* Send stop transmission command */
790 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
791 if(errorstate != HAL_MMC_ERROR_NONE)
793 /* Clear all the static flags */
794 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
795 hmmc->ErrorCode |= errorstate;
796 hmmc->State = HAL_MMC_STATE_READY;
797 return HAL_ERROR;
801 /* Get error state */
802 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DTIMEOUT))
804 /* Clear all the static flags */
805 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
806 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
807 hmmc->State = HAL_MMC_STATE_READY;
808 return HAL_ERROR;
810 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL))
812 /* Clear all the static flags */
813 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
814 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
815 hmmc->State = HAL_MMC_STATE_READY;
816 return HAL_ERROR;
818 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR))
820 /* Clear all the static flags */
821 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
822 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
823 hmmc->State = HAL_MMC_STATE_READY;
824 return HAL_ERROR;
827 /* Clear all the static flags */
828 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
830 hmmc->State = HAL_MMC_STATE_READY;
832 return HAL_OK;
834 else
836 hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY;
837 return HAL_ERROR;
842 * @brief Reads block(s) from a specified address in a card. The Data transfer
843 * is managed in interrupt mode.
844 * @note This API should be followed by a check on the card state through
845 * HAL_MMC_GetCardState().
846 * @note You could also check the IT transfer process through the MMC Rx
847 * interrupt event.
848 * @param hmmc: Pointer to MMC handle
849 * @param pData: Pointer to the buffer that will contain the received data
850 * @param BlockAdd: Block Address from where data is to be read
851 * @param NumberOfBlocks: Number of blocks to read.
852 * @retval HAL status
854 HAL_StatusTypeDef HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
856 SDIO_DataInitTypeDef config;
857 uint32_t errorstate = HAL_MMC_ERROR_NONE;
859 if(NULL == pData)
861 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
862 return HAL_ERROR;
865 if(hmmc->State == HAL_MMC_STATE_READY)
867 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
869 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
871 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
872 return HAL_ERROR;
875 hmmc->State = HAL_MMC_STATE_BUSY;
877 /* Initialize data control register */
878 hmmc->Instance->DCTRL = 0U;
880 hmmc->pRxBuffPtr = (uint32_t *)pData;
881 hmmc->RxXferSize = BLOCKSIZE * NumberOfBlocks;
883 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_FLAG_RXFIFOHF));
885 /* Check the Card capacity in term of Logical number of blocks */
886 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
888 BlockAdd *= 512U;
891 /* Configure the MMC DPSM (Data Path State Machine) */
892 config.DataTimeOut = SDMMC_DATATIMEOUT;
893 config.DataLength = BLOCKSIZE * NumberOfBlocks;
894 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
895 config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
896 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
897 config.DPSM = SDIO_DPSM_ENABLE;
898 SDIO_ConfigData(hmmc->Instance, &config);
900 /* Set Block Size for Card */
901 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
902 if(errorstate != HAL_MMC_ERROR_NONE)
904 /* Clear all the static flags */
905 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
906 hmmc->ErrorCode |= errorstate;
907 hmmc->State = HAL_MMC_STATE_READY;
908 return HAL_ERROR;
911 /* Read Blocks in IT mode */
912 if(NumberOfBlocks > 1U)
914 hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_IT);
916 /* Read Multi Block command */
917 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, BlockAdd);
919 else
921 hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_IT);
923 /* Read Single Block command */
924 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, BlockAdd);
926 if(errorstate != HAL_MMC_ERROR_NONE)
928 /* Clear all the static flags */
929 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
930 hmmc->ErrorCode |= errorstate;
931 hmmc->State = HAL_MMC_STATE_READY;
932 return HAL_ERROR;
935 return HAL_OK;
937 else
939 return HAL_BUSY;
944 * @brief Writes block(s) to a specified address in a card. The Data transfer
945 * is managed in interrupt mode.
946 * @note This API should be followed by a check on the card state through
947 * HAL_MMC_GetCardState().
948 * @note You could also check the IT transfer process through the MMC Tx
949 * interrupt event.
950 * @param hmmc: Pointer to MMC handle
951 * @param pData: Pointer to the buffer that will contain the data to transmit
952 * @param BlockAdd: Block Address where data will be written
953 * @param NumberOfBlocks: Number of blocks to write
954 * @retval HAL status
956 HAL_StatusTypeDef HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
958 SDIO_DataInitTypeDef config;
959 uint32_t errorstate = HAL_MMC_ERROR_NONE;
961 if(NULL == pData)
963 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
964 return HAL_ERROR;
967 if(hmmc->State == HAL_MMC_STATE_READY)
969 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
971 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
973 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
974 return HAL_ERROR;
977 hmmc->State = HAL_MMC_STATE_BUSY;
979 /* Initialize data control register */
980 hmmc->Instance->DCTRL = 0U;
982 hmmc->pTxBuffPtr = (uint32_t *)pData;
983 hmmc->TxXferSize = BLOCKSIZE * NumberOfBlocks;
985 /* Enable transfer interrupts */
986 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_DATAEND | SDIO_FLAG_TXFIFOHE));
988 /* Check the Card capacity in term of Logical number of blocks */
989 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
991 BlockAdd *= 512U;
994 /* Set Block Size for Card */
995 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
996 if(errorstate != HAL_MMC_ERROR_NONE)
998 /* Clear all the static flags */
999 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1000 hmmc->ErrorCode |= errorstate;
1001 hmmc->State = HAL_MMC_STATE_READY;
1002 return HAL_ERROR;
1005 /* Write Blocks in Polling mode */
1006 if(NumberOfBlocks > 1U)
1008 hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK| MMC_CONTEXT_IT);
1010 /* Write Multi Block command */
1011 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, BlockAdd);
1013 else
1015 hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_IT);
1017 /* Write Single Block command */
1018 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, BlockAdd);
1020 if(errorstate != HAL_MMC_ERROR_NONE)
1022 /* Clear all the static flags */
1023 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1024 hmmc->ErrorCode |= errorstate;
1025 hmmc->State = HAL_MMC_STATE_READY;
1026 return HAL_ERROR;
1029 /* Configure the MMC DPSM (Data Path State Machine) */
1030 config.DataTimeOut = SDMMC_DATATIMEOUT;
1031 config.DataLength = BLOCKSIZE * NumberOfBlocks;
1032 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
1033 config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
1034 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
1035 config.DPSM = SDIO_DPSM_ENABLE;
1036 SDIO_ConfigData(hmmc->Instance, &config);
1038 return HAL_OK;
1040 else
1042 return HAL_BUSY;
1047 * @brief Reads block(s) from a specified address in a card. The Data transfer
1048 * is managed by DMA mode.
1049 * @note This API should be followed by a check on the card state through
1050 * HAL_MMC_GetCardState().
1051 * @note You could also check the DMA transfer process through the MMC Rx
1052 * interrupt event.
1053 * @param hmmc: Pointer MMC handle
1054 * @param pData: Pointer to the buffer that will contain the received data
1055 * @param BlockAdd: Block Address from where data is to be read
1056 * @param NumberOfBlocks: Number of blocks to read.
1057 * @retval HAL status
1059 HAL_StatusTypeDef HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
1061 SDIO_DataInitTypeDef config;
1062 uint32_t errorstate = HAL_MMC_ERROR_NONE;
1064 if(NULL == pData)
1066 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1067 return HAL_ERROR;
1070 if(hmmc->State == HAL_MMC_STATE_READY)
1072 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
1074 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1076 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1077 return HAL_ERROR;
1080 hmmc->State = HAL_MMC_STATE_BUSY;
1082 /* Initialize data control register */
1083 hmmc->Instance->DCTRL = 0U;
1085 #ifdef SDIO_STA_STBITER
1086 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_IT_STBITERR));
1087 #else /* SDIO_STA_STBITERR not defined */
1088 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND));
1089 #endif /* SDIO_STA_STBITERR */
1091 /* Set the DMA transfer complete callback */
1092 hmmc->hdmarx->XferCpltCallback = MMC_DMAReceiveCplt;
1094 /* Set the DMA error callback */
1095 hmmc->hdmarx->XferErrorCallback = MMC_DMAError;
1097 /* Set the DMA Abort callback */
1098 hmmc->hdmarx->XferAbortCallback = NULL;
1100 /* Enable the DMA Channel */
1101 HAL_DMA_Start_IT(hmmc->hdmarx, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)pData, (uint32_t)(BLOCKSIZE * NumberOfBlocks)/4);
1103 /* Enable MMC DMA transfer */
1104 __HAL_MMC_DMA_ENABLE(hmmc);
1106 /* Check the Card capacity in term of Logical number of blocks */
1107 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
1109 BlockAdd *= 512U;
1112 /* Configure the MMC DPSM (Data Path State Machine) */
1113 config.DataTimeOut = SDMMC_DATATIMEOUT;
1114 config.DataLength = BLOCKSIZE * NumberOfBlocks;
1115 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
1116 config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO;
1117 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
1118 config.DPSM = SDIO_DPSM_ENABLE;
1119 SDIO_ConfigData(hmmc->Instance, &config);
1121 /* Set Block Size for Card */
1122 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
1123 if(errorstate != HAL_MMC_ERROR_NONE)
1125 /* Clear all the static flags */
1126 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1127 hmmc->ErrorCode |= errorstate;
1128 hmmc->State = HAL_MMC_STATE_READY;
1129 return HAL_ERROR;
1132 /* Read Blocks in DMA mode */
1133 if(NumberOfBlocks > 1U)
1135 hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
1137 /* Read Multi Block command */
1138 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, BlockAdd);
1140 else
1142 hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_DMA);
1144 /* Read Single Block command */
1145 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, BlockAdd);
1147 if(errorstate != HAL_MMC_ERROR_NONE)
1149 /* Clear all the static flags */
1150 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1151 hmmc->ErrorCode |= errorstate;
1152 hmmc->State = HAL_MMC_STATE_READY;
1153 return HAL_ERROR;
1156 return HAL_OK;
1158 else
1160 return HAL_BUSY;
1165 * @brief Writes block(s) to a specified address in a card. The Data transfer
1166 * is managed by DMA mode.
1167 * @note This API should be followed by a check on the card state through
1168 * HAL_MMC_GetCardState().
1169 * @note You could also check the DMA transfer process through the MMC Tx
1170 * interrupt event.
1171 * @param hmmc: Pointer to MMC handle
1172 * @param pData: Pointer to the buffer that will contain the data to transmit
1173 * @param BlockAdd: Block Address where data will be written
1174 * @param NumberOfBlocks: Number of blocks to write
1175 * @retval HAL status
1177 HAL_StatusTypeDef HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
1179 SDIO_DataInitTypeDef config;
1180 uint32_t errorstate = HAL_MMC_ERROR_NONE;
1182 if(NULL == pData)
1184 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1185 return HAL_ERROR;
1188 if(hmmc->State == HAL_MMC_STATE_READY)
1190 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
1192 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr))
1194 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1195 return HAL_ERROR;
1198 hmmc->State = HAL_MMC_STATE_BUSY;
1200 /* Initialize data control register */
1201 hmmc->Instance->DCTRL = 0U;
1203 /* Enable MMC Error interrupts */
1204 #ifdef SDIO_STA_STBITER
1205 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR));
1206 #else /* SDIO_STA_STBITERR not defined */
1207 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR));
1208 #endif /* SDIO_STA_STBITERR */
1210 /* Set the DMA transfer complete callback */
1211 hmmc->hdmatx->XferCpltCallback = MMC_DMATransmitCplt;
1213 /* Set the DMA error callback */
1214 hmmc->hdmatx->XferErrorCallback = MMC_DMAError;
1216 /* Set the DMA Abort callback */
1217 hmmc->hdmatx->XferAbortCallback = NULL;
1219 /* Check the Card capacity in term of Logical number of blocks */
1220 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
1222 BlockAdd *= 512U;
1225 /* Set Block Size for Card */
1226 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE);
1227 if(errorstate != HAL_MMC_ERROR_NONE)
1229 /* Clear all the static flags */
1230 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1231 hmmc->ErrorCode |= errorstate;
1232 hmmc->State = HAL_MMC_STATE_READY;
1233 return HAL_ERROR;
1236 /* Write Blocks in Polling mode */
1237 if(NumberOfBlocks > 1U)
1239 hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_DMA);
1241 /* Write Multi Block command */
1242 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, BlockAdd);
1244 else
1246 hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_DMA);
1248 /* Write Single Block command */
1249 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, BlockAdd);
1251 if(errorstate != HAL_MMC_ERROR_NONE)
1253 /* Clear all the static flags */
1254 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1255 hmmc->ErrorCode |= errorstate;
1256 hmmc->State = HAL_MMC_STATE_READY;
1257 return HAL_ERROR;
1260 /* Enable SDIO DMA transfer */
1261 __HAL_MMC_DMA_ENABLE(hmmc);
1263 /* Enable the DMA Channel */
1264 HAL_DMA_Start_IT(hmmc->hdmatx, (uint32_t)pData, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)(BLOCKSIZE * NumberOfBlocks)/4);
1266 /* Configure the MMC DPSM (Data Path State Machine) */
1267 config.DataTimeOut = SDMMC_DATATIMEOUT;
1268 config.DataLength = BLOCKSIZE * NumberOfBlocks;
1269 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
1270 config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD;
1271 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK;
1272 config.DPSM = SDIO_DPSM_ENABLE;
1273 SDIO_ConfigData(hmmc->Instance, &config);
1275 return HAL_OK;
1277 else
1279 return HAL_BUSY;
1284 * @brief Erases the specified memory area of the given MMC card.
1285 * @note This API should be followed by a check on the card state through
1286 * HAL_MMC_GetCardState().
1287 * @param hmmc: Pointer to MMC handle
1288 * @param BlockStartAdd: Start Block address
1289 * @param BlockEndAdd: End Block address
1290 * @retval HAL status
1292 HAL_StatusTypeDef HAL_MMC_Erase(MMC_HandleTypeDef *hmmc, uint32_t BlockStartAdd, uint32_t BlockEndAdd)
1294 uint32_t errorstate = HAL_MMC_ERROR_NONE;
1296 if(hmmc->State == HAL_MMC_STATE_READY)
1298 hmmc->ErrorCode = HAL_DMA_ERROR_NONE;
1300 if(BlockEndAdd < BlockStartAdd)
1302 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1303 return HAL_ERROR;
1306 if(BlockEndAdd > (hmmc->MmcCard.LogBlockNbr))
1308 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE;
1309 return HAL_ERROR;
1312 hmmc->State = HAL_MMC_STATE_BUSY;
1314 /* Check if the card command class supports erase command */
1315 if(((hmmc->MmcCard.Class) & SDIO_CCCC_ERASE) == 0U)
1317 /* Clear all the static flags */
1318 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1319 hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
1320 hmmc->State = HAL_MMC_STATE_READY;
1321 return HAL_ERROR;
1324 if((SDIO_GetResponse(hmmc->Instance, SDIO_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED)
1326 /* Clear all the static flags */
1327 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1328 hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED;
1329 hmmc->State = HAL_MMC_STATE_READY;
1330 return HAL_ERROR;
1333 /* Check the Card capacity in term of Logical number of blocks */
1334 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY)
1336 BlockStartAdd *= 512U;
1337 BlockEndAdd *= 512U;
1340 /* Send CMD35 MMC_ERASE_GRP_START with argument as addr */
1341 errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, BlockStartAdd);
1342 if(errorstate != HAL_MMC_ERROR_NONE)
1344 /* Clear all the static flags */
1345 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1346 hmmc->ErrorCode |= errorstate;
1347 hmmc->State = HAL_MMC_STATE_READY;
1348 return HAL_ERROR;
1351 /* Send CMD36 MMC_ERASE_GRP_END with argument as addr */
1352 errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, BlockEndAdd);
1353 if(errorstate != HAL_MMC_ERROR_NONE)
1355 /* Clear all the static flags */
1356 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1357 hmmc->ErrorCode |= errorstate;
1358 hmmc->State = HAL_MMC_STATE_READY;
1359 return HAL_ERROR;
1362 /* Send CMD38 ERASE */
1363 errorstate = SDMMC_CmdErase(hmmc->Instance);
1364 if(errorstate != HAL_MMC_ERROR_NONE)
1366 /* Clear all the static flags */
1367 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1368 hmmc->ErrorCode |= errorstate;
1369 hmmc->State = HAL_MMC_STATE_READY;
1370 return HAL_ERROR;
1373 hmmc->State = HAL_MMC_STATE_READY;
1375 return HAL_OK;
1377 else
1379 return HAL_BUSY;
1384 * @brief This function handles MMC card interrupt request.
1385 * @param hmmc: Pointer to MMC handle
1386 * @retval None
1388 void HAL_MMC_IRQHandler(MMC_HandleTypeDef *hmmc)
1390 uint32_t errorstate = HAL_MMC_ERROR_NONE;
1392 /* Check for SDIO interrupt flags */
1393 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DATAEND) != RESET)
1395 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_FLAG_DATAEND);
1397 #ifdef SDIO_STA_STBITERR
1398 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
1399 SDIO_IT_TXUNDERR | SDIO_IT_RXOVERR | SDIO_IT_STBITERR);
1400 #else /* SDIO_STA_STBITERR not defined */
1401 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
1402 SDIO_IT_TXUNDERR | SDIO_IT_RXOVERR);
1403 #endif
1405 if((hmmc->Context & MMC_CONTEXT_IT) != RESET)
1407 if(((hmmc->Context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != RESET) || ((hmmc->Context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != RESET))
1409 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
1410 if(errorstate != HAL_MMC_ERROR_NONE)
1412 hmmc->ErrorCode |= errorstate;
1413 HAL_MMC_ErrorCallback(hmmc);
1417 /* Clear all the static flags */
1418 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1420 hmmc->State = HAL_MMC_STATE_READY;
1421 if(((hmmc->Context & MMC_CONTEXT_READ_SINGLE_BLOCK) != RESET) || ((hmmc->Context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != RESET))
1423 HAL_MMC_RxCpltCallback(hmmc);
1425 else
1427 HAL_MMC_TxCpltCallback(hmmc);
1430 else if((hmmc->Context & MMC_CONTEXT_DMA) != RESET)
1432 if((hmmc->Context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != RESET)
1434 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
1435 if(errorstate != HAL_MMC_ERROR_NONE)
1437 hmmc->ErrorCode |= errorstate;
1438 HAL_MMC_ErrorCallback(hmmc);
1441 if(((hmmc->Context & MMC_CONTEXT_READ_SINGLE_BLOCK) == RESET) && ((hmmc->Context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) == RESET))
1443 /* Disable the DMA transfer for transmit request by setting the DMAEN bit
1444 in the MMC DCTRL register */
1445 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
1447 hmmc->State = HAL_MMC_STATE_READY;
1449 HAL_MMC_TxCpltCallback(hmmc);
1454 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_TXFIFOHE) != RESET)
1456 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_FLAG_TXFIFOHE);
1458 MMC_Write_IT(hmmc);
1461 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_RXFIFOHF) != RESET)
1463 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_FLAG_RXFIFOHF);
1465 MMC_Read_IT(hmmc);
1468 #ifdef SDIO_STA_STBITERR
1469 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR) != RESET)
1471 /* Set Error code */
1472 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DCRCFAIL) != RESET)
1474 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
1476 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DTIMEOUT) != RESET)
1478 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
1480 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_RXOVERR) != RESET)
1482 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
1484 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_TXUNDERR) != RESET)
1486 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
1488 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_STBITERR) != RESET)
1490 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
1493 /* Clear All flags */
1494 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS | SDIO_FLAG_STBITERR);
1496 /* Disable all interrupts */
1497 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
1498 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR |SDIO_IT_STBITERR);
1500 if((hmmc->Context & MMC_CONTEXT_DMA) != RESET)
1502 /* Abort the MMC DMA Streams */
1503 if(hmmc->hdmatx != NULL)
1505 /* Set the DMA Tx abort callback */
1506 hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort;
1507 /* Abort DMA in IT mode */
1508 if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
1510 MMC_DMATxAbort(hmmc->hdmatx);
1513 else if(hmmc->hdmarx != NULL)
1515 /* Set the DMA Rx abort callback */
1516 hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort;
1517 /* Abort DMA in IT mode */
1518 if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
1520 MMC_DMARxAbort(hmmc->hdmarx);
1523 else
1525 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1526 hmmc->State = HAL_MMC_STATE_READY;
1527 HAL_MMC_AbortCallback(hmmc);
1530 else if((hmmc->Context & MMC_CONTEXT_IT) != RESET)
1532 /* Set the MMC state to ready to be able to start again the process */
1533 hmmc->State = HAL_MMC_STATE_READY;
1534 HAL_MMC_ErrorCallback(hmmc);
1537 #else /* SDIO_STA_STBITERR not defined */
1538 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_TXUNDERR) != RESET)
1540 /* Set Error code */
1541 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DCRCFAIL) != RESET)
1543 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL;
1545 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DTIMEOUT) != RESET)
1547 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT;
1549 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_RXOVERR) != RESET)
1551 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN;
1553 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_TXUNDERR) != RESET)
1555 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN;
1558 /* Clear All flags */
1559 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
1561 /* Disable all interrupts */
1562 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
1563 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
1565 if((hmmc->Context & MMC_CONTEXT_DMA) != RESET)
1567 /* Abort the MMC DMA Streams */
1568 if(hmmc->hdmatx != NULL)
1570 /* Set the DMA Tx abort callback */
1571 hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort;
1572 /* Abort DMA in IT mode */
1573 if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
1575 MMC_DMATxAbort(hmmc->hdmatx);
1578 else if(hmmc->hdmarx != NULL)
1580 /* Set the DMA Rx abort callback */
1581 hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort;
1582 /* Abort DMA in IT mode */
1583 if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
1585 MMC_DMARxAbort(hmmc->hdmarx);
1588 else
1590 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
1591 hmmc->State = HAL_MMC_STATE_READY;
1592 HAL_MMC_AbortCallback(hmmc);
1595 else if((hmmc->Context & MMC_CONTEXT_IT) != RESET)
1597 /* Set the MMC state to ready to be able to start again the process */
1598 hmmc->State = HAL_MMC_STATE_READY;
1599 HAL_MMC_ErrorCallback(hmmc);
1602 #endif /* SDIO_STA_STBITERR */
1606 * @brief return the MMC state
1607 * @param hmmc: Pointer to mmc handle
1608 * @retval HAL state
1610 HAL_MMC_StateTypeDef HAL_MMC_GetState(MMC_HandleTypeDef *hmmc)
1612 return hmmc->State;
1616 * @brief Return the MMC error code
1617 * @param hmmc : Pointer to a MMC_HandleTypeDef structure that contains
1618 * the configuration information.
1619 * @retval MMC Error Code
1621 uint32_t HAL_MMC_GetError(MMC_HandleTypeDef *hmmc)
1623 return hmmc->ErrorCode;
1627 * @brief Tx Transfer completed callbacks
1628 * @param hmmc: Pointer to MMC handle
1629 * @retval None
1631 __weak void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef *hmmc)
1633 /* Prevent unused argument(s) compilation warning */
1634 UNUSED(hmmc);
1636 /* NOTE : This function should not be modified, when the callback is needed,
1637 the HAL_MMC_TxCpltCallback can be implemented in the user file
1642 * @brief Rx Transfer completed callbacks
1643 * @param hmmc: Pointer MMC handle
1644 * @retval None
1646 __weak void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef *hmmc)
1648 /* Prevent unused argument(s) compilation warning */
1649 UNUSED(hmmc);
1651 /* NOTE : This function should not be modified, when the callback is needed,
1652 the HAL_MMC_RxCpltCallback can be implemented in the user file
1657 * @brief MMC error callbacks
1658 * @param hmmc: Pointer MMC handle
1659 * @retval None
1661 __weak void HAL_MMC_ErrorCallback(MMC_HandleTypeDef *hmmc)
1663 /* Prevent unused argument(s) compilation warning */
1664 UNUSED(hmmc);
1666 /* NOTE : This function should not be modified, when the callback is needed,
1667 the HAL_MMC_ErrorCallback can be implemented in the user file
1672 * @brief MMC Abort callbacks
1673 * @param hmmc: Pointer MMC handle
1674 * @retval None
1676 __weak void HAL_MMC_AbortCallback(MMC_HandleTypeDef *hmmc)
1678 /* Prevent unused argument(s) compilation warning */
1679 UNUSED(hmmc);
1681 /* NOTE : This function should not be modified, when the callback is needed,
1682 the HAL_MMC_ErrorCallback can be implemented in the user file
1688 * @}
1691 /** @addtogroup MMC_Exported_Functions_Group3
1692 * @brief management functions
1694 @verbatim
1695 ==============================================================================
1696 ##### Peripheral Control functions #####
1697 ==============================================================================
1698 [..]
1699 This subsection provides a set of functions allowing to control the MMC card
1700 operations and get the related information
1702 @endverbatim
1703 * @{
1707 * @brief Returns information the information of the card which are stored on
1708 * the CID register.
1709 * @param hmmc: Pointer to MMC handle
1710 * @param pCID: Pointer to a HAL_MMC_CIDTypedef structure that
1711 * contains all CID register parameters
1712 * @retval HAL status
1714 HAL_StatusTypeDef HAL_MMC_GetCardCID(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCIDTypeDef *pCID)
1716 uint32_t tmp = 0U;
1718 /* Byte 0 */
1719 tmp = (uint8_t)((hmmc->CID[0U] & 0xFF000000U) >> 24U);
1720 pCID->ManufacturerID = tmp;
1722 /* Byte 1 */
1723 tmp = (uint8_t)((hmmc->CID[0U] & 0x00FF0000U) >> 16U);
1724 pCID->OEM_AppliID = tmp << 8U;
1726 /* Byte 2 */
1727 tmp = (uint8_t)((hmmc->CID[0U] & 0x000000FF00U) >> 8U);
1728 pCID->OEM_AppliID |= tmp;
1730 /* Byte 3 */
1731 tmp = (uint8_t)(hmmc->CID[0U] & 0x000000FFU);
1732 pCID->ProdName1 = tmp << 24U;
1734 /* Byte 4 */
1735 tmp = (uint8_t)((hmmc->CID[1U] & 0xFF000000U) >> 24U);
1736 pCID->ProdName1 |= tmp << 16U;
1738 /* Byte 5 */
1739 tmp = (uint8_t)((hmmc->CID[1U] & 0x00FF0000U) >> 16U);
1740 pCID->ProdName1 |= tmp << 8U;
1742 /* Byte 6 */
1743 tmp = (uint8_t)((hmmc->CID[1U] & 0x0000FF00U) >> 8U);
1744 pCID->ProdName1 |= tmp;
1746 /* Byte 7 */
1747 tmp = (uint8_t)(hmmc->CID[1U] & 0x000000FFU);
1748 pCID->ProdName2 = tmp;
1750 /* Byte 8 */
1751 tmp = (uint8_t)((hmmc->CID[2U] & 0xFF000000U) >> 24U);
1752 pCID->ProdRev = tmp;
1754 /* Byte 9 */
1755 tmp = (uint8_t)((hmmc->CID[2U] & 0x00FF0000U) >> 16U);
1756 pCID->ProdSN = tmp << 24U;
1758 /* Byte 10 */
1759 tmp = (uint8_t)((hmmc->CID[2U] & 0x0000FF00U) >> 8U);
1760 pCID->ProdSN |= tmp << 16U;
1762 /* Byte 11 */
1763 tmp = (uint8_t)(hmmc->CID[2U] & 0x000000FFU);
1764 pCID->ProdSN |= tmp << 8U;
1766 /* Byte 12 */
1767 tmp = (uint8_t)((hmmc->CID[3U] & 0xFF000000U) >> 24U);
1768 pCID->ProdSN |= tmp;
1770 /* Byte 13 */
1771 tmp = (uint8_t)((hmmc->CID[3U] & 0x00FF0000U) >> 16U);
1772 pCID->Reserved1 |= (tmp & 0xF0U) >> 4U;
1773 pCID->ManufactDate = (tmp & 0x0FU) << 8U;
1775 /* Byte 14 */
1776 tmp = (uint8_t)((hmmc->CID[3U] & 0x0000FF00U) >> 8U);
1777 pCID->ManufactDate |= tmp;
1779 /* Byte 15 */
1780 tmp = (uint8_t)(hmmc->CID[3U] & 0x000000FFU);
1781 pCID->CID_CRC = (tmp & 0xFEU) >> 1U;
1782 pCID->Reserved2 = 1U;
1784 return HAL_OK;
1788 * @brief Returns information the information of the card which are stored on
1789 * the CSD register.
1790 * @param hmmc: Pointer to MMC handle
1791 * @param pCSD: Pointer to a HAL_MMC_CardInfoTypeDef structure that
1792 * contains all CSD register parameters
1793 * @retval HAL status
1795 HAL_StatusTypeDef HAL_MMC_GetCardCSD(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCSDTypeDef *pCSD)
1797 uint32_t tmp = 0U;
1799 /* Byte 0 */
1800 tmp = (hmmc->CSD[0U] & 0xFF000000U) >> 24U;
1801 pCSD->CSDStruct = (uint8_t)((tmp & 0xC0U) >> 6U);
1802 pCSD->SysSpecVersion = (uint8_t)((tmp & 0x3CU) >> 2U);
1803 pCSD->Reserved1 = tmp & 0x03U;
1805 /* Byte 1 */
1806 tmp = (hmmc->CSD[0U] & 0x00FF0000U) >> 16U;
1807 pCSD->TAAC = (uint8_t)tmp;
1809 /* Byte 2 */
1810 tmp = (hmmc->CSD[0U] & 0x0000FF00U) >> 8U;
1811 pCSD->NSAC = (uint8_t)tmp;
1813 /* Byte 3 */
1814 tmp = hmmc->CSD[0U] & 0x000000FFU;
1815 pCSD->MaxBusClkFrec = (uint8_t)tmp;
1817 /* Byte 4 */
1818 tmp = (hmmc->CSD[1U] & 0xFF000000U) >> 24U;
1819 pCSD->CardComdClasses = (uint16_t)(tmp << 4U);
1821 /* Byte 5 */
1822 tmp = (hmmc->CSD[1U] & 0x00FF0000U) >> 16U;
1823 pCSD->CardComdClasses |= (uint16_t)((tmp & 0xF0U) >> 4U);
1824 pCSD->RdBlockLen = (uint8_t)(tmp & 0x0FU);
1826 /* Byte 6 */
1827 tmp = (hmmc->CSD[1U] & 0x0000FF00U) >> 8U;
1828 pCSD->PartBlockRead = (uint8_t)((tmp & 0x80U) >> 7U);
1829 pCSD->WrBlockMisalign = (uint8_t)((tmp & 0x40U) >> 6U);
1830 pCSD->RdBlockMisalign = (uint8_t)((tmp & 0x20U) >> 5U);
1831 pCSD->DSRImpl = (uint8_t)((tmp & 0x10U) >> 4U);
1832 pCSD->Reserved2 = 0; /*!< Reserved */
1834 pCSD->DeviceSize = (tmp & 0x03U) << 10U;
1836 /* Byte 7 */
1837 tmp = (uint8_t)(hmmc->CSD[1U] & 0x000000FFU);
1838 pCSD->DeviceSize |= (tmp) << 2U;
1840 /* Byte 8 */
1841 tmp = (uint8_t)((hmmc->CSD[2U] & 0xFF000000U) >> 24U);
1842 pCSD->DeviceSize |= (tmp & 0xC0U) >> 6U;
1844 pCSD->MaxRdCurrentVDDMin = (tmp & 0x38U) >> 3U;
1845 pCSD->MaxRdCurrentVDDMax = (tmp & 0x07U);
1847 /* Byte 9 */
1848 tmp = (uint8_t)((hmmc->CSD[2U] & 0x00FF0000U) >> 16U);
1849 pCSD->MaxWrCurrentVDDMin = (tmp & 0xE0U) >> 5U;
1850 pCSD->MaxWrCurrentVDDMax = (tmp & 0x1CU) >> 2U;
1851 pCSD->DeviceSizeMul = (tmp & 0x03U) << 1U;
1852 /* Byte 10 */
1853 tmp = (uint8_t)((hmmc->CSD[2] & 0x0000FF00U) >> 8U);
1854 pCSD->DeviceSizeMul |= (tmp & 0x80U) >> 7U;
1856 hmmc->MmcCard.BlockNbr = (pCSD->DeviceSize + 1U) ;
1857 hmmc->MmcCard.BlockNbr *= (1U << (pCSD->DeviceSizeMul + 2U));
1858 hmmc->MmcCard.BlockSize = 1U << (pCSD->RdBlockLen);
1860 hmmc->MmcCard.LogBlockNbr = (hmmc->MmcCard.BlockNbr) * ((hmmc->MmcCard.BlockSize) / 512U);
1861 hmmc->MmcCard.LogBlockSize = 512U;
1863 pCSD->EraseGrSize = (tmp & 0x40U) >> 6U;
1864 pCSD->EraseGrMul = (tmp & 0x3FU) << 1U;
1866 /* Byte 11 */
1867 tmp = (uint8_t)(hmmc->CSD[2U] & 0x000000FFU);
1868 pCSD->EraseGrMul |= (tmp & 0x80U) >> 7U;
1869 pCSD->WrProtectGrSize = (tmp & 0x7FU);
1871 /* Byte 12 */
1872 tmp = (uint8_t)((hmmc->CSD[3U] & 0xFF000000U) >> 24U);
1873 pCSD->WrProtectGrEnable = (tmp & 0x80U) >> 7U;
1874 pCSD->ManDeflECC = (tmp & 0x60U) >> 5U;
1875 pCSD->WrSpeedFact = (tmp & 0x1CU) >> 2U;
1876 pCSD->MaxWrBlockLen = (tmp & 0x03U) << 2U;
1878 /* Byte 13 */
1879 tmp = (uint8_t)((hmmc->CSD[3U] & 0x00FF0000U) >> 16U);
1880 pCSD->MaxWrBlockLen |= (tmp & 0xC0U) >> 6U;
1881 pCSD->WriteBlockPaPartial = (tmp & 0x20U) >> 5U;
1882 pCSD->Reserved3 = 0U;
1883 pCSD->ContentProtectAppli = (tmp & 0x01U);
1885 /* Byte 14 */
1886 tmp = (uint8_t)((hmmc->CSD[3U] & 0x0000FF00U) >> 8U);
1887 pCSD->FileFormatGrouop = (tmp & 0x80U) >> 7U;
1888 pCSD->CopyFlag = (tmp & 0x40U) >> 6U;
1889 pCSD->PermWrProtect = (tmp & 0x20U) >> 5U;
1890 pCSD->TempWrProtect = (tmp & 0x10U) >> 4U;
1891 pCSD->FileFormat = (tmp & 0x0CU) >> 2U;
1892 pCSD->ECC = (tmp & 0x03U);
1894 /* Byte 15 */
1895 tmp = (uint8_t)(hmmc->CSD[3U] & 0x000000FFU);
1896 pCSD->CSD_CRC = (tmp & 0xFEU) >> 1U;
1897 pCSD->Reserved4 = 1U;
1899 return HAL_OK;
1903 * @brief Gets the MMC card info.
1904 * @param hmmc: Pointer to MMC handle
1905 * @param pCardInfo: Pointer to the HAL_MMC_CardInfoTypeDef structure that
1906 * will contain the MMC card status information
1907 * @retval HAL status
1909 HAL_StatusTypeDef HAL_MMC_GetCardInfo(MMC_HandleTypeDef *hmmc, HAL_MMC_CardInfoTypeDef *pCardInfo)
1911 pCardInfo->CardType = (uint32_t)(hmmc->MmcCard.CardType);
1912 pCardInfo->Class = (uint32_t)(hmmc->MmcCard.Class);
1913 pCardInfo->RelCardAdd = (uint32_t)(hmmc->MmcCard.RelCardAdd);
1914 pCardInfo->BlockNbr = (uint32_t)(hmmc->MmcCard.BlockNbr);
1915 pCardInfo->BlockSize = (uint32_t)(hmmc->MmcCard.BlockSize);
1916 pCardInfo->LogBlockNbr = (uint32_t)(hmmc->MmcCard.LogBlockNbr);
1917 pCardInfo->LogBlockSize = (uint32_t)(hmmc->MmcCard.LogBlockSize);
1919 return HAL_OK;
1923 * @brief Enables wide bus operation for the requested card if supported by
1924 * card.
1925 * @param hmmc: Pointer to MMC handle
1926 * @param WideMode: Specifies the MMC card wide bus mode
1927 * This parameter can be one of the following values:
1928 * @arg SDIO_BUS_WIDE_8B: 8-bit data transfer
1929 * @arg SDIO_BUS_WIDE_4B: 4-bit data transfer
1930 * @arg SDIO_BUS_WIDE_1B: 1-bit data transfer
1931 * @retval HAL status
1933 HAL_StatusTypeDef HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef *hmmc, uint32_t WideMode)
1935 __IO uint32_t count = 0U;
1936 SDIO_InitTypeDef Init;
1937 uint32_t errorstate = HAL_MMC_ERROR_NONE;
1938 uint32_t response = 0U, busy = 0U;
1940 /* Check the parameters */
1941 assert_param(IS_SDIO_BUS_WIDE(WideMode));
1943 /* Chnage Satte */
1944 hmmc->State = HAL_MMC_STATE_BUSY;
1946 /* Update Clock for Bus mode update */
1947 Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
1948 Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
1949 Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
1950 Init.BusWide = WideMode;
1951 Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
1952 Init.ClockDiv = SDIO_INIT_CLK_DIV;
1953 /* Initialize SDIO*/
1954 SDIO_Init(hmmc->Instance, Init);
1956 if(WideMode == SDIO_BUS_WIDE_8B)
1958 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U);
1959 if(errorstate != HAL_MMC_ERROR_NONE)
1961 hmmc->ErrorCode |= errorstate;
1964 else if(WideMode == SDIO_BUS_WIDE_4B)
1966 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U);
1967 if(errorstate != HAL_MMC_ERROR_NONE)
1969 hmmc->ErrorCode |= errorstate;
1972 else if(WideMode == SDIO_BUS_WIDE_1B)
1974 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70000U);
1975 if(errorstate != HAL_MMC_ERROR_NONE)
1977 hmmc->ErrorCode |= errorstate;
1980 else
1982 /* WideMode is not a valid argument*/
1983 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM;
1986 /* Check for switch error and violation of the trial number of sending CMD 13 */
1987 while(busy == 0U)
1989 if(count++ == SDMMC_MAX_TRIAL)
1991 hmmc->State = HAL_MMC_STATE_READY;
1992 hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
1993 return HAL_ERROR;
1996 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
1997 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
1998 if(errorstate != HAL_MMC_ERROR_NONE)
2000 hmmc->ErrorCode |= errorstate;
2003 /* Get command response */
2004 response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
2006 /* Get operating voltage*/
2007 busy = (((response >> 7U) == 1U) ? 0U : 1U);
2010 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2011 count = SDMMC_DATATIMEOUT;
2012 while((response & 0x00000100U) == 0U)
2014 if(count-- == 0U)
2016 hmmc->State = HAL_MMC_STATE_READY;
2017 hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
2018 return HAL_ERROR;
2021 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */
2022 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2023 if(errorstate != HAL_MMC_ERROR_NONE)
2025 hmmc->ErrorCode |= errorstate;
2028 /* Get command response */
2029 response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
2032 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2034 /* Clear all the static flags */
2035 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
2036 hmmc->State = HAL_MMC_STATE_READY;
2037 return HAL_ERROR;
2039 else
2041 /* Configure the SDIO peripheral */
2042 Init.ClockEdge = hmmc->Init.ClockEdge;
2043 Init.ClockBypass = hmmc->Init.ClockBypass;
2044 Init.ClockPowerSave = hmmc->Init.ClockPowerSave;
2045 Init.BusWide = WideMode;
2046 Init.HardwareFlowControl = hmmc->Init.HardwareFlowControl;
2047 Init.ClockDiv = hmmc->Init.ClockDiv;
2048 SDIO_Init(hmmc->Instance, Init);
2051 /* Change State */
2052 hmmc->State = HAL_MMC_STATE_READY;
2054 return HAL_OK;
2059 * @brief Gets the current mmc card data state.
2060 * @param hmmc: pointer to MMC handle
2061 * @retval Card state
2063 HAL_MMC_CardStateTypeDef HAL_MMC_GetCardState(MMC_HandleTypeDef *hmmc)
2065 HAL_MMC_CardStateTypeDef cardstate = HAL_MMC_CARD_TRANSFER;
2066 uint32_t errorstate = HAL_MMC_ERROR_NONE;
2067 uint32_t resp1 = 0U;
2069 errorstate = MMC_SendStatus(hmmc, &resp1);
2070 if(errorstate != HAL_OK)
2072 hmmc->ErrorCode |= errorstate;
2075 cardstate = (HAL_MMC_CardStateTypeDef)((resp1 >> 9U) & 0x0FU);
2077 return cardstate;
2081 * @brief Abort the current transfer and disable the MMC.
2082 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2083 * the configuration information for MMC module.
2084 * @retval HAL status
2086 HAL_StatusTypeDef HAL_MMC_Abort(MMC_HandleTypeDef *hmmc)
2088 HAL_MMC_CardStateTypeDef CardState;
2090 /* DIsable All interrupts */
2091 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
2092 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
2094 /* Clear All flags */
2095 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
2097 if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL))
2099 /* Disable the MMC DMA request */
2100 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
2102 /* Abort the MMC DMA Tx Stream */
2103 if(hmmc->hdmatx != NULL)
2105 HAL_DMA_Abort(hmmc->hdmatx);
2107 /* Abort the MMC DMA Rx Stream */
2108 if(hmmc->hdmarx != NULL)
2110 HAL_DMA_Abort(hmmc->hdmarx);
2114 hmmc->State = HAL_MMC_STATE_READY;
2115 CardState = HAL_MMC_GetCardState(hmmc);
2116 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2118 hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
2120 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2122 return HAL_ERROR;
2124 return HAL_OK;
2128 * @brief Abort the current transfer and disable the MMC (IT mode).
2129 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2130 * the configuration information for MMC module.
2131 * @retval HAL status
2133 HAL_StatusTypeDef HAL_MMC_Abort_IT(MMC_HandleTypeDef *hmmc)
2135 HAL_MMC_CardStateTypeDef CardState;
2137 /* DIsable All interrupts */
2138 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
2139 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
2141 /* Clear All flags */
2142 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
2144 if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL))
2146 /* Disable the MMC DMA request */
2147 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
2149 /* Abort the MMC DMA Tx Stream */
2150 if(hmmc->hdmatx != NULL)
2152 hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort;
2153 if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK)
2155 hmmc->hdmatx = NULL;
2158 /* Abort the MMC DMA Rx Stream */
2159 if(hmmc->hdmarx != NULL)
2161 hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort;
2162 if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK)
2164 hmmc->hdmarx = NULL;
2169 /* No transfer ongoing on both DMA channels*/
2170 if((hmmc->hdmatx == NULL) && (hmmc->hdmarx == NULL))
2172 CardState = HAL_MMC_GetCardState(hmmc);
2173 hmmc->State = HAL_MMC_STATE_READY;
2174 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2176 hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance);
2178 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2180 return HAL_ERROR;
2182 else
2184 HAL_MMC_AbortCallback(hmmc);
2188 return HAL_OK;
2192 * @}
2196 * @}
2199 /* Private function ----------------------------------------------------------*/
2200 /** @addtogroup MMC_Private_Functions
2201 * @{
2205 * @brief DMA MMC transmit process complete callback
2206 * @param hdma: DMA handle
2207 * @retval None
2209 static void MMC_DMATransmitCplt(DMA_HandleTypeDef *hdma)
2211 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2213 /* Enable DATAEND Interrupt */
2214 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DATAEND));
2218 * @brief DMA MMC receive process complete callback
2219 * @param hdma: DMA handle
2220 * @retval None
2222 static void MMC_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
2224 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2225 uint32_t errorstate = HAL_MMC_ERROR_NONE;
2227 /* Send stop command in multiblock write */
2228 if(hmmc->Context == (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA))
2230 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance);
2231 if(errorstate != HAL_MMC_ERROR_NONE)
2233 hmmc->ErrorCode |= errorstate;
2234 HAL_MMC_ErrorCallback(hmmc);
2238 /* Disable the DMA transfer for transmit request by setting the DMAEN bit
2239 in the MMC DCTRL register */
2240 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
2242 /* Clear all the static flags */
2243 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
2245 hmmc->State = HAL_MMC_STATE_READY;
2247 HAL_MMC_RxCpltCallback(hmmc);
2251 * @brief DMA MMC communication error callback
2252 * @param hdma: DMA handle
2253 * @retval None
2255 static void MMC_DMAError(DMA_HandleTypeDef *hdma)
2257 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2258 HAL_MMC_CardStateTypeDef CardState;
2260 if((hmmc->hdmarx->ErrorCode == HAL_DMA_ERROR_TE) || (hmmc->hdmatx->ErrorCode == HAL_DMA_ERROR_TE))
2262 /* Clear All flags */
2263 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS);
2265 /* Disable All interrupts */
2266 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\
2267 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR);
2269 hmmc->ErrorCode |= HAL_MMC_ERROR_DMA;
2270 CardState = HAL_MMC_GetCardState(hmmc);
2271 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2273 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
2276 hmmc->State= HAL_MMC_STATE_READY;
2279 HAL_MMC_ErrorCallback(hmmc);
2283 * @brief DMA MMC Tx Abort callback
2284 * @param hdma: DMA handle
2285 * @retval None
2287 static void MMC_DMATxAbort(DMA_HandleTypeDef *hdma)
2289 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2290 HAL_MMC_CardStateTypeDef CardState;
2292 if(hmmc->hdmatx != NULL)
2294 hmmc->hdmatx = NULL;
2297 /* All DMA channels are aborted */
2298 if(hmmc->hdmarx == NULL)
2300 CardState = HAL_MMC_GetCardState(hmmc);
2301 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
2302 hmmc->State = HAL_MMC_STATE_READY;
2303 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2305 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
2307 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2309 HAL_MMC_AbortCallback(hmmc);
2311 else
2313 HAL_MMC_ErrorCallback(hmmc);
2320 * @brief DMA MMC Rx Abort callback
2321 * @param hdma: DMA handle
2322 * @retval None
2324 static void MMC_DMARxAbort(DMA_HandleTypeDef *hdma)
2326 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent);
2327 HAL_MMC_CardStateTypeDef CardState;
2329 if(hmmc->hdmarx != NULL)
2331 hmmc->hdmarx = NULL;
2334 /* All DMA channels are aborted */
2335 if(hmmc->hdmatx == NULL)
2337 CardState = HAL_MMC_GetCardState(hmmc);
2338 hmmc->ErrorCode = HAL_MMC_ERROR_NONE;
2339 hmmc->State = HAL_MMC_STATE_READY;
2340 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING))
2342 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance);
2344 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE)
2346 HAL_MMC_AbortCallback(hmmc);
2348 else
2350 HAL_MMC_ErrorCallback(hmmc);
2358 * @brief Initializes the mmc card.
2359 * @param hmmc: Pointer to MMC handle
2360 * @retval MMC Card error state
2362 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc)
2364 HAL_MMC_CardCSDTypeDef CSD;
2365 uint32_t errorstate = HAL_MMC_ERROR_NONE;
2366 uint16_t mmc_rca = 1;
2368 /* Check the power State */
2369 if(SDIO_GetPowerState(hmmc->Instance) == 0U)
2371 /* Power off */
2372 return HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE;
2375 /* Send CMD2 ALL_SEND_CID */
2376 errorstate = SDMMC_CmdSendCID(hmmc->Instance);
2377 if(errorstate != HAL_MMC_ERROR_NONE)
2379 return errorstate;
2381 else
2383 /* Get Card identification number data */
2384 hmmc->CID[0U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
2385 hmmc->CID[1U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP2);
2386 hmmc->CID[2U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP3);
2387 hmmc->CID[3U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP4);
2390 /* Send CMD3 SET_REL_ADDR with argument 0 */
2391 /* MMC Card publishes its RCA. */
2392 errorstate = SDMMC_CmdSetRelAdd(hmmc->Instance, &mmc_rca);
2393 if(errorstate != HAL_MMC_ERROR_NONE)
2395 return errorstate;
2398 /* Get the MMC card RCA */
2399 hmmc->MmcCard.RelCardAdd = mmc_rca;
2401 /* Send CMD9 SEND_CSD with argument as card's RCA */
2402 errorstate = SDMMC_CmdSendCSD(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
2403 if(errorstate != HAL_MMC_ERROR_NONE)
2405 return errorstate;
2407 else
2409 /* Get Card Specific Data */
2410 hmmc->CSD[0U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
2411 hmmc->CSD[1U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP2);
2412 hmmc->CSD[2U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP3);
2413 hmmc->CSD[3U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP4);
2416 /* Get the Card Class */
2417 hmmc->MmcCard.Class = (SDIO_GetResponse(hmmc->Instance, SDIO_RESP2) >> 20U);
2419 /* Get CSD parameters */
2420 HAL_MMC_GetCardCSD(hmmc, &CSD);
2422 /* Select the Card */
2423 errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U));
2424 if(errorstate != HAL_MMC_ERROR_NONE)
2426 return errorstate;
2429 /* Configure SDIO peripheral interface */
2430 SDIO_Init(hmmc->Instance, hmmc->Init);
2432 /* All cards are initialized */
2433 return HAL_MMC_ERROR_NONE;
2437 * @brief Enquires cards about their operating voltage and configures clock
2438 * controls and stores MMC information that will be needed in future
2439 * in the MMC handle.
2440 * @param hmmc: Pointer to MMC handle
2441 * @retval error state
2443 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc)
2445 __IO uint32_t count = 0U;
2446 uint32_t response = 0U, validvoltage = 0U;
2447 uint32_t errorstate = HAL_MMC_ERROR_NONE;
2449 /* CMD0: GO_IDLE_STATE */
2450 errorstate = SDMMC_CmdGoIdleState(hmmc->Instance);
2451 if(errorstate != HAL_MMC_ERROR_NONE)
2453 return errorstate;
2456 while(validvoltage == 0U)
2458 if(count++ == SDMMC_MAX_VOLT_TRIAL)
2460 return HAL_MMC_ERROR_INVALID_VOLTRANGE;
2463 /* SEND CMD1 APP_CMD with MMC_HIGH_VOLTAGE_RANGE(0xC0FF8000) as argument */
2464 errorstate = SDMMC_CmdOpCondition(hmmc->Instance, eMMC_HIGH_VOLTAGE_RANGE);
2465 if(errorstate != HAL_MMC_ERROR_NONE)
2467 return HAL_MMC_ERROR_UNSUPPORTED_FEATURE;
2470 /* Get command response */
2471 response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
2473 /* Get operating voltage*/
2474 validvoltage = (((response >> 31U) == 1U) ? 1U : 0U);
2477 /* When power routine is finished and command returns valid voltage */
2478 if ((response & eMMC_HIGH_VOLTAGE_RANGE) == MMC_HIGH_VOLTAGE_RANGE)
2480 /* When voltage range of the card is within 2.7V and 3.6V */
2481 hmmc->MmcCard.CardType = MMC_HIGH_VOLTAGE_CARD;
2483 else
2485 /* When voltage range of the card is within 1.65V and 1.95V or 2.7V and 3.6V */
2486 hmmc->MmcCard.CardType = MMC_DUAL_VOLTAGE_CARD;
2489 return HAL_MMC_ERROR_NONE;
2493 * @brief Turns the SDIO output signals off.
2494 * @param hmmc: Pointer to MMC handle
2495 * @retval HAL status
2497 static HAL_StatusTypeDef MMC_PowerOFF(MMC_HandleTypeDef *hmmc)
2499 /* Set Power State to OFF */
2500 SDIO_PowerState_OFF(hmmc->Instance);
2502 return HAL_OK;
2506 * @brief Returns the current card's status.
2507 * @param hmmc: Pointer to MMC handle
2508 * @param pCardStatus: pointer to the buffer that will contain the MMC card
2509 * status (Card Status register)
2510 * @retval error state
2512 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus)
2514 uint32_t errorstate = HAL_MMC_ERROR_NONE;
2516 if(pCardStatus == NULL)
2518 return HAL_MMC_ERROR_PARAM;
2521 /* Send Status command */
2522 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U));
2523 if(errorstate != HAL_OK)
2525 return errorstate;
2528 /* Get MMC card status */
2529 *pCardStatus = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1);
2531 return HAL_MMC_ERROR_NONE;
2535 * @brief Wrap up reading in non-blocking mode.
2536 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2537 * the configuration information.
2538 * @retval HAL status
2540 static HAL_StatusTypeDef MMC_Read_IT(MMC_HandleTypeDef *hmmc)
2542 uint32_t count = 0U;
2543 uint32_t* tmp;
2545 tmp = (uint32_t*)hmmc->pRxBuffPtr;
2547 /* Read data from SDMMC Rx FIFO */
2548 for(count = 0U; count < 8U; count++)
2550 *(tmp + count) = SDIO_ReadFIFO(hmmc->Instance);
2553 hmmc->pRxBuffPtr += 8U;
2555 return HAL_OK;
2559 * @brief Wrap up writing in non-blocking mode.
2560 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains
2561 * the configuration information.
2562 * @retval HAL status
2564 static HAL_StatusTypeDef MMC_Write_IT(MMC_HandleTypeDef *hmmc)
2566 uint32_t count = 0U;
2567 uint32_t* tmp;
2569 tmp = (uint32_t*)hmmc->pTxBuffPtr;
2571 /* Write data to SDMMC Tx FIFO */
2572 for(count = 0U; count < 8U; count++)
2574 SDIO_WriteFIFO(hmmc->Instance, (tmp + count));
2577 hmmc->pTxBuffPtr += 8U;
2579 return HAL_OK;
2583 * @}
2586 #endif /* STM32F103xE || STM32F103xG */
2588 #endif /* HAL_MMC_MODULE_ENABLED */
2591 * @}
2595 * @}
2598 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/