STM32F479xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32f4xx_hal_mmc.c 00004 * @author MCD Application Team 00005 * @brief MMC card HAL module driver. 00006 * This file provides firmware functions to manage the following 00007 * functionalities of the Secure Digital (MMC) peripheral: 00008 * + Initialization and de-initialization functions 00009 * + IO operation functions 00010 * + Peripheral Control functions 00011 * + MMC card Control functions 00012 * 00013 @verbatim 00014 ============================================================================== 00015 ##### How to use this driver ##### 00016 ============================================================================== 00017 [..] 00018 This driver implements a high level communication layer for read and write from/to 00019 this memory. The needed STM32 hardware resources (SDMMC and GPIO) are performed by 00020 the user in HAL_MMC_MspInit() function (MSP layer). 00021 Basically, the MSP layer configuration should be the same as we provide in the 00022 examples. 00023 You can easily tailor this configuration according to hardware resources. 00024 00025 [..] 00026 This driver is a generic layered driver for SDMMC memories which uses the HAL 00027 SDMMC driver functions to interface with MMC and eMMC cards devices. 00028 It is used as follows: 00029 00030 (#)Initialize the SDMMC low level resources by implement the HAL_MMC_MspInit() API: 00031 (##) Enable the SDMMC interface clock using __HAL_RCC_SDMMC_CLK_ENABLE(); 00032 (##) SDMMC pins configuration for MMC card 00033 (+++) Enable the clock for the SDMMC GPIOs using the functions __HAL_RCC_GPIOx_CLK_ENABLE(); 00034 (+++) Configure these SDMMC pins as alternate function pull-up using HAL_GPIO_Init() 00035 and according to your pin assignment; 00036 (##) DMA Configuration if you need to use DMA process (HAL_MMC_ReadBlocks_DMA() 00037 and HAL_MMC_WriteBlocks_DMA() APIs). 00038 (+++) Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE(); 00039 (+++) Configure the DMA using the function HAL_DMA_Init() with predeclared and filled. 00040 (##) NVIC configuration if you need to use interrupt process when using DMA transfer. 00041 (+++) Configure the SDMMC and DMA interrupt priorities using 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 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 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 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 HAL_MMC_Init 00223 and HAL_MMC_DeInit only when these callbacks are null (not registered beforehand). 00224 If not, MspInit or MspDeInit are not null, the HAL_MMC_Init and 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 HAL_MMC_RegisterCallback before calling HAL_MMC_DeInit 00233 or 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) 2017 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 "stm32f4xx_hal.h" 00256 00257 /** @addtogroup STM32F4xx_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 #if defined(SDIO_STA_STBITERR) 00635 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_FLAG_STBITERR)) 00636 #else /* SDIO_STA_STBITERR not defined */ 00637 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND)) 00638 #endif /* SDIO_STA_STBITERR */ 00639 { 00640 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXFIFOHF) && (dataremaining > 0U)) 00641 { 00642 /* Read data from SDIO Rx FIFO */ 00643 for(count = 0U; count < 8U; count++) 00644 { 00645 data = SDIO_ReadFIFO(hmmc->Instance); 00646 *tempbuff = (uint8_t)(data & 0xFFU); 00647 tempbuff++; 00648 dataremaining--; 00649 *tempbuff = (uint8_t)((data >> 8U) & 0xFFU); 00650 tempbuff++; 00651 dataremaining--; 00652 *tempbuff = (uint8_t)((data >> 16U) & 0xFFU); 00653 tempbuff++; 00654 dataremaining--; 00655 *tempbuff = (uint8_t)((data >> 24U) & 0xFFU); 00656 tempbuff++; 00657 dataremaining--; 00658 } 00659 } 00660 00661 if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U)) 00662 { 00663 /* Clear all the static flags */ 00664 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 00665 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT; 00666 hmmc->State= HAL_MMC_STATE_READY; 00667 return HAL_TIMEOUT; 00668 } 00669 } 00670 00671 /* Send stop transmission command in case of multiblock read */ 00672 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1U)) 00673 { 00674 /* Send stop transmission command */ 00675 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance); 00676 if(errorstate != HAL_MMC_ERROR_NONE) 00677 { 00678 /* Clear all the static flags */ 00679 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 00680 hmmc->ErrorCode |= errorstate; 00681 hmmc->State = HAL_MMC_STATE_READY; 00682 return HAL_ERROR; 00683 } 00684 } 00685 00686 /* Get error state */ 00687 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DTIMEOUT)) 00688 { 00689 /* Clear all the static flags */ 00690 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 00691 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT; 00692 hmmc->State = HAL_MMC_STATE_READY; 00693 return HAL_ERROR; 00694 } 00695 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL)) 00696 { 00697 /* Clear all the static flags */ 00698 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 00699 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL; 00700 hmmc->State = HAL_MMC_STATE_READY; 00701 return HAL_ERROR; 00702 } 00703 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR)) 00704 { 00705 /* Clear all the static flags */ 00706 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 00707 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN; 00708 hmmc->State = HAL_MMC_STATE_READY; 00709 return HAL_ERROR; 00710 } 00711 else 00712 { 00713 /* Nothing to do */ 00714 } 00715 00716 /* Empty FIFO if there is still any data */ 00717 while ((__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXDAVL)) && (dataremaining > 0U)) 00718 { 00719 data = SDIO_ReadFIFO(hmmc->Instance); 00720 *tempbuff = (uint8_t)(data & 0xFFU); 00721 tempbuff++; 00722 dataremaining--; 00723 *tempbuff = (uint8_t)((data >> 8U) & 0xFFU); 00724 tempbuff++; 00725 dataremaining--; 00726 *tempbuff = (uint8_t)((data >> 16U) & 0xFFU); 00727 tempbuff++; 00728 dataremaining--; 00729 *tempbuff = (uint8_t)((data >> 24U) & 0xFFU); 00730 tempbuff++; 00731 dataremaining--; 00732 00733 if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U)) 00734 { 00735 /* Clear all the static flags */ 00736 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 00737 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT; 00738 hmmc->State= HAL_MMC_STATE_READY; 00739 return HAL_ERROR; 00740 } 00741 } 00742 00743 /* Clear all the static flags */ 00744 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS); 00745 00746 hmmc->State = HAL_MMC_STATE_READY; 00747 00748 return HAL_OK; 00749 } 00750 else 00751 { 00752 hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY; 00753 return HAL_ERROR; 00754 } 00755 } 00756 00757 /** 00758 * @brief Allows to write block(s) to a specified address in a card. The Data 00759 * transfer is managed by polling mode. 00760 * @note This API should be followed by a check on the card state through 00761 * HAL_MMC_GetCardState(). 00762 * @param hmmc: Pointer to MMC handle 00763 * @param pData: pointer to the buffer that will contain the data to transmit 00764 * @param BlockAdd: Block Address where data will be written 00765 * @param NumberOfBlocks: Number of MMC blocks to write 00766 * @param Timeout: Specify timeout value 00767 * @retval HAL status 00768 */ 00769 HAL_StatusTypeDef HAL_MMC_WriteBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout) 00770 { 00771 SDIO_DataInitTypeDef config; 00772 uint32_t errorstate; 00773 uint32_t tickstart = HAL_GetTick(); 00774 uint32_t count, data, dataremaining; 00775 uint32_t add = BlockAdd; 00776 uint8_t *tempbuff = pData; 00777 00778 if(NULL == pData) 00779 { 00780 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; 00781 return HAL_ERROR; 00782 } 00783 00784 if(hmmc->State == HAL_MMC_STATE_READY) 00785 { 00786 hmmc->ErrorCode = HAL_MMC_ERROR_NONE; 00787 00788 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr)) 00789 { 00790 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; 00791 return HAL_ERROR; 00792 } 00793 00794 hmmc->State = HAL_MMC_STATE_BUSY; 00795 00796 /* Initialize data control register */ 00797 hmmc->Instance->DCTRL = 0U; 00798 00799 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD) 00800 { 00801 add *= 512U; 00802 } 00803 00804 /* Write Blocks in Polling mode */ 00805 if(NumberOfBlocks > 1U) 00806 { 00807 hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK; 00808 00809 /* Write Multi Block command */ 00810 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add); 00811 } 00812 else 00813 { 00814 hmmc->Context = MMC_CONTEXT_WRITE_SINGLE_BLOCK; 00815 00816 /* Write Single Block command */ 00817 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add); 00818 } 00819 if(errorstate != HAL_MMC_ERROR_NONE) 00820 { 00821 /* Clear all the static flags */ 00822 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 00823 hmmc->ErrorCode |= errorstate; 00824 hmmc->State = HAL_MMC_STATE_READY; 00825 return HAL_ERROR; 00826 } 00827 00828 /* Configure the MMC DPSM (Data Path State Machine) */ 00829 config.DataTimeOut = SDMMC_DATATIMEOUT; 00830 config.DataLength = NumberOfBlocks * MMC_BLOCKSIZE; 00831 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B; 00832 config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD; 00833 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK; 00834 config.DPSM = SDIO_DPSM_ENABLE; 00835 (void)SDIO_ConfigData(hmmc->Instance, &config); 00836 00837 /* Write block(s) in polling mode */ 00838 dataremaining = config.DataLength; 00839 #if defined(SDIO_STA_STBITERR) 00840 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND | SDIO_FLAG_STBITERR)) 00841 #else /* SDIO_STA_STBITERR not defined */ 00842 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND)) 00843 #endif /* SDIO_STA_STBITERR */ 00844 { 00845 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXFIFOHE) && (dataremaining > 0U)) 00846 { 00847 /* Write data to SDIO Tx FIFO */ 00848 for(count = 0U; count < 8U; count++) 00849 { 00850 data = (uint32_t)(*tempbuff); 00851 tempbuff++; 00852 dataremaining--; 00853 data |= ((uint32_t)(*tempbuff) << 8U); 00854 tempbuff++; 00855 dataremaining--; 00856 data |= ((uint32_t)(*tempbuff) << 16U); 00857 tempbuff++; 00858 dataremaining--; 00859 data |= ((uint32_t)(*tempbuff) << 24U); 00860 tempbuff++; 00861 dataremaining--; 00862 (void)SDIO_WriteFIFO(hmmc->Instance, &data); 00863 } 00864 } 00865 00866 if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U)) 00867 { 00868 /* Clear all the static flags */ 00869 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 00870 hmmc->ErrorCode |= errorstate; 00871 hmmc->State = HAL_MMC_STATE_READY; 00872 return HAL_TIMEOUT; 00873 } 00874 } 00875 00876 /* Send stop transmission command in case of multiblock write */ 00877 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DATAEND) && (NumberOfBlocks > 1U)) 00878 { 00879 /* Send stop transmission command */ 00880 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance); 00881 if(errorstate != HAL_MMC_ERROR_NONE) 00882 { 00883 /* Clear all the static flags */ 00884 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 00885 hmmc->ErrorCode |= errorstate; 00886 hmmc->State = HAL_MMC_STATE_READY; 00887 return HAL_ERROR; 00888 } 00889 } 00890 00891 /* Get error state */ 00892 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DTIMEOUT)) 00893 { 00894 /* Clear all the static flags */ 00895 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 00896 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT; 00897 hmmc->State = HAL_MMC_STATE_READY; 00898 return HAL_ERROR; 00899 } 00900 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL)) 00901 { 00902 /* Clear all the static flags */ 00903 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 00904 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL; 00905 hmmc->State = HAL_MMC_STATE_READY; 00906 return HAL_ERROR; 00907 } 00908 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR)) 00909 { 00910 /* Clear all the static flags */ 00911 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 00912 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN; 00913 hmmc->State = HAL_MMC_STATE_READY; 00914 return HAL_ERROR; 00915 } 00916 else 00917 { 00918 /* Nothing to do */ 00919 } 00920 00921 /* Clear all the static flags */ 00922 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS); 00923 00924 hmmc->State = HAL_MMC_STATE_READY; 00925 00926 return HAL_OK; 00927 } 00928 else 00929 { 00930 hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY; 00931 return HAL_ERROR; 00932 } 00933 } 00934 00935 /** 00936 * @brief Reads block(s) from a specified address in a card. The Data transfer 00937 * is managed in interrupt mode. 00938 * @note This API should be followed by a check on the card state through 00939 * HAL_MMC_GetCardState(). 00940 * @note You could also check the IT transfer process through the MMC Rx 00941 * interrupt event. 00942 * @param hmmc: Pointer to MMC handle 00943 * @param pData: Pointer to the buffer that will contain the received data 00944 * @param BlockAdd: Block Address from where data is to be read 00945 * @param NumberOfBlocks: Number of blocks to read. 00946 * @retval HAL status 00947 */ 00948 HAL_StatusTypeDef HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks) 00949 { 00950 SDIO_DataInitTypeDef config; 00951 uint32_t errorstate; 00952 uint32_t add = BlockAdd; 00953 00954 if(NULL == pData) 00955 { 00956 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; 00957 return HAL_ERROR; 00958 } 00959 00960 if(hmmc->State == HAL_MMC_STATE_READY) 00961 { 00962 hmmc->ErrorCode = HAL_MMC_ERROR_NONE; 00963 00964 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr)) 00965 { 00966 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; 00967 return HAL_ERROR; 00968 } 00969 00970 hmmc->State = HAL_MMC_STATE_BUSY; 00971 00972 /* Initialize data control register */ 00973 hmmc->Instance->DCTRL = 0U; 00974 00975 hmmc->pRxBuffPtr = pData; 00976 hmmc->RxXferSize = MMC_BLOCKSIZE * NumberOfBlocks; 00977 00978 #if defined(SDIO_STA_STBITERR) 00979 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_FLAG_RXFIFOHF | SDIO_IT_STBITERR)); 00980 #else /* SDIO_STA_STBITERR not defined */ 00981 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_FLAG_RXFIFOHF)); 00982 #endif /* SDIO_STA_STBITERR */ 00983 00984 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD) 00985 { 00986 add *= 512U; 00987 } 00988 00989 /* Configure the MMC DPSM (Data Path State Machine) */ 00990 config.DataTimeOut = SDMMC_DATATIMEOUT; 00991 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks; 00992 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B; 00993 config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO; 00994 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK; 00995 config.DPSM = SDIO_DPSM_ENABLE; 00996 (void)SDIO_ConfigData(hmmc->Instance, &config); 00997 00998 /* Read Blocks in IT mode */ 00999 if(NumberOfBlocks > 1U) 01000 { 01001 hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_IT); 01002 01003 /* Read Multi Block command */ 01004 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add); 01005 } 01006 else 01007 { 01008 hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_IT); 01009 01010 /* Read Single Block command */ 01011 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add); 01012 } 01013 01014 if(errorstate != HAL_MMC_ERROR_NONE) 01015 { 01016 /* Clear all the static flags */ 01017 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 01018 hmmc->ErrorCode |= errorstate; 01019 hmmc->State = HAL_MMC_STATE_READY; 01020 return HAL_ERROR; 01021 } 01022 01023 return HAL_OK; 01024 } 01025 else 01026 { 01027 return HAL_BUSY; 01028 } 01029 } 01030 01031 /** 01032 * @brief Writes block(s) to a specified address in a card. The Data transfer 01033 * is managed in interrupt mode. 01034 * @note This API should be followed by a check on the card state through 01035 * HAL_MMC_GetCardState(). 01036 * @note You could also check the IT transfer process through the MMC Tx 01037 * interrupt event. 01038 * @param hmmc: Pointer to MMC handle 01039 * @param pData: Pointer to the buffer that will contain the data to transmit 01040 * @param BlockAdd: Block Address where data will be written 01041 * @param NumberOfBlocks: Number of blocks to write 01042 * @retval HAL status 01043 */ 01044 HAL_StatusTypeDef HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks) 01045 { 01046 SDIO_DataInitTypeDef config; 01047 uint32_t errorstate; 01048 uint32_t add = BlockAdd; 01049 01050 if(NULL == pData) 01051 { 01052 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; 01053 return HAL_ERROR; 01054 } 01055 01056 if(hmmc->State == HAL_MMC_STATE_READY) 01057 { 01058 hmmc->ErrorCode = HAL_MMC_ERROR_NONE; 01059 01060 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr)) 01061 { 01062 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; 01063 return HAL_ERROR; 01064 } 01065 01066 hmmc->State = HAL_MMC_STATE_BUSY; 01067 01068 /* Initialize data control register */ 01069 hmmc->Instance->DCTRL = 0U; 01070 01071 hmmc->pTxBuffPtr = pData; 01072 hmmc->TxXferSize = MMC_BLOCKSIZE * NumberOfBlocks; 01073 01074 /* Enable transfer interrupts */ 01075 #if defined(SDIO_STA_STBITERR) 01076 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_DATAEND | SDIO_FLAG_TXFIFOHE | SDIO_IT_STBITERR)); 01077 #else /* SDIO_STA_STBITERR not defined */ 01078 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_DATAEND | SDIO_FLAG_TXFIFOHE)); 01079 #endif /* SDIO_STA_STBITERR */ 01080 01081 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD) 01082 { 01083 add *= 512U; 01084 } 01085 01086 /* Write Blocks in Polling mode */ 01087 if(NumberOfBlocks > 1U) 01088 { 01089 hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK| MMC_CONTEXT_IT); 01090 01091 /* Write Multi Block command */ 01092 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add); 01093 } 01094 else 01095 { 01096 hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_IT); 01097 01098 /* Write Single Block command */ 01099 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add); 01100 } 01101 if(errorstate != HAL_MMC_ERROR_NONE) 01102 { 01103 /* Clear all the static flags */ 01104 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 01105 hmmc->ErrorCode |= errorstate; 01106 hmmc->State = HAL_MMC_STATE_READY; 01107 return HAL_ERROR; 01108 } 01109 01110 /* Configure the MMC DPSM (Data Path State Machine) */ 01111 config.DataTimeOut = SDMMC_DATATIMEOUT; 01112 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks; 01113 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B; 01114 config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD; 01115 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK; 01116 config.DPSM = SDIO_DPSM_ENABLE; 01117 (void)SDIO_ConfigData(hmmc->Instance, &config); 01118 01119 return HAL_OK; 01120 } 01121 else 01122 { 01123 return HAL_BUSY; 01124 } 01125 } 01126 01127 /** 01128 * @brief Reads block(s) from a specified address in a card. The Data transfer 01129 * is managed by DMA mode. 01130 * @note This API should be followed by a check on the card state through 01131 * HAL_MMC_GetCardState(). 01132 * @note You could also check the DMA transfer process through the MMC Rx 01133 * interrupt event. 01134 * @param hmmc: Pointer MMC handle 01135 * @param pData: Pointer to the buffer that will contain the received data 01136 * @param BlockAdd: Block Address from where data is to be read 01137 * @param NumberOfBlocks: Number of blocks to read. 01138 * @retval HAL status 01139 */ 01140 HAL_StatusTypeDef HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks) 01141 { 01142 SDIO_DataInitTypeDef config; 01143 uint32_t errorstate; 01144 uint32_t add = BlockAdd; 01145 01146 if(NULL == pData) 01147 { 01148 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; 01149 return HAL_ERROR; 01150 } 01151 01152 if(hmmc->State == HAL_MMC_STATE_READY) 01153 { 01154 hmmc->ErrorCode = HAL_DMA_ERROR_NONE; 01155 01156 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr)) 01157 { 01158 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; 01159 return HAL_ERROR; 01160 } 01161 01162 hmmc->State = HAL_MMC_STATE_BUSY; 01163 01164 /* Initialize data control register */ 01165 hmmc->Instance->DCTRL = 0U; 01166 01167 #if defined(SDIO_STA_STBITERR) 01168 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND | SDIO_IT_STBITERR)); 01169 #else /* SDIO_STA_STBITERR not defined */ 01170 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND)); 01171 #endif /* SDIO_STA_STBITERR */ 01172 01173 /* Set the DMA transfer complete callback */ 01174 hmmc->hdmarx->XferCpltCallback = MMC_DMAReceiveCplt; 01175 01176 /* Set the DMA error callback */ 01177 hmmc->hdmarx->XferErrorCallback = MMC_DMAError; 01178 01179 /* Set the DMA Abort callback */ 01180 hmmc->hdmarx->XferAbortCallback = NULL; 01181 01182 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD) 01183 { 01184 add *= 512U; 01185 } 01186 01187 /* Force DMA Direction */ 01188 hmmc->hdmarx->Init.Direction = DMA_PERIPH_TO_MEMORY; 01189 MODIFY_REG(hmmc->hdmarx->Instance->CR, DMA_SxCR_DIR, hmmc->hdmarx->Init.Direction); 01190 01191 /* Enable the DMA Channel */ 01192 if(HAL_DMA_Start_IT(hmmc->hdmarx, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)pData, (uint32_t)(MMC_BLOCKSIZE * NumberOfBlocks)/4) != HAL_OK) 01193 { 01194 __HAL_MMC_DISABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND)); 01195 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 01196 hmmc->ErrorCode = HAL_MMC_ERROR_DMA; 01197 hmmc->State = HAL_MMC_STATE_READY; 01198 return HAL_ERROR; 01199 } 01200 else 01201 { 01202 /* Enable MMC DMA transfer */ 01203 __HAL_MMC_DMA_ENABLE(hmmc); 01204 01205 /* Configure the MMC DPSM (Data Path State Machine) */ 01206 config.DataTimeOut = SDMMC_DATATIMEOUT; 01207 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks; 01208 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B; 01209 config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO; 01210 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK; 01211 config.DPSM = SDIO_DPSM_ENABLE; 01212 (void)SDIO_ConfigData(hmmc->Instance, &config); 01213 01214 /* Read Blocks in DMA mode */ 01215 if(NumberOfBlocks > 1U) 01216 { 01217 hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA); 01218 01219 /* Read Multi Block command */ 01220 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add); 01221 } 01222 else 01223 { 01224 hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_DMA); 01225 01226 /* Read Single Block command */ 01227 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add); 01228 } 01229 if(errorstate != HAL_MMC_ERROR_NONE) 01230 { 01231 /* Clear all the static flags */ 01232 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 01233 __HAL_MMC_DISABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_RXOVERR | SDIO_IT_DATAEND)); 01234 hmmc->ErrorCode = errorstate; 01235 hmmc->State = HAL_MMC_STATE_READY; 01236 return HAL_ERROR; 01237 } 01238 01239 return HAL_OK; 01240 } 01241 } 01242 else 01243 { 01244 return HAL_BUSY; 01245 } 01246 } 01247 01248 /** 01249 * @brief Writes block(s) to a specified address in a card. The Data transfer 01250 * is managed by DMA mode. 01251 * @note This API should be followed by a check on the card state through 01252 * HAL_MMC_GetCardState(). 01253 * @note You could also check the DMA transfer process through the MMC Tx 01254 * interrupt event. 01255 * @param hmmc: Pointer to MMC handle 01256 * @param pData: Pointer to the buffer that will contain the data to transmit 01257 * @param BlockAdd: Block Address where data will be written 01258 * @param NumberOfBlocks: Number of blocks to write 01259 * @retval HAL status 01260 */ 01261 HAL_StatusTypeDef HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks) 01262 { 01263 SDIO_DataInitTypeDef config; 01264 uint32_t errorstate; 01265 uint32_t add = BlockAdd; 01266 01267 if(NULL == pData) 01268 { 01269 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; 01270 return HAL_ERROR; 01271 } 01272 01273 if(hmmc->State == HAL_MMC_STATE_READY) 01274 { 01275 hmmc->ErrorCode = HAL_MMC_ERROR_NONE; 01276 01277 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr)) 01278 { 01279 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; 01280 return HAL_ERROR; 01281 } 01282 01283 hmmc->State = HAL_MMC_STATE_BUSY; 01284 01285 /* Initialize data control register */ 01286 hmmc->Instance->DCTRL = 0U; 01287 01288 /* Enable MMC Error interrupts */ 01289 #if defined(SDIO_STA_STBITERR) 01290 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR)); 01291 #else /* SDIO_STA_STBITERR not defined */ 01292 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR)); 01293 #endif /* SDIO_STA_STBITERR */ 01294 01295 /* Set the DMA transfer complete callback */ 01296 hmmc->hdmatx->XferCpltCallback = MMC_DMATransmitCplt; 01297 01298 /* Set the DMA error callback */ 01299 hmmc->hdmatx->XferErrorCallback = MMC_DMAError; 01300 01301 /* Set the DMA Abort callback */ 01302 hmmc->hdmatx->XferAbortCallback = NULL; 01303 01304 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD) 01305 { 01306 add *= 512U; 01307 } 01308 01309 01310 /* Write Blocks in Polling mode */ 01311 if(NumberOfBlocks > 1U) 01312 { 01313 hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_DMA); 01314 01315 /* Write Multi Block command */ 01316 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add); 01317 } 01318 else 01319 { 01320 hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_DMA); 01321 01322 /* Write Single Block command */ 01323 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add); 01324 } 01325 if(errorstate != HAL_MMC_ERROR_NONE) 01326 { 01327 /* Clear all the static flags */ 01328 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 01329 __HAL_MMC_DISABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_DATAEND)); 01330 hmmc->ErrorCode |= errorstate; 01331 hmmc->State = HAL_MMC_STATE_READY; 01332 return HAL_ERROR; 01333 } 01334 01335 /* Enable SDIO DMA transfer */ 01336 __HAL_MMC_DMA_ENABLE(hmmc); 01337 01338 /* Force DMA Direction */ 01339 hmmc->hdmatx->Init.Direction = DMA_MEMORY_TO_PERIPH; 01340 MODIFY_REG(hmmc->hdmatx->Instance->CR, DMA_SxCR_DIR, hmmc->hdmatx->Init.Direction); 01341 01342 /* Enable the DMA Channel */ 01343 if(HAL_DMA_Start_IT(hmmc->hdmatx, (uint32_t)pData, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)(MMC_BLOCKSIZE * NumberOfBlocks)/4) != HAL_OK) 01344 { 01345 __HAL_MMC_DISABLE_IT(hmmc, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_DATAEND)); 01346 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 01347 hmmc->ErrorCode |= HAL_MMC_ERROR_DMA; 01348 hmmc->State = HAL_MMC_STATE_READY; 01349 return HAL_ERROR; 01350 } 01351 else 01352 { 01353 /* Configure the MMC DPSM (Data Path State Machine) */ 01354 config.DataTimeOut = SDMMC_DATATIMEOUT; 01355 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks; 01356 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B; 01357 config.TransferDir = SDIO_TRANSFER_DIR_TO_CARD; 01358 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK; 01359 config.DPSM = SDIO_DPSM_ENABLE; 01360 (void)SDIO_ConfigData(hmmc->Instance, &config); 01361 01362 return HAL_OK; 01363 } 01364 } 01365 else 01366 { 01367 return HAL_BUSY; 01368 } 01369 } 01370 01371 /** 01372 * @brief Erases the specified memory area of the given MMC card. 01373 * @note This API should be followed by a check on the card state through 01374 * HAL_MMC_GetCardState(). 01375 * @param hmmc: Pointer to MMC handle 01376 * @param BlockStartAdd: Start Block address 01377 * @param BlockEndAdd: End Block address 01378 * @retval HAL status 01379 */ 01380 HAL_StatusTypeDef HAL_MMC_Erase(MMC_HandleTypeDef *hmmc, uint32_t BlockStartAdd, uint32_t BlockEndAdd) 01381 { 01382 uint32_t errorstate; 01383 uint32_t start_add = BlockStartAdd; 01384 uint32_t end_add = BlockEndAdd; 01385 01386 if(hmmc->State == HAL_MMC_STATE_READY) 01387 { 01388 hmmc->ErrorCode = HAL_MMC_ERROR_NONE; 01389 01390 if(end_add < start_add) 01391 { 01392 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; 01393 return HAL_ERROR; 01394 } 01395 01396 if(end_add > (hmmc->MmcCard.LogBlockNbr)) 01397 { 01398 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; 01399 return HAL_ERROR; 01400 } 01401 01402 hmmc->State = HAL_MMC_STATE_BUSY; 01403 01404 /* Check if the card command class supports erase command */ 01405 if(((hmmc->MmcCard.Class) & SDIO_CCCC_ERASE) == 0U) 01406 { 01407 /* Clear all the static flags */ 01408 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 01409 hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE; 01410 hmmc->State = HAL_MMC_STATE_READY; 01411 return HAL_ERROR; 01412 } 01413 01414 if((SDIO_GetResponse(hmmc->Instance, SDIO_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED) 01415 { 01416 /* Clear all the static flags */ 01417 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 01418 hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED; 01419 hmmc->State = HAL_MMC_STATE_READY; 01420 return HAL_ERROR; 01421 } 01422 01423 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD) 01424 { 01425 start_add *= 512U; 01426 end_add *= 512U; 01427 } 01428 01429 /* Send CMD35 MMC_ERASE_GRP_START with argument as addr */ 01430 errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, start_add); 01431 if(errorstate != HAL_MMC_ERROR_NONE) 01432 { 01433 /* Clear all the static flags */ 01434 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 01435 hmmc->ErrorCode |= errorstate; 01436 hmmc->State = HAL_MMC_STATE_READY; 01437 return HAL_ERROR; 01438 } 01439 01440 /* Send CMD36 MMC_ERASE_GRP_END with argument as addr */ 01441 errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, end_add); 01442 if(errorstate != HAL_MMC_ERROR_NONE) 01443 { 01444 /* Clear all the static flags */ 01445 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 01446 hmmc->ErrorCode |= errorstate; 01447 hmmc->State = HAL_MMC_STATE_READY; 01448 return HAL_ERROR; 01449 } 01450 01451 /* Send CMD38 ERASE */ 01452 errorstate = SDMMC_CmdErase(hmmc->Instance); 01453 if(errorstate != HAL_MMC_ERROR_NONE) 01454 { 01455 /* Clear all the static flags */ 01456 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 01457 hmmc->ErrorCode |= errorstate; 01458 hmmc->State = HAL_MMC_STATE_READY; 01459 return HAL_ERROR; 01460 } 01461 01462 hmmc->State = HAL_MMC_STATE_READY; 01463 01464 return HAL_OK; 01465 } 01466 else 01467 { 01468 return HAL_BUSY; 01469 } 01470 } 01471 01472 /** 01473 * @brief This function handles MMC card interrupt request. 01474 * @param hmmc: Pointer to MMC handle 01475 * @retval None 01476 */ 01477 void HAL_MMC_IRQHandler(MMC_HandleTypeDef *hmmc) 01478 { 01479 uint32_t errorstate; 01480 uint32_t context = hmmc->Context; 01481 01482 /* Check for SDIO interrupt flags */ 01483 if((__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXFIFOHF) != RESET) && ((context & MMC_CONTEXT_IT) != 0U)) 01484 { 01485 MMC_Read_IT(hmmc); 01486 } 01487 01488 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DATAEND) != RESET) 01489 { 01490 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_FLAG_DATAEND); 01491 01492 #if defined(SDIO_STA_STBITERR) 01493 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\ 01494 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR | SDIO_IT_STBITERR); 01495 #else /* SDIO_STA_STBITERR not defined */ 01496 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT |\ 01497 SDIO_IT_TXUNDERR | SDIO_IT_RXOVERR | SDIO_IT_TXFIFOHE |\ 01498 SDIO_IT_RXFIFOHF); 01499 #endif /* SDIO_STA_STBITERR */ 01500 01501 hmmc->Instance->DCTRL &= ~(SDIO_DCTRL_DTEN); 01502 01503 if((context & MMC_CONTEXT_DMA) != 0U) 01504 { 01505 if((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U) 01506 { 01507 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance); 01508 if(errorstate != HAL_MMC_ERROR_NONE) 01509 { 01510 hmmc->ErrorCode |= errorstate; 01511 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 01512 hmmc->ErrorCallback(hmmc); 01513 #else 01514 HAL_MMC_ErrorCallback(hmmc); 01515 #endif 01516 } 01517 } 01518 if(((context & MMC_CONTEXT_READ_SINGLE_BLOCK) == 0U) && ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) == 0U)) 01519 { 01520 /* Disable the DMA transfer for transmit request by setting the DMAEN bit 01521 in the MMC DCTRL register */ 01522 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN); 01523 01524 hmmc->State = HAL_MMC_STATE_READY; 01525 01526 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 01527 hmmc->TxCpltCallback(hmmc); 01528 #else 01529 HAL_MMC_TxCpltCallback(hmmc); 01530 #endif 01531 } 01532 } 01533 else if((context & MMC_CONTEXT_IT) != 0U) 01534 { 01535 /* Stop Transfer for Write Multi blocks or Read Multi blocks */ 01536 if(((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)) 01537 { 01538 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance); 01539 if(errorstate != HAL_MMC_ERROR_NONE) 01540 { 01541 hmmc->ErrorCode |= errorstate; 01542 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 01543 hmmc->ErrorCallback(hmmc); 01544 #else 01545 HAL_MMC_ErrorCallback(hmmc); 01546 #endif 01547 } 01548 } 01549 01550 /* Clear all the static flags */ 01551 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS); 01552 01553 hmmc->State = HAL_MMC_STATE_READY; 01554 if(((context & MMC_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U)) 01555 { 01556 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 01557 hmmc->RxCpltCallback(hmmc); 01558 #else 01559 HAL_MMC_RxCpltCallback(hmmc); 01560 #endif 01561 } 01562 else 01563 { 01564 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 01565 hmmc->TxCpltCallback(hmmc); 01566 #else 01567 HAL_MMC_TxCpltCallback(hmmc); 01568 #endif 01569 } 01570 } 01571 else 01572 { 01573 /* Nothing to do */ 01574 } 01575 } 01576 01577 else if((__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXFIFOHE) != RESET) && ((context & MMC_CONTEXT_IT) != 0U)) 01578 { 01579 MMC_Write_IT(hmmc); 01580 } 01581 01582 #if defined(SDIO_STA_STBITERR) 01583 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_RXOVERR | SDIO_FLAG_TXUNDERR | SDIO_FLAG_STBITERR) != RESET) 01584 #else /* SDIO_STA_STBITERR not defined */ 01585 else if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_RXOVERR | SDIO_FLAG_TXUNDERR) != RESET) 01586 #endif /* SDIO_STA_STBITERR */ 01587 { 01588 /* Set Error code */ 01589 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DCRCFAIL) != RESET) 01590 { 01591 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL; 01592 } 01593 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_DTIMEOUT) != RESET) 01594 { 01595 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT; 01596 } 01597 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR) != RESET) 01598 { 01599 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN; 01600 } 01601 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_TXUNDERR) != RESET) 01602 { 01603 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN; 01604 } 01605 #if defined(SDIO_STA_STBITERR) 01606 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_STBITERR) != RESET) 01607 { 01608 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT; 01609 } 01610 #endif /* SDIO_STA_STBITERR */ 01611 01612 #if defined(SDIO_STA_STBITERR) 01613 /* Clear All flags */ 01614 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS | SDIO_FLAG_STBITERR); 01615 01616 /* Disable all interrupts */ 01617 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\ 01618 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR | SDIO_IT_STBITERR); 01619 #else /* SDIO_STA_STBITERR */ 01620 /* Clear All flags */ 01621 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS); 01622 01623 /* Disable all interrupts */ 01624 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\ 01625 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR); 01626 #endif /* SDIO_STA_STBITERR */ 01627 01628 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance); 01629 01630 if((context & MMC_CONTEXT_IT) != 0U) 01631 { 01632 /* Set the MMC state to ready to be able to start again the process */ 01633 hmmc->State = HAL_MMC_STATE_READY; 01634 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 01635 hmmc->ErrorCallback(hmmc); 01636 #else 01637 HAL_MMC_ErrorCallback(hmmc); 01638 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */ 01639 } 01640 else if((context & MMC_CONTEXT_DMA) != 0U) 01641 { 01642 /* Abort the MMC DMA Streams */ 01643 if(hmmc->hdmatx != NULL) 01644 { 01645 /* Set the DMA Tx abort callback */ 01646 hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort; 01647 /* Abort DMA in IT mode */ 01648 if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK) 01649 { 01650 MMC_DMATxAbort(hmmc->hdmatx); 01651 } 01652 } 01653 else if(hmmc->hdmarx != NULL) 01654 { 01655 /* Set the DMA Rx abort callback */ 01656 hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort; 01657 /* Abort DMA in IT mode */ 01658 if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK) 01659 { 01660 MMC_DMARxAbort(hmmc->hdmarx); 01661 } 01662 } 01663 else 01664 { 01665 hmmc->ErrorCode = HAL_MMC_ERROR_NONE; 01666 hmmc->State = HAL_MMC_STATE_READY; 01667 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 01668 hmmc->AbortCpltCallback(hmmc); 01669 #else 01670 HAL_MMC_AbortCallback(hmmc); 01671 #endif 01672 } 01673 } 01674 else 01675 { 01676 /* Nothing to do */ 01677 } 01678 } 01679 01680 else 01681 { 01682 /* Nothing to do */ 01683 } 01684 } 01685 01686 /** 01687 * @brief return the MMC state 01688 * @param hmmc: Pointer to mmc handle 01689 * @retval HAL state 01690 */ 01691 HAL_MMC_StateTypeDef HAL_MMC_GetState(MMC_HandleTypeDef *hmmc) 01692 { 01693 return hmmc->State; 01694 } 01695 01696 /** 01697 * @brief Return the MMC error code 01698 * @param hmmc : Pointer to a MMC_HandleTypeDef structure that contains 01699 * the configuration information. 01700 * @retval MMC Error Code 01701 */ 01702 uint32_t HAL_MMC_GetError(MMC_HandleTypeDef *hmmc) 01703 { 01704 return hmmc->ErrorCode; 01705 } 01706 01707 /** 01708 * @brief Tx Transfer completed callbacks 01709 * @param hmmc: Pointer to MMC handle 01710 * @retval None 01711 */ 01712 __weak void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef *hmmc) 01713 { 01714 /* Prevent unused argument(s) compilation warning */ 01715 UNUSED(hmmc); 01716 01717 /* NOTE : This function should not be modified, when the callback is needed, 01718 the HAL_MMC_TxCpltCallback can be implemented in the user file 01719 */ 01720 } 01721 01722 /** 01723 * @brief Rx Transfer completed callbacks 01724 * @param hmmc: Pointer MMC handle 01725 * @retval None 01726 */ 01727 __weak void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef *hmmc) 01728 { 01729 /* Prevent unused argument(s) compilation warning */ 01730 UNUSED(hmmc); 01731 01732 /* NOTE : This function should not be modified, when the callback is needed, 01733 the HAL_MMC_RxCpltCallback can be implemented in the user file 01734 */ 01735 } 01736 01737 /** 01738 * @brief MMC error callbacks 01739 * @param hmmc: Pointer MMC handle 01740 * @retval None 01741 */ 01742 __weak void HAL_MMC_ErrorCallback(MMC_HandleTypeDef *hmmc) 01743 { 01744 /* Prevent unused argument(s) compilation warning */ 01745 UNUSED(hmmc); 01746 01747 /* NOTE : This function should not be modified, when the callback is needed, 01748 the HAL_MMC_ErrorCallback can be implemented in the user file 01749 */ 01750 } 01751 01752 /** 01753 * @brief MMC Abort callbacks 01754 * @param hmmc: Pointer MMC handle 01755 * @retval None 01756 */ 01757 __weak void HAL_MMC_AbortCallback(MMC_HandleTypeDef *hmmc) 01758 { 01759 /* Prevent unused argument(s) compilation warning */ 01760 UNUSED(hmmc); 01761 01762 /* NOTE : This function should not be modified, when the callback is needed, 01763 the HAL_MMC_AbortCallback can be implemented in the user file 01764 */ 01765 } 01766 01767 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 01768 /** 01769 * @brief Register a User MMC Callback 01770 * To be used instead of the weak (surcharged) predefined callback 01771 * @param hmmc : MMC handle 01772 * @param CallbackId : ID of the callback to be registered 01773 * This parameter can be one of the following values: 01774 * @arg @ref HAL_MMC_TX_CPLT_CB_ID MMC Tx Complete Callback ID 01775 * @arg @ref HAL_MMC_RX_CPLT_CB_ID MMC Rx Complete Callback ID 01776 * @arg @ref HAL_MMC_ERROR_CB_ID MMC Error Callback ID 01777 * @arg @ref HAL_MMC_ABORT_CB_ID MMC Abort Callback ID 01778 * @arg @ref HAL_MMC_MSP_INIT_CB_ID MMC MspInit Callback ID 01779 * @arg @ref HAL_MMC_MSP_DEINIT_CB_ID MMC MspDeInit Callback ID 01780 * @param pCallback : pointer to the Callback function 01781 * @retval status 01782 */ 01783 HAL_StatusTypeDef HAL_MMC_RegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId, pMMC_CallbackTypeDef pCallback) 01784 { 01785 HAL_StatusTypeDef status = HAL_OK; 01786 01787 if(pCallback == NULL) 01788 { 01789 /* Update the error code */ 01790 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK; 01791 return HAL_ERROR; 01792 } 01793 01794 /* Process locked */ 01795 __HAL_LOCK(hmmc); 01796 01797 if(hmmc->State == HAL_MMC_STATE_READY) 01798 { 01799 switch (CallbackId) 01800 { 01801 case HAL_MMC_TX_CPLT_CB_ID : 01802 hmmc->TxCpltCallback = pCallback; 01803 break; 01804 case HAL_MMC_RX_CPLT_CB_ID : 01805 hmmc->RxCpltCallback = pCallback; 01806 break; 01807 case HAL_MMC_ERROR_CB_ID : 01808 hmmc->ErrorCallback = pCallback; 01809 break; 01810 case HAL_MMC_ABORT_CB_ID : 01811 hmmc->AbortCpltCallback = pCallback; 01812 break; 01813 case HAL_MMC_MSP_INIT_CB_ID : 01814 hmmc->MspInitCallback = pCallback; 01815 break; 01816 case HAL_MMC_MSP_DEINIT_CB_ID : 01817 hmmc->MspDeInitCallback = pCallback; 01818 break; 01819 default : 01820 /* Update the error code */ 01821 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK; 01822 /* update return status */ 01823 status = HAL_ERROR; 01824 break; 01825 } 01826 } 01827 else if (hmmc->State == HAL_MMC_STATE_RESET) 01828 { 01829 switch (CallbackId) 01830 { 01831 case HAL_MMC_MSP_INIT_CB_ID : 01832 hmmc->MspInitCallback = pCallback; 01833 break; 01834 case HAL_MMC_MSP_DEINIT_CB_ID : 01835 hmmc->MspDeInitCallback = pCallback; 01836 break; 01837 default : 01838 /* Update the error code */ 01839 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK; 01840 /* update return status */ 01841 status = HAL_ERROR; 01842 break; 01843 } 01844 } 01845 else 01846 { 01847 /* Update the error code */ 01848 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK; 01849 /* update return status */ 01850 status = HAL_ERROR; 01851 } 01852 01853 /* Release Lock */ 01854 __HAL_UNLOCK(hmmc); 01855 return status; 01856 } 01857 01858 /** 01859 * @brief Unregister a User MMC Callback 01860 * MMC Callback is redirected to the weak (surcharged) predefined callback 01861 * @param hmmc : MMC handle 01862 * @param CallbackId : ID of the callback to be unregistered 01863 * This parameter can be one of the following values: 01864 * @arg @ref HAL_MMC_TX_CPLT_CB_ID MMC Tx Complete Callback ID 01865 * @arg @ref HAL_MMC_RX_CPLT_CB_ID MMC Rx Complete Callback ID 01866 * @arg @ref HAL_MMC_ERROR_CB_ID MMC Error Callback ID 01867 * @arg @ref HAL_MMC_ABORT_CB_ID MMC Abort Callback ID 01868 * @arg @ref HAL_MMC_MSP_INIT_CB_ID MMC MspInit Callback ID 01869 * @arg @ref HAL_MMC_MSP_DEINIT_CB_ID MMC MspDeInit Callback ID 01870 * @retval status 01871 */ 01872 HAL_StatusTypeDef HAL_MMC_UnRegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId) 01873 { 01874 HAL_StatusTypeDef status = HAL_OK; 01875 01876 /* Process locked */ 01877 __HAL_LOCK(hmmc); 01878 01879 if(hmmc->State == HAL_MMC_STATE_READY) 01880 { 01881 switch (CallbackId) 01882 { 01883 case HAL_MMC_TX_CPLT_CB_ID : 01884 hmmc->TxCpltCallback = HAL_MMC_TxCpltCallback; 01885 break; 01886 case HAL_MMC_RX_CPLT_CB_ID : 01887 hmmc->RxCpltCallback = HAL_MMC_RxCpltCallback; 01888 break; 01889 case HAL_MMC_ERROR_CB_ID : 01890 hmmc->ErrorCallback = HAL_MMC_ErrorCallback; 01891 break; 01892 case HAL_MMC_ABORT_CB_ID : 01893 hmmc->AbortCpltCallback = HAL_MMC_AbortCallback; 01894 break; 01895 case HAL_MMC_MSP_INIT_CB_ID : 01896 hmmc->MspInitCallback = HAL_MMC_MspInit; 01897 break; 01898 case HAL_MMC_MSP_DEINIT_CB_ID : 01899 hmmc->MspDeInitCallback = HAL_MMC_MspDeInit; 01900 break; 01901 default : 01902 /* Update the error code */ 01903 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK; 01904 /* update return status */ 01905 status = HAL_ERROR; 01906 break; 01907 } 01908 } 01909 else if (hmmc->State == HAL_MMC_STATE_RESET) 01910 { 01911 switch (CallbackId) 01912 { 01913 case HAL_MMC_MSP_INIT_CB_ID : 01914 hmmc->MspInitCallback = HAL_MMC_MspInit; 01915 break; 01916 case HAL_MMC_MSP_DEINIT_CB_ID : 01917 hmmc->MspDeInitCallback = HAL_MMC_MspDeInit; 01918 break; 01919 default : 01920 /* Update the error code */ 01921 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK; 01922 /* update return status */ 01923 status = HAL_ERROR; 01924 break; 01925 } 01926 } 01927 else 01928 { 01929 /* Update the error code */ 01930 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK; 01931 /* update return status */ 01932 status = HAL_ERROR; 01933 } 01934 01935 /* Release Lock */ 01936 __HAL_UNLOCK(hmmc); 01937 return status; 01938 } 01939 #endif 01940 01941 /** 01942 * @} 01943 */ 01944 01945 /** @addtogroup MMC_Exported_Functions_Group3 01946 * @brief management functions 01947 * 01948 @verbatim 01949 ============================================================================== 01950 ##### Peripheral Control functions ##### 01951 ============================================================================== 01952 [..] 01953 This subsection provides a set of functions allowing to control the MMC card 01954 operations and get the related information 01955 01956 @endverbatim 01957 * @{ 01958 */ 01959 01960 /** 01961 * @brief Returns information the information of the card which are stored on 01962 * the CID register. 01963 * @param hmmc: Pointer to MMC handle 01964 * @param pCID: Pointer to a HAL_MMC_CIDTypedef structure that 01965 * contains all CID register parameters 01966 * @retval HAL status 01967 */ 01968 HAL_StatusTypeDef HAL_MMC_GetCardCID(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCIDTypeDef *pCID) 01969 { 01970 pCID->ManufacturerID = (uint8_t)((hmmc->CID[0] & 0xFF000000U) >> 24U); 01971 01972 pCID->OEM_AppliID = (uint16_t)((hmmc->CID[0] & 0x00FFFF00U) >> 8U); 01973 01974 pCID->ProdName1 = (((hmmc->CID[0] & 0x000000FFU) << 24U) | ((hmmc->CID[1] & 0xFFFFFF00U) >> 8U)); 01975 01976 pCID->ProdName2 = (uint8_t)(hmmc->CID[1] & 0x000000FFU); 01977 01978 pCID->ProdRev = (uint8_t)((hmmc->CID[2] & 0xFF000000U) >> 24U); 01979 01980 pCID->ProdSN = (((hmmc->CID[2] & 0x00FFFFFFU) << 8U) | ((hmmc->CID[3] & 0xFF000000U) >> 24U)); 01981 01982 pCID->Reserved1 = (uint8_t)((hmmc->CID[3] & 0x00F00000U) >> 20U); 01983 01984 pCID->ManufactDate = (uint16_t)((hmmc->CID[3] & 0x000FFF00U) >> 8U); 01985 01986 pCID->CID_CRC = (uint8_t)((hmmc->CID[3] & 0x000000FEU) >> 1U); 01987 01988 pCID->Reserved2 = 1U; 01989 01990 return HAL_OK; 01991 } 01992 01993 /** 01994 * @brief Returns information the information of the card which are stored on 01995 * the CSD register. 01996 * @param hmmc: Pointer to MMC handle 01997 * @param pCSD: Pointer to a HAL_MMC_CardCSDTypeDef structure that 01998 * contains all CSD register parameters 01999 * @retval HAL status 02000 */ 02001 HAL_StatusTypeDef HAL_MMC_GetCardCSD(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCSDTypeDef *pCSD) 02002 { 02003 uint32_t block_nbr = 0; 02004 02005 pCSD->CSDStruct = (uint8_t)((hmmc->CSD[0] & 0xC0000000U) >> 30U); 02006 02007 pCSD->SysSpecVersion = (uint8_t)((hmmc->CSD[0] & 0x3C000000U) >> 26U); 02008 02009 pCSD->Reserved1 = (uint8_t)((hmmc->CSD[0] & 0x03000000U) >> 24U); 02010 02011 pCSD->TAAC = (uint8_t)((hmmc->CSD[0] & 0x00FF0000U) >> 16U); 02012 02013 pCSD->NSAC = (uint8_t)((hmmc->CSD[0] & 0x0000FF00U) >> 8U); 02014 02015 pCSD->MaxBusClkFrec = (uint8_t)(hmmc->CSD[0] & 0x000000FFU); 02016 02017 pCSD->CardComdClasses = (uint16_t)((hmmc->CSD[1] & 0xFFF00000U) >> 20U); 02018 02019 pCSD->RdBlockLen = (uint8_t)((hmmc->CSD[1] & 0x000F0000U) >> 16U); 02020 02021 pCSD->PartBlockRead = (uint8_t)((hmmc->CSD[1] & 0x00008000U) >> 15U); 02022 02023 pCSD->WrBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00004000U) >> 14U); 02024 02025 pCSD->RdBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00002000U) >> 13U); 02026 02027 pCSD->DSRImpl = (uint8_t)((hmmc->CSD[1] & 0x00001000U) >> 12U); 02028 02029 pCSD->Reserved2 = 0U; /*!< Reserved */ 02030 02031 pCSD->DeviceSize = (((hmmc->CSD[1] & 0x000003FFU) << 2U) | ((hmmc->CSD[2] & 0xC0000000U) >> 30U)); 02032 02033 pCSD->MaxRdCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x38000000U) >> 27U); 02034 02035 pCSD->MaxRdCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x07000000U) >> 24U); 02036 02037 pCSD->MaxWrCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x00E00000U) >> 21U); 02038 02039 pCSD->MaxWrCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x001C0000U) >> 18U); 02040 02041 pCSD->DeviceSizeMul = (uint8_t)((hmmc->CSD[2] & 0x00038000U) >> 15U); 02042 02043 if(MMC_ReadExtCSD(hmmc, &block_nbr, 212, 0x0FFFFFFFU) != HAL_OK) /* Field SEC_COUNT [215:212] */ 02044 { 02045 return HAL_ERROR; 02046 } 02047 02048 if(hmmc->MmcCard.CardType == MMC_LOW_CAPACITY_CARD) 02049 { 02050 hmmc->MmcCard.BlockNbr = (pCSD->DeviceSize + 1U) ; 02051 hmmc->MmcCard.BlockNbr *= (1UL << ((pCSD->DeviceSizeMul & 0x07U) + 2U)); 02052 hmmc->MmcCard.BlockSize = (1UL << (pCSD->RdBlockLen & 0x0FU)); 02053 hmmc->MmcCard.LogBlockNbr = (hmmc->MmcCard.BlockNbr) * ((hmmc->MmcCard.BlockSize) / 512U); 02054 hmmc->MmcCard.LogBlockSize = 512U; 02055 } 02056 else if(hmmc->MmcCard.CardType == MMC_HIGH_CAPACITY_CARD) 02057 { 02058 hmmc->MmcCard.BlockNbr = block_nbr; 02059 hmmc->MmcCard.LogBlockNbr = hmmc->MmcCard.BlockNbr; 02060 hmmc->MmcCard.BlockSize = 512U; 02061 hmmc->MmcCard.LogBlockSize = hmmc->MmcCard.BlockSize; 02062 } 02063 else 02064 { 02065 /* Clear all the static flags */ 02066 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 02067 hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE; 02068 hmmc->State = HAL_MMC_STATE_READY; 02069 return HAL_ERROR; 02070 } 02071 02072 pCSD->EraseGrSize = (uint8_t)((hmmc->CSD[2] & 0x00004000U) >> 14U); 02073 02074 pCSD->EraseGrMul = (uint8_t)((hmmc->CSD[2] & 0x00003F80U) >> 7U); 02075 02076 pCSD->WrProtectGrSize = (uint8_t)(hmmc->CSD[2] & 0x0000007FU); 02077 02078 pCSD->WrProtectGrEnable = (uint8_t)((hmmc->CSD[3] & 0x80000000U) >> 31U); 02079 02080 pCSD->ManDeflECC = (uint8_t)((hmmc->CSD[3] & 0x60000000U) >> 29U); 02081 02082 pCSD->WrSpeedFact = (uint8_t)((hmmc->CSD[3] & 0x1C000000U) >> 26U); 02083 02084 pCSD->MaxWrBlockLen= (uint8_t)((hmmc->CSD[3] & 0x03C00000U) >> 22U); 02085 02086 pCSD->WriteBlockPaPartial = (uint8_t)((hmmc->CSD[3] & 0x00200000U) >> 21U); 02087 02088 pCSD->Reserved3 = 0; 02089 02090 pCSD->ContentProtectAppli = (uint8_t)((hmmc->CSD[3] & 0x00010000U) >> 16U); 02091 02092 pCSD->FileFormatGroup = (uint8_t)((hmmc->CSD[3] & 0x00008000U) >> 15U); 02093 02094 pCSD->CopyFlag = (uint8_t)((hmmc->CSD[3] & 0x00004000U) >> 14U); 02095 02096 pCSD->PermWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00002000U) >> 13U); 02097 02098 pCSD->TempWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00001000U) >> 12U); 02099 02100 pCSD->FileFormat = (uint8_t)((hmmc->CSD[3] & 0x00000C00U) >> 10U); 02101 02102 pCSD->ECC= (uint8_t)((hmmc->CSD[3] & 0x00000300U) >> 8U); 02103 02104 pCSD->CSD_CRC = (uint8_t)((hmmc->CSD[3] & 0x000000FEU) >> 1U); 02105 02106 pCSD->Reserved4 = 1; 02107 02108 return HAL_OK; 02109 } 02110 02111 /** 02112 * @brief Gets the MMC card info. 02113 * @param hmmc: Pointer to MMC handle 02114 * @param pCardInfo: Pointer to the HAL_MMC_CardInfoTypeDef structure that 02115 * will contain the MMC card status information 02116 * @retval HAL status 02117 */ 02118 HAL_StatusTypeDef HAL_MMC_GetCardInfo(MMC_HandleTypeDef *hmmc, HAL_MMC_CardInfoTypeDef *pCardInfo) 02119 { 02120 pCardInfo->CardType = (uint32_t)(hmmc->MmcCard.CardType); 02121 pCardInfo->Class = (uint32_t)(hmmc->MmcCard.Class); 02122 pCardInfo->RelCardAdd = (uint32_t)(hmmc->MmcCard.RelCardAdd); 02123 pCardInfo->BlockNbr = (uint32_t)(hmmc->MmcCard.BlockNbr); 02124 pCardInfo->BlockSize = (uint32_t)(hmmc->MmcCard.BlockSize); 02125 pCardInfo->LogBlockNbr = (uint32_t)(hmmc->MmcCard.LogBlockNbr); 02126 pCardInfo->LogBlockSize = (uint32_t)(hmmc->MmcCard.LogBlockSize); 02127 02128 return HAL_OK; 02129 } 02130 02131 /** 02132 * @brief Enables wide bus operation for the requested card if supported by 02133 * card. 02134 * @param hmmc: Pointer to MMC handle 02135 * @param WideMode: Specifies the MMC card wide bus mode 02136 * This parameter can be one of the following values: 02137 * @arg SDIO_BUS_WIDE_8B: 8-bit data transfer 02138 * @arg SDIO_BUS_WIDE_4B: 4-bit data transfer 02139 * @arg SDIO_BUS_WIDE_1B: 1-bit data transfer 02140 * @retval HAL status 02141 */ 02142 HAL_StatusTypeDef HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef *hmmc, uint32_t WideMode) 02143 { 02144 __IO uint32_t count = 0U; 02145 SDIO_InitTypeDef Init; 02146 uint32_t errorstate; 02147 uint32_t response = 0U, busy = 0U; 02148 02149 /* Check the parameters */ 02150 assert_param(IS_SDIO_BUS_WIDE(WideMode)); 02151 02152 /* Change State */ 02153 hmmc->State = HAL_MMC_STATE_BUSY; 02154 02155 /* Update Clock for Bus mode update */ 02156 Init.ClockEdge = SDIO_CLOCK_EDGE_RISING; 02157 Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE; 02158 Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE; 02159 Init.BusWide = WideMode; 02160 Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE; 02161 Init.ClockDiv = SDIO_INIT_CLK_DIV; 02162 /* Initialize SDIO*/ 02163 (void)SDIO_Init(hmmc->Instance, Init); 02164 02165 if(WideMode == SDIO_BUS_WIDE_8B) 02166 { 02167 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U); 02168 if(errorstate != HAL_MMC_ERROR_NONE) 02169 { 02170 hmmc->ErrorCode |= errorstate; 02171 } 02172 } 02173 else if(WideMode == SDIO_BUS_WIDE_4B) 02174 { 02175 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U); 02176 if(errorstate != HAL_MMC_ERROR_NONE) 02177 { 02178 hmmc->ErrorCode |= errorstate; 02179 } 02180 } 02181 else if(WideMode == SDIO_BUS_WIDE_1B) 02182 { 02183 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70000U); 02184 if(errorstate != HAL_MMC_ERROR_NONE) 02185 { 02186 hmmc->ErrorCode |= errorstate; 02187 } 02188 } 02189 else 02190 { 02191 /* WideMode is not a valid argument*/ 02192 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; 02193 } 02194 02195 /* Check for switch error and violation of the trial number of sending CMD 13 */ 02196 while(busy == 0U) 02197 { 02198 if(count == SDMMC_MAX_TRIAL) 02199 { 02200 hmmc->State = HAL_MMC_STATE_READY; 02201 hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE; 02202 return HAL_ERROR; 02203 } 02204 count++; 02205 02206 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ 02207 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); 02208 if(errorstate != HAL_MMC_ERROR_NONE) 02209 { 02210 hmmc->ErrorCode |= errorstate; 02211 } 02212 02213 /* Get command response */ 02214 response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1); 02215 02216 /* Get operating voltage*/ 02217 busy = (((response >> 7U) == 1U) ? 0U : 1U); 02218 } 02219 02220 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ 02221 count = SDMMC_DATATIMEOUT; 02222 while((response & 0x00000100U) == 0U) 02223 { 02224 if(count == 0U) 02225 { 02226 hmmc->State = HAL_MMC_STATE_READY; 02227 hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE; 02228 return HAL_ERROR; 02229 } 02230 count--; 02231 02232 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ 02233 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); 02234 if(errorstate != HAL_MMC_ERROR_NONE) 02235 { 02236 hmmc->ErrorCode |= errorstate; 02237 } 02238 02239 /* Get command response */ 02240 response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1); 02241 } 02242 02243 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE) 02244 { 02245 /* Clear all the static flags */ 02246 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 02247 hmmc->State = HAL_MMC_STATE_READY; 02248 return HAL_ERROR; 02249 } 02250 else 02251 { 02252 /* Configure the SDIO peripheral */ 02253 Init.ClockEdge = hmmc->Init.ClockEdge; 02254 Init.ClockBypass = hmmc->Init.ClockBypass; 02255 Init.ClockPowerSave = hmmc->Init.ClockPowerSave; 02256 Init.BusWide = WideMode; 02257 Init.HardwareFlowControl = hmmc->Init.HardwareFlowControl; 02258 Init.ClockDiv = hmmc->Init.ClockDiv; 02259 (void)SDIO_Init(hmmc->Instance, Init); 02260 } 02261 02262 /* Change State */ 02263 hmmc->State = HAL_MMC_STATE_READY; 02264 02265 return HAL_OK; 02266 } 02267 02268 /** 02269 * @brief Gets the current mmc card data state. 02270 * @param hmmc: pointer to MMC handle 02271 * @retval Card state 02272 */ 02273 HAL_MMC_CardStateTypeDef HAL_MMC_GetCardState(MMC_HandleTypeDef *hmmc) 02274 { 02275 uint32_t cardstate; 02276 uint32_t errorstate; 02277 uint32_t resp1 = 0U; 02278 02279 errorstate = MMC_SendStatus(hmmc, &resp1); 02280 if(errorstate != HAL_MMC_ERROR_NONE) 02281 { 02282 hmmc->ErrorCode |= errorstate; 02283 } 02284 02285 cardstate = ((resp1 >> 9U) & 0x0FU); 02286 02287 return (HAL_MMC_CardStateTypeDef)cardstate; 02288 } 02289 02290 /** 02291 * @brief Abort the current transfer and disable the MMC. 02292 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains 02293 * the configuration information for MMC module. 02294 * @retval HAL status 02295 */ 02296 HAL_StatusTypeDef HAL_MMC_Abort(MMC_HandleTypeDef *hmmc) 02297 { 02298 HAL_MMC_CardStateTypeDef CardState; 02299 02300 /* DIsable All interrupts */ 02301 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\ 02302 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR); 02303 02304 /* Clear All flags */ 02305 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS); 02306 02307 if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL)) 02308 { 02309 /* Disable the MMC DMA request */ 02310 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN); 02311 02312 /* Abort the MMC DMA Tx Stream */ 02313 if(hmmc->hdmatx != NULL) 02314 { 02315 if(HAL_DMA_Abort(hmmc->hdmatx) != HAL_OK) 02316 { 02317 hmmc->ErrorCode |= HAL_MMC_ERROR_DMA; 02318 } 02319 } 02320 /* Abort the MMC DMA Rx Stream */ 02321 if(hmmc->hdmarx != NULL) 02322 { 02323 if(HAL_DMA_Abort(hmmc->hdmarx) != HAL_OK) 02324 { 02325 hmmc->ErrorCode |= HAL_MMC_ERROR_DMA; 02326 } 02327 } 02328 } 02329 02330 hmmc->State = HAL_MMC_STATE_READY; 02331 02332 /* Initialize the MMC operation */ 02333 hmmc->Context = MMC_CONTEXT_NONE; 02334 02335 CardState = HAL_MMC_GetCardState(hmmc); 02336 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING)) 02337 { 02338 hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance); 02339 } 02340 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE) 02341 { 02342 return HAL_ERROR; 02343 } 02344 return HAL_OK; 02345 } 02346 02347 /** 02348 * @brief Abort the current transfer and disable the MMC (IT mode). 02349 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains 02350 * the configuration information for MMC module. 02351 * @retval HAL status 02352 */ 02353 HAL_StatusTypeDef HAL_MMC_Abort_IT(MMC_HandleTypeDef *hmmc) 02354 { 02355 HAL_MMC_CardStateTypeDef CardState; 02356 02357 /* DIsable All interrupts */ 02358 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\ 02359 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR); 02360 02361 /* Clear All flags */ 02362 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS); 02363 02364 if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL)) 02365 { 02366 /* Disable the MMC DMA request */ 02367 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN); 02368 02369 /* Abort the MMC DMA Tx Stream */ 02370 if(hmmc->hdmatx != NULL) 02371 { 02372 hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort; 02373 if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK) 02374 { 02375 hmmc->hdmatx = NULL; 02376 } 02377 } 02378 /* Abort the MMC DMA Rx Stream */ 02379 if(hmmc->hdmarx != NULL) 02380 { 02381 hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort; 02382 if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK) 02383 { 02384 hmmc->hdmarx = NULL; 02385 } 02386 } 02387 } 02388 02389 /* No transfer ongoing on both DMA channels*/ 02390 if((hmmc->hdmatx == NULL) && (hmmc->hdmarx == NULL)) 02391 { 02392 CardState = HAL_MMC_GetCardState(hmmc); 02393 hmmc->State = HAL_MMC_STATE_READY; 02394 02395 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING)) 02396 { 02397 hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance); 02398 } 02399 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE) 02400 { 02401 return HAL_ERROR; 02402 } 02403 else 02404 { 02405 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 02406 hmmc->AbortCpltCallback(hmmc); 02407 #else 02408 HAL_MMC_AbortCallback(hmmc); 02409 #endif 02410 } 02411 } 02412 02413 return HAL_OK; 02414 } 02415 02416 /** 02417 * @} 02418 */ 02419 02420 /** 02421 * @} 02422 */ 02423 02424 /* Private function ----------------------------------------------------------*/ 02425 /** @addtogroup MMC_Private_Functions 02426 * @{ 02427 */ 02428 02429 /** 02430 * @brief DMA MMC transmit process complete callback 02431 * @param hdma: DMA handle 02432 * @retval None 02433 */ 02434 static void MMC_DMATransmitCplt(DMA_HandleTypeDef *hdma) 02435 { 02436 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent); 02437 02438 /* Enable DATAEND Interrupt */ 02439 __HAL_MMC_ENABLE_IT(hmmc, (SDIO_IT_DATAEND)); 02440 } 02441 02442 /** 02443 * @brief DMA MMC receive process complete callback 02444 * @param hdma: DMA handle 02445 * @retval None 02446 */ 02447 static void MMC_DMAReceiveCplt(DMA_HandleTypeDef *hdma) 02448 { 02449 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent); 02450 uint32_t errorstate; 02451 02452 /* Send stop command in multiblock write */ 02453 if(hmmc->Context == (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA)) 02454 { 02455 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance); 02456 if(errorstate != HAL_MMC_ERROR_NONE) 02457 { 02458 hmmc->ErrorCode |= errorstate; 02459 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 02460 hmmc->ErrorCallback(hmmc); 02461 #else 02462 HAL_MMC_ErrorCallback(hmmc); 02463 #endif 02464 } 02465 } 02466 02467 /* Disable the DMA transfer for transmit request by setting the DMAEN bit 02468 in the MMC DCTRL register */ 02469 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN); 02470 02471 /* Clear all the static flags */ 02472 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS); 02473 02474 hmmc->State = HAL_MMC_STATE_READY; 02475 02476 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 02477 hmmc->RxCpltCallback(hmmc); 02478 #else 02479 HAL_MMC_RxCpltCallback(hmmc); 02480 #endif 02481 } 02482 02483 /** 02484 * @brief DMA MMC communication error callback 02485 * @param hdma: DMA handle 02486 * @retval None 02487 */ 02488 static void MMC_DMAError(DMA_HandleTypeDef *hdma) 02489 { 02490 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent); 02491 HAL_MMC_CardStateTypeDef CardState; 02492 uint32_t RxErrorCode, TxErrorCode; 02493 02494 /* if DMA error is FIFO error ignore it */ 02495 if(HAL_DMA_GetError(hdma) != HAL_DMA_ERROR_FE) 02496 { 02497 RxErrorCode = hmmc->hdmarx->ErrorCode; 02498 TxErrorCode = hmmc->hdmatx->ErrorCode; 02499 if((RxErrorCode == HAL_DMA_ERROR_TE) || (TxErrorCode == HAL_DMA_ERROR_TE)) 02500 { 02501 /* Clear All flags */ 02502 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 02503 02504 /* Disable All interrupts */ 02505 __HAL_MMC_DISABLE_IT(hmmc, SDIO_IT_DATAEND | SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT|\ 02506 SDIO_IT_TXUNDERR| SDIO_IT_RXOVERR); 02507 02508 hmmc->ErrorCode |= HAL_MMC_ERROR_DMA; 02509 CardState = HAL_MMC_GetCardState(hmmc); 02510 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING)) 02511 { 02512 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance); 02513 } 02514 02515 hmmc->State= HAL_MMC_STATE_READY; 02516 } 02517 02518 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 02519 hmmc->ErrorCallback(hmmc); 02520 #else 02521 HAL_MMC_ErrorCallback(hmmc); 02522 #endif 02523 } 02524 } 02525 02526 /** 02527 * @brief DMA MMC Tx Abort callback 02528 * @param hdma: DMA handle 02529 * @retval None 02530 */ 02531 static void MMC_DMATxAbort(DMA_HandleTypeDef *hdma) 02532 { 02533 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent); 02534 HAL_MMC_CardStateTypeDef CardState; 02535 02536 if(hmmc->hdmatx != NULL) 02537 { 02538 hmmc->hdmatx = NULL; 02539 } 02540 02541 /* All DMA channels are aborted */ 02542 if(hmmc->hdmarx == NULL) 02543 { 02544 CardState = HAL_MMC_GetCardState(hmmc); 02545 hmmc->ErrorCode = HAL_MMC_ERROR_NONE; 02546 hmmc->State = HAL_MMC_STATE_READY; 02547 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING)) 02548 { 02549 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance); 02550 02551 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE) 02552 { 02553 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 02554 hmmc->AbortCpltCallback(hmmc); 02555 #else 02556 HAL_MMC_AbortCallback(hmmc); 02557 #endif 02558 } 02559 else 02560 { 02561 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 02562 hmmc->ErrorCallback(hmmc); 02563 #else 02564 HAL_MMC_ErrorCallback(hmmc); 02565 #endif 02566 } 02567 } 02568 } 02569 } 02570 02571 /** 02572 * @brief DMA MMC Rx Abort callback 02573 * @param hdma: DMA handle 02574 * @retval None 02575 */ 02576 static void MMC_DMARxAbort(DMA_HandleTypeDef *hdma) 02577 { 02578 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent); 02579 HAL_MMC_CardStateTypeDef CardState; 02580 02581 if(hmmc->hdmarx != NULL) 02582 { 02583 hmmc->hdmarx = NULL; 02584 } 02585 02586 /* All DMA channels are aborted */ 02587 if(hmmc->hdmatx == NULL) 02588 { 02589 CardState = HAL_MMC_GetCardState(hmmc); 02590 hmmc->ErrorCode = HAL_MMC_ERROR_NONE; 02591 hmmc->State = HAL_MMC_STATE_READY; 02592 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING)) 02593 { 02594 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance); 02595 02596 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE) 02597 { 02598 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 02599 hmmc->AbortCpltCallback(hmmc); 02600 #else 02601 HAL_MMC_AbortCallback(hmmc); 02602 #endif 02603 } 02604 else 02605 { 02606 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 02607 hmmc->ErrorCallback(hmmc); 02608 #else 02609 HAL_MMC_ErrorCallback(hmmc); 02610 #endif 02611 } 02612 } 02613 } 02614 } 02615 02616 /** 02617 * @brief Initializes the mmc card. 02618 * @param hmmc: Pointer to MMC handle 02619 * @retval MMC Card error state 02620 */ 02621 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc) 02622 { 02623 HAL_MMC_CardCSDTypeDef CSD; 02624 uint32_t errorstate; 02625 uint16_t mmc_rca = 1U; 02626 02627 /* Check the power State */ 02628 if(SDIO_GetPowerState(hmmc->Instance) == 0U) 02629 { 02630 /* Power off */ 02631 return HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE; 02632 } 02633 02634 /* Send CMD2 ALL_SEND_CID */ 02635 errorstate = SDMMC_CmdSendCID(hmmc->Instance); 02636 if(errorstate != HAL_MMC_ERROR_NONE) 02637 { 02638 return errorstate; 02639 } 02640 else 02641 { 02642 /* Get Card identification number data */ 02643 hmmc->CID[0U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1); 02644 hmmc->CID[1U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP2); 02645 hmmc->CID[2U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP3); 02646 hmmc->CID[3U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP4); 02647 } 02648 02649 /* Send CMD3 SET_REL_ADDR with argument 0 */ 02650 /* MMC Card publishes its RCA. */ 02651 errorstate = SDMMC_CmdSetRelAdd(hmmc->Instance, &mmc_rca); 02652 if(errorstate != HAL_MMC_ERROR_NONE) 02653 { 02654 return errorstate; 02655 } 02656 02657 /* Get the MMC card RCA */ 02658 hmmc->MmcCard.RelCardAdd = mmc_rca; 02659 02660 /* Send CMD9 SEND_CSD with argument as card's RCA */ 02661 errorstate = SDMMC_CmdSendCSD(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U)); 02662 if(errorstate != HAL_MMC_ERROR_NONE) 02663 { 02664 return errorstate; 02665 } 02666 else 02667 { 02668 /* Get Card Specific Data */ 02669 hmmc->CSD[0U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1); 02670 hmmc->CSD[1U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP2); 02671 hmmc->CSD[2U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP3); 02672 hmmc->CSD[3U] = SDIO_GetResponse(hmmc->Instance, SDIO_RESP4); 02673 } 02674 02675 /* Get the Card Class */ 02676 hmmc->MmcCard.Class = (SDIO_GetResponse(hmmc->Instance, SDIO_RESP2) >> 20U); 02677 02678 /* Get CSD parameters */ 02679 if (HAL_MMC_GetCardCSD(hmmc, &CSD) != HAL_OK) 02680 { 02681 return hmmc->ErrorCode; 02682 } 02683 02684 /* Select the Card */ 02685 errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); 02686 if(errorstate != HAL_MMC_ERROR_NONE) 02687 { 02688 return errorstate; 02689 } 02690 02691 /* Configure SDIO peripheral interface */ 02692 (void)SDIO_Init(hmmc->Instance, hmmc->Init); 02693 02694 /* All cards are initialized */ 02695 return HAL_MMC_ERROR_NONE; 02696 } 02697 02698 /** 02699 * @brief Enquires cards about their operating voltage and configures clock 02700 * controls and stores MMC information that will be needed in future 02701 * in the MMC handle. 02702 * @param hmmc: Pointer to MMC handle 02703 * @retval error state 02704 */ 02705 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc) 02706 { 02707 __IO uint32_t count = 0U; 02708 uint32_t response = 0U, validvoltage = 0U; 02709 uint32_t errorstate; 02710 02711 /* CMD0: GO_IDLE_STATE */ 02712 errorstate = SDMMC_CmdGoIdleState(hmmc->Instance); 02713 if(errorstate != HAL_MMC_ERROR_NONE) 02714 { 02715 return errorstate; 02716 } 02717 02718 while(validvoltage == 0U) 02719 { 02720 if(count++ == SDMMC_MAX_VOLT_TRIAL) 02721 { 02722 return HAL_MMC_ERROR_INVALID_VOLTRANGE; 02723 } 02724 02725 /* SEND CMD1 APP_CMD with MMC_HIGH_VOLTAGE_RANGE(0xC0FF8000) as argument */ 02726 errorstate = SDMMC_CmdOpCondition(hmmc->Instance, eMMC_HIGH_VOLTAGE_RANGE); 02727 if(errorstate != HAL_MMC_ERROR_NONE) 02728 { 02729 return HAL_MMC_ERROR_UNSUPPORTED_FEATURE; 02730 } 02731 02732 /* Get command response */ 02733 response = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1); 02734 02735 /* Get operating voltage*/ 02736 validvoltage = (((response >> 31U) == 1U) ? 1U : 0U); 02737 } 02738 02739 /* When power routine is finished and command returns valid voltage */ 02740 if (((response & (0xFF000000U)) >> 24U) == 0xC0U) 02741 { 02742 hmmc->MmcCard.CardType = MMC_HIGH_CAPACITY_CARD; 02743 } 02744 else 02745 { 02746 hmmc->MmcCard.CardType = MMC_LOW_CAPACITY_CARD; 02747 } 02748 02749 return HAL_MMC_ERROR_NONE; 02750 } 02751 02752 /** 02753 * @brief Turns the SDIO output signals off. 02754 * @param hmmc: Pointer to MMC handle 02755 * @retval None 02756 */ 02757 static void MMC_PowerOFF(MMC_HandleTypeDef *hmmc) 02758 { 02759 /* Set Power State to OFF */ 02760 (void)SDIO_PowerState_OFF(hmmc->Instance); 02761 } 02762 02763 /** 02764 * @brief Returns the current card's status. 02765 * @param hmmc: Pointer to MMC handle 02766 * @param pCardStatus: pointer to the buffer that will contain the MMC card 02767 * status (Card Status register) 02768 * @retval error state 02769 */ 02770 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus) 02771 { 02772 uint32_t errorstate; 02773 02774 if(pCardStatus == NULL) 02775 { 02776 return HAL_MMC_ERROR_PARAM; 02777 } 02778 02779 /* Send Status command */ 02780 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U)); 02781 if(errorstate != HAL_MMC_ERROR_NONE) 02782 { 02783 return errorstate; 02784 } 02785 02786 /* Get MMC card status */ 02787 *pCardStatus = SDIO_GetResponse(hmmc->Instance, SDIO_RESP1); 02788 02789 return HAL_MMC_ERROR_NONE; 02790 } 02791 02792 /** 02793 * @brief Reads extended CSD register to get the sectors number of the device 02794 * @param hmmc: Pointer to MMC handle 02795 * @param pFieldData: Pointer to the read buffer 02796 * @param FieldIndex: Index of the field to be read 02797 * @param Timeout: Specify timeout value 02798 * @retval HAL status 02799 */ 02800 static uint32_t MMC_ReadExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pFieldData, uint16_t FieldIndex, uint32_t Timeout) 02801 { 02802 SDIO_DataInitTypeDef config; 02803 uint32_t errorstate; 02804 uint32_t tickstart = HAL_GetTick(); 02805 uint32_t count; 02806 uint32_t i = 0; 02807 uint32_t tmp_data; 02808 02809 hmmc->ErrorCode = HAL_MMC_ERROR_NONE; 02810 02811 /* Initialize data control register */ 02812 hmmc->Instance->DCTRL = 0; 02813 02814 /* Configure the MMC DPSM (Data Path State Machine) */ 02815 config.DataTimeOut = SDMMC_DATATIMEOUT; 02816 config.DataLength = 512; 02817 config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B; 02818 config.TransferDir = SDIO_TRANSFER_DIR_TO_SDIO; 02819 config.TransferMode = SDIO_TRANSFER_MODE_BLOCK; 02820 config.DPSM = SDIO_DPSM_ENABLE; 02821 (void)SDIO_ConfigData(hmmc->Instance, &config); 02822 02823 /* Set Block Size for Card */ 02824 errorstate = SDMMC_CmdSendEXTCSD(hmmc->Instance, 0); 02825 if(errorstate != HAL_MMC_ERROR_NONE) 02826 { 02827 /* Clear all the static flags */ 02828 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 02829 hmmc->ErrorCode |= errorstate; 02830 hmmc->State = HAL_MMC_STATE_READY; 02831 return HAL_ERROR; 02832 } 02833 02834 /* Poll on SDMMC flags */ 02835 while(!__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DATAEND)) 02836 { 02837 if(__HAL_MMC_GET_FLAG(hmmc, SDIO_FLAG_RXFIFOHF)) 02838 { 02839 /* Read data from SDMMC Rx FIFO */ 02840 for(count = 0U; count < 8U; count++) 02841 { 02842 tmp_data = SDIO_ReadFIFO(hmmc->Instance); 02843 /* eg : SEC_COUNT : FieldIndex = 212 => i+count = 53 */ 02844 /* DEVICE_TYPE : FieldIndex = 196 => i+count = 49 */ 02845 if ((i + count) == ((uint32_t)FieldIndex/4U)) 02846 { 02847 *pFieldData = tmp_data; 02848 } 02849 } 02850 i += 8U; 02851 } 02852 02853 if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U)) 02854 { 02855 /* Clear all the static flags */ 02856 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_FLAGS); 02857 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT; 02858 hmmc->State= HAL_MMC_STATE_READY; 02859 return HAL_TIMEOUT; 02860 } 02861 } 02862 02863 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ 02864 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16)); 02865 if(errorstate != HAL_MMC_ERROR_NONE) 02866 { 02867 hmmc->ErrorCode |= errorstate; 02868 } 02869 02870 /* Clear all the static flags */ 02871 __HAL_MMC_CLEAR_FLAG(hmmc, SDIO_STATIC_DATA_FLAGS); 02872 02873 hmmc->State = HAL_MMC_STATE_READY; 02874 02875 return HAL_OK; 02876 } 02877 02878 02879 /** 02880 * @brief Wrap up reading in non-blocking mode. 02881 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains 02882 * the configuration information. 02883 * @retval None 02884 */ 02885 static void MMC_Read_IT(MMC_HandleTypeDef *hmmc) 02886 { 02887 uint32_t count, data, dataremaining; 02888 uint8_t* tmp; 02889 02890 tmp = hmmc->pRxBuffPtr; 02891 dataremaining = hmmc->RxXferSize; 02892 02893 if (dataremaining > 0U) 02894 { 02895 /* Read data from SDIO Rx FIFO */ 02896 for(count = 0U; count < 8U; count++) 02897 { 02898 data = SDIO_ReadFIFO(hmmc->Instance); 02899 *tmp = (uint8_t)(data & 0xFFU); 02900 tmp++; 02901 dataremaining--; 02902 *tmp = (uint8_t)((data >> 8U) & 0xFFU); 02903 tmp++; 02904 dataremaining--; 02905 *tmp = (uint8_t)((data >> 16U) & 0xFFU); 02906 tmp++; 02907 dataremaining--; 02908 *tmp = (uint8_t)((data >> 24U) & 0xFFU); 02909 tmp++; 02910 dataremaining--; 02911 } 02912 02913 hmmc->pRxBuffPtr = tmp; 02914 hmmc->RxXferSize = dataremaining; 02915 } 02916 } 02917 02918 /** 02919 * @brief Wrap up writing in non-blocking mode. 02920 * @param hmmc: pointer to a MMC_HandleTypeDef structure that contains 02921 * the configuration information. 02922 * @retval None 02923 */ 02924 static void MMC_Write_IT(MMC_HandleTypeDef *hmmc) 02925 { 02926 uint32_t count, data, dataremaining; 02927 uint8_t* tmp; 02928 02929 tmp = hmmc->pTxBuffPtr; 02930 dataremaining = hmmc->TxXferSize; 02931 02932 if (dataremaining > 0U) 02933 { 02934 /* Write data to SDIO Tx FIFO */ 02935 for(count = 0U; count < 8U; count++) 02936 { 02937 data = (uint32_t)(*tmp); 02938 tmp++; 02939 dataremaining--; 02940 data |= ((uint32_t)(*tmp) << 8U); 02941 tmp++; 02942 dataremaining--; 02943 data |= ((uint32_t)(*tmp) << 16U); 02944 tmp++; 02945 dataremaining--; 02946 data |= ((uint32_t)(*tmp) << 24U); 02947 tmp++; 02948 dataremaining--; 02949 (void)SDIO_WriteFIFO(hmmc->Instance, &data); 02950 } 02951 02952 hmmc->pTxBuffPtr = tmp; 02953 hmmc->TxXferSize = dataremaining; 02954 } 02955 } 02956 02957 /** 02958 * @} 02959 */ 02960 02961 #endif /* SDIO */ 02962 02963 #endif /* HAL_MMC_MODULE_ENABLED */ 02964 02965 /** 02966 * @} 02967 */ 02968 02969 /** 02970 * @} 02971 */ 02972 02973 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/