2 ******************************************************************************
3 * @file stm32f1xx_hal_mmc.c
4 * @author MCD Application Team
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
16 ==============================================================================
17 ##### How to use this driver #####
18 ==============================================================================
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
25 You can easily tailor this configuration according to hardware resources.
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 ================================================
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
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
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
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 ==============================
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 ===============================
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 ======================
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 ===========================
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,
168 *** MMC card CSD register ***
169 ============================
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 ============================
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 ==================================
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
195 (@) You can refer to the MMC HAL driver header file for more useful macros
198 ******************************************************************************
201 * <h2><center>© 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
239 #ifdef HAL_MMC_MODULE_ENABLED
241 #if defined(STM32F103xE) || defined(STM32F103xG)
243 /* Private typedef -----------------------------------------------------------*/
244 /* Private define ------------------------------------------------------------*/
245 /** @addtogroup MMC_Private_Defines
253 /* Private macro -------------------------------------------------------------*/
254 /* Private variables ---------------------------------------------------------*/
255 /* Private function prototypes -----------------------------------------------*/
256 /* Private functions ---------------------------------------------------------*/
257 /** @defgroup MMC_Private_Functions MMC Private Functions
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
);
275 /* Exported functions --------------------------------------------------------*/
276 /** @addtogroup MMC_Exported_Functions
280 /** @addtogroup MMC_Exported_Functions_Group1
281 * @brief Initialization and de-initialization functions
284 ==============================================================================
285 ##### Initialization and de-initialization functions #####
286 ==============================================================================
288 This section provides functions allowing to initialize/de-initialize the MMC
289 card device to be ready for use.
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
301 HAL_StatusTypeDef
HAL_MMC_Init(MMC_HandleTypeDef
*hmmc
)
303 /* Check the MMC handle allocation */
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
;
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.
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
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
;
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
;
401 * @brief De-Initializes the MMC card.
402 * @param hmmc: Pointer to MMC handle
405 HAL_StatusTypeDef
HAL_MMC_DeInit(MMC_HandleTypeDef
*hmmc
)
407 /* Check the MMC handle allocation */
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 */
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
;
432 * @brief Initializes the MMC MSP.
433 * @param hmmc: Pointer to MMC handle
436 __weak
void HAL_MMC_MspInit(MMC_HandleTypeDef
*hmmc
)
438 /* Prevent unused argument(s) compilation warning */
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
451 __weak
void HAL_MMC_MspDeInit(MMC_HandleTypeDef
*hmmc
)
453 /* Prevent unused argument(s) compilation warning */
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
465 /** @addtogroup MMC_Exported_Functions_Group2
466 * @brief Data transfer functions
469 ==============================================================================
470 ##### IO operation functions #####
471 ==============================================================================
473 This subsection provides a set of functions allowing to manage the data
474 transfer from/to MMC card.
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
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
;
501 hmmc
->ErrorCode
|= HAL_MMC_ERROR_PARAM
;
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
;
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
)
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
;
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
);
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
;
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
);
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
;
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
;
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
;
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
;
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
;
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
);
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
;
654 /* Clear all the static flags */
655 __HAL_MMC_CLEAR_FLAG(hmmc
, SDIO_STATIC_FLAGS
);
657 hmmc
->State
= HAL_MMC_STATE_READY
;
663 hmmc
->ErrorCode
|= HAL_MMC_ERROR_BUSY
;
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
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();
686 uint32_t *tempbuff
= (uint32_t *)pData
;
690 hmmc
->ErrorCode
|= HAL_MMC_ERROR_PARAM
;
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
;
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
)
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
;
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
);
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
;
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
));
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
;
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
;
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
;
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
;
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
;
827 /* Clear all the static flags */
828 __HAL_MMC_CLEAR_FLAG(hmmc
, SDIO_STATIC_FLAGS
);
830 hmmc
->State
= HAL_MMC_STATE_READY
;
836 hmmc
->ErrorCode
|= HAL_MMC_ERROR_BUSY
;
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
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.
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
;
861 hmmc
->ErrorCode
|= HAL_MMC_ERROR_PARAM
;
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
;
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
)
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
;
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
);
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
;
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
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
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
;
963 hmmc
->ErrorCode
|= HAL_MMC_ERROR_PARAM
;
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
;
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
)
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
;
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
);
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
;
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
);
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
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
;
1066 hmmc
->ErrorCode
|= HAL_MMC_ERROR_PARAM
;
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
;
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
)
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
;
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
);
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
;
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
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
;
1184 hmmc
->ErrorCode
|= HAL_MMC_ERROR_PARAM
;
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
;
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
)
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
;
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
);
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
;
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
);
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
;
1306 if(BlockEndAdd
> (hmmc
->MmcCard
.LogBlockNbr
))
1308 hmmc
->ErrorCode
|= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE
;
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
;
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
;
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
;
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
;
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
;
1373 hmmc
->State
= HAL_MMC_STATE_READY
;
1384 * @brief This function handles MMC card interrupt request.
1385 * @param hmmc: Pointer to MMC handle
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
);
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
);
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
);
1461 else if(__HAL_MMC_GET_FLAG(hmmc
, SDIO_IT_RXFIFOHF
) != RESET
)
1463 __HAL_MMC_CLEAR_FLAG(hmmc
, SDIO_FLAG_RXFIFOHF
);
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
);
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
);
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
1610 HAL_MMC_StateTypeDef
HAL_MMC_GetState(MMC_HandleTypeDef
*hmmc
)
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
1631 __weak
void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef
*hmmc
)
1633 /* Prevent unused argument(s) compilation warning */
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
1646 __weak
void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef
*hmmc
)
1648 /* Prevent unused argument(s) compilation warning */
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
1661 __weak
void HAL_MMC_ErrorCallback(MMC_HandleTypeDef
*hmmc
)
1663 /* Prevent unused argument(s) compilation warning */
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
1676 __weak
void HAL_MMC_AbortCallback(MMC_HandleTypeDef
*hmmc
)
1678 /* Prevent unused argument(s) compilation warning */
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
1691 /** @addtogroup MMC_Exported_Functions_Group3
1692 * @brief management functions
1695 ==============================================================================
1696 ##### Peripheral Control functions #####
1697 ==============================================================================
1699 This subsection provides a set of functions allowing to control the MMC card
1700 operations and get the related information
1707 * @brief Returns information the information of the card which are stored on
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
)
1719 tmp
= (uint8_t)((hmmc
->CID
[0U] & 0xFF000000U
) >> 24U);
1720 pCID
->ManufacturerID
= tmp
;
1723 tmp
= (uint8_t)((hmmc
->CID
[0U] & 0x00FF0000U
) >> 16U);
1724 pCID
->OEM_AppliID
= tmp
<< 8U;
1727 tmp
= (uint8_t)((hmmc
->CID
[0U] & 0x000000FF00U
) >> 8U);
1728 pCID
->OEM_AppliID
|= tmp
;
1731 tmp
= (uint8_t)(hmmc
->CID
[0U] & 0x000000FFU
);
1732 pCID
->ProdName1
= tmp
<< 24U;
1735 tmp
= (uint8_t)((hmmc
->CID
[1U] & 0xFF000000U
) >> 24U);
1736 pCID
->ProdName1
|= tmp
<< 16U;
1739 tmp
= (uint8_t)((hmmc
->CID
[1U] & 0x00FF0000U
) >> 16U);
1740 pCID
->ProdName1
|= tmp
<< 8U;
1743 tmp
= (uint8_t)((hmmc
->CID
[1U] & 0x0000FF00U
) >> 8U);
1744 pCID
->ProdName1
|= tmp
;
1747 tmp
= (uint8_t)(hmmc
->CID
[1U] & 0x000000FFU
);
1748 pCID
->ProdName2
= tmp
;
1751 tmp
= (uint8_t)((hmmc
->CID
[2U] & 0xFF000000U
) >> 24U);
1752 pCID
->ProdRev
= tmp
;
1755 tmp
= (uint8_t)((hmmc
->CID
[2U] & 0x00FF0000U
) >> 16U);
1756 pCID
->ProdSN
= tmp
<< 24U;
1759 tmp
= (uint8_t)((hmmc
->CID
[2U] & 0x0000FF00U
) >> 8U);
1760 pCID
->ProdSN
|= tmp
<< 16U;
1763 tmp
= (uint8_t)(hmmc
->CID
[2U] & 0x000000FFU
);
1764 pCID
->ProdSN
|= tmp
<< 8U;
1767 tmp
= (uint8_t)((hmmc
->CID
[3U] & 0xFF000000U
) >> 24U);
1768 pCID
->ProdSN
|= tmp
;
1771 tmp
= (uint8_t)((hmmc
->CID
[3U] & 0x00FF0000U
) >> 16U);
1772 pCID
->Reserved1
|= (tmp
& 0xF0U
) >> 4U;
1773 pCID
->ManufactDate
= (tmp
& 0x0FU
) << 8U;
1776 tmp
= (uint8_t)((hmmc
->CID
[3U] & 0x0000FF00U
) >> 8U);
1777 pCID
->ManufactDate
|= tmp
;
1780 tmp
= (uint8_t)(hmmc
->CID
[3U] & 0x000000FFU
);
1781 pCID
->CID_CRC
= (tmp
& 0xFEU
) >> 1U;
1782 pCID
->Reserved2
= 1U;
1788 * @brief Returns information the information of the card which are stored on
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
)
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
;
1806 tmp
= (hmmc
->CSD
[0U] & 0x00FF0000U
) >> 16U;
1807 pCSD
->TAAC
= (uint8_t)tmp
;
1810 tmp
= (hmmc
->CSD
[0U] & 0x0000FF00U
) >> 8U;
1811 pCSD
->NSAC
= (uint8_t)tmp
;
1814 tmp
= hmmc
->CSD
[0U] & 0x000000FFU
;
1815 pCSD
->MaxBusClkFrec
= (uint8_t)tmp
;
1818 tmp
= (hmmc
->CSD
[1U] & 0xFF000000U
) >> 24U;
1819 pCSD
->CardComdClasses
= (uint16_t)(tmp
<< 4U);
1822 tmp
= (hmmc
->CSD
[1U] & 0x00FF0000U
) >> 16U;
1823 pCSD
->CardComdClasses
|= (uint16_t)((tmp
& 0xF0U
) >> 4U);
1824 pCSD
->RdBlockLen
= (uint8_t)(tmp
& 0x0FU
);
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;
1837 tmp
= (uint8_t)(hmmc
->CSD
[1U] & 0x000000FFU
);
1838 pCSD
->DeviceSize
|= (tmp
) << 2U;
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
);
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;
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;
1867 tmp
= (uint8_t)(hmmc
->CSD
[2U] & 0x000000FFU
);
1868 pCSD
->EraseGrMul
|= (tmp
& 0x80U
) >> 7U;
1869 pCSD
->WrProtectGrSize
= (tmp
& 0x7FU
);
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;
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
);
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
);
1895 tmp
= (uint8_t)(hmmc
->CSD
[3U] & 0x000000FFU
);
1896 pCSD
->CSD_CRC
= (tmp
& 0xFEU
) >> 1U;
1897 pCSD
->Reserved4
= 1U;
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
);
1923 * @brief Enables wide bus operation for the requested card if supported by
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
));
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
;
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 */
1989 if(count
++ == SDMMC_MAX_TRIAL
)
1991 hmmc
->State
= HAL_MMC_STATE_READY
;
1992 hmmc
->ErrorCode
|= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE
;
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)
2016 hmmc
->State
= HAL_MMC_STATE_READY
;
2017 hmmc
->ErrorCode
|= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE
;
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
;
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
);
2052 hmmc
->State
= HAL_MMC_STATE_READY
;
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
);
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
)
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
)
2184 HAL_MMC_AbortCallback(hmmc
);
2199 /* Private function ----------------------------------------------------------*/
2200 /** @addtogroup MMC_Private_Functions
2205 * @brief DMA MMC transmit process complete callback
2206 * @param hdma: DMA handle
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
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
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
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
);
2313 HAL_MMC_ErrorCallback(hmmc
);
2320 * @brief DMA MMC Rx Abort callback
2321 * @param hdma: DMA handle
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
);
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)
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
)
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
)
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
)
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
)
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
)
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
;
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
);
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
)
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;
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;
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;
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;
2586 #endif /* STM32F103xE || STM32F103xG */
2588 #endif /* HAL_MMC_MODULE_ENABLED */
2598 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/