STM32F439xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32f4xx_hal_mmc.c 00004 * @author MCD Application Team 00005 * @brief MMC card HAL module driver. 00006 * This file provides firmware functions to manage the following 00007 * functionalities of the Secure Digital (MMC) peripheral: 00008 * + Initialization and de-initialization functions 00009 * + IO operation functions 00010 * + Peripheral Control functions 00011 * + MMC card Control functions 00012 * 00013 @verbatim 00014 ============================================================================== 00015 ##### How to use this driver ##### 00016 ============================================================================== 00017 [..] 00018 This driver implements a high level communication layer for read and write from/to 00019 this memory. The needed STM32 hardware resources (SDMMC and GPIO) are performed by 00020 the user in HAL_MMC_MspInit() function (MSP layer). 00021 Basically, the MSP layer configuration should be the same as we provide in the 00022 examples. 00023 You can easily tailor this configuration according to hardware resources. 00024 00025 [..] 00026 This driver is a generic layered driver for SDMMC memories which uses the HAL 00027 SDMMC driver functions to interface with MMC and eMMC cards devices. 00028 It is used as follows: 00029 00030 (#)Initialize the SDMMC low level resources by implement the HAL_MMC_MspInit() API: 00031 (##) Enable the SDMMC interface clock using __HAL_RCC_SDMMC_CLK_ENABLE(); 00032 (##) SDMMC pins configuration for MMC card 00033 (+++) Enable the clock for the SDMMC GPIOs using the functions __HAL_RCC_GPIOx_CLK_ENABLE(); 00034 (+++) Configure these SDMMC pins as alternate function pull-up using HAL_GPIO_Init() 00035 and according to your pin assignment; 00036 (##) DMA Configuration if you need to use DMA process (HAL_MMC_ReadBlocks_DMA() 00037 and HAL_MMC_WriteBlocks_DMA() APIs). 00038 (+++) Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE(); 00039 (+++) Configure the DMA using the function HAL_DMA_Init() with predeclared and filled. 00040 (##) NVIC configuration if you need to use interrupt process when using DMA transfer. 00041 (+++) Configure the SDMMC and DMA interrupt priorities using functions 00042 HAL_NVIC_SetPriority(); DMA priority is superior to SDMMC's priority 00043 (+++) Enable the NVIC DMA and SDMMC IRQs using function HAL_NVIC_EnableIRQ() 00044 (+++) SDMMC interrupts are managed using the macros __HAL_MMC_ENABLE_IT() 00045 and __HAL_MMC_DISABLE_IT() inside the communication process. 00046 (+++) SDMMC interrupts pending bits are managed using the macros __HAL_MMC_GET_IT() 00047 and __HAL_MMC_CLEAR_IT() 00048 (##) NVIC configuration if you need to use interrupt process (HAL_MMC_ReadBlocks_IT() 00049 and HAL_MMC_WriteBlocks_IT() APIs). 00050 (+++) Configure the SDMMC interrupt priorities using function 00051 HAL_NVIC_SetPriority(); 00052 (+++) Enable the NVIC SDMMC IRQs using function HAL_NVIC_EnableIRQ() 00053 (+++) SDMMC interrupts are managed using the macros __HAL_MMC_ENABLE_IT() 00054 and __HAL_MMC_DISABLE_IT() inside the communication process. 00055 (+++) SDMMC interrupts pending bits are managed using the macros __HAL_MMC_GET_IT() 00056 and __HAL_MMC_CLEAR_IT() 00057 (#) At this stage, you can perform MMC read/write/erase operations after MMC card initialization 00058 00059 00060 *** MMC Card Initialization and configuration *** 00061 ================================================ 00062 [..] 00063 To initialize the MMC Card, use the HAL_MMC_Init() function. It Initializes 00064 SDMMC IP (STM32 side) and the MMC Card, and put it into StandBy State (Ready for data transfer). 00065 This function provide the following operations: 00066 00067 (#) Initialize the SDMMC peripheral interface with defaullt configuration. 00068 The initialization process is done at 400KHz. You can change or adapt 00069 this frequency by adjusting the "ClockDiv" field. 00070 The MMC Card frequency (SDMMC_CK) is computed as follows: 00071 00072 SDMMC_CK = SDMMCCLK / (ClockDiv + 2) 00073 00074 In initialization mode and according to the MMC Card standard, 00075 make sure that the SDMMC_CK frequency doesn't exceed 400KHz. 00076 00077 This phase of initialization is done through SDMMC_Init() and 00078 SDMMC_PowerState_ON() SDMMC low level APIs. 00079 00080 (#) Initialize the MMC card. The API used is HAL_MMC_InitCard(). 00081 This phase allows the card initialization and identification 00082 and check the MMC Card type (Standard Capacity or High Capacity) 00083 The initialization flow is compatible with MMC standard. 00084 00085 This API (HAL_MMC_InitCard()) could be used also to reinitialize the card in case 00086 of plug-off plug-in. 00087 00088 (#) Configure the MMC Card Data transfer frequency. By Default, the card transfer 00089 frequency is set to 24MHz. You can change or adapt this frequency by adjusting 00090 the "ClockDiv" field. 00091 In transfer mode and according to the MMC Card standard, make sure that the 00092 SDMMC_CK frequency doesn't exceed 25MHz and 50MHz in High-speed mode switch. 00093 To be able to use a frequency higher than 24MHz, you should use the SDMMC 00094 peripheral in bypass mode. Refer to the corresponding reference manual 00095 for more details. 00096 00097 (#) Select the corresponding MMC Card according to the address read with the step 2. 00098 00099 (#) Configure the MMC Card in wide bus mode: 4-bits data. 00100 00101 *** MMC Card Read operation *** 00102 ============================== 00103 [..] 00104 (+) You can read from MMC card in polling mode by using function HAL_MMC_ReadBlocks(). 00105 This function allows the read of 512 bytes blocks. 00106 You can choose either one block read operation or multiple block read operation 00107 by adjusting the "NumberOfBlocks" parameter. 00108 After this, you have to ensure that the transfer is done correctly. The check is done 00109 through HAL_MMC_GetCardState() function for MMC card state. 00110 00111 (+) You can read from MMC card in DMA mode by using function HAL_MMC_ReadBlocks_DMA(). 00112 This function allows the read of 512 bytes blocks. 00113 You can choose either one block read operation or multiple block read operation 00114 by adjusting the "NumberOfBlocks" parameter. 00115 After this, you have to ensure that the transfer is done correctly. The check is done 00116 through HAL_MMC_GetCardState() function for MMC card state. 00117 You could also check the DMA transfer process through the MMC Rx interrupt event. 00118 00119 (+) You can read from MMC card in Interrupt mode by using function HAL_MMC_ReadBlocks_IT(). 00120 This function allows the read of 512 bytes blocks. 00121 You can choose either one block read operation or multiple block read operation 00122 by adjusting the "NumberOfBlocks" parameter. 00123 After this, you have to ensure that the transfer is done correctly. The check is done 00124 through HAL_MMC_GetCardState() function for MMC card state. 00125 You could also check the IT transfer process through the MMC Rx interrupt event. 00126 00127 *** MMC Card Write operation *** 00128 =============================== 00129 [..] 00130 (+) You can write to MMC card in polling mode by using function HAL_MMC_WriteBlocks(). 00131 This function allows the read of 512 bytes blocks. 00132 You can choose either one block read operation or multiple block read operation 00133 by adjusting the "NumberOfBlocks" parameter. 00134 After this, you have to ensure that the transfer is done correctly. The check is done 00135 through HAL_MMC_GetCardState() function for MMC card state. 00136 00137 (+) You can write to MMC card in DMA mode by using function HAL_MMC_WriteBlocks_DMA(). 00138 This function allows the read of 512 bytes blocks. 00139 You can choose either one block read operation or multiple block read operation 00140 by adjusting the "NumberOfBlocks" parameter. 00141 After this, you have to ensure that the transfer is done correctly. The check is done 00142 through HAL_MMC_GetCardState() function for MMC card state. 00143 You could also check the DMA transfer process through the MMC Tx interrupt event. 00144 00145 (+) You can write to MMC card in Interrupt mode by using function HAL_MMC_WriteBlocks_IT(). 00146 This function allows the read of 512 bytes blocks. 00147 You can choose either one block read operation or multiple block read operation 00148 by adjusting the "NumberOfBlocks" parameter. 00149 After this, you have to ensure that the transfer is done correctly. The check is done 00150 through HAL_MMC_GetCardState() function for MMC card state. 00151 You could also check the IT transfer process through the MMC Tx interrupt event. 00152 00153 *** MMC card status *** 00154 ====================== 00155 [..] 00156 (+) The MMC Status contains status bits that are related to the MMC Memory 00157 Card proprietary features. To get MMC card status use the HAL_MMC_GetCardStatus(). 00158 00159 *** MMC card information *** 00160 =========================== 00161 [..] 00162 (+) To get MMC card information, you can use the function HAL_MMC_GetCardInfo(). 00163 It returns useful information about the MMC card such as block size, card type, 00164 block number ... 00165 00166 *** MMC card CSD register *** 00167 ============================ 00168 [..] 00169 (+) The HAL_MMC_GetCardCSD() API allows to get the parameters of the CSD register. 00170 Some of the CSD parameters are useful for card initialization and identification. 00171 00172 *** MMC card CID register *** 00173 ============================ 00174 [..] 00175 (+) The HAL_MMC_GetCardCID() API allows to get the parameters of the CID register. 00176 Some of the CID parameters are useful for card initialization and identification. 00177 00178 *** MMC HAL driver macros list *** 00179 ================================== 00180 [..] 00181 Below the list of most used macros in MMC HAL driver. 00182 00183 (+) __HAL_MMC_ENABLE : Enable the MMC device 00184 (+) __HAL_MMC_DISABLE : Disable the MMC device 00185 (+) __HAL_MMC_DMA_ENABLE: Enable the SDMMC DMA transfer 00186 (+) __HAL_MMC_DMA_DISABLE: Disable the SDMMC DMA transfer 00187 (+) __HAL_MMC_ENABLE_IT: Enable the MMC device interrupt 00188 (+) __HAL_MMC_DISABLE_IT: Disable the MMC device interrupt 00189 (+) __HAL_MMC_GET_FLAG:Check whether the specified MMC flag is set or not 00190 (+) __HAL_MMC_CLEAR_FLAG: Clear the MMC's pending flags 00191 00192 [..] 00193 (@) You can refer to the MMC HAL driver header file for more useful macros 00194 00195 @endverbatim 00196 ****************************************************************************** 00197 * @attention 00198 * 00199 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2> 00200 * 00201 * Redistribution and use in source and binary forms, with or without modification, 00202 * are permitted provided that the following conditions are met: 00203 * 1. Redistributions of source code must retain the above copyright notice, 00204 * this list of conditions and the following disclaimer. 00205 * 2. Redistributions in binary form must reproduce the above copyright notice, 00206 * this list of conditions and the following disclaimer in the documentation 00207 * and/or other materials provided with the distribution. 00208 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00209 * may be used to endorse or promote products derived from this software 00210 * without specific prior written permission. 00211 * 00212 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00213 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00214 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00215 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00216 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00217 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00218 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00219 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00220 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00221 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00222 * 00223 ****************************************************************************** 00224 */ 00225 00226 /* Includes ------------------------------------------------------------------*/ 00227 #include "stm32f4xx_hal.h" 00228 00229 /** @addtogroup STM32F4xx_HAL_Driver 00230 * @{ 00231 */ 00232 00233 /** @addtogroup MMC 00234 * @{ 00235 */ 00236 00237 #ifdef HAL_MMC_MODULE_ENABLED 00238 00239 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || \ 00240 defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || \ 00241 defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F446xx) || \ 00242 defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || \ 00243 defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx) 00244 00245 /* Private typedef -----------------------------------------------------------*/ 00246 /* Private define ------------------------------------------------------------*/ 00247 /** @addtogroup MMC_Private_Defines 00248 * @{ 00249 */ 00250 00251 /** 00252 * @} 00253 */ 00254 00255 /* Private macro -------------------------------------------------------------*/ 00256 /* Private variables ---------------------------------------------------------*/ 00257 /* Private function prototypes -----------------------------------------------*/ 00258 /* Private functions ---------------------------------------------------------*/ 00259 /** @defgroup MMC_Private_Functions MMC Private Functions 00260 * @{ 00261 */ 00262 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc); 00263 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc); 00264 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus); 00265 static HAL_StatusTypeDef MMC_PowerOFF(MMC_HandleTypeDef *hmmc); 00266 static HAL_StatusTypeDef MMC_Write_IT(MMC_HandleTypeDef *hmmc); 00267 static HAL_StatusTypeDef MMC_Read_IT(MMC_HandleTypeDef *hmmc); 00268 static void MMC_DMATransmitCplt(DMA_HandleTypeDef *hdma); 00269 static void MMC_DMAReceiveCplt(DMA_HandleTypeDef *hdma); 00270 static void MMC_DMAError(DMA_HandleTypeDef *hdma); 00271 static void MMC_DMATxAbort(DMA_HandleTypeDef *hdma); 00272 static void MMC_DMARxAbort(DMA_HandleTypeDef *hdma); 00273 /** 00274 * @} 00275 */ 00276 00277 /* Exported functions --------------------------------------------------------*/ 00278 /** @addtogroup MMC_Exported_Functions 00279 * @{ 00280 */ 00281 00282 /** @addtogroup MMC_Exported_Functions_Group1 00283 * @brief Initialization and de-initialization functions 00284 * 00285 @verbatim 00286 ============================================================================== 00287 ##### Initialization and de-initialization functions ##### 00288 ============================================================================== 00289 [..] 00290 This section provides functions allowing to initialize/de-initialize the MMC 00291 card device to be ready for use. 00292 00293 @endverbatim 00294 * @{ 00295 */ 00296 00297 /** 00298 * @brief Initializes the MMC according to the specified parameters in the 00299 MMC_HandleTypeDef and create the associated handle. 00300 * @param hmmc Pointer to the MMC handle 00301 * @retval HAL status 00302 */ 00303 HAL_StatusTypeDef HAL_MMC_Init(MMC_HandleTypeDef *hmmc) 00304 { 00305 /* Check the MMC handle allocation */ 00306 if(hmmc == NULL) 00307 { 00308 return HAL_ERROR; 00309 } 00310 00311 /* Check the parameters */ 00312 assert_param(IS_SDIO_ALL_INSTANCE(hmmc->Instance)); 00313 assert_param(IS_SDIO_CLOCK_EDGE(hmmc->Init.ClockEdge)); 00314 assert_param(IS_SDIO_CLOCK_BYPASS(hmmc->Init.ClockBypass)); 00315 assert_param(IS_SDIO_CLOCK_POWER_SAVE(hmmc->Init.ClockPowerSave)); 00316 assert_param(IS_SDIO_BUS_WIDE(hmmc->Init.BusWide)); 00317 assert_param(IS_SDIO_HARDWARE_FLOW_CONTROL(hmmc->Init.HardwareFlowControl)); 00318 assert_param(IS_SDIO_CLKDIV(hmmc->Init.ClockDiv)); 00319 00320 if(hmmc->State == HAL_MMC_STATE_RESET) 00321 { 00322 /* Allocate lock resource and initialize it */ 00323 hmmc->Lock = HAL_UNLOCKED; 00324 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */ 00325 HAL_MMC_MspInit(hmmc); 00326 } 00327 00328 hmmc->State = HAL_MMC_STATE_BUSY; 00329 00330 /* Initialize the Card parameters */ 00331 HAL_MMC_InitCard(hmmc); 00332 00333 /* Initialize the error code */ 00334 hmmc->ErrorCode = HAL_DMA_ERROR_NONE; 00335 00336 /* Initialize the MMC operation */ 00337 hmmc->Context = MMC_CONTEXT_NONE; 00338 00339 /* Initialize the MMC state */ 00340 hmmc->State = HAL_MMC_STATE_READY; 00341 00342 return HAL_OK; 00343 } 00344 00345 /** 00346 * @brief Initializes the MMC Card. 00347 * @param hmmc Pointer to MMC handle 00348 * @note This function initializes the MMC card. It could be used when a card 00349 re-initialization is needed. 00350 * @retval HAL status 00351 */ 00352 HAL_StatusTypeDef HAL_MMC_InitCard(MMC_HandleTypeDef *hmmc) 00353 { 00354 uint32_t errorstate = HAL_MMC_ERROR_NONE; 00355 MMC_InitTypeDef Init; 00356 00357 /* Default SDMMC peripheral configuration for MMC card initialization */ 00358 Init.ClockEdge = SDIO_CLOCK_EDGE_RISING; 00359 Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE; 00360 Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE; 00361 Init.BusWide = SDIO_BUS_WIDE_1B; 00362 Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE; 00363 Init.ClockDiv = SDIO_INIT_CLK_DIV; 00364 00365 /* Initialize SDMMC peripheral interface with default configuration */ 00366 SDIO_Init(hmmc->Instance, Init); 00367 00368 /* Disable SDMMC Clock */ 00369 __HAL_MMC_DISABLE(hmmc); 00370 00371 /* Set Power State to ON */ 00372 SDIO_PowerState_ON(hmmc->Instance); 00373 00374 /* Enable SDMMC Clock */ 00375 __HAL_MMC_ENABLE(hmmc); 00376 00377 /* Required power up waiting time before starting the SD initialization 00378 sequence */ 00379 HAL_Delay(2U); 00380 00381 /* Identify card operating voltage */ 00382 errorstate = MMC_PowerON(hmmc); 00383 if(errorstate != HAL_MMC_ERROR_NONE) 00384 { 00385 hmmc->State = HAL_MMC_STATE_READY; 00386 hmmc->ErrorCode |= errorstate; 00387 return HAL_ERROR; 00388 } 00389 00390 /* Card initialization */ 00391 errorstate = MMC_InitCard(hmmc); 00392 if(errorstate != HAL_MMC_ERROR_NONE) 00393 { 00394 hmmc->State = HAL_MMC_STATE_READY; 00395 hmmc->ErrorCode |= errorstate; 00396 return HAL_ERROR; 00397 } 00398 00399 return HAL_OK; 00400 } 00401 00402 /** 00403 * @brief De-Initializes the MMC card. 00404 * @param hmmc Pointer to MMC handle 00405 * @retval HAL status 00406 */ 00407 HAL_StatusTypeDef HAL_MMC_DeInit(MMC_HandleTypeDef *hmmc) 00408 { 00409 /* Check the MMC handle allocation */ 00410 if(hmmc == NULL) 00411 { 00412 return HAL_ERROR; 00413 } 00414 00415 /* Check the parameters */ 00416 assert_param(IS_SDIO_ALL_INSTANCE(hmmc->Instance)); 00417 00418 hmmc->State = HAL_MMC_STATE_BUSY; 00419 00420 /* Set SD power state to off */ 00421 MMC_PowerOFF(hmmc); 00422 00423 /* De-Initialize the MSP layer */ 00424 HAL_MMC_MspDeInit(hmmc); 00425 00426 hmmc->ErrorCode = HAL_MMC_ERROR_NONE; 00427 hmmc->State = HAL_MMC_STATE_RESET; 00428 00429 return HAL_OK; 00430 } 00431 00432 00433 /** 00434 * @brief Initializes the MMC MSP. 00435 * @param hmmc Pointer to MMC handle 00436 * @retval None 00437 */ 00438 __weak void HAL_MMC_MspInit(MMC_HandleTypeDef *hmmc) 00439 { 00440 /* Prevent unused argument(s) compilation warning */ 00441 UNUSED(hmmc); 00442 00443 /* NOTE : This function Should not be modified, when the callback is needed, 00444 the HAL_MMC_MspInit could be implemented in the user file 00445 */ 00446 } 00447 00448 /** 00449 * @brief De-Initialize MMC MSP. 00450 * @param hmmc Pointer to MMC handle 00451 * @retval None 00452 */ 00453 __weak void HAL_MMC_MspDeInit(MMC_HandleTypeDef *hmmc) 00454 { 00455 /* Prevent unused argument(s) compilation warning */ 00456 UNUSED(hmmc); 00457 00458 /* NOTE : This function Should not be modified, when the callback is needed, 00459 the HAL_MMC_MspDeInit could be implemented in the user file 00460 */ 00461 } 00462 00463 /** 00464 * @} 00465 */ 00466 00467 /** @addtogroup MMC_Exported_Functions_Group2 00468 * @brief Data transfer functions 00469 * 00470 @verbatim 00471 ============================================================================== 00472 ##### IO operation functions ##### 00473 ============================================================================== 00474 [..] 00475 This subsection provides a set of functions allowing to manage the data 00476 transfer from/to MMC card. 00477 00478 @endverbatim 00479 * @{ 00480 */ 00481 00482 /** 00483 * @brief Reads block(s) from a specified address in a card. The Data transfer 00484 * is managed by polling mode. 00485 * @note This API should be followed by a check on the card state through 00486 * HAL_MMC_GetCardState(). 00487 * @param hmmc Pointer to MMC handle 00488 * @param pData pointer to the buffer that will contain the received data 00489 * @param BlockAdd Block Address from where data is to be read 00490 * @param NumberOfBlocks Number of MMC blocks to read 00491 * @param Timeout Specify timeout value 00492 * @retval HAL status 00493 */ 00494 HAL_StatusTypeDef HAL_MMC_ReadBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout) 00495 { 00496 SDIO_DataInitTypeDef config; 00497 uint32_t errorstate = HAL_MMC_ERROR_NONE; 00498 uint32_t tickstart = HAL_GetTick(); 00499 uint32_t count = 0U, *tempbuff = (uint32_t *)pData; 00500 00501 if(NULL == pData) 00502 { 00503 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; 00504 return HAL_ERROR; 00505 } 00506 00507 if(hmmc->State == HAL_MMC_STATE_READY) 00508 { 00509 hmmc->ErrorCode = HAL_DMA_ERROR_NONE; 00510 00511 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr)) 00512 { 00513 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; 00514 return HAL_ERROR; 00515 } 00516 00517 hmmc->State = HAL_MMC_STATE_BUSY; 00518 00519 /* Initialize data control register */ 00520 hmmc->Instance->DCTRL = 0U; 00521 00522 /* Check the Card capacity in term of Logical number of blocks */ 00523 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY) 00524 { 00525 BlockAdd *= 512U; 00526 } 00527 00528 /* Set Block Size for Card */ 00529 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE); 00530 if(errorstate != HAL_MMC_ERROR_NONE) 00531 { 00532 /* Clear all the static flags */ 00533 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 00534 hmmc->ErrorCode |= errorstate; 00535 hmmc->State = HAL_MMC_STATE_READY; 00536 return HAL_ERROR; 00537 } 00538 00539 /* Configure the MMC DPSM (Data Path State Machine) */ 00540 config.DataTimeOut = SDMMC_DATATIMEOUT; 00541 config.DataLength = NumberOfBlocks * BLOCKSIZE; 00542 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B; 00543 config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO; 00544 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK; 00545 config.DPSM = SDIO_DPSM_ENABLE; 00546 SDIO_ConfigData(hmmc->Instance, &config); 00547 00548 /* Read block(s) in polling mode */ 00549 if(NumberOfBlocks > 1U) 00550 { 00551 hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK; 00552 00553 /* Read Multi Block command */ 00554 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, BlockAdd); 00555 } 00556 else 00557 { 00558 hmmc->Context = MMC_CONTEXT_READ_SINGLE_BLOCK; 00559 00560 /* Read Single Block command */ 00561 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, BlockAdd); 00562 } 00563 if(errorstate != HAL_MMC_ERROR_NONE) 00564 { 00565 /* Clear all the static flags */ 00566 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 00567 hmmc->ErrorCode |= errorstate; 00568 hmmc->State = HAL_MMC_STATE_READY; 00569 return HAL_ERROR; 00570 } 00571 00572 /* Poll on SDMMC flags */ 00573 #ifdef SDIO_STA_STBITERR 00574 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_STA_STBITERR)) 00575 #else /* SDIO_STA_STBITERR not defined */ 00576 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND)) 00577 #endif /* SDIO_STA_STBITERR */ 00578 { 00579 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXFIFOHF)) 00580 { 00581 /* Read data from SDMMC Rx FIFO */ 00582 for(count = 0U; count < 8U; count++) 00583 { 00584 *(tempbuff + count) = SDIO_ReadFIFO(hmmc->Instance); 00585 } 00586 tempbuff += 8U; 00587 } 00588 00589 if((Timeout == 0U)||((HAL_GetTick()-tickstart) >= Timeout)) 00590 { 00591 /* Clear all the static flags */ 00592 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 00593 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT; 00594 hmmc->State= HAL_MMC_STATE_READY; 00595 return HAL_TIMEOUT; 00596 } 00597 } 00598 00599 /* Send stop transmission command in case of multiblock read */ 00600 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1U)) 00601 { 00602 /* Send stop transmission command */ 00603 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance); 00604 if(errorstate != HAL_MMC_ERROR_NONE) 00605 { 00606 /* Clear all the static flags */ 00607 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 00608 hmmc->ErrorCode |= errorstate; 00609 hmmc->State = HAL_MMC_STATE_READY; 00610 return HAL_ERROR; 00611 } 00612 } 00613 00614 /* Get error state */ 00615 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DTIMEOUT)) 00616 { 00617 /* Clear all the static flags */ 00618 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 00619 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT; 00620 hmmc->State = HAL_MMC_STATE_READY; 00621 return HAL_ERROR; 00622 } 00623 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL)) 00624 { 00625 /* Clear all the static flags */ 00626 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 00627 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL; 00628 hmmc->State = HAL_MMC_STATE_READY; 00629 return HAL_ERROR; 00630 } 00631 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR)) 00632 { 00633 /* Clear all the static flags */ 00634 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 00635 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN; 00636 hmmc->State = HAL_MMC_STATE_READY; 00637 return HAL_ERROR; 00638 } 00639 00640 /* Empty FIFO if there is still any data */ 00641 while ((__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXDAVL))) 00642 { 00643 *tempbuff = SDIO_ReadFIFO(hmmc->Instance); 00644 tempbuff++; 00645 00646 if((Timeout == 0U)||((HAL_GetTick()-tickstart) >= Timeout)) 00647 { 00648 /* Clear all the static flags */ 00649 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 00650 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT; 00651 hmmc->State= HAL_MMC_STATE_READY; 00652 return HAL_ERROR; 00653 } 00654 } 00655 00656 /* Clear all the static flags */ 00657 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 00658 00659 hmmc->State = HAL_MMC_STATE_READY; 00660 00661 return HAL_OK; 00662 } 00663 else 00664 { 00665 hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY; 00666 return HAL_ERROR; 00667 } 00668 } 00669 00670 /** 00671 * @brief Allows to write block(s) to a specified address in a card. The Data 00672 * transfer is managed by polling mode. 00673 * @note This API should be followed by a check on the card state through 00674 * HAL_MMC_GetCardState(). 00675 * @param hmmc Pointer to MMC handle 00676 * @param pData pointer to the buffer that will contain the data to transmit 00677 * @param BlockAdd Block Address where data will be written 00678 * @param NumberOfBlocks Number of MMC blocks to write 00679 * @param Timeout Specify timeout value 00680 * @retval HAL status 00681 */ 00682 HAL_StatusTypeDef HAL_MMC_WriteBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout) 00683 { 00684 SDIO_DataInitTypeDef config; 00685 uint32_t errorstate = HAL_MMC_ERROR_NONE; 00686 uint32_t tickstart = HAL_GetTick(); 00687 uint32_t count = 0U; 00688 uint32_t *tempbuff = (uint32_t *)pData; 00689 00690 if(NULL == pData) 00691 { 00692 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; 00693 return HAL_ERROR; 00694 } 00695 00696 if(hmmc->State == HAL_MMC_STATE_READY) 00697 { 00698 hmmc->ErrorCode = HAL_DMA_ERROR_NONE; 00699 00700 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr)) 00701 { 00702 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; 00703 return HAL_ERROR; 00704 } 00705 00706 hmmc->State = HAL_MMC_STATE_BUSY; 00707 00708 /* Initialize data control register */ 00709 hmmc->Instance->DCTRL = 0U; 00710 00711 /* Check the Card capacity in term of Logical number of blocks */ 00712 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY) 00713 { 00714 BlockAdd *= 512U; 00715 } 00716 00717 /* Set Block Size for Card */ 00718 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE); 00719 if(errorstate != HAL_MMC_ERROR_NONE) 00720 { 00721 /* Clear all the static flags */ 00722 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 00723 hmmc->ErrorCode |= errorstate; 00724 hmmc->State = HAL_MMC_STATE_READY; 00725 return HAL_ERROR; 00726 } 00727 00728 /* Write Blocks in Polling mode */ 00729 if(NumberOfBlocks > 1U) 00730 { 00731 hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK; 00732 00733 /* Write Multi Block command */ 00734 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, BlockAdd); 00735 } 00736 else 00737 { 00738 hmmc->Context = MMC_CONTEXT_WRITE_SINGLE_BLOCK; 00739 00740 /* Write Single Block command */ 00741 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, BlockAdd); 00742 } 00743 if(errorstate != HAL_MMC_ERROR_NONE) 00744 { 00745 /* Clear all the static flags */ 00746 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 00747 hmmc->ErrorCode |= errorstate; 00748 hmmc->State = HAL_MMC_STATE_READY; 00749 return HAL_ERROR; 00750 } 00751 00752 /* Configure the MMC DPSM (Data Path State Machine) */ 00753 config.DataTimeOut = SDMMC_DATATIMEOUT; 00754 config.DataLength = NumberOfBlocks * BLOCKSIZE; 00755 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B; 00756 config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD; 00757 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK; 00758 config.DPSM = SDIO_DPSM_ENABLE; 00759 SDIO_ConfigData(hmmc->Instance, &config); 00760 00761 /* Write block(s) in polling mode */ 00762 #ifdef SDIO_STA_STBITERR 00763 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_FLAG_STBITERR)) 00764 #else /* SDIO_STA_STBITERR not defined */ 00765 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND)) 00766 #endif /* SDIO_STA_STBITERR */ 00767 { 00768 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXFIFOHE)) 00769 { 00770 /* Write data to SDIO Tx FIFO */ 00771 for(count = 0U; count < 8U; count++) 00772 { 00773 SDIO_WriteFIFO(hmmc->Instance, (tempbuff + count)); 00774 } 00775 tempbuff += 8U; 00776 } 00777 00778 if((Timeout == 0U)||((HAL_GetTick()-tickstart) >= Timeout)) 00779 { 00780 /* Clear all the static flags */ 00781 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 00782 hmmc->ErrorCode |= errorstate; 00783 hmmc->State = HAL_MMC_STATE_READY; 00784 return HAL_TIMEOUT; 00785 } 00786 } 00787 00788 /* Send stop transmission command in case of multiblock write */ 00789 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1U)) 00790 { 00791 /* Send stop transmission command */ 00792 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance); 00793 if(errorstate != HAL_MMC_ERROR_NONE) 00794 { 00795 /* Clear all the static flags */ 00796 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 00797 hmmc->ErrorCode |= errorstate; 00798 hmmc->State = HAL_MMC_STATE_READY; 00799 return HAL_ERROR; 00800 } 00801 } 00802 00803 /* Get error state */ 00804 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DTIMEOUT)) 00805 { 00806 /* Clear all the static flags */ 00807 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 00808 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT; 00809 hmmc->State = HAL_MMC_STATE_READY; 00810 return HAL_ERROR; 00811 } 00812 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL)) 00813 { 00814 /* Clear all the static flags */ 00815 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 00816 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL; 00817 hmmc->State = HAL_MMC_STATE_READY; 00818 return HAL_ERROR; 00819 } 00820 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR)) 00821 { 00822 /* Clear all the static flags */ 00823 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 00824 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN; 00825 hmmc->State = HAL_MMC_STATE_READY; 00826 return HAL_ERROR; 00827 } 00828 00829 /* Clear all the static flags */ 00830 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 00831 00832 hmmc->State = HAL_MMC_STATE_READY; 00833 00834 return HAL_OK; 00835 } 00836 else 00837 { 00838 hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY; 00839 return HAL_ERROR; 00840 } 00841 } 00842 00843 /** 00844 * @brief Reads block(s) from a specified address in a card. The Data transfer 00845 * is managed in interrupt mode. 00846 * @note This API should be followed by a check on the card state through 00847 * HAL_MMC_GetCardState(). 00848 * @note You could also check the IT transfer process through the MMC Rx 00849 * interrupt event. 00850 * @param hmmc Pointer to MMC handle 00851 * @param pData Pointer to the buffer that will contain the received data 00852 * @param BlockAdd Block Address from where data is to be read 00853 * @param NumberOfBlocks Number of blocks to read. 00854 * @retval HAL status 00855 */ 00856 HAL_StatusTypeDef HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks) 00857 { 00858 SDIO_DataInitTypeDef config; 00859 uint32_t errorstate = HAL_MMC_ERROR_NONE; 00860 00861 if(NULL == pData) 00862 { 00863 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; 00864 return HAL_ERROR; 00865 } 00866 00867 if(hmmc->State == HAL_MMC_STATE_READY) 00868 { 00869 hmmc->ErrorCode = HAL_DMA_ERROR_NONE; 00870 00871 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr)) 00872 { 00873 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; 00874 return HAL_ERROR; 00875 } 00876 00877 hmmc->State = HAL_MMC_STATE_BUSY; 00878 00879 /* Initialize data control register */ 00880 hmmc->Instance->DCTRL = 0U; 00881 00882 hmmc->pRxBuffPtr = (uint32_t *)pData; 00883 hmmc->RxXferSize = BLOCKSIZE * NumberOfBlocks; 00884 00885 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_FLAG_RXFIFOHF)); 00886 00887 /* Check the Card capacity in term of Logical number of blocks */ 00888 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY) 00889 { 00890 BlockAdd *= 512U; 00891 } 00892 00893 /* Configure the MMC DPSM (Data Path State Machine) */ 00894 config.DataTimeOut = SDMMC_DATATIMEOUT; 00895 config.DataLength = BLOCKSIZE * NumberOfBlocks; 00896 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B; 00897 config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO; 00898 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK; 00899 config.DPSM = SDIO_DPSM_ENABLE; 00900 SDIO_ConfigData(hmmc->Instance, &config); 00901 00902 /* Set Block Size for Card */ 00903 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE); 00904 if(errorstate != HAL_MMC_ERROR_NONE) 00905 { 00906 /* Clear all the static flags */ 00907 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 00908 hmmc->ErrorCode |= errorstate; 00909 hmmc->State = HAL_MMC_STATE_READY; 00910 return HAL_ERROR; 00911 } 00912 00913 /* Read Blocks in IT mode */ 00914 if(NumberOfBlocks > 1U) 00915 { 00916 hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_IT); 00917 00918 /* Read Multi Block command */ 00919 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, BlockAdd); 00920 } 00921 else 00922 { 00923 hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_IT); 00924 00925 /* Read Single Block command */ 00926 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, BlockAdd); 00927 } 00928 if(errorstate != HAL_MMC_ERROR_NONE) 00929 { 00930 /* Clear all the static flags */ 00931 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 00932 hmmc->ErrorCode |= errorstate; 00933 hmmc->State = HAL_MMC_STATE_READY; 00934 return HAL_ERROR; 00935 } 00936 00937 return HAL_OK; 00938 } 00939 else 00940 { 00941 return HAL_BUSY; 00942 } 00943 } 00944 00945 /** 00946 * @brief Writes block(s) to a specified address in a card. The Data transfer 00947 * is managed in interrupt mode. 00948 * @note This API should be followed by a check on the card state through 00949 * HAL_MMC_GetCardState(). 00950 * @note You could also check the IT transfer process through the MMC Tx 00951 * interrupt event. 00952 * @param hmmc Pointer to MMC handle 00953 * @param pData Pointer to the buffer that will contain the data to transmit 00954 * @param BlockAdd Block Address where data will be written 00955 * @param NumberOfBlocks Number of blocks to write 00956 * @retval HAL status 00957 */ 00958 HAL_StatusTypeDef HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks) 00959 { 00960 SDIO_DataInitTypeDef config; 00961 uint32_t errorstate = HAL_MMC_ERROR_NONE; 00962 00963 if(NULL == pData) 00964 { 00965 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; 00966 return HAL_ERROR; 00967 } 00968 00969 if(hmmc->State == HAL_MMC_STATE_READY) 00970 { 00971 hmmc->ErrorCode = HAL_DMA_ERROR_NONE; 00972 00973 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr)) 00974 { 00975 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; 00976 return HAL_ERROR; 00977 } 00978 00979 hmmc->State = HAL_MMC_STATE_BUSY; 00980 00981 /* Initialize data control register */ 00982 hmmc->Instance->DCTRL = 0U; 00983 00984 hmmc->pTxBuffPtr = (uint32_t *)pData; 00985 hmmc->TxXferSize = BLOCKSIZE * NumberOfBlocks; 00986 00987 /* Enable transfer interrupts */ 00988 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_DATAEND | SDIO_FLAG_TXFIFOHE)); 00989 00990 /* Check the Card capacity in term of Logical number of blocks */ 00991 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY) 00992 { 00993 BlockAdd *= 512U; 00994 } 00995 00996 /* Set Block Size for Card */ 00997 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE); 00998 if(errorstate != HAL_MMC_ERROR_NONE) 00999 { 01000 /* Clear all the static flags */ 01001 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 01002 hmmc->ErrorCode |= errorstate; 01003 hmmc->State = HAL_MMC_STATE_READY; 01004 return HAL_ERROR; 01005 } 01006 01007 /* Write Blocks in Polling mode */ 01008 if(NumberOfBlocks > 1U) 01009 { 01010 hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK| MMC_CONTEXT_IT); 01011 01012 /* Write Multi Block command */ 01013 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, BlockAdd); 01014 } 01015 else 01016 { 01017 hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_IT); 01018 01019 /* Write Single Block command */ 01020 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, BlockAdd); 01021 } 01022 if(errorstate != HAL_MMC_ERROR_NONE) 01023 { 01024 /* Clear all the static flags */ 01025 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 01026 hmmc->ErrorCode |= errorstate; 01027 hmmc->State = HAL_MMC_STATE_READY; 01028 return HAL_ERROR; 01029 } 01030 01031 /* Configure the MMC DPSM (Data Path State Machine) */ 01032 config.DataTimeOut = SDMMC_DATATIMEOUT; 01033 config.DataLength = BLOCKSIZE * NumberOfBlocks; 01034 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B; 01035 config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD; 01036 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK; 01037 config.DPSM = SDIO_DPSM_ENABLE; 01038 SDIO_ConfigData(hmmc->Instance, &config); 01039 01040 return HAL_OK; 01041 } 01042 else 01043 { 01044 return HAL_BUSY; 01045 } 01046 } 01047 01048 /** 01049 * @brief Reads block(s) from a specified address in a card. The Data transfer 01050 * is managed by DMA mode. 01051 * @note This API should be followed by a check on the card state through 01052 * HAL_MMC_GetCardState(). 01053 * @note You could also check the DMA transfer process through the MMC Rx 01054 * interrupt event. 01055 * @param hmmc Pointer MMC handle 01056 * @param pData Pointer to the buffer that will contain the received data 01057 * @param BlockAdd Block Address from where data is to be read 01058 * @param NumberOfBlocks Number of blocks to read. 01059 * @retval HAL status 01060 */ 01061 HAL_StatusTypeDef HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks) 01062 { 01063 SDIO_DataInitTypeDef config; 01064 uint32_t errorstate = HAL_MMC_ERROR_NONE; 01065 01066 if(NULL == pData) 01067 { 01068 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; 01069 return HAL_ERROR; 01070 } 01071 01072 if(hmmc->State == HAL_MMC_STATE_READY) 01073 { 01074 hmmc->ErrorCode = HAL_DMA_ERROR_NONE; 01075 01076 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr)) 01077 { 01078 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; 01079 return HAL_ERROR; 01080 } 01081 01082 hmmc->State = HAL_MMC_STATE_BUSY; 01083 01084 /* Initialize data control register */ 01085 hmmc->Instance->DCTRL = 0U; 01086 01087 #ifdef SDIO_STA_STBITER 01088 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_IT_STBITERR)); 01089 #else /* SDIO_STA_STBITERR not defined */ 01090 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND)); 01091 #endif /* SDIO_STA_STBITERR */ 01092 01093 /* Set the DMA transfer complete callback */ 01094 hmmc->hdmarx->XferCpltCallback = MMC_DMAReceiveCplt; 01095 01096 /* Set the DMA error callback */ 01097 hmmc->hdmarx->XferErrorCallback = MMC_DMAError; 01098 01099 /* Set the DMA Abort callback */ 01100 hmmc->hdmarx->XferAbortCallback = NULL; 01101 01102 /* Enable the DMA Channel */ 01103 HAL_DMA_Start_IT(hmmc->hdmarx, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)pData, (uint32_t)(BLOCKSIZE * NumberOfBlocks)/4); 01104 01105 /* Enable MMC DMA transfer */ 01106 __HAL_MMC_DMA_ENABLE(hmmc); 01107 01108 /* Check the Card capacity in term of Logical number of blocks */ 01109 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY) 01110 { 01111 BlockAdd *= 512U; 01112 } 01113 01114 /* Configure the MMC DPSM (Data Path State Machine) */ 01115 config.DataTimeOut = SDMMC_DATATIMEOUT; 01116 config.DataLength = BLOCKSIZE * NumberOfBlocks; 01117 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B; 01118 config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO; 01119 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK; 01120 config.DPSM = SDIO_DPSM_ENABLE; 01121 SDIO_ConfigData(hmmc->Instance, &config); 01122 01123 /* Set Block Size for Card */ 01124 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE); 01125 if(errorstate != HAL_MMC_ERROR_NONE) 01126 { 01127 /* Clear all the static flags */ 01128 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 01129 hmmc->ErrorCode |= errorstate; 01130 hmmc->State = HAL_MMC_STATE_READY; 01131 return HAL_ERROR; 01132 } 01133 01134 /* Read Blocks in DMA mode */ 01135 if(NumberOfBlocks > 1U) 01136 { 01137 hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA); 01138 01139 /* Read Multi Block command */ 01140 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, BlockAdd); 01141 } 01142 else 01143 { 01144 hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_DMA); 01145 01146 /* Read Single Block command */ 01147 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, BlockAdd); 01148 } 01149 if(errorstate != HAL_MMC_ERROR_NONE) 01150 { 01151 /* Clear all the static flags */ 01152 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 01153 hmmc->ErrorCode |= errorstate; 01154 hmmc->State = HAL_MMC_STATE_READY; 01155 return HAL_ERROR; 01156 } 01157 01158 return HAL_OK; 01159 } 01160 else 01161 { 01162 return HAL_BUSY; 01163 } 01164 } 01165 01166 /** 01167 * @brief Writes block(s) to a specified address in a card. The Data transfer 01168 * is managed by DMA mode. 01169 * @note This API should be followed by a check on the card state through 01170 * HAL_MMC_GetCardState(). 01171 * @note You could also check the DMA transfer process through the MMC Tx 01172 * interrupt event. 01173 * @param hmmc Pointer to MMC handle 01174 * @param pData Pointer to the buffer that will contain the data to transmit 01175 * @param BlockAdd Block Address where data will be written 01176 * @param NumberOfBlocks Number of blocks to write 01177 * @retval HAL status 01178 */ 01179 HAL_StatusTypeDef HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks) 01180 { 01181 SDIO_DataInitTypeDef config; 01182 uint32_t errorstate = HAL_MMC_ERROR_NONE; 01183 01184 if(NULL == pData) 01185 { 01186 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; 01187 return HAL_ERROR; 01188 } 01189 01190 if(hmmc->State == HAL_MMC_STATE_READY) 01191 { 01192 hmmc->ErrorCode = HAL_DMA_ERROR_NONE; 01193 01194 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr)) 01195 { 01196 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; 01197 return HAL_ERROR; 01198 } 01199 01200 hmmc->State = HAL_MMC_STATE_BUSY; 01201 01202 /* Initialize data control register */ 01203 hmmc->Instance->DCTRL = 0U; 01204 01205 /* Enable MMC Error interrupts */ 01206 #ifdef SDIO_STA_STBITER 01207 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR)); 01208 #else /* SDIO_STA_STBITERR not defined */ 01209 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR)); 01210 #endif /* SDIO_STA_STBITERR */ 01211 01212 /* Set the DMA transfer complete callback */ 01213 hmmc->hdmatx->XferCpltCallback = MMC_DMATransmitCplt; 01214 01215 /* Set the DMA error callback */ 01216 hmmc->hdmatx->XferErrorCallback = MMC_DMAError; 01217 01218 /* Set the DMA Abort callback */ 01219 hmmc->hdmatx->XferAbortCallback = NULL; 01220 01221 /* Check the Card capacity in term of Logical number of blocks */ 01222 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY) 01223 { 01224 BlockAdd *= 512U; 01225 } 01226 01227 /* Set Block Size for Card */ 01228 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, BLOCKSIZE); 01229 if(errorstate != HAL_MMC_ERROR_NONE) 01230 { 01231 /* Clear all the static flags */ 01232 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 01233 hmmc->ErrorCode |= errorstate; 01234 hmmc->State = HAL_MMC_STATE_READY; 01235 return HAL_ERROR; 01236 } 01237 01238 /* Write Blocks in Polling mode */ 01239 if(NumberOfBlocks > 1U) 01240 { 01241 hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_DMA); 01242 01243 /* Write Multi Block command */ 01244 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, BlockAdd); 01245 } 01246 else 01247 { 01248 hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_DMA); 01249 01250 /* Write Single Block command */ 01251 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, BlockAdd); 01252 } 01253 if(errorstate != HAL_MMC_ERROR_NONE) 01254 { 01255 /* Clear all the static flags */ 01256 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 01257 hmmc->ErrorCode |= errorstate; 01258 hmmc->State = HAL_MMC_STATE_READY; 01259 return HAL_ERROR; 01260 } 01261 01262 /* Enable SDIO DMA transfer */ 01263 __HAL_MMC_DMA_ENABLE(hmmc); 01264 01265 /* Enable the DMA Channel */ 01266 HAL_DMA_Start_IT(hmmc->hdmatx, (uint32_t)pData, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)(BLOCKSIZE * NumberOfBlocks)/4); 01267 01268 /* Configure the MMC DPSM (Data Path State Machine) */ 01269 config.DataTimeOut = SDMMC_DATATIMEOUT; 01270 config.DataLength = BLOCKSIZE * NumberOfBlocks; 01271 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B; 01272 config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD; 01273 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK; 01274 config.DPSM = SDIO_DPSM_ENABLE; 01275 SDIO_ConfigData(hmmc->Instance, &config); 01276 01277 return HAL_OK; 01278 } 01279 else 01280 { 01281 return HAL_BUSY; 01282 } 01283 } 01284 01285 /** 01286 * @brief Erases the specified memory area of the given MMC card. 01287 * @note This API should be followed by a check on the card state through 01288 * HAL_MMC_GetCardState(). 01289 * @param hmmc Pointer to MMC handle 01290 * @param BlockStartAdd Start Block address 01291 * @param BlockEndAdd End Block address 01292 * @retval HAL status 01293 */ 01294 HAL_StatusTypeDef HAL_MMC_Erase(MMC_HandleTypeDef *hmmc, uint32_t BlockStartAdd, uint32_t BlockEndAdd) 01295 { 01296 uint32_t errorstate = HAL_MMC_ERROR_NONE; 01297 01298 if(hmmc->State == HAL_MMC_STATE_READY) 01299 { 01300 hmmc->ErrorCode = HAL_DMA_ERROR_NONE; 01301 01302 if(BlockEndAdd < BlockStartAdd) 01303 { 01304 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; 01305 return HAL_ERROR; 01306 } 01307 01308 if(BlockEndAdd > (hmmc->MmcCard.LogBlockNbr)) 01309 { 01310 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; 01311 return HAL_ERROR; 01312 } 01313 01314 hmmc->State = HAL_MMC_STATE_BUSY; 01315 01316 /* Check if the card command class supports erase command */ 01317 if(((hmmc->MmcCard.Class) & SDIO_CCCC_ERASE) == 0U) 01318 { 01319 /* Clear all the static flags */ 01320 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 01321 hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE; 01322 hmmc->State = HAL_MMC_STATE_READY; 01323 return HAL_ERROR; 01324 } 01325 01326 if((SDIO_GetResponse(hmmc->Instance, SDIO_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED) 01327 { 01328 /* Clear all the static flags */ 01329 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 01330 hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED; 01331 hmmc->State = HAL_MMC_STATE_READY; 01332 return HAL_ERROR; 01333 } 01334 01335 /* Check the Card capacity in term of Logical number of blocks */ 01336 if ((hmmc->MmcCard.LogBlockNbr) < CAPACITY) 01337 { 01338 BlockStartAdd *= 512U; 01339 BlockEndAdd *= 512U; 01340 } 01341 01342 /* Send CMD35 MMC_ERASE_GRP_START with argument as addr */ 01343 errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, BlockStartAdd); 01344 if(errorstate != HAL_MMC_ERROR_NONE) 01345 { 01346 /* Clear all the static flags */ 01347 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 01348 hmmc->ErrorCode |= errorstate; 01349 hmmc->State = HAL_MMC_STATE_READY; 01350 return HAL_ERROR; 01351 } 01352 01353 /* Send CMD36 MMC_ERASE_GRP_END with argument as addr */ 01354 errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, BlockEndAdd); 01355 if(errorstate != HAL_MMC_ERROR_NONE) 01356 { 01357 /* Clear all the static flags */ 01358 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 01359 hmmc->ErrorCode |= errorstate; 01360 hmmc->State = HAL_MMC_STATE_READY; 01361 return HAL_ERROR; 01362 } 01363 01364 /* Send CMD38 ERASE */ 01365 errorstate = SDMMC_CmdErase(hmmc->Instance); 01366 if(errorstate != HAL_MMC_ERROR_NONE) 01367 { 01368 /* Clear all the static flags */ 01369 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 01370 hmmc->ErrorCode |= errorstate; 01371 hmmc->State = HAL_MMC_STATE_READY; 01372 return HAL_ERROR; 01373 } 01374 01375 hmmc->State = HAL_MMC_STATE_READY; 01376 01377 return HAL_OK; 01378 } 01379 else 01380 { 01381 return HAL_BUSY; 01382 } 01383 } 01384 01385 /** 01386 * @brief This function handles MMC card interrupt request. 01387 * @param hmmc Pointer to MMC handle 01388 * @retval None 01389 */ 01390 void HAL_MMC_IRQHandler(MMC_HandleTypeDef *hmmc) 01391 { 01392 uint32_t errorstate = HAL_MMC_ERROR_NONE; 01393 01394 /* Check for SDIO interrupt flags */ 01395 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DATAEND) != RESET) 01396 { 01397 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_FLAG_DATAEND); 01398 01399 #ifdef SDIO_STA_STBITERR 01400 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\ 01401 SDIO_IT_TXUNDERR | SDIO_IT_RXOVERR | SDIO_IT_STBITERR); 01402 #else /* SDIO_STA_STBITERR not defined */ 01403 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\ 01404 SDIO_IT_TXUNDERR | SDIO_IT_RXOVERR); 01405 #endif 01406 01407 if((hmmc->Context & MMC_CONTEXT_IT) != RESET) 01408 { 01409 if(((hmmc->Context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != RESET) || ((hmmc->Context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != RESET)) 01410 { 01411 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance); 01412 if(errorstate != HAL_MMC_ERROR_NONE) 01413 { 01414 hmmc->ErrorCode |= errorstate; 01415 HAL_MMC_ErrorCallback(hmmc); 01416 } 01417 } 01418 01419 /* Clear all the static flags */ 01420 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 01421 01422 hmmc->State = HAL_MMC_STATE_READY; 01423 if(((hmmc->Context & MMC_CONTEXT_READ_SINGLE_BLOCK) != RESET) || ((hmmc->Context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != RESET)) 01424 { 01425 HAL_MMC_RxCpltCallback(hmmc); 01426 } 01427 else 01428 { 01429 HAL_MMC_TxCpltCallback(hmmc); 01430 } 01431 } 01432 else if((hmmc->Context & MMC_CONTEXT_DMA) != RESET) 01433 { 01434 if((hmmc->Context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != RESET) 01435 { 01436 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance); 01437 if(errorstate != HAL_MMC_ERROR_NONE) 01438 { 01439 hmmc->ErrorCode |= errorstate; 01440 HAL_MMC_ErrorCallback(hmmc); 01441 } 01442 } 01443 if(((hmmc->Context & MMC_CONTEXT_READ_SINGLE_BLOCK) == RESET) && ((hmmc->Context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) == RESET)) 01444 { 01445 /* Disable the DMA transfer for transmit request by setting the DMAEN bit 01446 in the MMC DCTRL register */ 01447 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN); 01448 01449 hmmc->State = HAL_MMC_STATE_READY; 01450 01451 HAL_MMC_TxCpltCallback(hmmc); 01452 } 01453 } 01454 } 01455 01456 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_TXFIFOHE) != RESET) 01457 { 01458 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_FLAG_TXFIFOHE); 01459 01460 MMC_Write_IT(hmmc); 01461 } 01462 01463 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_RXFIFOHF) != RESET) 01464 { 01465 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_FLAG_RXFIFOHF); 01466 01467 MMC_Read_IT(hmmc); 01468 } 01469 01470 #ifdef SDIO_STA_STBITERR 01471 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR) != RESET) 01472 { 01473 /* Set Error code */ 01474 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DCRCFAIL) != RESET) 01475 { 01476 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL; 01477 } 01478 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DTIMEOUT) != RESET) 01479 { 01480 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT; 01481 } 01482 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_RXOVERR) != RESET) 01483 { 01484 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN; 01485 } 01486 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_TXUNDERR) != RESET) 01487 { 01488 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN; 01489 } 01490 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_STBITERR) != RESET) 01491 { 01492 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT; 01493 } 01494 01495 /* Clear All flags */ 01496 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS | SDIO_FLAG_STBITERR); 01497 01498 /* Disable all interrupts */ 01499 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\ 01500 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR |SDIO_IT_STBITERR); 01501 01502 if((hmmc->Context & MMC_CONTEXT_DMA) != RESET) 01503 { 01504 /* Abort the MMC DMA Streams */ 01505 if(hmmc->hdmatx != NULL) 01506 { 01507 /* Set the DMA Tx abort callback */ 01508 hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort; 01509 /* Abort DMA in IT mode */ 01510 if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK) 01511 { 01512 MMC_DMATxAbort(hmmc->hdmatx); 01513 } 01514 } 01515 else if(hmmc->hdmarx != NULL) 01516 { 01517 /* Set the DMA Rx abort callback */ 01518 hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort; 01519 /* Abort DMA in IT mode */ 01520 if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK) 01521 { 01522 MMC_DMARxAbort(hmmc->hdmarx); 01523 } 01524 } 01525 else 01526 { 01527 hmmc->ErrorCode = HAL_MMC_ERROR_NONE; 01528 hmmc->State = HAL_MMC_STATE_READY; 01529 HAL_MMC_AbortCallback(hmmc); 01530 } 01531 } 01532 else if((hmmc->Context & MMC_CONTEXT_IT) != RESET) 01533 { 01534 /* Set the MMC state to ready to be able to start again the process */ 01535 hmmc->State = HAL_MMC_STATE_READY; 01536 HAL_MMC_ErrorCallback(hmmc); 01537 } 01538 } 01539 #else /* SDIO_STA_STBITERR not defined */ 01540 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_TXUNDERR) != RESET) 01541 { 01542 /* Set Error code */ 01543 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DCRCFAIL) != RESET) 01544 { 01545 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL; 01546 } 01547 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_DTIMEOUT) != RESET) 01548 { 01549 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT; 01550 } 01551 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_RXOVERR) != RESET) 01552 { 01553 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN; 01554 } 01555 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_IT_TXUNDERR) != RESET) 01556 { 01557 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN; 01558 } 01559 01560 /* Clear All flags */ 01561 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 01562 01563 /* Disable all interrupts */ 01564 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\ 01565 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR); 01566 01567 if((hmmc->Context & MMC_CONTEXT_DMA) != RESET) 01568 { 01569 /* Abort the MMC DMA Streams */ 01570 if(hmmc->hdmatx != NULL) 01571 { 01572 /* Set the DMA Tx abort callback */ 01573 hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort; 01574 /* Abort DMA in IT mode */ 01575 if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK) 01576 { 01577 MMC_DMATxAbort(hmmc->hdmatx); 01578 } 01579 } 01580 else if(hmmc->hdmarx != NULL) 01581 { 01582 /* Set the DMA Rx abort callback */ 01583 hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort; 01584 /* Abort DMA in IT mode */ 01585 if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK) 01586 { 01587 MMC_DMARxAbort(hmmc->hdmarx); 01588 } 01589 } 01590 else 01591 { 01592 hmmc->ErrorCode = HAL_MMC_ERROR_NONE; 01593 hmmc->State = HAL_MMC_STATE_READY; 01594 HAL_MMC_AbortCallback(hmmc); 01595 } 01596 } 01597 else if((hmmc->Context & MMC_CONTEXT_IT) != RESET) 01598 { 01599 /* Set the MMC state to ready to be able to start again the process */ 01600 hmmc->State = HAL_MMC_STATE_READY; 01601 HAL_MMC_ErrorCallback(hmmc); 01602 } 01603 } 01604 #endif /* SDIO_STA_STBITERR */ 01605 } 01606 01607 /** 01608 * @brief return the MMC state 01609 * @param hmmc Pointer to mmc handle 01610 * @retval HAL state 01611 */ 01612 HAL_MMC_StateTypeDef HAL_MMC_GetState(MMC_HandleTypeDef *hmmc) 01613 { 01614 return hmmc->State; 01615 } 01616 01617 /** 01618 * @brief Return the MMC error code 01619 * @param hmmc Pointer to a MMC_HandleTypeDef structure that contains 01620 * the configuration information. 01621 * @retval MMC Error Code 01622 */ 01623 uint32_t HAL_MMC_GetError(MMC_HandleTypeDef *hmmc) 01624 { 01625 return hmmc->ErrorCode; 01626 } 01627 01628 /** 01629 * @brief Tx Transfer completed callbacks 01630 * @param hmmc Pointer to MMC handle 01631 * @retval None 01632 */ 01633 __weak void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef *hmmc) 01634 { 01635 /* Prevent unused argument(s) compilation warning */ 01636 UNUSED(hmmc); 01637 01638 /* NOTE : This function should not be modified, when the callback is needed, 01639 the HAL_MMC_TxCpltCallback can be implemented in the user file 01640 */ 01641 } 01642 01643 /** 01644 * @brief Rx Transfer completed callbacks 01645 * @param hmmc Pointer MMC handle 01646 * @retval None 01647 */ 01648 __weak void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef *hmmc) 01649 { 01650 /* Prevent unused argument(s) compilation warning */ 01651 UNUSED(hmmc); 01652 01653 /* NOTE : This function should not be modified, when the callback is needed, 01654 the HAL_MMC_RxCpltCallback can be implemented in the user file 01655 */ 01656 } 01657 01658 /** 01659 * @brief MMC error callbacks 01660 * @param hmmc Pointer MMC handle 01661 * @retval None 01662 */ 01663 __weak void HAL_MMC_ErrorCallback(MMC_HandleTypeDef *hmmc) 01664 { 01665 /* Prevent unused argument(s) compilation warning */ 01666 UNUSED(hmmc); 01667 01668 /* NOTE : This function should not be modified, when the callback is needed, 01669 the HAL_MMC_ErrorCallback can be implemented in the user file 01670 */ 01671 } 01672 01673 /** 01674 * @brief MMC Abort callbacks 01675 * @param hmmc Pointer MMC handle 01676 * @retval None 01677 */ 01678 __weak void HAL_MMC_AbortCallback(MMC_HandleTypeDef *hmmc) 01679 { 01680 /* Prevent unused argument(s) compilation warning */ 01681 UNUSED(hmmc); 01682 01683 /* NOTE : This function should not be modified, when the callback is needed, 01684 the HAL_MMC_ErrorCallback can be implemented in the user file 01685 */ 01686 } 01687 01688 01689 /** 01690 * @} 01691 */ 01692 01693 /** @addtogroup MMC_Exported_Functions_Group3 01694 * @brief management functions 01695 * 01696 @verbatim 01697 ============================================================================== 01698 ##### Peripheral Control functions ##### 01699 ============================================================================== 01700 [..] 01701 This subsection provides a set of functions allowing to control the MMC card 01702 operations and get the related information 01703 01704 @endverbatim 01705 * @{ 01706 */ 01707 01708 /** 01709 * @brief Returns information the information of the card which are stored on 01710 * the CID register. 01711 * @param hmmc Pointer to MMC handle 01712 * @param pCID Pointer to a HAL_MMC_CIDTypedef structure that 01713 * contains all CID register parameters 01714 * @retval HAL status 01715 */ 01716 HAL_StatusTypeDef HAL_MMC_GetCardCID(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCIDTypeDef *pCID) 01717 { 01718 uint32_t tmp = 0U; 01719 01720 /* Byte 0 */ 01721 tmp = (uint8_t)((hmmc->CID[0U] & 0xFF000000U) >> 24U); 01722 pCID->ManufacturerID = tmp; 01723 01724 /* Byte 1 */ 01725 tmp = (uint8_t)((hmmc->CID[0U] & 0x00FF0000U) >> 16U); 01726 pCID->OEM_AppliID = tmp << 8U; 01727 01728 /* Byte 2 */ 01729 tmp = (uint8_t)((hmmc->CID[0U] & 0x000000FF00U) >> 8U); 01730 pCID->OEM_AppliID |= tmp; 01731 01732 /* Byte 3 */ 01733 tmp = (uint8_t)(hmmc->CID[0U] & 0x000000FFU); 01734 pCID->ProdName1 = tmp << 24U; 01735 01736 /* Byte 4 */ 01737 tmp = (uint8_t)((hmmc->CID[1U] & 0xFF000000U) >> 24U); 01738 pCID->ProdName1 |= tmp << 16U; 01739 01740 /* Byte 5 */ 01741 tmp = (uint8_t)((hmmc->CID[1U] & 0x00FF0000U) >> 16U); 01742 pCID->ProdName1 |= tmp << 8U; 01743 01744 /* Byte 6 */ 01745 tmp = (uint8_t)((hmmc->CID[1U] & 0x0000FF00U) >> 8U); 01746 pCID->ProdName1 |= tmp; 01747 01748 /* Byte 7 */ 01749 tmp = (uint8_t)(hmmc->CID[1U] & 0x000000FFU); 01750 pCID->ProdName2 = tmp; 01751 01752 /* Byte 8 */ 01753 tmp = (uint8_t)((hmmc->CID[2U] & 0xFF000000U) >> 24U); 01754 pCID->ProdRev = tmp; 01755 01756 /* Byte 9 */ 01757 tmp = (uint8_t)((hmmc->CID[2U] & 0x00FF0000U) >> 16U); 01758 pCID->ProdSN = tmp << 24U; 01759 01760 /* Byte 10 */ 01761 tmp = (uint8_t)((hmmc->CID[2U] & 0x0000FF00U) >> 8U); 01762 pCID->ProdSN |= tmp << 16U; 01763 01764 /* Byte 11 */ 01765 tmp = (uint8_t)(hmmc->CID[2U] & 0x000000FFU); 01766 pCID->ProdSN |= tmp << 8U; 01767 01768 /* Byte 12 */ 01769 tmp = (uint8_t)((hmmc->CID[3U] & 0xFF000000U) >> 24U); 01770 pCID->ProdSN |= tmp; 01771 01772 /* Byte 13 */ 01773 tmp = (uint8_t)((hmmc->CID[3U] & 0x00FF0000U) >> 16U); 01774 pCID->Reserved1 |= (tmp & 0xF0U) >> 4U; 01775 pCID->ManufactDate = (tmp & 0x0FU) << 8U; 01776 01777 /* Byte 14 */ 01778 tmp = (uint8_t)((hmmc->CID[3U] & 0x0000FF00U) >> 8U); 01779 pCID->ManufactDate |= tmp; 01780 01781 /* Byte 15 */ 01782 tmp = (uint8_t)(hmmc->CID[3U] & 0x000000FFU); 01783 pCID->CID_CRC = (tmp & 0xFEU) >> 1U; 01784 pCID->Reserved2 = 1U; 01785 01786 return HAL_OK; 01787 } 01788 01789 /** 01790 * @brief Returns information the information of the card which are stored on 01791 * the CSD register. 01792 * @param hmmc Pointer to MMC handle 01793 * @param pCSD Pointer to a HAL_MMC_CardInfoTypeDef structure that 01794 * contains all CSD register parameters 01795 * @retval HAL status 01796 */ 01797 HAL_StatusTypeDef HAL_MMC_GetCardCSD(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCSDTypeDef *pCSD) 01798 { 01799 uint32_t tmp = 0U; 01800 01801 /* Byte 0 */ 01802 tmp = (hmmc->CSD[0U] & 0xFF000000U) >> 24U; 01803 pCSD->CSDStruct = (uint8_t)((tmp & 0xC0U) >> 6U); 01804 pCSD->SysSpecVersion = (uint8_t)((tmp & 0x3CU) >> 2U); 01805 pCSD->Reserved1 = tmp & 0x03U; 01806 01807 /* Byte 1 */ 01808 tmp = (hmmc->CSD[0U] & 0x00FF0000U) >> 16U; 01809 pCSD->TAAC = (uint8_t)tmp; 01810 01811 /* Byte 2 */ 01812 tmp = (hmmc->CSD[0U] & 0x0000FF00U) >> 8U; 01813 pCSD->NSAC = (uint8_t)tmp; 01814 01815 /* Byte 3 */ 01816 tmp = hmmc->CSD[0U] & 0x000000FFU; 01817 pCSD->MaxBusClkFrec = (uint8_t)tmp; 01818 01819 /* Byte 4 */ 01820 tmp = (hmmc->CSD[1U] & 0xFF000000U) >> 24U; 01821 pCSD->CardComdClasses = (uint16_t)(tmp << 4U); 01822 01823 /* Byte 5 */ 01824 tmp = (hmmc->CSD[1U] & 0x00FF0000U) >> 16U; 01825 pCSD->CardComdClasses |= (uint16_t)((tmp & 0xF0U) >> 4U); 01826 pCSD->RdBlockLen = (uint8_t)(tmp & 0x0FU); 01827 01828 /* Byte 6 */ 01829 tmp = (hmmc->CSD[1U] & 0x0000FF00U) >> 8U; 01830 pCSD->PartBlockRead = (uint8_t)((tmp & 0x80U) >> 7U); 01831 pCSD->WrBlockMisalign = (uint8_t)((tmp & 0x40U) >> 6U); 01832 pCSD->RdBlockMisalign = (uint8_t)((tmp & 0x20U) >> 5U); 01833 pCSD->DSRImpl = (uint8_t)((tmp & 0x10U) >> 4U); 01834 pCSD->Reserved2 = 0; /*!< Reserved */ 01835 01836 pCSD->DeviceSize = (tmp & 0x03U) << 10U; 01837 01838 /* Byte 7 */ 01839 tmp = (uint8_t)(hmmc->CSD[1U] & 0x000000FFU); 01840 pCSD->DeviceSize |= (tmp) << 2U; 01841 01842 /* Byte 8 */ 01843 tmp = (uint8_t)((hmmc->CSD[2U] & 0xFF000000U) >> 24U); 01844 pCSD->DeviceSize |= (tmp & 0xC0U) >> 6U; 01845 01846 pCSD->MaxRdCurrentVDDMin = (tmp & 0x38U) >> 3U; 01847 pCSD->MaxRdCurrentVDDMax = (tmp & 0x07U); 01848 01849 /* Byte 9 */ 01850 tmp = (uint8_t)((hmmc->CSD[2U] & 0x00FF0000U) >> 16U); 01851 pCSD->MaxWrCurrentVDDMin = (tmp & 0xE0U) >> 5U; 01852 pCSD->MaxWrCurrentVDDMax = (tmp & 0x1CU) >> 2U; 01853 pCSD->DeviceSizeMul = (tmp & 0x03U) << 1U; 01854 /* Byte 10 */ 01855 tmp = (uint8_t)((hmmc->CSD[2] & 0x0000FF00U) >> 8U); 01856 pCSD->DeviceSizeMul |= (tmp & 0x80U) >> 7U; 01857 01858 hmmc->MmcCard.BlockNbr = (pCSD->DeviceSize + 1U) ; 01859 hmmc->MmcCard.BlockNbr *= (1U << (pCSD->DeviceSizeMul + 2U)); 01860 hmmc->MmcCard.BlockSize = 1U << (pCSD->RdBlockLen); 01861 01862 hmmc->MmcCard.LogBlockNbr = (hmmc->MmcCard.BlockNbr) * ((hmmc->MmcCard.BlockSize) / 512U); 01863 hmmc->MmcCard.LogBlockSize = 512U; 01864 01865 pCSD->EraseGrSize = (tmp & 0x40U) >> 6U; 01866 pCSD->EraseGrMul = (tmp & 0x3FU) << 1U; 01867 01868 /* Byte 11 */ 01869 tmp = (uint8_t)(hmmc->CSD[2U] & 0x000000FFU); 01870 pCSD->EraseGrMul |= (tmp & 0x80U) >> 7U; 01871 pCSD->WrProtectGrSize = (tmp & 0x7FU); 01872 01873 /* Byte 12 */ 01874 tmp = (uint8_t)((hmmc->CSD[3U] & 0xFF000000U) >> 24U); 01875 pCSD->WrProtectGrEnable = (tmp & 0x80U) >> 7U; 01876 pCSD->ManDeflECC = (tmp & 0x60U) >> 5U; 01877 pCSD->WrSpeedFact = (tmp & 0x1CU) >> 2U; 01878 pCSD->MaxWrBlockLen = (tmp & 0x03U) << 2U; 01879 01880 /* Byte 13 */ 01881 tmp = (uint8_t)((hmmc->CSD[3U] & 0x00FF0000U) >> 16U); 01882 pCSD->MaxWrBlockLen |= (tmp & 0xC0U) >> 6U; 01883 pCSD->WriteBlockPaPartial = (tmp & 0x20U) >> 5U; 01884 pCSD->Reserved3 = 0U; 01885 pCSD->ContentProtectAppli = (tmp & 0x01U); 01886 01887 /* Byte 14 */ 01888 tmp = (uint8_t)((hmmc->CSD[3U] & 0x0000FF00U) >> 8U); 01889 pCSD->FileFormatGrouop = (tmp & 0x80U) >> 7U; 01890 pCSD->CopyFlag = (tmp & 0x40U) >> 6U; 01891 pCSD->PermWrProtect = (tmp & 0x20U) >> 5U; 01892 pCSD->TempWrProtect = (tmp & 0x10U) >> 4U; 01893 pCSD->FileFormat = (tmp & 0x0CU) >> 2U; 01894 pCSD->ECC = (tmp & 0x03U); 01895 01896 /* Byte 15 */ 01897 tmp = (uint8_t)(hmmc->CSD[3U] & 0x000000FFU); 01898 pCSD->CSD_CRC = (tmp & 0xFEU) >> 1U; 01899 pCSD->Reserved4 = 1U; 01900 01901 return HAL_OK; 01902 } 01903 01904 /** 01905 * @brief Gets the MMC card info. 01906 * @param hmmc Pointer to MMC handle 01907 * @param pCardInfo Pointer to the HAL_MMC_CardInfoTypeDef structure that 01908 * will contain the MMC card status information 01909 * @retval HAL status 01910 */ 01911 HAL_StatusTypeDef HAL_MMC_GetCardInfo(MMC_HandleTypeDef *hmmc, HAL_MMC_CardInfoTypeDef *pCardInfo) 01912 { 01913 pCardInfo->CardType = (uint32_t)(hmmc->MmcCard.CardType); 01914 pCardInfo->Class = (uint32_t)(hmmc->MmcCard.Class); 01915 pCardInfo->RelCardAdd = (uint32_t)(hmmc->MmcCard.RelCardAdd); 01916 pCardInfo->BlockNbr = (uint32_t)(hmmc->MmcCard.BlockNbr); 01917 pCardInfo->BlockSize = (uint32_t)(hmmc->MmcCard.BlockSize); 01918 pCardInfo->LogBlockNbr = (uint32_t)(hmmc->MmcCard.LogBlockNbr); 01919 pCardInfo->LogBlockSize = (uint32_t)(hmmc->MmcCard.LogBlockSize); 01920 01921 return HAL_OK; 01922 } 01923 01924 /** 01925 * @brief Enables wide bus operation for the requested card if supported by 01926 * card. 01927 * @param hmmc Pointer to MMC handle 01928 * @param WideMode Specifies the MMC card wide bus mode 01929 * This parameter can be one of the following values: 01930 * @arg SDIO_BUS_WIDE_8B: 8-bit data transfer 01931 * @arg SDIO_BUS_WIDE_4B: 4-bit data transfer 01932 * @arg SDIO_BUS_WIDE_1B: 1-bit data transfer 01933 * @retval HAL status 01934 */ 01935 HAL_StatusTypeDef HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef *hmmc, uint32_t WideMode) 01936 { 01937 __IO uint32_t count = 0U; 01938 SDIO_InitTypeDef Init; 01939 uint32_t errorstate = HAL_MMC_ERROR_NONE; 01940 uint32_t response = 0U, busy = 0U; 01941 01942 /* Check the parameters */ 01943 assert_param(IS_SDIO_BUS_WIDE(WideMode)); 01944 01945 /* Chnage Satte */ 01946 hmmc->State = HAL_MMC_STATE_BUSY; 01947 01948 /* Update Clock for Bus mode update */ 01949 Init.ClockEdge = SDIO_CLOCK_EDGE_RISING; 01950 Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE; 01951 Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE; 01952 Init.BusWide = WideMode; 01953 Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE; 01954 Init.ClockDiv = SDIO_INIT_CLK_DIV; 01955 /* Initialize SDIO*/ 01956 SDIO_Init(hmmc->Instance, Init); 01957 01958 if(WideMode == SDIO_BUS_WIDE_8B) 01959 { 01960 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U); 01961 if(errorstate != HAL_MMC_ERROR_NONE) 01962 { 01963 hmmc->ErrorCode |= errorstate; 01964 } 01965 } 01966 else if(WideMode == SDIO_BUS_WIDE_4B) 01967 { 01968 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U); 01969 if(errorstate != HAL_MMC_ERROR_NONE) 01970 { 01971 hmmc->ErrorCode |= errorstate; 01972 } 01973 } 01974 else if(WideMode == SDIO_BUS_WIDE_1B) 01975 { 01976 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70000U); 01977 if(errorstate != HAL_MMC_ERROR_NONE) 01978 { 01979 hmmc->ErrorCode |= errorstate; 01980 } 01981 } 01982 else 01983 { 01984 /* WideMode is not a valid argument*/ 01985 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; 01986 } 01987 01988 /* Check for switch error and violation of the trial number of sending CMD 13 */ 01989 while(busy == 0U) 01990 { 01991 if(count++ == SDMMC_MAX_TRIAL) 01992 { 01993 hmmc->State = HAL_MMC_STATE_READY; 01994 hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE; 01995 return HAL_ERROR; 01996 } 01997 01998 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ 01999 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); 02000 if(errorstate != HAL_MMC_ERROR_NONE) 02001 { 02002 hmmc->ErrorCode |= errorstate; 02003 } 02004 02005 /* Get command response */ 02006 response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1); 02007 02008 /* Get operating voltage*/ 02009 busy = (((response >> 7U) == 1U) ? 0U : 1U); 02010 } 02011 02012 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ 02013 count = SDMMC_DATATIMEOUT; 02014 while((response & 0x00000100U) == 0U) 02015 { 02016 if(count-- == 0U) 02017 { 02018 hmmc->State = HAL_MMC_STATE_READY; 02019 hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE; 02020 return HAL_ERROR; 02021 } 02022 02023 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ 02024 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); 02025 if(errorstate != HAL_MMC_ERROR_NONE) 02026 { 02027 hmmc->ErrorCode |= errorstate; 02028 } 02029 02030 /* Get command response */ 02031 response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1); 02032 } 02033 02034 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE) 02035 { 02036 /* Clear all the static flags */ 02037 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 02038 hmmc->State = HAL_MMC_STATE_READY; 02039 return HAL_ERROR; 02040 } 02041 else 02042 { 02043 /* Configure the SDIO peripheral */ 02044 Init.ClockEdge = hmmc->Init.ClockEdge; 02045 Init.ClockBypass = hmmc->Init.ClockBypass; 02046 Init.ClockPowerSave = hmmc->Init.ClockPowerSave; 02047 Init.BusWide = WideMode; 02048 Init.HardwareFlowControl = hmmc->Init.HardwareFlowControl; 02049 Init.ClockDiv = hmmc->Init.ClockDiv; 02050 SDIO_Init(hmmc->Instance, Init); 02051 } 02052 02053 /* Change State */ 02054 hmmc->State = HAL_MMC_STATE_READY; 02055 02056 return HAL_OK; 02057 } 02058 02059 02060 /** 02061 * @brief Gets the current mmc card data state. 02062 * @param hmmc pointer to MMC handle 02063 * @retval Card state 02064 */ 02065 HAL_MMC_CardStateTypeDef HAL_MMC_GetCardState(MMC_HandleTypeDef *hmmc) 02066 { 02067 HAL_MMC_CardStateTypeDef cardstate = HAL_MMC_CARD_TRANSFER; 02068 uint32_t errorstate = HAL_MMC_ERROR_NONE; 02069 uint32_t resp1 = 0U; 02070 02071 errorstate = MMC_SendStatus(hmmc, &resp1); 02072 if(errorstate != HAL_OK) 02073 { 02074 hmmc->ErrorCode |= errorstate; 02075 } 02076 02077 cardstate = (HAL_MMC_CardStateTypeDef)((resp1 >> 9U) & 0x0FU); 02078 02079 return cardstate; 02080 } 02081 02082 /** 02083 * @brief Abort the current transfer and disable the MMC. 02084 * @param hmmc pointer to a MMC_HandleTypeDef structure that contains 02085 * the configuration information for MMC module. 02086 * @retval HAL status 02087 */ 02088 HAL_StatusTypeDef HAL_MMC_Abort(MMC_HandleTypeDef *hmmc) 02089 { 02090 HAL_MMC_CardStateTypeDef CardState; 02091 02092 /* DIsable All interrupts */ 02093 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\ 02094 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR); 02095 02096 /* Clear All flags */ 02097 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 02098 02099 if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL)) 02100 { 02101 /* Disable the MMC DMA request */ 02102 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN); 02103 02104 /* Abort the MMC DMA Tx Stream */ 02105 if(hmmc->hdmatx != NULL) 02106 { 02107 HAL_DMA_Abort(hmmc->hdmatx); 02108 } 02109 /* Abort the MMC DMA Rx Stream */ 02110 if(hmmc->hdmarx != NULL) 02111 { 02112 HAL_DMA_Abort(hmmc->hdmarx); 02113 } 02114 } 02115 02116 hmmc->State = HAL_MMC_STATE_READY; 02117 CardState = HAL_MMC_GetCardState(hmmc); 02118 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING)) 02119 { 02120 hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance); 02121 } 02122 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE) 02123 { 02124 return HAL_ERROR; 02125 } 02126 return HAL_OK; 02127 } 02128 02129 /** 02130 * @brief Abort the current transfer and disable the MMC (IT mode). 02131 * @param hmmc pointer to a MMC_HandleTypeDef structure that contains 02132 * the configuration information for MMC module. 02133 * @retval HAL status 02134 */ 02135 HAL_StatusTypeDef HAL_MMC_Abort_IT(MMC_HandleTypeDef *hmmc) 02136 { 02137 HAL_MMC_CardStateTypeDef CardState; 02138 02139 /* DIsable All interrupts */ 02140 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\ 02141 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR); 02142 02143 /* Clear All flags */ 02144 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 02145 02146 if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL)) 02147 { 02148 /* Disable the MMC DMA request */ 02149 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN); 02150 02151 /* Abort the MMC DMA Tx Stream */ 02152 if(hmmc->hdmatx != NULL) 02153 { 02154 hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort; 02155 if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK) 02156 { 02157 hmmc->hdmatx = NULL; 02158 } 02159 } 02160 /* Abort the MMC DMA Rx Stream */ 02161 if(hmmc->hdmarx != NULL) 02162 { 02163 hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort; 02164 if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK) 02165 { 02166 hmmc->hdmarx = NULL; 02167 } 02168 } 02169 } 02170 02171 /* No transfer ongoing on both DMA channels*/ 02172 if((hmmc->hdmatx == NULL) && (hmmc->hdmarx == NULL)) 02173 { 02174 CardState = HAL_MMC_GetCardState(hmmc); 02175 hmmc->State = HAL_MMC_STATE_READY; 02176 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING)) 02177 { 02178 hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance); 02179 } 02180 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE) 02181 { 02182 return HAL_ERROR; 02183 } 02184 else 02185 { 02186 HAL_MMC_AbortCallback(hmmc); 02187 } 02188 } 02189 02190 return HAL_OK; 02191 } 02192 02193 /** 02194 * @} 02195 */ 02196 02197 /** 02198 * @} 02199 */ 02200 02201 /* Private function ----------------------------------------------------------*/ 02202 /** @addtogroup MMC_Private_Functions 02203 * @{ 02204 */ 02205 02206 /** 02207 * @brief DMA MMC transmit process complete callback 02208 * @param hdma DMA handle 02209 * @retval None 02210 */ 02211 static void MMC_DMATransmitCplt(DMA_HandleTypeDef *hdma) 02212 { 02213 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent); 02214 02215 /* Enable DATAEND Interrupt */ 02216 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DATAEND)); 02217 } 02218 02219 /** 02220 * @brief DMA MMC receive process complete callback 02221 * @param hdma DMA handle 02222 * @retval None 02223 */ 02224 static void MMC_DMAReceiveCplt(DMA_HandleTypeDef *hdma) 02225 { 02226 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent); 02227 uint32_t errorstate = HAL_MMC_ERROR_NONE; 02228 02229 /* Send stop command in multiblock write */ 02230 if(hmmc->Context == (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA)) 02231 { 02232 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance); 02233 if(errorstate != HAL_MMC_ERROR_NONE) 02234 { 02235 hmmc->ErrorCode |= errorstate; 02236 HAL_MMC_ErrorCallback(hmmc); 02237 } 02238 } 02239 02240 /* Disable the DMA transfer for transmit request by setting the DMAEN bit 02241 in the MMC DCTRL register */ 02242 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN); 02243 02244 /* Clear all the static flags */ 02245 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 02246 02247 hmmc->State = HAL_MMC_STATE_READY; 02248 02249 HAL_MMC_RxCpltCallback(hmmc); 02250 } 02251 02252 /** 02253 * @brief DMA MMC communication error callback 02254 * @param hdma DMA handle 02255 * @retval None 02256 */ 02257 static void MMC_DMAError(DMA_HandleTypeDef *hdma) 02258 { 02259 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent); 02260 HAL_MMC_CardStateTypeDef CardState; 02261 02262 if((hmmc->hdmarx->ErrorCode == HAL_DMA_ERROR_TE) || (hmmc->hdmatx->ErrorCode == HAL_DMA_ERROR_TE)) 02263 { 02264 /* Clear All flags */ 02265 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 02266 02267 /* Disable All interrupts */ 02268 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\ 02269 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR); 02270 02271 hmmc->ErrorCode |= HAL_MMC_ERROR_DMA; 02272 CardState = HAL_MMC_GetCardState(hmmc); 02273 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING)) 02274 { 02275 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance); 02276 } 02277 02278 hmmc->State= HAL_MMC_STATE_READY; 02279 } 02280 02281 HAL_MMC_ErrorCallback(hmmc); 02282 } 02283 02284 /** 02285 * @brief DMA MMC Tx Abort callback 02286 * @param hdma DMA handle 02287 * @retval None 02288 */ 02289 static void MMC_DMATxAbort(DMA_HandleTypeDef *hdma) 02290 { 02291 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent); 02292 HAL_MMC_CardStateTypeDef CardState; 02293 02294 if(hmmc->hdmatx != NULL) 02295 { 02296 hmmc->hdmatx = NULL; 02297 } 02298 02299 /* All DMA channels are aborted */ 02300 if(hmmc->hdmarx == NULL) 02301 { 02302 CardState = HAL_MMC_GetCardState(hmmc); 02303 hmmc->ErrorCode = HAL_MMC_ERROR_NONE; 02304 hmmc->State = HAL_MMC_STATE_READY; 02305 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING)) 02306 { 02307 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance); 02308 02309 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE) 02310 { 02311 HAL_MMC_AbortCallback(hmmc); 02312 } 02313 else 02314 { 02315 HAL_MMC_ErrorCallback(hmmc); 02316 } 02317 } 02318 } 02319 } 02320 02321 /** 02322 * @brief DMA MMC Rx Abort callback 02323 * @param hdma DMA handle 02324 * @retval None 02325 */ 02326 static void MMC_DMARxAbort(DMA_HandleTypeDef *hdma) 02327 { 02328 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent); 02329 HAL_MMC_CardStateTypeDef CardState; 02330 02331 if(hmmc->hdmarx != NULL) 02332 { 02333 hmmc->hdmarx = NULL; 02334 } 02335 02336 /* All DMA channels are aborted */ 02337 if(hmmc->hdmatx == NULL) 02338 { 02339 CardState = HAL_MMC_GetCardState(hmmc); 02340 hmmc->ErrorCode = HAL_MMC_ERROR_NONE; 02341 hmmc->State = HAL_MMC_STATE_READY; 02342 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING)) 02343 { 02344 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance); 02345 02346 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE) 02347 { 02348 HAL_MMC_AbortCallback(hmmc); 02349 } 02350 else 02351 { 02352 HAL_MMC_ErrorCallback(hmmc); 02353 } 02354 } 02355 } 02356 } 02357 02358 02359 /** 02360 * @brief Initializes the mmc card. 02361 * @param hmmc Pointer to MMC handle 02362 * @retval MMC Card error state 02363 */ 02364 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc) 02365 { 02366 HAL_MMC_CardCSDTypeDef CSD; 02367 uint32_t errorstate = HAL_MMC_ERROR_NONE; 02368 uint16_t mmc_rca = 1; 02369 02370 /* Check the power State */ 02371 if(SDIO_GetPowerState(hmmc->Instance) == 0U) 02372 { 02373 /* Power off */ 02374 return HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE; 02375 } 02376 02377 /* Send CMD2 ALL_SEND_CID */ 02378 errorstate = SDMMC_CmdSendCID(hmmc->Instance); 02379 if(errorstate != HAL_MMC_ERROR_NONE) 02380 { 02381 return errorstate; 02382 } 02383 else 02384 { 02385 /* Get Card identification number data */ 02386 hmmc->CID[0U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1); 02387 hmmc->CID[1U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP2); 02388 hmmc->CID[2U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP3); 02389 hmmc->CID[3U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP4); 02390 } 02391 02392 /* Send CMD3 SET_REL_ADDR with argument 0 */ 02393 /* MMC Card publishes its RCA. */ 02394 errorstate = SDMMC_CmdSetRelAdd(hmmc->Instance, &mmc_rca); 02395 if(errorstate != HAL_MMC_ERROR_NONE) 02396 { 02397 return errorstate; 02398 } 02399 02400 /* Get the MMC card RCA */ 02401 hmmc->MmcCard.RelCardAdd = mmc_rca; 02402 02403 /* Send CMD9 SEND_CSD with argument as card's RCA */ 02404 errorstate = SDMMC_CmdSendCSD(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U)); 02405 if(errorstate != HAL_MMC_ERROR_NONE) 02406 { 02407 return errorstate; 02408 } 02409 else 02410 { 02411 /* Get Card Specific Data */ 02412 hmmc->CSD[0U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1); 02413 hmmc->CSD[1U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP2); 02414 hmmc->CSD[2U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP3); 02415 hmmc->CSD[3U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP4); 02416 } 02417 02418 /* Get the Card Class */ 02419 hmmc->MmcCard.Class = (SDIO_GetResponse(hmmc->Instance, SDIO_RESP2) >> 20U); 02420 02421 /* Get CSD parameters */ 02422 HAL_MMC_GetCardCSD(hmmc, &CSD); 02423 02424 /* Select the Card */ 02425 errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); 02426 if(errorstate != HAL_MMC_ERROR_NONE) 02427 { 02428 return errorstate; 02429 } 02430 02431 /* Configure SDIO peripheral interface */ 02432 SDIO_Init(hmmc->Instance, hmmc->Init); 02433 02434 /* All cards are initialized */ 02435 return HAL_MMC_ERROR_NONE; 02436 } 02437 02438 /** 02439 * @brief Enquires cards about their operating voltage and configures clock 02440 * controls and stores MMC information that will be needed in future 02441 * in the MMC handle. 02442 * @param hmmc Pointer to MMC handle 02443 * @retval error state 02444 */ 02445 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc) 02446 { 02447 __IO uint32_t count = 0U; 02448 uint32_t response = 0U, validvoltage = 0U; 02449 uint32_t errorstate = HAL_MMC_ERROR_NONE; 02450 02451 /* CMD0: GO_IDLE_STATE */ 02452 errorstate = SDMMC_CmdGoIdleState(hmmc->Instance); 02453 if(errorstate != HAL_MMC_ERROR_NONE) 02454 { 02455 return errorstate; 02456 } 02457 02458 while(validvoltage == 0U) 02459 { 02460 if(count++ == SDMMC_MAX_VOLT_TRIAL) 02461 { 02462 return HAL_MMC_ERROR_INVALID_VOLTRANGE; 02463 } 02464 02465 /* SEND CMD1 APP_CMD with MMC_HIGH_VOLTAGE_RANGE(0xC0FF8000) as argument */ 02466 errorstate = SDMMC_CmdOpCondition(hmmc->Instance, eMMC_HIGH_VOLTAGE_RANGE); 02467 if(errorstate != HAL_MMC_ERROR_NONE) 02468 { 02469 return HAL_MMC_ERROR_UNSUPPORTED_FEATURE; 02470 } 02471 02472 /* Get command response */ 02473 response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1); 02474 02475 /* Get operating voltage*/ 02476 validvoltage = (((response >> 31U) == 1U) ? 1U : 0U); 02477 } 02478 02479 /* When power routine is finished and command returns valid voltage */ 02480 if ((response & eMMC_HIGH_VOLTAGE_RANGE) == MMC_HIGH_VOLTAGE_RANGE) 02481 { 02482 /* When voltage range of the card is within 2.7V and 3.6V */ 02483 hmmc->MmcCard.CardType = MMC_HIGH_VOLTAGE_CARD; 02484 } 02485 else 02486 { 02487 /* When voltage range of the card is within 1.65V and 1.95V or 2.7V and 3.6V */ 02488 hmmc->MmcCard.CardType = MMC_DUAL_VOLTAGE_CARD; 02489 } 02490 02491 return HAL_MMC_ERROR_NONE; 02492 } 02493 02494 /** 02495 * @brief Turns the SDIO output signals off. 02496 * @param hmmc Pointer to MMC handle 02497 * @retval HAL status 02498 */ 02499 static HAL_StatusTypeDef MMC_PowerOFF(MMC_HandleTypeDef *hmmc) 02500 { 02501 /* Set Power State to OFF */ 02502 SDIO_PowerState_OFF(hmmc->Instance); 02503 02504 return HAL_OK; 02505 } 02506 02507 /** 02508 * @brief Returns the current card's status. 02509 * @param hmmc Pointer to MMC handle 02510 * @param pCardStatus pointer to the buffer that will contain the MMC card 02511 * status (Card Status register) 02512 * @retval error state 02513 */ 02514 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus) 02515 { 02516 uint32_t errorstate = HAL_MMC_ERROR_NONE; 02517 02518 if(pCardStatus == NULL) 02519 { 02520 return HAL_MMC_ERROR_PARAM; 02521 } 02522 02523 /* Send Status command */ 02524 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U)); 02525 if(errorstate != HAL_OK) 02526 { 02527 return errorstate; 02528 } 02529 02530 /* Get MMC card status */ 02531 *pCardStatus = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1); 02532 02533 return HAL_MMC_ERROR_NONE; 02534 } 02535 02536 /** 02537 * @brief Wrap up reading in non-blocking mode. 02538 * @param hmmc pointer to a MMC_HandleTypeDef structure that contains 02539 * the configuration information. 02540 * @retval HAL status 02541 */ 02542 static HAL_StatusTypeDef MMC_Read_IT(MMC_HandleTypeDef *hmmc) 02543 { 02544 uint32_t count = 0U; 02545 uint32_t* tmp; 02546 02547 tmp = (uint32_t*)hmmc->pRxBuffPtr; 02548 02549 /* Read data from SDMMC Rx FIFO */ 02550 for(count = 0U; count < 8U; count++) 02551 { 02552 *(tmp + count) = SDIO_ReadFIFO(hmmc->Instance); 02553 } 02554 02555 hmmc->pRxBuffPtr += 8U; 02556 02557 return HAL_OK; 02558 } 02559 02560 /** 02561 * @brief Wrap up writing in non-blocking mode. 02562 * @param hmmc pointer to a MMC_HandleTypeDef structure that contains 02563 * the configuration information. 02564 * @retval HAL status 02565 */ 02566 static HAL_StatusTypeDef MMC_Write_IT(MMC_HandleTypeDef *hmmc) 02567 { 02568 uint32_t count = 0U; 02569 uint32_t* tmp; 02570 02571 tmp = (uint32_t*)hmmc->pTxBuffPtr; 02572 02573 /* Write data to SDMMC Tx FIFO */ 02574 for(count = 0U; count < 8U; count++) 02575 { 02576 SDIO_WriteFIFO(hmmc->Instance, (tmp + count)); 02577 } 02578 02579 hmmc->pTxBuffPtr += 8U; 02580 02581 return HAL_OK; 02582 } 02583 02584 /** 02585 * @} 02586 */ 02587 02588 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || 02589 STM32F401xC || STM32F401xE || STM32F411xE || STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx || 02590 STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */ 02591 02592 #endif /* HAL_MMC_MODULE_ENABLED */ 02593 02594 /** 02595 * @} 02596 */ 02597 02598 /** 02599 * @} 02600 */ 02601 02602 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/