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