STM32L443xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l4xx_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 ****************************************************************************** 00014 * @attention 00015 * 00016 * Copyright (c) 2017 STMicroelectronics. 00017 * All rights reserved. 00018 * 00019 * This software is licensed under terms that can be found in the LICENSE file 00020 * in the root directory of this software component. 00021 * If no LICENSE file comes with this software, it is provided AS-IS. 00022 * 00023 ****************************************************************************** 00024 @verbatim 00025 ============================================================================== 00026 ##### How to use this driver ##### 00027 ============================================================================== 00028 [..] 00029 This driver implements a high level communication layer for read and write from/to 00030 this memory. The needed STM32 hardware resources (SDMMC and GPIO) are performed by 00031 the user in HAL_MMC_MspInit() function (MSP layer). 00032 Basically, the MSP layer configuration should be the same as we provide in the 00033 examples. 00034 You can easily tailor this configuration according to hardware resources. 00035 00036 [..] 00037 This driver is a generic layered driver for SDMMC memories which uses the HAL 00038 SDMMC driver functions to interface with MMC and eMMC cards devices. 00039 It is used as follows: 00040 00041 (#)Initialize the SDMMC low level resources by implement the HAL_MMC_MspInit() API: 00042 (##) Enable the SDMMC interface clock using __HAL_RCC_SDMMC_CLK_ENABLE(); 00043 (##) SDMMC pins configuration for MMC card 00044 (+++) Enable the clock for the SDMMC GPIOs using the functions __HAL_RCC_GPIOx_CLK_ENABLE(); 00045 (+++) Configure these SDMMC pins as alternate function pull-up using HAL_GPIO_Init() 00046 and according to your pin assignment; 00047 (##) On STM32L4Rx/STM32L4Sxx devices, no DMA configuration is need, an internal DMA for SDMMC Peripheral is used. 00048 (##) On other devices, perform DMA Configuration if you need to use DMA process (HAL_MMC_ReadBlocks_DMA() 00049 and HAL_MMC_WriteBlocks_DMA() APIs). 00050 (+++) Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE(); 00051 (+++) Configure the DMA using the function HAL_DMA_Init() with predeclared and filled. 00052 (##) NVIC configuration if you need to use interrupt process when using DMA transfer. 00053 (+++) Configure the SDMMC and DMA interrupt priorities using function HAL_NVIC_SetPriority(); 00054 DMA priority is superior to SDMMC's priority 00055 (+++) Enable the NVIC DMA and SDMMC IRQs using function HAL_NVIC_EnableIRQ() 00056 (+++) SDMMC interrupts are managed using the macros __HAL_MMC_ENABLE_IT() 00057 and __HAL_MMC_DISABLE_IT() inside the communication process. 00058 (+++) SDMMC interrupts pending bits are managed using the macros __HAL_MMC_GET_IT() 00059 and __HAL_MMC_CLEAR_IT() 00060 (##) NVIC configuration if you need to use interrupt process (HAL_MMC_ReadBlocks_IT() 00061 and HAL_MMC_WriteBlocks_IT() APIs). 00062 (+++) Configure the SDMMC interrupt priorities using function HAL_NVIC_SetPriority(); 00063 (+++) Enable the NVIC SDMMC IRQs using function HAL_NVIC_EnableIRQ() 00064 (+++) SDMMC interrupts are managed using the macros __HAL_MMC_ENABLE_IT() 00065 and __HAL_MMC_DISABLE_IT() inside the communication process. 00066 (+++) SDMMC interrupts pending bits are managed using the macros __HAL_MMC_GET_IT() 00067 and __HAL_MMC_CLEAR_IT() 00068 (#) At this stage, you can perform MMC read/write/erase operations after MMC card initialization 00069 00070 00071 *** MMC Card Initialization and configuration *** 00072 ================================================ 00073 [..] 00074 To initialize the MMC Card, use the HAL_MMC_Init() function. It Initializes 00075 SDMMC Peripheral (STM32 side) and the MMC Card, and put it into StandBy State (Ready for data transfer). 00076 This function provide the following operations: 00077 00078 (#) Initialize the SDMMC peripheral interface with defaullt configuration. 00079 The initialization process is done at 400KHz. You can change or adapt 00080 this frequency by adjusting the "ClockDiv" field. 00081 The MMC Card frequency (SDMMC_CK) is computed as follows: 00082 00083 SDMMC_CK = SDMMCCLK / (2 * ClockDiv) on STM32L4Rx/STM32L4Sxx devices 00084 SDMMC_CK = SDMMCCLK / (ClockDiv + 2) on other devices 00085 00086 In initialization mode and according to the MMC Card standard, 00087 make sure that the SDMMC_CK frequency doesn't exceed 400KHz. 00088 00089 This phase of initialization is done through SDMMC_Init() and 00090 SDMMC_PowerState_ON() SDMMC low level APIs. 00091 00092 (#) Initialize the MMC card. The API used is HAL_MMC_InitCard(). 00093 This phase allows the card initialization and identification 00094 and check the MMC Card type (Standard Capacity or High Capacity) 00095 The initialization flow is compatible with MMC standard. 00096 00097 This API (HAL_MMC_InitCard()) could be used also to reinitialize the card in case 00098 of plug-off plug-in. 00099 00100 (#) Configure the MMC Card Data transfer frequency. By Default, the card transfer 00101 frequency by adjusting the "ClockDiv" field. 00102 In transfer mode and according to the MMC Card standard, make sure that the 00103 SDMMC_CK frequency doesn't exceed 25MHz and 100MHz in High-speed mode switch. 00104 00105 (#) Select the corresponding MMC Card according to the address read with the step 2. 00106 00107 (#) Configure the MMC Card in wide bus mode: 4-bits data. 00108 00109 *** MMC Card Read operation *** 00110 ============================== 00111 [..] 00112 (+) You can read from MMC card in polling mode by using function HAL_MMC_ReadBlocks(). 00113 This function support only 512-bytes block length (the block size should be 00114 chosen as 512 bytes). 00115 You can choose either one block read operation or multiple block read operation 00116 by adjusting the "NumberOfBlocks" parameter. 00117 After this, you have to ensure that the transfer is done correctly. The check is done 00118 through HAL_MMC_GetCardState() function for MMC card state. 00119 00120 (+) You can read from MMC card in DMA mode by using function HAL_MMC_ReadBlocks_DMA(). 00121 This function support only 512-bytes block length (the block size should be 00122 chosen as 512 bytes). 00123 You can choose either one block read operation or multiple block read operation 00124 by adjusting the "NumberOfBlocks" parameter. 00125 After this, you have to ensure that the transfer is done correctly. The check is done 00126 through HAL_MMC_GetCardState() function for MMC card state. 00127 You could also check the DMA transfer process through the MMC Rx interrupt event. 00128 00129 (+) You can read from MMC card in Interrupt mode by using function HAL_MMC_ReadBlocks_IT(). 00130 This function allows the read of 512 bytes blocks. 00131 You can choose either one block read operation or multiple block read operation 00132 by adjusting the "NumberOfBlocks" parameter. 00133 After this, you have to ensure that the transfer is done correctly. The check is done 00134 through HAL_MMC_GetCardState() function for MMC card state. 00135 You could also check the IT transfer process through the MMC Rx interrupt event. 00136 00137 *** MMC Card Write operation *** 00138 =============================== 00139 [..] 00140 (+) You can write to MMC card in polling mode by using function HAL_MMC_WriteBlocks(). 00141 This function support only 512-bytes block length (the block size should be 00142 chosen as 512 bytes). 00143 You can choose either one block read operation or multiple block read operation 00144 by adjusting the "NumberOfBlocks" parameter. 00145 After this, you have to ensure that the transfer is done correctly. The check is done 00146 through HAL_MMC_GetCardState() function for MMC card state. 00147 00148 (+) You can write to MMC card in DMA mode by using function HAL_MMC_WriteBlocks_DMA(). 00149 This function support only 512-bytes block length (the block size should be 00150 chosen as 512 byte). 00151 You can choose either one block read operation or multiple block read operation 00152 by adjusting the "NumberOfBlocks" parameter. 00153 After this, you have to ensure that the transfer is done correctly. The check is done 00154 through HAL_MMC_GetCardState() function for MMC card state. 00155 You could also check the DMA transfer process through the MMC Tx interrupt event. 00156 00157 (+) You can write to MMC card in Interrupt mode by using function HAL_MMC_WriteBlocks_IT(). 00158 This function allows the read of 512 bytes blocks. 00159 You can choose either one block read operation or multiple block read operation 00160 by adjusting the "NumberOfBlocks" parameter. 00161 After this, you have to ensure that the transfer is done correctly. The check is done 00162 through HAL_MMC_GetCardState() function for MMC card state. 00163 You could also check the IT transfer process through the MMC Tx interrupt event. 00164 00165 *** MMC card information *** 00166 =========================== 00167 [..] 00168 (+) To get MMC card information, you can use the function HAL_MMC_GetCardInfo(). 00169 It returns useful information about the MMC card such as block size, card type, 00170 block number ... 00171 00172 *** MMC card CSD register *** 00173 ============================ 00174 [..] 00175 (+) The HAL_MMC_GetCardCSD() API allows to get the parameters of the CSD register. 00176 Some of the CSD parameters are useful for card initialization and identification. 00177 00178 *** MMC card CID register *** 00179 ============================ 00180 [..] 00181 (+) The HAL_MMC_GetCardCID() API allows to get the parameters of the CID register. 00182 Some of the CID parameters are useful for card initialization and identification. 00183 00184 *** MMC HAL driver macros list *** 00185 ================================== 00186 [..] 00187 Below the list of most used macros in MMC HAL driver. 00188 00189 (+) __HAL_MMC_ENABLE : Enable the MMC device 00190 (+) __HAL_MMC_DISABLE : Disable the MMC device 00191 (+) __HAL_MMC_DMA_ENABLE: Enable the SDMMC DMA transfer 00192 (+) __HAL_MMC_DMA_DISABLE: Disable the SDMMC DMA transfer 00193 (+) __HAL_MMC_ENABLE_IT: Enable the MMC device interrupt 00194 (+) __HAL_MMC_DISABLE_IT: Disable the MMC device interrupt 00195 (+) __HAL_MMC_GET_FLAG:Check whether the specified MMC flag is set or not 00196 (+) __HAL_MMC_CLEAR_FLAG: Clear the MMC's pending flags 00197 00198 [..] 00199 (@) You can refer to the MMC HAL driver header file for more useful macros 00200 00201 *** Callback registration *** 00202 ============================================= 00203 [..] 00204 The compilation define USE_HAL_MMC_REGISTER_CALLBACKS when set to 1 00205 allows the user to configure dynamically the driver callbacks. 00206 00207 Use Functions HAL_MMC_RegisterCallback() to register a user callback, 00208 it allows to register following callbacks: 00209 (+) TxCpltCallback : callback when a transmission transfer is completed. 00210 (+) RxCpltCallback : callback when a reception transfer is completed. 00211 (+) ErrorCallback : callback when error occurs. 00212 (+) AbortCpltCallback : callback when abort is completed. 00213 (+) Read_DMADblBuf0CpltCallback : callback when the DMA reception of first buffer is completed. 00214 (+) Read_DMADblBuf1CpltCallback : callback when the DMA reception of second buffer is completed. 00215 (+) Write_DMADblBuf0CpltCallback : callback when the DMA transmission of first buffer is completed. 00216 (+) Write_DMADblBuf1CpltCallback : callback when the DMA transmission of second buffer is completed. 00217 (+) MspInitCallback : MMC MspInit. 00218 (+) MspDeInitCallback : MMC MspDeInit. 00219 This function takes as parameters the HAL peripheral handle, the Callback ID 00220 and a pointer to the user callback function. 00221 00222 Use function HAL_MMC_UnRegisterCallback() to reset a callback to the default 00223 weak (surcharged) function. It allows to reset following callbacks: 00224 (+) TxCpltCallback : callback when a transmission transfer is completed. 00225 (+) RxCpltCallback : callback when a reception transfer is completed. 00226 (+) ErrorCallback : callback when error occurs. 00227 (+) AbortCpltCallback : callback when abort is completed. 00228 (+) Read_DMADblBuf0CpltCallback : callback when the DMA reception of first buffer is completed. 00229 (+) Read_DMADblBuf1CpltCallback : callback when the DMA reception of second buffer is completed. 00230 (+) Write_DMADblBuf0CpltCallback : callback when the DMA transmission of first buffer is completed. 00231 (+) Write_DMADblBuf1CpltCallback : callback when the DMA transmission of second buffer is completed. 00232 (+) MspInitCallback : MMC MspInit. 00233 (+) MspDeInitCallback : MMC MspDeInit. 00234 This function) takes as parameters the HAL peripheral handle and the Callback ID. 00235 00236 By default, after the HAL_MMC_Init and if the state is HAL_MMC_STATE_RESET 00237 all callbacks are reset to the corresponding legacy weak (surcharged) functions. 00238 Exception done for MspInit and MspDeInit callbacks that are respectively 00239 reset to the legacy weak (surcharged) functions in the HAL_MMC_Init 00240 and HAL_MMC_DeInit only when these callbacks are null (not registered beforehand). 00241 If not, MspInit or MspDeInit are not null, the HAL_MMC_Init and HAL_MMC_DeInit 00242 keep and use the user MspInit/MspDeInit callbacks (registered beforehand) 00243 00244 Callbacks can be registered/unregistered in READY state only. 00245 Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered 00246 in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used 00247 during the Init/DeInit. 00248 In that case first register the MspInit/MspDeInit user callbacks 00249 using HAL_MMC_RegisterCallback before calling HAL_MMC_DeInit 00250 or HAL_MMC_Init function. 00251 00252 When The compilation define USE_HAL_MMC_REGISTER_CALLBACKS is set to 0 or 00253 not defined, the callback registering feature is not available 00254 and weak (surcharged) callbacks are used. 00255 00256 @endverbatim 00257 ****************************************************************************** 00258 */ 00259 00260 /* Includes ------------------------------------------------------------------*/ 00261 #include "stm32l4xx_hal.h" 00262 00263 #ifdef HAL_MMC_MODULE_ENABLED 00264 00265 #if defined(SDMMC1) 00266 00267 /** @addtogroup STM32L4xx_HAL_Driver 00268 * @{ 00269 */ 00270 00271 /** @defgroup MMC MMC 00272 * @{ 00273 */ 00274 00275 /* Private typedef -----------------------------------------------------------*/ 00276 /* Private define ------------------------------------------------------------*/ 00277 /** @addtogroup MMC_Private_Defines 00278 * @{ 00279 */ 00280 #if defined (VDD_VALUE) && (VDD_VALUE <= 1950U) 00281 #define MMC_VOLTAGE_RANGE EMMC_LOW_VOLTAGE_RANGE 00282 00283 #define MMC_EXT_CSD_PWR_CL_26_INDEX 201 00284 #define MMC_EXT_CSD_PWR_CL_52_INDEX 200 00285 #define MMC_EXT_CSD_PWR_CL_DDR_52_INDEX 238 00286 00287 #define MMC_EXT_CSD_PWR_CL_26_POS 8 00288 #define MMC_EXT_CSD_PWR_CL_52_POS 0 00289 #define MMC_EXT_CSD_PWR_CL_DDR_52_POS 16 00290 #else 00291 #define MMC_VOLTAGE_RANGE EMMC_HIGH_VOLTAGE_RANGE 00292 00293 #define MMC_EXT_CSD_PWR_CL_26_INDEX 203 00294 #define MMC_EXT_CSD_PWR_CL_52_INDEX 202 00295 #define MMC_EXT_CSD_PWR_CL_DDR_52_INDEX 239 00296 00297 #define MMC_EXT_CSD_PWR_CL_26_POS 24 00298 #define MMC_EXT_CSD_PWR_CL_52_POS 16 00299 #define MMC_EXT_CSD_PWR_CL_DDR_52_POS 24 00300 #endif 00301 00302 #define MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_INDEX 216 00303 #define MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_POS 0 00304 #define MMC_EXT_CSD_S_A_TIMEOUT_INDEX 217 00305 #define MMC_EXT_CSD_S_A_TIMEOUT_POS 8 00306 00307 /* Frequencies used in the driver for clock divider calculation */ 00308 #define MMC_INIT_FREQ 400000U /* Initalization phase : 400 kHz max */ 00309 #define MMC_HIGH_SPEED_FREQ 52000000U /* High speed phase : 52 MHz max */ 00310 /** 00311 * @} 00312 */ 00313 00314 /* Private macro -------------------------------------------------------------*/ 00315 /* Private variables ---------------------------------------------------------*/ 00316 /* Private function prototypes -----------------------------------------------*/ 00317 /* Private functions ---------------------------------------------------------*/ 00318 /** @defgroup MMC_Private_Functions MMC Private Functions 00319 * @{ 00320 */ 00321 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc); 00322 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc); 00323 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus); 00324 static void MMC_PowerOFF(MMC_HandleTypeDef *hmmc); 00325 static void MMC_Write_IT(MMC_HandleTypeDef *hmmc); 00326 static void MMC_Read_IT(MMC_HandleTypeDef *hmmc); 00327 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 00328 static void MMC_DMATransmitCplt(DMA_HandleTypeDef *hdma); 00329 static void MMC_DMAReceiveCplt(DMA_HandleTypeDef *hdma); 00330 static void MMC_DMAError(DMA_HandleTypeDef *hdma); 00331 static void MMC_DMATxAbort(DMA_HandleTypeDef *hdma); 00332 static void MMC_DMARxAbort(DMA_HandleTypeDef *hdma); 00333 #else 00334 static uint32_t MMC_HighSpeed(MMC_HandleTypeDef *hmmc, FunctionalState state); 00335 static uint32_t MMC_DDR_Mode(MMC_HandleTypeDef *hmmc, FunctionalState state); 00336 #endif 00337 static HAL_StatusTypeDef MMC_ReadExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pFieldData, uint16_t FieldIndex, uint32_t Timeout); 00338 static uint32_t MMC_PwrClassUpdate(MMC_HandleTypeDef *hmmc, uint32_t Wide, uint32_t Speed); 00339 00340 /** 00341 * @} 00342 */ 00343 /* Exported functions --------------------------------------------------------*/ 00344 /** @defgroup MMC_Exported_Functions MMC Exported Functions 00345 * @{ 00346 */ 00347 00348 /** @defgroup MMC_Exported_Functions_Group1 MMC_Exported_Functions_Group1 00349 * @brief Initialization and de-initialization functions 00350 * 00351 @verbatim 00352 ============================================================================== 00353 ##### Initialization and de-initialization functions ##### 00354 ============================================================================== 00355 [..] 00356 This section provides functions allowing to initialize/de-initialize the MMC 00357 card device to be ready for use. 00358 00359 @endverbatim 00360 * @{ 00361 */ 00362 00363 /** 00364 * @brief Initializes the MMC according to the specified parameters in the 00365 MMC_HandleTypeDef and create the associated handle. 00366 * @param hmmc Pointer to the MMC handle 00367 * @retval HAL status 00368 */ 00369 HAL_StatusTypeDef HAL_MMC_Init(MMC_HandleTypeDef *hmmc) 00370 { 00371 /* Check the MMC handle allocation */ 00372 if(hmmc == NULL) 00373 { 00374 return HAL_ERROR; 00375 } 00376 00377 /* Check the parameters */ 00378 assert_param(IS_SDMMC_ALL_INSTANCE(hmmc->Instance)); 00379 assert_param(IS_SDMMC_CLOCK_EDGE(hmmc->Init.ClockEdge)); 00380 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 00381 assert_param(IS_SDMMC_CLOCK_BYPASS(hmmc->Init.ClockBypass)); 00382 #endif 00383 assert_param(IS_SDMMC_CLOCK_POWER_SAVE(hmmc->Init.ClockPowerSave)); 00384 assert_param(IS_SDMMC_BUS_WIDE(hmmc->Init.BusWide)); 00385 assert_param(IS_SDMMC_HARDWARE_FLOW_CONTROL(hmmc->Init.HardwareFlowControl)); 00386 assert_param(IS_SDMMC_CLKDIV(hmmc->Init.ClockDiv)); 00387 00388 if(hmmc->State == HAL_MMC_STATE_RESET) 00389 { 00390 /* Allocate lock resource and initialize it */ 00391 hmmc->Lock = HAL_UNLOCKED; 00392 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 00393 /* Reset Callback pointers in HAL_MMC_STATE_RESET only */ 00394 hmmc->TxCpltCallback = HAL_MMC_TxCpltCallback; 00395 hmmc->RxCpltCallback = HAL_MMC_RxCpltCallback; 00396 hmmc->ErrorCallback = HAL_MMC_ErrorCallback; 00397 hmmc->AbortCpltCallback = HAL_MMC_AbortCallback; 00398 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 00399 hmmc->Read_DMADblBuf0CpltCallback = HAL_MMCEx_Read_DMADoubleBuffer0CpltCallback; 00400 hmmc->Read_DMADblBuf1CpltCallback = HAL_MMCEx_Read_DMADoubleBuffer1CpltCallback; 00401 hmmc->Write_DMADblBuf0CpltCallback = HAL_MMCEx_Write_DMADoubleBuffer0CpltCallback; 00402 hmmc->Write_DMADblBuf1CpltCallback = HAL_MMCEx_Write_DMADoubleBuffer1CpltCallback; 00403 #endif 00404 00405 if(hmmc->MspInitCallback == NULL) 00406 { 00407 hmmc->MspInitCallback = HAL_MMC_MspInit; 00408 } 00409 00410 /* Init the low level hardware */ 00411 hmmc->MspInitCallback(hmmc); 00412 #else 00413 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */ 00414 HAL_MMC_MspInit(hmmc); 00415 #endif 00416 } 00417 00418 hmmc->State = HAL_MMC_STATE_BUSY; 00419 00420 /* Initialize the Card parameters */ 00421 if(HAL_MMC_InitCard(hmmc) == HAL_ERROR) 00422 { 00423 return HAL_ERROR; 00424 } 00425 00426 /* Initialize the error code */ 00427 hmmc->ErrorCode = HAL_DMA_ERROR_NONE; 00428 00429 /* Initialize the MMC operation */ 00430 hmmc->Context = MMC_CONTEXT_NONE; 00431 00432 /* Initialize the MMC state */ 00433 hmmc->State = HAL_MMC_STATE_READY; 00434 00435 /* Configure bus width */ 00436 if (hmmc->Init.BusWide != SDMMC_BUS_WIDE_1B) 00437 { 00438 if (HAL_MMC_ConfigWideBusOperation(hmmc, hmmc->Init.BusWide) != HAL_OK) 00439 { 00440 return HAL_ERROR; 00441 } 00442 } 00443 00444 return HAL_OK; 00445 } 00446 00447 /** 00448 * @brief Initializes the MMC Card. 00449 * @param hmmc Pointer to MMC handle 00450 * @note This function initializes the MMC card. It could be used when a card 00451 re-initialization is needed. 00452 * @retval HAL status 00453 */ 00454 HAL_StatusTypeDef HAL_MMC_InitCard(MMC_HandleTypeDef *hmmc) 00455 { 00456 uint32_t errorstate; 00457 MMC_InitTypeDef Init; 00458 uint32_t sdmmc_clk; 00459 00460 /* Default SDMMC peripheral configuration for MMC card initialization */ 00461 Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING; 00462 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 00463 Init.ClockBypass = SDMMC_CLOCK_BYPASS_DISABLE; 00464 #endif 00465 Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE; 00466 Init.BusWide = SDMMC_BUS_WIDE_1B; 00467 Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE; 00468 00469 /* Init Clock should be less or equal to 400Khz*/ 00470 sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC1); 00471 if (sdmmc_clk == 0U) 00472 { 00473 hmmc->State = HAL_MMC_STATE_READY; 00474 hmmc->ErrorCode = SDMMC_ERROR_INVALID_PARAMETER; 00475 return HAL_ERROR; 00476 } 00477 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 00478 Init.ClockDiv = ((sdmmc_clk/MMC_INIT_FREQ) - 2U); 00479 #else 00480 Init.ClockDiv = sdmmc_clk/(2U*MMC_INIT_FREQ); 00481 Init.Transceiver = SDMMC_TRANSCEIVER_DISABLE; 00482 #endif 00483 00484 /* Initialize SDMMC peripheral interface with default configuration */ 00485 (void)SDMMC_Init(hmmc->Instance, Init); 00486 00487 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 00488 /* Disable SDMMC Clock */ 00489 __HAL_MMC_DISABLE(hmmc); 00490 #endif 00491 00492 /* Set Power State to ON */ 00493 (void)SDMMC_PowerState_ON(hmmc->Instance); 00494 00495 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 00496 /* Enable MMC Clock */ 00497 __HAL_MMC_ENABLE(hmmc); 00498 #endif 00499 00500 /* wait 74 Cycles: required power up waiting time before starting 00501 the MMC initialization sequence */ 00502 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 00503 sdmmc_clk = sdmmc_clk/(Init.ClockDiv + 2U); 00504 #else 00505 sdmmc_clk = sdmmc_clk/(2U*Init.ClockDiv); 00506 #endif 00507 HAL_Delay(1U+ (74U*1000U/(sdmmc_clk))); 00508 00509 /* Identify card operating voltage */ 00510 errorstate = MMC_PowerON(hmmc); 00511 if(errorstate != HAL_MMC_ERROR_NONE) 00512 { 00513 hmmc->State = HAL_MMC_STATE_READY; 00514 hmmc->ErrorCode |= errorstate; 00515 return HAL_ERROR; 00516 } 00517 00518 /* Card initialization */ 00519 errorstate = MMC_InitCard(hmmc); 00520 if(errorstate != HAL_MMC_ERROR_NONE) 00521 { 00522 hmmc->State = HAL_MMC_STATE_READY; 00523 hmmc->ErrorCode |= errorstate; 00524 return HAL_ERROR; 00525 } 00526 00527 /* Set Block Size for Card */ 00528 errorstate = SDMMC_CmdBlockLength(hmmc->Instance, MMC_BLOCKSIZE); 00529 if(errorstate != HAL_MMC_ERROR_NONE) 00530 { 00531 /* Clear all the static flags */ 00532 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 00533 hmmc->ErrorCode |= errorstate; 00534 hmmc->State = HAL_MMC_STATE_READY; 00535 return HAL_ERROR; 00536 } 00537 00538 return HAL_OK; 00539 } 00540 00541 /** 00542 * @brief De-Initializes the MMC card. 00543 * @param hmmc Pointer to MMC handle 00544 * @retval HAL status 00545 */ 00546 HAL_StatusTypeDef HAL_MMC_DeInit(MMC_HandleTypeDef *hmmc) 00547 { 00548 /* Check the MMC handle allocation */ 00549 if(hmmc == NULL) 00550 { 00551 return HAL_ERROR; 00552 } 00553 00554 /* Check the parameters */ 00555 assert_param(IS_SDMMC_ALL_INSTANCE(hmmc->Instance)); 00556 00557 hmmc->State = HAL_MMC_STATE_BUSY; 00558 00559 /* Set MMC power state to off */ 00560 MMC_PowerOFF(hmmc); 00561 00562 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 00563 if(hmmc->MspDeInitCallback == NULL) 00564 { 00565 hmmc->MspDeInitCallback = HAL_MMC_MspDeInit; 00566 } 00567 00568 /* DeInit the low level hardware */ 00569 hmmc->MspDeInitCallback(hmmc); 00570 #else 00571 /* De-Initialize the MSP layer */ 00572 HAL_MMC_MspDeInit(hmmc); 00573 #endif 00574 00575 hmmc->ErrorCode = HAL_MMC_ERROR_NONE; 00576 hmmc->State = HAL_MMC_STATE_RESET; 00577 00578 return HAL_OK; 00579 } 00580 00581 00582 /** 00583 * @brief Initializes the MMC MSP. 00584 * @param hmmc Pointer to MMC handle 00585 * @retval None 00586 */ 00587 __weak void HAL_MMC_MspInit(MMC_HandleTypeDef *hmmc) 00588 { 00589 /* Prevent unused argument(s) compilation warning */ 00590 UNUSED(hmmc); 00591 00592 /* NOTE : This function Should not be modified, when the callback is needed, 00593 the HAL_MMC_MspInit could be implemented in the user file 00594 */ 00595 } 00596 00597 /** 00598 * @brief De-Initialize MMC MSP. 00599 * @param hmmc Pointer to MMC handle 00600 * @retval None 00601 */ 00602 __weak void HAL_MMC_MspDeInit(MMC_HandleTypeDef *hmmc) 00603 { 00604 /* Prevent unused argument(s) compilation warning */ 00605 UNUSED(hmmc); 00606 00607 /* NOTE : This function Should not be modified, when the callback is needed, 00608 the HAL_MMC_MspDeInit could be implemented in the user file 00609 */ 00610 } 00611 00612 /** 00613 * @} 00614 */ 00615 00616 /** @addtogroup MMC_Exported_Functions_Group2 00617 * @brief Data transfer functions 00618 * 00619 @verbatim 00620 ============================================================================== 00621 ##### IO operation functions ##### 00622 ============================================================================== 00623 [..] 00624 This subsection provides a set of functions allowing to manage the data 00625 transfer from/to MMC card. 00626 00627 @endverbatim 00628 * @{ 00629 */ 00630 00631 /** 00632 * @brief Reads block(s) from a specified address in a card. The Data transfer 00633 * is managed by polling mode. 00634 * @note This API should be followed by a check on the card state through 00635 * HAL_MMC_GetCardState(). 00636 * @param hmmc Pointer to MMC handle 00637 * @param pData pointer to the buffer that will contain the received data 00638 * @param BlockAdd Block Address from where data is to be read 00639 * @param NumberOfBlocks Number of MMC blocks to read 00640 * @param Timeout Specify timeout value 00641 * @retval HAL status 00642 */ 00643 HAL_StatusTypeDef HAL_MMC_ReadBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout) 00644 { 00645 SDMMC_DataInitTypeDef config; 00646 uint32_t errorstate; 00647 uint32_t tickstart = HAL_GetTick(); 00648 uint32_t count, data, dataremaining; 00649 uint32_t add = BlockAdd; 00650 uint8_t *tempbuff = pData; 00651 00652 if(NULL == pData) 00653 { 00654 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; 00655 return HAL_ERROR; 00656 } 00657 00658 if(hmmc->State == HAL_MMC_STATE_READY) 00659 { 00660 hmmc->ErrorCode = HAL_MMC_ERROR_NONE; 00661 00662 if((add + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr)) 00663 { 00664 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; 00665 return HAL_ERROR; 00666 } 00667 00668 hmmc->State = HAL_MMC_STATE_BUSY; 00669 00670 /* Initialize data control register */ 00671 hmmc->Instance->DCTRL = 0U; 00672 00673 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD) 00674 { 00675 add *= 512U; 00676 } 00677 00678 /* Configure the MMC DPSM (Data Path State Machine) */ 00679 config.DataTimeOut = SDMMC_DATATIMEOUT; 00680 config.DataLength = NumberOfBlocks * MMC_BLOCKSIZE; 00681 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; 00682 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; 00683 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; 00684 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 00685 config.DPSM = SDMMC_DPSM_ENABLE; 00686 #else 00687 config.DPSM = SDMMC_DPSM_DISABLE; 00688 #endif 00689 (void)SDMMC_ConfigData(hmmc->Instance, &config); 00690 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 00691 __SDMMC_CMDTRANS_ENABLE( hmmc->Instance); 00692 #endif 00693 00694 /* Read block(s) in polling mode */ 00695 if(NumberOfBlocks > 1U) 00696 { 00697 hmmc->Context = MMC_CONTEXT_READ_MULTIPLE_BLOCK; 00698 00699 /* Read Multi Block command */ 00700 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add); 00701 } 00702 else 00703 { 00704 hmmc->Context = MMC_CONTEXT_READ_SINGLE_BLOCK; 00705 00706 /* Read Single Block command */ 00707 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add); 00708 } 00709 if(errorstate != HAL_MMC_ERROR_NONE) 00710 { 00711 /* Clear all the static flags */ 00712 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 00713 hmmc->ErrorCode |= errorstate; 00714 hmmc->State = HAL_MMC_STATE_READY; 00715 hmmc->Context = MMC_CONTEXT_NONE; 00716 return HAL_ERROR; 00717 } 00718 00719 /* Poll on SDMMC flags */ 00720 dataremaining = config.DataLength; 00721 while(!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND)) 00722 { 00723 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) && (dataremaining > 0U)) 00724 { 00725 /* Read data from SDMMC Rx FIFO */ 00726 for(count = 0U; count < 8U; count++) 00727 { 00728 data = SDMMC_ReadFIFO(hmmc->Instance); 00729 *tempbuff = (uint8_t)(data & 0xFFU); 00730 tempbuff++; 00731 dataremaining--; 00732 *tempbuff = (uint8_t)((data >> 8U) & 0xFFU); 00733 tempbuff++; 00734 dataremaining--; 00735 *tempbuff = (uint8_t)((data >> 16U) & 0xFFU); 00736 tempbuff++; 00737 dataremaining--; 00738 *tempbuff = (uint8_t)((data >> 24U) & 0xFFU); 00739 tempbuff++; 00740 dataremaining--; 00741 } 00742 } 00743 00744 if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U)) 00745 { 00746 /* Clear all the static flags */ 00747 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 00748 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT; 00749 hmmc->State= HAL_MMC_STATE_READY; 00750 hmmc->Context = MMC_CONTEXT_NONE; 00751 return HAL_TIMEOUT; 00752 } 00753 } 00754 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 00755 __SDMMC_CMDTRANS_DISABLE( hmmc->Instance); 00756 #endif 00757 00758 /* Send stop transmission command in case of multiblock read */ 00759 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U)) 00760 { 00761 /* Send stop transmission command */ 00762 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance); 00763 if(errorstate != HAL_MMC_ERROR_NONE) 00764 { 00765 /* Clear all the static flags */ 00766 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 00767 hmmc->ErrorCode |= errorstate; 00768 hmmc->State = HAL_MMC_STATE_READY; 00769 hmmc->Context = MMC_CONTEXT_NONE; 00770 return HAL_ERROR; 00771 } 00772 } 00773 00774 /* Get error state */ 00775 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT)) 00776 { 00777 /* Clear all the static flags */ 00778 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 00779 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT; 00780 hmmc->State = HAL_MMC_STATE_READY; 00781 hmmc->Context = MMC_CONTEXT_NONE; 00782 return HAL_ERROR; 00783 } 00784 else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL)) 00785 { 00786 /* Clear all the static flags */ 00787 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 00788 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL; 00789 hmmc->State = HAL_MMC_STATE_READY; 00790 hmmc->Context = MMC_CONTEXT_NONE; 00791 return HAL_ERROR; 00792 } 00793 else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR)) 00794 { 00795 /* Clear all the static flags */ 00796 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 00797 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN; 00798 hmmc->State = HAL_MMC_STATE_READY; 00799 hmmc->Context = MMC_CONTEXT_NONE; 00800 return HAL_ERROR; 00801 } 00802 else 00803 { 00804 /* Nothing to do */ 00805 } 00806 00807 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 00808 /* Empty FIFO if there is still any data */ 00809 while ((__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXDAVL)) && (dataremaining > 0U)) 00810 { 00811 data = SDMMC_ReadFIFO(hmmc->Instance); 00812 *tempbuff = (uint8_t)(data & 0xFFU); 00813 tempbuff++; 00814 dataremaining--; 00815 *tempbuff = (uint8_t)((data >> 8U) & 0xFFU); 00816 tempbuff++; 00817 dataremaining--; 00818 *tempbuff = (uint8_t)((data >> 16U) & 0xFFU); 00819 tempbuff++; 00820 dataremaining--; 00821 *tempbuff = (uint8_t)((data >> 24U) & 0xFFU); 00822 tempbuff++; 00823 dataremaining--; 00824 00825 if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U)) 00826 { 00827 /* Clear all the static flags */ 00828 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 00829 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT; 00830 hmmc->State= HAL_MMC_STATE_READY; 00831 hmmc->Context = MMC_CONTEXT_NONE; 00832 return HAL_ERROR; 00833 } 00834 } 00835 #endif 00836 00837 /* Clear all the static flags */ 00838 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS); 00839 00840 hmmc->State = HAL_MMC_STATE_READY; 00841 00842 return HAL_OK; 00843 } 00844 else 00845 { 00846 hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY; 00847 return HAL_ERROR; 00848 } 00849 } 00850 00851 /** 00852 * @brief Allows to write block(s) to a specified address in a card. The Data 00853 * transfer is managed by polling mode. 00854 * @note This API should be followed by a check on the card state through 00855 * HAL_MMC_GetCardState(). 00856 * @param hmmc Pointer to MMC handle 00857 * @param pData pointer to the buffer that will contain the data to transmit 00858 * @param BlockAdd Block Address where data will be written 00859 * @param NumberOfBlocks Number of MMC blocks to write 00860 * @param Timeout Specify timeout value 00861 * @retval HAL status 00862 */ 00863 HAL_StatusTypeDef HAL_MMC_WriteBlocks(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout) 00864 { 00865 SDMMC_DataInitTypeDef config; 00866 uint32_t errorstate; 00867 uint32_t tickstart = HAL_GetTick(); 00868 uint32_t count, data, dataremaining; 00869 uint32_t add = BlockAdd; 00870 uint8_t *tempbuff = pData; 00871 00872 if(NULL == pData) 00873 { 00874 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; 00875 return HAL_ERROR; 00876 } 00877 00878 if(hmmc->State == HAL_MMC_STATE_READY) 00879 { 00880 hmmc->ErrorCode = HAL_MMC_ERROR_NONE; 00881 00882 if((add + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr)) 00883 { 00884 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; 00885 return HAL_ERROR; 00886 } 00887 00888 hmmc->State = HAL_MMC_STATE_BUSY; 00889 00890 /* Initialize data control register */ 00891 hmmc->Instance->DCTRL = 0U; 00892 00893 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD) 00894 { 00895 add *= 512U; 00896 } 00897 00898 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 00899 /* Configure the MMC DPSM (Data Path State Machine) */ 00900 config.DataTimeOut = SDMMC_DATATIMEOUT; 00901 config.DataLength = NumberOfBlocks * MMC_BLOCKSIZE; 00902 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; 00903 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD; 00904 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; 00905 config.DPSM = SDMMC_DPSM_DISABLE; 00906 (void)SDMMC_ConfigData(hmmc->Instance, &config); 00907 __SDMMC_CMDTRANS_ENABLE( hmmc->Instance); 00908 #endif 00909 00910 /* Write Blocks in Polling mode */ 00911 if(NumberOfBlocks > 1U) 00912 { 00913 hmmc->Context = MMC_CONTEXT_WRITE_MULTIPLE_BLOCK; 00914 00915 /* Write Multi Block command */ 00916 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add); 00917 } 00918 else 00919 { 00920 hmmc->Context = MMC_CONTEXT_WRITE_SINGLE_BLOCK; 00921 00922 /* Write Single Block command */ 00923 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add); 00924 } 00925 if(errorstate != HAL_MMC_ERROR_NONE) 00926 { 00927 /* Clear all the static flags */ 00928 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 00929 hmmc->ErrorCode |= errorstate; 00930 hmmc->State = HAL_MMC_STATE_READY; 00931 hmmc->Context = MMC_CONTEXT_NONE; 00932 return HAL_ERROR; 00933 } 00934 00935 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 00936 /* Configure the MMC DPSM (Data Path State Machine) */ 00937 config.DataTimeOut = SDMMC_DATATIMEOUT; 00938 config.DataLength = NumberOfBlocks * MMC_BLOCKSIZE; 00939 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; 00940 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD; 00941 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; 00942 config.DPSM = SDMMC_DPSM_ENABLE; 00943 (void)SDMMC_ConfigData(hmmc->Instance, &config); 00944 #endif 00945 00946 /* Write block(s) in polling mode */ 00947 dataremaining = config.DataLength; 00948 while(!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND)) 00949 { 00950 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) && (dataremaining > 0U)) 00951 { 00952 /* Write data to SDMMC Tx FIFO */ 00953 for(count = 0U; count < 8U; count++) 00954 { 00955 data = (uint32_t)(*tempbuff); 00956 tempbuff++; 00957 dataremaining--; 00958 data |= ((uint32_t)(*tempbuff) << 8U); 00959 tempbuff++; 00960 dataremaining--; 00961 data |= ((uint32_t)(*tempbuff) << 16U); 00962 tempbuff++; 00963 dataremaining--; 00964 data |= ((uint32_t)(*tempbuff) << 24U); 00965 tempbuff++; 00966 dataremaining--; 00967 (void)SDMMC_WriteFIFO(hmmc->Instance, &data); 00968 } 00969 } 00970 00971 if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U)) 00972 { 00973 /* Clear all the static flags */ 00974 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 00975 hmmc->ErrorCode |= errorstate; 00976 hmmc->State = HAL_MMC_STATE_READY; 00977 hmmc->Context = MMC_CONTEXT_NONE; 00978 return HAL_TIMEOUT; 00979 } 00980 } 00981 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 00982 __SDMMC_CMDTRANS_DISABLE( hmmc->Instance); 00983 #endif 00984 00985 /* Send stop transmission command in case of multiblock write */ 00986 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U)) 00987 { 00988 /* Send stop transmission command */ 00989 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance); 00990 if(errorstate != HAL_MMC_ERROR_NONE) 00991 { 00992 /* Clear all the static flags */ 00993 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 00994 hmmc->ErrorCode |= errorstate; 00995 hmmc->State = HAL_MMC_STATE_READY; 00996 hmmc->Context = MMC_CONTEXT_NONE; 00997 return HAL_ERROR; 00998 } 00999 } 01000 01001 /* Get error state */ 01002 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT)) 01003 { 01004 /* Clear all the static flags */ 01005 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 01006 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT; 01007 hmmc->State = HAL_MMC_STATE_READY; 01008 hmmc->Context = MMC_CONTEXT_NONE; 01009 return HAL_ERROR; 01010 } 01011 else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL)) 01012 { 01013 /* Clear all the static flags */ 01014 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 01015 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL; 01016 hmmc->State = HAL_MMC_STATE_READY; 01017 hmmc->Context = MMC_CONTEXT_NONE; 01018 return HAL_ERROR; 01019 } 01020 else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXUNDERR)) 01021 { 01022 /* Clear all the static flags */ 01023 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 01024 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN; 01025 hmmc->State = HAL_MMC_STATE_READY; 01026 hmmc->Context = MMC_CONTEXT_NONE; 01027 return HAL_ERROR; 01028 } 01029 else 01030 { 01031 /* Nothing to do */ 01032 } 01033 01034 /* Clear all the static flags */ 01035 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS); 01036 01037 hmmc->State = HAL_MMC_STATE_READY; 01038 01039 return HAL_OK; 01040 } 01041 else 01042 { 01043 hmmc->ErrorCode |= HAL_MMC_ERROR_BUSY; 01044 return HAL_ERROR; 01045 } 01046 } 01047 01048 /** 01049 * @brief Reads block(s) from a specified address in a card. The Data transfer 01050 * is managed in interrupt mode. 01051 * @note This API should be followed by a check on the card state through 01052 * HAL_MMC_GetCardState(). 01053 * @note You could also check the IT transfer process through the MMC Rx 01054 * interrupt event. 01055 * @param hmmc Pointer to MMC handle 01056 * @param pData Pointer to the buffer that will contain the received data 01057 * @param BlockAdd Block Address from where data is to be read 01058 * @param NumberOfBlocks Number of blocks to read. 01059 * @retval HAL status 01060 */ 01061 HAL_StatusTypeDef HAL_MMC_ReadBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks) 01062 { 01063 SDMMC_DataInitTypeDef config; 01064 uint32_t errorstate; 01065 uint32_t add = BlockAdd; 01066 01067 if(NULL == pData) 01068 { 01069 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; 01070 return HAL_ERROR; 01071 } 01072 01073 if(hmmc->State == HAL_MMC_STATE_READY) 01074 { 01075 hmmc->ErrorCode = HAL_MMC_ERROR_NONE; 01076 01077 if((add + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr)) 01078 { 01079 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; 01080 return HAL_ERROR; 01081 } 01082 01083 hmmc->State = HAL_MMC_STATE_BUSY; 01084 01085 /* Initialize data control register */ 01086 hmmc->Instance->DCTRL = 0U; 01087 01088 hmmc->pRxBuffPtr = pData; 01089 hmmc->RxXferSize = MMC_BLOCKSIZE * NumberOfBlocks; 01090 01091 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD) 01092 { 01093 add *= 512U; 01094 } 01095 01096 /* Configure the MMC DPSM (Data Path State Machine) */ 01097 config.DataTimeOut = SDMMC_DATATIMEOUT; 01098 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks; 01099 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; 01100 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; 01101 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; 01102 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 01103 config.DPSM = SDMMC_DPSM_ENABLE; 01104 #else 01105 config.DPSM = SDMMC_DPSM_DISABLE; 01106 #endif 01107 (void)SDMMC_ConfigData(hmmc->Instance, &config); 01108 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 01109 __SDMMC_CMDTRANS_ENABLE( hmmc->Instance); 01110 #endif 01111 /* Read Blocks in IT mode */ 01112 if(NumberOfBlocks > 1U) 01113 { 01114 hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_IT); 01115 01116 /* Read Multi Block command */ 01117 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add); 01118 } 01119 else 01120 { 01121 hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_IT); 01122 01123 /* Read Single Block command */ 01124 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add); 01125 } 01126 01127 if(errorstate != HAL_MMC_ERROR_NONE) 01128 { 01129 /* Clear all the static flags */ 01130 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 01131 hmmc->ErrorCode |= errorstate; 01132 hmmc->State = HAL_MMC_STATE_READY; 01133 hmmc->Context = MMC_CONTEXT_NONE; 01134 return HAL_ERROR; 01135 } 01136 01137 __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND | SDMMC_FLAG_RXFIFOHF)); 01138 01139 return HAL_OK; 01140 } 01141 else 01142 { 01143 return HAL_BUSY; 01144 } 01145 } 01146 01147 /** 01148 * @brief Writes block(s) to a specified address in a card. The Data transfer 01149 * is managed in interrupt mode. 01150 * @note This API should be followed by a check on the card state through 01151 * HAL_MMC_GetCardState(). 01152 * @note You could also check the IT transfer process through the MMC Tx 01153 * interrupt event. 01154 * @param hmmc Pointer to MMC handle 01155 * @param pData Pointer to the buffer that will contain the data to transmit 01156 * @param BlockAdd Block Address where data will be written 01157 * @param NumberOfBlocks Number of blocks to write 01158 * @retval HAL status 01159 */ 01160 HAL_StatusTypeDef HAL_MMC_WriteBlocks_IT(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks) 01161 { 01162 SDMMC_DataInitTypeDef config; 01163 uint32_t errorstate; 01164 uint32_t add = BlockAdd; 01165 01166 if(NULL == pData) 01167 { 01168 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; 01169 return HAL_ERROR; 01170 } 01171 01172 if(hmmc->State == HAL_MMC_STATE_READY) 01173 { 01174 hmmc->ErrorCode = HAL_MMC_ERROR_NONE; 01175 01176 if((add + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr)) 01177 { 01178 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; 01179 return HAL_ERROR; 01180 } 01181 01182 hmmc->State = HAL_MMC_STATE_BUSY; 01183 01184 /* Initialize data control register */ 01185 hmmc->Instance->DCTRL = 0U; 01186 01187 hmmc->pTxBuffPtr = pData; 01188 hmmc->TxXferSize = MMC_BLOCKSIZE * NumberOfBlocks; 01189 01190 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD) 01191 { 01192 add *= 512U; 01193 } 01194 01195 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 01196 /* Configure the MMC DPSM (Data Path State Machine) */ 01197 config.DataTimeOut = SDMMC_DATATIMEOUT; 01198 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks; 01199 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; 01200 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD; 01201 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; 01202 config.DPSM = SDMMC_DPSM_DISABLE; 01203 (void)SDMMC_ConfigData(hmmc->Instance, &config); 01204 01205 __SDMMC_CMDTRANS_ENABLE( hmmc->Instance); 01206 #endif 01207 01208 /* Write Blocks in Polling mode */ 01209 if(NumberOfBlocks > 1U) 01210 { 01211 hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK| MMC_CONTEXT_IT); 01212 01213 /* Write Multi Block command */ 01214 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add); 01215 } 01216 else 01217 { 01218 hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_IT); 01219 01220 /* Write Single Block command */ 01221 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add); 01222 } 01223 if(errorstate != HAL_MMC_ERROR_NONE) 01224 { 01225 /* Clear all the static flags */ 01226 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 01227 hmmc->ErrorCode |= errorstate; 01228 hmmc->State = HAL_MMC_STATE_READY; 01229 hmmc->Context = MMC_CONTEXT_NONE; 01230 return HAL_ERROR; 01231 } 01232 01233 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 01234 /* Configure the MMC DPSM (Data Path State Machine) */ 01235 config.DataTimeOut = SDMMC_DATATIMEOUT; 01236 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks; 01237 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; 01238 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD; 01239 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; 01240 config.DPSM = SDMMC_DPSM_ENABLE; 01241 (void)SDMMC_ConfigData(hmmc->Instance, &config); 01242 #endif 01243 01244 /* Enable transfer interrupts */ 01245 __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND | SDMMC_FLAG_TXFIFOHE)); 01246 01247 return HAL_OK; 01248 } 01249 else 01250 { 01251 return HAL_BUSY; 01252 } 01253 } 01254 01255 /** 01256 * @brief Reads block(s) from a specified address in a card. The Data transfer 01257 * is managed by DMA mode. 01258 * @note This API should be followed by a check on the card state through 01259 * HAL_MMC_GetCardState(). 01260 * @note You could also check the DMA transfer process through the MMC Rx 01261 * interrupt event. 01262 * @param hmmc Pointer MMC handle 01263 * @param pData Pointer to the buffer that will contain the received data 01264 * @param BlockAdd Block Address from where data is to be read 01265 * @param NumberOfBlocks Number of blocks to read. 01266 * @retval HAL status 01267 */ 01268 HAL_StatusTypeDef HAL_MMC_ReadBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks) 01269 { 01270 SDMMC_DataInitTypeDef config; 01271 uint32_t errorstate; 01272 uint32_t add = BlockAdd; 01273 01274 if(NULL == pData) 01275 { 01276 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; 01277 return HAL_ERROR; 01278 } 01279 01280 if(hmmc->State == HAL_MMC_STATE_READY) 01281 { 01282 hmmc->ErrorCode = HAL_MMC_ERROR_NONE; 01283 01284 if((add + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr)) 01285 { 01286 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; 01287 return HAL_ERROR; 01288 } 01289 01290 hmmc->State = HAL_MMC_STATE_BUSY; 01291 01292 /* Initialize data control register */ 01293 hmmc->Instance->DCTRL = 0U; 01294 01295 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 01296 /* Set the DMA transfer complete callback */ 01297 hmmc->hdmarx->XferCpltCallback = MMC_DMAReceiveCplt; 01298 01299 /* Set the DMA error callback */ 01300 hmmc->hdmarx->XferErrorCallback = MMC_DMAError; 01301 01302 /* Set the DMA Abort callback */ 01303 hmmc->hdmarx->XferAbortCallback = NULL; 01304 01305 #else 01306 hmmc->pRxBuffPtr = pData; 01307 hmmc->RxXferSize = MMC_BLOCKSIZE * NumberOfBlocks; 01308 #endif 01309 01310 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD) 01311 { 01312 add *= 512U; 01313 } 01314 01315 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 01316 /* Configure the MMC DPSM (Data Path State Machine) */ 01317 config.DataTimeOut = SDMMC_DATATIMEOUT; 01318 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks; 01319 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; 01320 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; 01321 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; 01322 config.DPSM = SDMMC_DPSM_DISABLE; 01323 (void)SDMMC_ConfigData(hmmc->Instance, &config); 01324 01325 __SDMMC_CMDTRANS_ENABLE( hmmc->Instance); 01326 hmmc->Instance->IDMABASE0 = (uint32_t) pData ; 01327 hmmc->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_SINGLE_BUFF; 01328 #else 01329 /* Enable the DMA Channel */ 01330 if(HAL_DMA_Start_IT(hmmc->hdmarx, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)pData, (uint32_t)(MMC_BLOCKSIZE * NumberOfBlocks)/4) != HAL_OK) 01331 { 01332 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 01333 hmmc->ErrorCode = HAL_MMC_ERROR_DMA; 01334 hmmc->State = HAL_MMC_STATE_READY; 01335 return HAL_ERROR; 01336 } 01337 else 01338 { 01339 /* Enable MMC DMA transfer */ 01340 __HAL_MMC_DMA_ENABLE(hmmc); 01341 01342 /* Configure the MMC DPSM (Data Path State Machine) */ 01343 config.DataTimeOut = SDMMC_DATATIMEOUT; 01344 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks; 01345 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; 01346 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; 01347 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; 01348 config.DPSM = SDMMC_DPSM_ENABLE; 01349 (void)SDMMC_ConfigData(hmmc->Instance, &config); 01350 #endif 01351 01352 /* Read Blocks in DMA mode */ 01353 if(NumberOfBlocks > 1U) 01354 { 01355 hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA); 01356 01357 /* Read Multi Block command */ 01358 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add); 01359 } 01360 else 01361 { 01362 hmmc->Context = (MMC_CONTEXT_READ_SINGLE_BLOCK | MMC_CONTEXT_DMA); 01363 01364 /* Read Single Block command */ 01365 errorstate = SDMMC_CmdReadSingleBlock(hmmc->Instance, add); 01366 } 01367 if(errorstate != HAL_MMC_ERROR_NONE) 01368 { 01369 /* Clear all the static flags */ 01370 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 01371 hmmc->ErrorCode = errorstate; 01372 hmmc->State = HAL_MMC_STATE_READY; 01373 hmmc->Context = MMC_CONTEXT_NONE; 01374 return HAL_ERROR; 01375 } 01376 01377 /* Enable transfer interrupts */ 01378 __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND)); 01379 01380 return HAL_OK; 01381 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 01382 } 01383 #endif 01384 } 01385 else 01386 { 01387 return HAL_BUSY; 01388 } 01389 } 01390 01391 /** 01392 * @brief Writes block(s) to a specified address in a card. The Data transfer 01393 * is managed by DMA mode. 01394 * @note This API should be followed by a check on the card state through 01395 * HAL_MMC_GetCardState(). 01396 * @note You could also check the DMA transfer process through the MMC Tx 01397 * interrupt event. 01398 * @param hmmc Pointer to MMC handle 01399 * @param pData Pointer to the buffer that will contain the data to transmit 01400 * @param BlockAdd Block Address where data will be written 01401 * @param NumberOfBlocks Number of blocks to write 01402 * @retval HAL status 01403 */ 01404 HAL_StatusTypeDef HAL_MMC_WriteBlocks_DMA(MMC_HandleTypeDef *hmmc, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks) 01405 { 01406 SDMMC_DataInitTypeDef config; 01407 uint32_t errorstate; 01408 uint32_t add = BlockAdd; 01409 01410 if(NULL == pData) 01411 { 01412 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; 01413 return HAL_ERROR; 01414 } 01415 01416 if(hmmc->State == HAL_MMC_STATE_READY) 01417 { 01418 hmmc->ErrorCode = HAL_MMC_ERROR_NONE; 01419 01420 if((add + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr)) 01421 { 01422 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; 01423 return HAL_ERROR; 01424 } 01425 01426 hmmc->State = HAL_MMC_STATE_BUSY; 01427 01428 /* Initialize data control register */ 01429 hmmc->Instance->DCTRL = 0U; 01430 01431 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 01432 /* Set the DMA transfer complete callback */ 01433 hmmc->hdmatx->XferCpltCallback = MMC_DMATransmitCplt; 01434 01435 /* Set the DMA error callback */ 01436 hmmc->hdmatx->XferErrorCallback = MMC_DMAError; 01437 01438 /* Set the DMA Abort callback */ 01439 hmmc->hdmatx->XferAbortCallback = NULL; 01440 #else 01441 hmmc->pTxBuffPtr = pData; 01442 hmmc->TxXferSize = MMC_BLOCKSIZE * NumberOfBlocks; 01443 #endif 01444 01445 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD) 01446 { 01447 add *= 512U; 01448 } 01449 01450 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 01451 /* Configure the MMC DPSM (Data Path State Machine) */ 01452 config.DataTimeOut = SDMMC_DATATIMEOUT; 01453 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks; 01454 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; 01455 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD; 01456 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; 01457 config.DPSM = SDMMC_DPSM_DISABLE; 01458 (void)SDMMC_ConfigData(hmmc->Instance, &config); 01459 01460 __SDMMC_CMDTRANS_ENABLE( hmmc->Instance); 01461 01462 hmmc->Instance->IDMABASE0 = (uint32_t) pData ; 01463 hmmc->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_SINGLE_BUFF; 01464 #endif 01465 01466 /* Write Blocks in Polling mode */ 01467 if(NumberOfBlocks > 1U) 01468 { 01469 hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_DMA); 01470 01471 /* Write Multi Block command */ 01472 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add); 01473 } 01474 else 01475 { 01476 hmmc->Context = (MMC_CONTEXT_WRITE_SINGLE_BLOCK | MMC_CONTEXT_DMA); 01477 01478 /* Write Single Block command */ 01479 errorstate = SDMMC_CmdWriteSingleBlock(hmmc->Instance, add); 01480 } 01481 if(errorstate != HAL_MMC_ERROR_NONE) 01482 { 01483 /* Clear all the static flags */ 01484 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 01485 hmmc->ErrorCode |= errorstate; 01486 hmmc->State = HAL_MMC_STATE_READY; 01487 hmmc->Context = MMC_CONTEXT_NONE; 01488 return HAL_ERROR; 01489 } 01490 01491 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 01492 /* Enable SDMMC DMA transfer */ 01493 __HAL_MMC_DMA_ENABLE(hmmc); 01494 01495 /* Enable the DMA Channel */ 01496 if(HAL_DMA_Start_IT(hmmc->hdmatx, (uint32_t)pData, (uint32_t)&hmmc->Instance->FIFO, (uint32_t)(MMC_BLOCKSIZE * NumberOfBlocks)/4) != HAL_OK) 01497 { 01498 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 01499 hmmc->ErrorCode |= HAL_MMC_ERROR_DMA; 01500 hmmc->State = HAL_MMC_STATE_READY; 01501 hmmc->Context = MMC_CONTEXT_NONE; 01502 return HAL_ERROR; 01503 } 01504 else 01505 { 01506 /* Configure the MMC DPSM (Data Path State Machine) */ 01507 config.DataTimeOut = SDMMC_DATATIMEOUT; 01508 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks; 01509 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; 01510 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD; 01511 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; 01512 config.DPSM = SDMMC_DPSM_ENABLE; 01513 (void)SDMMC_ConfigData(hmmc->Instance, &config); 01514 01515 /* Enable MMC Error interrupts */ 01516 __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR)); 01517 01518 return HAL_OK; 01519 } 01520 #else 01521 /* Enable MMC Error interrupts */ 01522 __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND)); 01523 01524 return HAL_OK; 01525 #endif 01526 } 01527 else 01528 { 01529 return HAL_BUSY; 01530 } 01531 } 01532 01533 /** 01534 * @brief Erases the specified memory area of the given MMC card. 01535 * @note This API should be followed by a check on the card state through 01536 * HAL_MMC_GetCardState(). 01537 * @param hmmc Pointer to MMC handle 01538 * @param BlockStartAdd Start Block address 01539 * @param BlockEndAdd End Block address 01540 * @retval HAL status 01541 */ 01542 HAL_StatusTypeDef HAL_MMC_Erase(MMC_HandleTypeDef *hmmc, uint32_t BlockStartAdd, uint32_t BlockEndAdd) 01543 { 01544 uint32_t errorstate; 01545 uint32_t start_add = BlockStartAdd; 01546 uint32_t end_add = BlockEndAdd; 01547 01548 if(hmmc->State == HAL_MMC_STATE_READY) 01549 { 01550 hmmc->ErrorCode = HAL_MMC_ERROR_NONE; 01551 01552 if(end_add < start_add) 01553 { 01554 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; 01555 return HAL_ERROR; 01556 } 01557 01558 if(end_add > (hmmc->MmcCard.LogBlockNbr)) 01559 { 01560 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; 01561 return HAL_ERROR; 01562 } 01563 01564 hmmc->State = HAL_MMC_STATE_BUSY; 01565 01566 /* Check if the card command class supports erase command */ 01567 if(((hmmc->MmcCard.Class) & SDMMC_CCCC_ERASE) == 0U) 01568 { 01569 /* Clear all the static flags */ 01570 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 01571 hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE; 01572 hmmc->State = HAL_MMC_STATE_READY; 01573 return HAL_ERROR; 01574 } 01575 01576 if((SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED) 01577 { 01578 /* Clear all the static flags */ 01579 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 01580 hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED; 01581 hmmc->State = HAL_MMC_STATE_READY; 01582 return HAL_ERROR; 01583 } 01584 01585 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD) 01586 { 01587 start_add *= 512U; 01588 end_add *= 512U; 01589 } 01590 01591 /* Send CMD35 MMC_ERASE_GRP_START with argument as addr */ 01592 errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, start_add); 01593 if(errorstate != HAL_MMC_ERROR_NONE) 01594 { 01595 /* Clear all the static flags */ 01596 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 01597 hmmc->ErrorCode |= errorstate; 01598 hmmc->State = HAL_MMC_STATE_READY; 01599 return HAL_ERROR; 01600 } 01601 01602 /* Send CMD36 MMC_ERASE_GRP_END with argument as addr */ 01603 errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, end_add); 01604 if(errorstate != HAL_MMC_ERROR_NONE) 01605 { 01606 /* Clear all the static flags */ 01607 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 01608 hmmc->ErrorCode |= errorstate; 01609 hmmc->State = HAL_MMC_STATE_READY; 01610 return HAL_ERROR; 01611 } 01612 01613 /* Send CMD38 ERASE */ 01614 errorstate = SDMMC_CmdErase(hmmc->Instance, 0UL); 01615 if(errorstate != HAL_MMC_ERROR_NONE) 01616 { 01617 /* Clear all the static flags */ 01618 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 01619 hmmc->ErrorCode |= errorstate; 01620 hmmc->State = HAL_MMC_STATE_READY; 01621 return HAL_ERROR; 01622 } 01623 01624 hmmc->State = HAL_MMC_STATE_READY; 01625 01626 return HAL_OK; 01627 } 01628 else 01629 { 01630 return HAL_BUSY; 01631 } 01632 } 01633 01634 /** 01635 * @brief This function handles MMC card interrupt request. 01636 * @param hmmc Pointer to MMC handle 01637 * @retval None 01638 */ 01639 void HAL_MMC_IRQHandler(MMC_HandleTypeDef *hmmc) 01640 { 01641 uint32_t errorstate; 01642 uint32_t context = hmmc->Context; 01643 01644 /* Check for SDMMC interrupt flags */ 01645 if((__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF) != RESET) && ((context & MMC_CONTEXT_IT) != 0U)) 01646 { 01647 MMC_Read_IT(hmmc); 01648 } 01649 01650 else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DATAEND) != RESET) 01651 { 01652 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_DATAEND); 01653 01654 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT |\ 01655 SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR | SDMMC_IT_TXFIFOHE |\ 01656 SDMMC_IT_RXFIFOHF); 01657 01658 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 01659 hmmc->Instance->DCTRL &= ~(SDMMC_DCTRL_DTEN); 01660 #else 01661 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_IDMABTC); 01662 __SDMMC_CMDTRANS_DISABLE( hmmc->Instance); 01663 #endif 01664 01665 if((context & MMC_CONTEXT_DMA) != 0U) 01666 { 01667 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 01668 hmmc->Instance->DLEN = 0; 01669 hmmc->Instance->DCTRL = 0; 01670 hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA ; 01671 01672 /* Stop Transfer for Write Multi blocks or Read Multi blocks */ 01673 if(((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)) 01674 { 01675 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance); 01676 if(errorstate != HAL_MMC_ERROR_NONE) 01677 { 01678 hmmc->ErrorCode |= errorstate; 01679 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 01680 hmmc->ErrorCallback(hmmc); 01681 #else 01682 HAL_MMC_ErrorCallback(hmmc); 01683 #endif 01684 } 01685 } 01686 01687 /* Clear all the static flags */ 01688 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS); 01689 01690 hmmc->State = HAL_MMC_STATE_READY; 01691 hmmc->Context = MMC_CONTEXT_NONE; 01692 if(((context & MMC_CONTEXT_WRITE_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)) 01693 { 01694 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 01695 hmmc->TxCpltCallback(hmmc); 01696 #else 01697 HAL_MMC_TxCpltCallback(hmmc); 01698 #endif 01699 } 01700 if(((context & MMC_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U)) 01701 { 01702 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 01703 hmmc->RxCpltCallback(hmmc); 01704 #else 01705 HAL_MMC_RxCpltCallback(hmmc); 01706 #endif 01707 } 01708 #else 01709 if((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U) 01710 { 01711 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance); 01712 if(errorstate != HAL_MMC_ERROR_NONE) 01713 { 01714 hmmc->ErrorCode |= errorstate; 01715 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 01716 hmmc->ErrorCallback(hmmc); 01717 #else 01718 HAL_MMC_ErrorCallback(hmmc); 01719 #endif 01720 } 01721 } 01722 if(((context & MMC_CONTEXT_READ_SINGLE_BLOCK) == 0U) && ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) == 0U)) 01723 { 01724 /* Disable the DMA transfer for transmit request by setting the DMAEN bit 01725 in the MMC DCTRL register */ 01726 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN); 01727 01728 hmmc->State = HAL_MMC_STATE_READY; 01729 hmmc->Context = MMC_CONTEXT_NONE; 01730 01731 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 01732 hmmc->TxCpltCallback(hmmc); 01733 #else 01734 HAL_MMC_TxCpltCallback(hmmc); 01735 #endif 01736 } 01737 #endif 01738 } 01739 else if((context & MMC_CONTEXT_IT) != 0U) 01740 { 01741 /* Stop Transfer for Write Multi blocks or Read Multi blocks */ 01742 if(((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)) 01743 { 01744 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance); 01745 if(errorstate != HAL_MMC_ERROR_NONE) 01746 { 01747 hmmc->ErrorCode |= errorstate; 01748 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 01749 hmmc->ErrorCallback(hmmc); 01750 #else 01751 HAL_MMC_ErrorCallback(hmmc); 01752 #endif 01753 } 01754 } 01755 01756 /* Clear all the static flags */ 01757 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS); 01758 01759 hmmc->State = HAL_MMC_STATE_READY; 01760 hmmc->Context = MMC_CONTEXT_NONE; 01761 if(((context & MMC_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & MMC_CONTEXT_READ_MULTIPLE_BLOCK) != 0U)) 01762 { 01763 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 01764 hmmc->RxCpltCallback(hmmc); 01765 #else 01766 HAL_MMC_RxCpltCallback(hmmc); 01767 #endif 01768 } 01769 else 01770 { 01771 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 01772 hmmc->TxCpltCallback(hmmc); 01773 #else 01774 HAL_MMC_TxCpltCallback(hmmc); 01775 #endif 01776 } 01777 } 01778 else 01779 { 01780 /* Nothing to do */ 01781 } 01782 } 01783 01784 else if((__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_TXFIFOHE) != RESET) && ((context & MMC_CONTEXT_IT) != 0U)) 01785 { 01786 MMC_Write_IT(hmmc); 01787 } 01788 01789 else if (__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL| SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_RXOVERR | SDMMC_FLAG_TXUNDERR) != RESET) 01790 { 01791 /* Set Error code */ 01792 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_DCRCFAIL) != RESET) 01793 { 01794 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL; 01795 } 01796 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_DTIMEOUT) != RESET) 01797 { 01798 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT; 01799 } 01800 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_RXOVERR) != RESET) 01801 { 01802 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN; 01803 } 01804 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_IT_TXUNDERR) != RESET) 01805 { 01806 hmmc->ErrorCode |= HAL_MMC_ERROR_TX_UNDERRUN; 01807 } 01808 01809 /* Clear All flags */ 01810 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS); 01811 01812 /* Disable all interrupts */ 01813 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\ 01814 SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR); 01815 01816 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 01817 __SDMMC_CMDTRANS_DISABLE( hmmc->Instance); 01818 hmmc->Instance->DCTRL |= SDMMC_DCTRL_FIFORST; 01819 hmmc->Instance->CMD |= SDMMC_CMD_CMDSTOP; 01820 #endif 01821 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance); 01822 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 01823 hmmc->Instance->CMD &= ~(SDMMC_CMD_CMDSTOP); 01824 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_DABORT); 01825 #endif 01826 01827 if((context & MMC_CONTEXT_IT) != 0U) 01828 { 01829 /* Set the MMC state to ready to be able to start again the process */ 01830 hmmc->State = HAL_MMC_STATE_READY; 01831 hmmc->Context = MMC_CONTEXT_NONE; 01832 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 01833 hmmc->ErrorCallback(hmmc); 01834 #else 01835 HAL_MMC_ErrorCallback(hmmc); 01836 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */ 01837 } 01838 else if((context & MMC_CONTEXT_DMA) != 0U) 01839 { 01840 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 01841 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE) 01842 { 01843 /* Disable Internal DMA */ 01844 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_IDMABTC); 01845 hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA; 01846 01847 /* Set the MMC state to ready to be able to start again the process */ 01848 hmmc->State = HAL_MMC_STATE_READY; 01849 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 01850 hmmc->ErrorCallback(hmmc); 01851 #else 01852 HAL_MMC_ErrorCallback(hmmc); 01853 #endif /* USE_HAL_MMC_REGISTER_CALLBACKS */ 01854 } 01855 #else 01856 /* Abort the MMC DMA Streams */ 01857 if(hmmc->hdmatx != NULL) 01858 { 01859 /* Set the DMA Tx abort callback */ 01860 hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort; 01861 /* Abort DMA in IT mode */ 01862 if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK) 01863 { 01864 MMC_DMATxAbort(hmmc->hdmatx); 01865 } 01866 } 01867 else if(hmmc->hdmarx != NULL) 01868 { 01869 /* Set the DMA Rx abort callback */ 01870 hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort; 01871 /* Abort DMA in IT mode */ 01872 if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK) 01873 { 01874 MMC_DMARxAbort(hmmc->hdmarx); 01875 } 01876 } 01877 else 01878 { 01879 hmmc->ErrorCode = HAL_MMC_ERROR_NONE; 01880 hmmc->State = HAL_MMC_STATE_READY; 01881 hmmc->Context = MMC_CONTEXT_NONE; 01882 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 01883 hmmc->AbortCpltCallback(hmmc); 01884 #else 01885 HAL_MMC_AbortCallback(hmmc); 01886 #endif 01887 } 01888 #endif 01889 } 01890 else 01891 { 01892 /* Nothing to do */ 01893 } 01894 } 01895 01896 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 01897 else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_IDMABTC) != RESET) 01898 { 01899 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_IT_IDMABTC); 01900 if(READ_BIT(hmmc->Instance->IDMACTRL, SDMMC_IDMA_IDMABACT) == 0U) 01901 { 01902 /* Current buffer is buffer0, Transfer complete for buffer1 */ 01903 if((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U) 01904 { 01905 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 01906 hmmc->Write_DMADblBuf1CpltCallback(hmmc); 01907 #else 01908 HAL_MMCEx_Write_DMADoubleBuffer1CpltCallback(hmmc); 01909 #endif 01910 } 01911 else /* MMC_CONTEXT_READ_MULTIPLE_BLOCK */ 01912 { 01913 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 01914 hmmc->Read_DMADblBuf1CpltCallback(hmmc); 01915 #else 01916 HAL_MMCEx_Read_DMADoubleBuffer1CpltCallback(hmmc); 01917 #endif 01918 } 01919 } 01920 else /* MMC_DMA_BUFFER1 */ 01921 { 01922 /* Current buffer is buffer1, Transfer complete for buffer0 */ 01923 if((context & MMC_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U) 01924 { 01925 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 01926 hmmc->Write_DMADblBuf0CpltCallback(hmmc); 01927 #else 01928 HAL_MMCEx_Write_DMADoubleBuffer0CpltCallback(hmmc); 01929 #endif 01930 } 01931 else /* MMC_CONTEXT_READ_MULTIPLE_BLOCK */ 01932 { 01933 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 01934 hmmc->Read_DMADblBuf0CpltCallback(hmmc); 01935 #else 01936 HAL_MMCEx_Read_DMADoubleBuffer0CpltCallback(hmmc); 01937 #endif 01938 } 01939 } 01940 } 01941 #endif 01942 01943 else 01944 { 01945 /* Nothing to do */ 01946 } 01947 } 01948 01949 /** 01950 * @brief return the MMC state 01951 * @param hmmc Pointer to mmc handle 01952 * @retval HAL state 01953 */ 01954 HAL_MMC_StateTypeDef HAL_MMC_GetState(MMC_HandleTypeDef *hmmc) 01955 { 01956 return hmmc->State; 01957 } 01958 01959 /** 01960 * @brief Return the MMC error code 01961 * @param hmmc : Pointer to a MMC_HandleTypeDef structure that contains 01962 * the configuration information. 01963 * @retval MMC Error Code 01964 */ 01965 uint32_t HAL_MMC_GetError(MMC_HandleTypeDef *hmmc) 01966 { 01967 return hmmc->ErrorCode; 01968 } 01969 01970 /** 01971 * @brief Tx Transfer completed callbacks 01972 * @param hmmc Pointer to MMC handle 01973 * @retval None 01974 */ 01975 __weak void HAL_MMC_TxCpltCallback(MMC_HandleTypeDef *hmmc) 01976 { 01977 /* Prevent unused argument(s) compilation warning */ 01978 UNUSED(hmmc); 01979 01980 /* NOTE : This function should not be modified, when the callback is needed, 01981 the HAL_MMC_TxCpltCallback can be implemented in the user file 01982 */ 01983 } 01984 01985 /** 01986 * @brief Rx Transfer completed callbacks 01987 * @param hmmc Pointer MMC handle 01988 * @retval None 01989 */ 01990 __weak void HAL_MMC_RxCpltCallback(MMC_HandleTypeDef *hmmc) 01991 { 01992 /* Prevent unused argument(s) compilation warning */ 01993 UNUSED(hmmc); 01994 01995 /* NOTE : This function should not be modified, when the callback is needed, 01996 the HAL_MMC_RxCpltCallback can be implemented in the user file 01997 */ 01998 } 01999 02000 /** 02001 * @brief MMC error callbacks 02002 * @param hmmc Pointer MMC handle 02003 * @retval None 02004 */ 02005 __weak void HAL_MMC_ErrorCallback(MMC_HandleTypeDef *hmmc) 02006 { 02007 /* Prevent unused argument(s) compilation warning */ 02008 UNUSED(hmmc); 02009 02010 /* NOTE : This function should not be modified, when the callback is needed, 02011 the HAL_MMC_ErrorCallback can be implemented in the user file 02012 */ 02013 } 02014 02015 /** 02016 * @brief MMC Abort callbacks 02017 * @param hmmc Pointer MMC handle 02018 * @retval None 02019 */ 02020 __weak void HAL_MMC_AbortCallback(MMC_HandleTypeDef *hmmc) 02021 { 02022 /* Prevent unused argument(s) compilation warning */ 02023 UNUSED(hmmc); 02024 02025 /* NOTE : This function should not be modified, when the callback is needed, 02026 the HAL_MMC_AbortCallback can be implemented in the user file 02027 */ 02028 } 02029 02030 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 02031 /** 02032 * @brief Register a User MMC Callback 02033 * To be used instead of the weak (surcharged) predefined callback 02034 * @param hmmc : MMC handle 02035 * @param CallbackId : ID of the callback to be registered 02036 * This parameter can be one of the following values: 02037 * @arg @ref HAL_MMC_TX_CPLT_CB_ID MMC Tx Complete Callback ID 02038 * @arg @ref HAL_MMC_RX_CPLT_CB_ID MMC Rx Complete Callback ID 02039 * @arg @ref HAL_MMC_ERROR_CB_ID MMC Error Callback ID 02040 * @arg @ref HAL_MMC_ABORT_CB_ID MMC Abort Callback ID 02041 * @arg @ref HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID MMC DMA Rx Double buffer 0 Callback ID 02042 * @arg @ref HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID MMC DMA Rx Double buffer 1 Callback ID 02043 * @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID MMC DMA Tx Double buffer 0 Callback ID 02044 * @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID MMC DMA Tx Double buffer 1 Callback ID 02045 * @arg @ref HAL_MMC_MSP_INIT_CB_ID MMC MspInit Callback ID 02046 * @arg @ref HAL_MMC_MSP_DEINIT_CB_ID MMC MspDeInit Callback ID 02047 * @param pCallback : pointer to the Callback function 02048 * @retval status 02049 */ 02050 HAL_StatusTypeDef HAL_MMC_RegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId, pMMC_CallbackTypeDef pCallback) 02051 { 02052 HAL_StatusTypeDef status = HAL_OK; 02053 02054 if(pCallback == NULL) 02055 { 02056 /* Update the error code */ 02057 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK; 02058 return HAL_ERROR; 02059 } 02060 02061 /* Process locked */ 02062 __HAL_LOCK(hmmc); 02063 02064 if(hmmc->State == HAL_MMC_STATE_READY) 02065 { 02066 switch (CallbackId) 02067 { 02068 case HAL_MMC_TX_CPLT_CB_ID : 02069 hmmc->TxCpltCallback = pCallback; 02070 break; 02071 case HAL_MMC_RX_CPLT_CB_ID : 02072 hmmc->RxCpltCallback = pCallback; 02073 break; 02074 case HAL_MMC_ERROR_CB_ID : 02075 hmmc->ErrorCallback = pCallback; 02076 break; 02077 case HAL_MMC_ABORT_CB_ID : 02078 hmmc->AbortCpltCallback = pCallback; 02079 break; 02080 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 02081 case HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID : 02082 hmmc->Read_DMADblBuf0CpltCallback = pCallback; 02083 break; 02084 case HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID : 02085 hmmc->Read_DMADblBuf1CpltCallback = pCallback; 02086 break; 02087 case HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID : 02088 hmmc->Write_DMADblBuf0CpltCallback = pCallback; 02089 break; 02090 case HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID : 02091 hmmc->Write_DMADblBuf1CpltCallback = pCallback; 02092 break; 02093 #endif 02094 case HAL_MMC_MSP_INIT_CB_ID : 02095 hmmc->MspInitCallback = pCallback; 02096 break; 02097 case HAL_MMC_MSP_DEINIT_CB_ID : 02098 hmmc->MspDeInitCallback = pCallback; 02099 break; 02100 default : 02101 /* Update the error code */ 02102 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK; 02103 /* update return status */ 02104 status = HAL_ERROR; 02105 break; 02106 } 02107 } 02108 else if (hmmc->State == HAL_MMC_STATE_RESET) 02109 { 02110 switch (CallbackId) 02111 { 02112 case HAL_MMC_MSP_INIT_CB_ID : 02113 hmmc->MspInitCallback = pCallback; 02114 break; 02115 case HAL_MMC_MSP_DEINIT_CB_ID : 02116 hmmc->MspDeInitCallback = pCallback; 02117 break; 02118 default : 02119 /* Update the error code */ 02120 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK; 02121 /* update return status */ 02122 status = HAL_ERROR; 02123 break; 02124 } 02125 } 02126 else 02127 { 02128 /* Update the error code */ 02129 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK; 02130 /* update return status */ 02131 status = HAL_ERROR; 02132 } 02133 02134 /* Release Lock */ 02135 __HAL_UNLOCK(hmmc); 02136 return status; 02137 } 02138 02139 /** 02140 * @brief Unregister a User MMC Callback 02141 * MMC Callback is redirected to the weak (surcharged) predefined callback 02142 * @param hmmc : MMC handle 02143 * @param CallbackId : ID of the callback to be unregistered 02144 * This parameter can be one of the following values: 02145 * @arg @ref HAL_MMC_TX_CPLT_CB_ID MMC Tx Complete Callback ID 02146 * @arg @ref HAL_MMC_RX_CPLT_CB_ID MMC Rx Complete Callback ID 02147 * @arg @ref HAL_MMC_ERROR_CB_ID MMC Error Callback ID 02148 * @arg @ref HAL_MMC_ABORT_CB_ID MMC Abort Callback ID 02149 * @arg @ref HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID MMC DMA Rx Double buffer 0 Callback ID 02150 * @arg @ref HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID MMC DMA Rx Double buffer 1 Callback ID 02151 * @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID MMC DMA Tx Double buffer 0 Callback ID 02152 * @arg @ref HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID MMC DMA Tx Double buffer 1 Callback ID 02153 * @arg @ref HAL_MMC_MSP_INIT_CB_ID MMC MspInit Callback ID 02154 * @arg @ref HAL_MMC_MSP_DEINIT_CB_ID MMC MspDeInit Callback ID 02155 * @retval status 02156 */ 02157 HAL_StatusTypeDef HAL_MMC_UnRegisterCallback(MMC_HandleTypeDef *hmmc, HAL_MMC_CallbackIDTypeDef CallbackId) 02158 { 02159 HAL_StatusTypeDef status = HAL_OK; 02160 02161 /* Process locked */ 02162 __HAL_LOCK(hmmc); 02163 02164 if(hmmc->State == HAL_MMC_STATE_READY) 02165 { 02166 switch (CallbackId) 02167 { 02168 case HAL_MMC_TX_CPLT_CB_ID : 02169 hmmc->TxCpltCallback = HAL_MMC_TxCpltCallback; 02170 break; 02171 case HAL_MMC_RX_CPLT_CB_ID : 02172 hmmc->RxCpltCallback = HAL_MMC_RxCpltCallback; 02173 break; 02174 case HAL_MMC_ERROR_CB_ID : 02175 hmmc->ErrorCallback = HAL_MMC_ErrorCallback; 02176 break; 02177 case HAL_MMC_ABORT_CB_ID : 02178 hmmc->AbortCpltCallback = HAL_MMC_AbortCallback; 02179 break; 02180 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 02181 case HAL_MMC_READ_DMA_DBL_BUF0_CPLT_CB_ID : 02182 hmmc->Read_DMADblBuf0CpltCallback = HAL_MMCEx_Read_DMADoubleBuffer0CpltCallback; 02183 break; 02184 case HAL_MMC_READ_DMA_DBL_BUF1_CPLT_CB_ID : 02185 hmmc->Read_DMADblBuf1CpltCallback = HAL_MMCEx_Read_DMADoubleBuffer1CpltCallback; 02186 break; 02187 case HAL_MMC_WRITE_DMA_DBL_BUF0_CPLT_CB_ID : 02188 hmmc->Write_DMADblBuf0CpltCallback = HAL_MMCEx_Write_DMADoubleBuffer0CpltCallback; 02189 break; 02190 case HAL_MMC_WRITE_DMA_DBL_BUF1_CPLT_CB_ID : 02191 hmmc->Write_DMADblBuf1CpltCallback = HAL_MMCEx_Write_DMADoubleBuffer1CpltCallback; 02192 break; 02193 #endif 02194 case HAL_MMC_MSP_INIT_CB_ID : 02195 hmmc->MspInitCallback = HAL_MMC_MspInit; 02196 break; 02197 case HAL_MMC_MSP_DEINIT_CB_ID : 02198 hmmc->MspDeInitCallback = HAL_MMC_MspDeInit; 02199 break; 02200 default : 02201 /* Update the error code */ 02202 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK; 02203 /* update return status */ 02204 status = HAL_ERROR; 02205 break; 02206 } 02207 } 02208 else if (hmmc->State == HAL_MMC_STATE_RESET) 02209 { 02210 switch (CallbackId) 02211 { 02212 case HAL_MMC_MSP_INIT_CB_ID : 02213 hmmc->MspInitCallback = HAL_MMC_MspInit; 02214 break; 02215 case HAL_MMC_MSP_DEINIT_CB_ID : 02216 hmmc->MspDeInitCallback = HAL_MMC_MspDeInit; 02217 break; 02218 default : 02219 /* Update the error code */ 02220 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK; 02221 /* update return status */ 02222 status = HAL_ERROR; 02223 break; 02224 } 02225 } 02226 else 02227 { 02228 /* Update the error code */ 02229 hmmc->ErrorCode |= HAL_MMC_ERROR_INVALID_CALLBACK; 02230 /* update return status */ 02231 status = HAL_ERROR; 02232 } 02233 02234 /* Release Lock */ 02235 __HAL_UNLOCK(hmmc); 02236 return status; 02237 } 02238 #endif 02239 02240 /** 02241 * @} 02242 */ 02243 02244 /** @addtogroup MMC_Exported_Functions_Group3 02245 * @brief management functions 02246 * 02247 @verbatim 02248 ============================================================================== 02249 ##### Peripheral Control functions ##### 02250 ============================================================================== 02251 [..] 02252 This subsection provides a set of functions allowing to control the MMC card 02253 operations and get the related information 02254 02255 @endverbatim 02256 * @{ 02257 */ 02258 02259 /** 02260 * @brief Returns information the information of the card which are stored on 02261 * the CID register. 02262 * @param hmmc Pointer to MMC handle 02263 * @param pCID Pointer to a HAL_MMC_CIDTypedef structure that 02264 * contains all CID register parameters 02265 * @retval HAL status 02266 */ 02267 HAL_StatusTypeDef HAL_MMC_GetCardCID(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCIDTypeDef *pCID) 02268 { 02269 pCID->ManufacturerID = (uint8_t)((hmmc->CID[0] & 0xFF000000U) >> 24U); 02270 02271 pCID->OEM_AppliID = (uint16_t)((hmmc->CID[0] & 0x00FFFF00U) >> 8U); 02272 02273 pCID->ProdName1 = (((hmmc->CID[0] & 0x000000FFU) << 24U) | ((hmmc->CID[1] & 0xFFFFFF00U) >> 8U)); 02274 02275 pCID->ProdName2 = (uint8_t)(hmmc->CID[1] & 0x000000FFU); 02276 02277 pCID->ProdRev = (uint8_t)((hmmc->CID[2] & 0xFF000000U) >> 24U); 02278 02279 pCID->ProdSN = (((hmmc->CID[2] & 0x00FFFFFFU) << 8U) | ((hmmc->CID[3] & 0xFF000000U) >> 24U)); 02280 02281 pCID->Reserved1 = (uint8_t)((hmmc->CID[3] & 0x00F00000U) >> 20U); 02282 02283 pCID->ManufactDate = (uint16_t)((hmmc->CID[3] & 0x000FFF00U) >> 8U); 02284 02285 pCID->CID_CRC = (uint8_t)((hmmc->CID[3] & 0x000000FEU) >> 1U); 02286 02287 pCID->Reserved2 = 1U; 02288 02289 return HAL_OK; 02290 } 02291 02292 /** 02293 * @brief Returns information the information of the card which are stored on 02294 * the CSD register. 02295 * @param hmmc Pointer to MMC handle 02296 * @param pCSD Pointer to a HAL_MMC_CardCSDTypeDef structure that 02297 * contains all CSD register parameters 02298 * @retval HAL status 02299 */ 02300 HAL_StatusTypeDef HAL_MMC_GetCardCSD(MMC_HandleTypeDef *hmmc, HAL_MMC_CardCSDTypeDef *pCSD) 02301 { 02302 uint32_t block_nbr = 0; 02303 02304 pCSD->CSDStruct = (uint8_t)((hmmc->CSD[0] & 0xC0000000U) >> 30U); 02305 02306 pCSD->SysSpecVersion = (uint8_t)((hmmc->CSD[0] & 0x3C000000U) >> 26U); 02307 02308 pCSD->Reserved1 = (uint8_t)((hmmc->CSD[0] & 0x03000000U) >> 24U); 02309 02310 pCSD->TAAC = (uint8_t)((hmmc->CSD[0] & 0x00FF0000U) >> 16U); 02311 02312 pCSD->NSAC = (uint8_t)((hmmc->CSD[0] & 0x0000FF00U) >> 8U); 02313 02314 pCSD->MaxBusClkFrec = (uint8_t)(hmmc->CSD[0] & 0x000000FFU); 02315 02316 pCSD->CardComdClasses = (uint16_t)((hmmc->CSD[1] & 0xFFF00000U) >> 20U); 02317 02318 pCSD->RdBlockLen = (uint8_t)((hmmc->CSD[1] & 0x000F0000U) >> 16U); 02319 02320 pCSD->PartBlockRead = (uint8_t)((hmmc->CSD[1] & 0x00008000U) >> 15U); 02321 02322 pCSD->WrBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00004000U) >> 14U); 02323 02324 pCSD->RdBlockMisalign = (uint8_t)((hmmc->CSD[1] & 0x00002000U) >> 13U); 02325 02326 pCSD->DSRImpl = (uint8_t)((hmmc->CSD[1] & 0x00001000U) >> 12U); 02327 02328 pCSD->Reserved2 = 0U; /*!< Reserved */ 02329 02330 if(MMC_ReadExtCSD(hmmc, &block_nbr, 212, 0x0FFFFFFFU) != HAL_OK) /* Field SEC_COUNT [215:212] */ 02331 { 02332 return HAL_ERROR; 02333 } 02334 02335 if(hmmc->MmcCard.CardType == MMC_LOW_CAPACITY_CARD) 02336 { 02337 pCSD->DeviceSize = (((hmmc->CSD[1] & 0x000003FFU) << 2U) | ((hmmc->CSD[2] & 0xC0000000U) >> 30U)); 02338 02339 pCSD->MaxRdCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x38000000U) >> 27U); 02340 02341 pCSD->MaxRdCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x07000000U) >> 24U); 02342 02343 pCSD->MaxWrCurrentVDDMin = (uint8_t)((hmmc->CSD[2] & 0x00E00000U) >> 21U); 02344 02345 pCSD->MaxWrCurrentVDDMax = (uint8_t)((hmmc->CSD[2] & 0x001C0000U) >> 18U); 02346 02347 pCSD->DeviceSizeMul = (uint8_t)((hmmc->CSD[2] & 0x00038000U) >> 15U); 02348 02349 hmmc->MmcCard.BlockNbr = (pCSD->DeviceSize + 1U) ; 02350 hmmc->MmcCard.BlockNbr *= (1UL << ((pCSD->DeviceSizeMul & 0x07U) + 2U)); 02351 hmmc->MmcCard.BlockSize = (1UL << (pCSD->RdBlockLen & 0x0FU)); 02352 02353 hmmc->MmcCard.LogBlockNbr = (hmmc->MmcCard.BlockNbr) * ((hmmc->MmcCard.BlockSize) / 512U); 02354 hmmc->MmcCard.LogBlockSize = 512U; 02355 } 02356 else if(hmmc->MmcCard.CardType == MMC_HIGH_CAPACITY_CARD) 02357 { 02358 hmmc->MmcCard.BlockNbr = block_nbr; 02359 hmmc->MmcCard.LogBlockNbr = hmmc->MmcCard.BlockNbr; 02360 hmmc->MmcCard.BlockSize = 512U; 02361 hmmc->MmcCard.LogBlockSize = hmmc->MmcCard.BlockSize; 02362 } 02363 else 02364 { 02365 /* Clear all the static flags */ 02366 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 02367 hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE; 02368 hmmc->State = HAL_MMC_STATE_READY; 02369 return HAL_ERROR; 02370 } 02371 02372 pCSD->EraseGrSize = (uint8_t)((hmmc->CSD[2] & 0x00004000U) >> 14U); 02373 02374 pCSD->EraseGrMul = (uint8_t)((hmmc->CSD[2] & 0x00003F80U) >> 7U); 02375 02376 pCSD->WrProtectGrSize = (uint8_t)(hmmc->CSD[2] & 0x0000007FU); 02377 02378 pCSD->WrProtectGrEnable = (uint8_t)((hmmc->CSD[3] & 0x80000000U) >> 31U); 02379 02380 pCSD->ManDeflECC = (uint8_t)((hmmc->CSD[3] & 0x60000000U) >> 29U); 02381 02382 pCSD->WrSpeedFact = (uint8_t)((hmmc->CSD[3] & 0x1C000000U) >> 26U); 02383 02384 pCSD->MaxWrBlockLen= (uint8_t)((hmmc->CSD[3] & 0x03C00000U) >> 22U); 02385 02386 pCSD->WriteBlockPaPartial = (uint8_t)((hmmc->CSD[3] & 0x00200000U) >> 21U); 02387 02388 pCSD->Reserved3 = 0; 02389 02390 pCSD->ContentProtectAppli = (uint8_t)((hmmc->CSD[3] & 0x00010000U) >> 16U); 02391 02392 pCSD->FileFormatGroup = (uint8_t)((hmmc->CSD[3] & 0x00008000U) >> 15U); 02393 02394 pCSD->CopyFlag = (uint8_t)((hmmc->CSD[3] & 0x00004000U) >> 14U); 02395 02396 pCSD->PermWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00002000U) >> 13U); 02397 02398 pCSD->TempWrProtect = (uint8_t)((hmmc->CSD[3] & 0x00001000U) >> 12U); 02399 02400 pCSD->FileFormat = (uint8_t)((hmmc->CSD[3] & 0x00000C00U) >> 10U); 02401 02402 pCSD->ECC= (uint8_t)((hmmc->CSD[3] & 0x00000300U) >> 8U); 02403 02404 pCSD->CSD_CRC = (uint8_t)((hmmc->CSD[3] & 0x000000FEU) >> 1U); 02405 02406 pCSD->Reserved4 = 1; 02407 02408 return HAL_OK; 02409 } 02410 02411 /** 02412 * @brief Gets the MMC card info. 02413 * @param hmmc Pointer to MMC handle 02414 * @param pCardInfo Pointer to the HAL_MMC_CardInfoTypeDef structure that 02415 * will contain the MMC card status information 02416 * @retval HAL status 02417 */ 02418 HAL_StatusTypeDef HAL_MMC_GetCardInfo(MMC_HandleTypeDef *hmmc, HAL_MMC_CardInfoTypeDef *pCardInfo) 02419 { 02420 pCardInfo->CardType = (uint32_t)(hmmc->MmcCard.CardType); 02421 pCardInfo->Class = (uint32_t)(hmmc->MmcCard.Class); 02422 pCardInfo->RelCardAdd = (uint32_t)(hmmc->MmcCard.RelCardAdd); 02423 pCardInfo->BlockNbr = (uint32_t)(hmmc->MmcCard.BlockNbr); 02424 pCardInfo->BlockSize = (uint32_t)(hmmc->MmcCard.BlockSize); 02425 pCardInfo->LogBlockNbr = (uint32_t)(hmmc->MmcCard.LogBlockNbr); 02426 pCardInfo->LogBlockSize = (uint32_t)(hmmc->MmcCard.LogBlockSize); 02427 02428 return HAL_OK; 02429 } 02430 02431 /** 02432 * @brief Returns information the information of the card which are stored on 02433 * the Extended CSD register. 02434 * @param hmmc Pointer to MMC handle 02435 * @param pExtCSD Pointer to a memory area (512 bytes) that contains all 02436 * Extended CSD register parameters 02437 * @param Timeout Specify timeout value 02438 * @retval HAL status 02439 */ 02440 HAL_StatusTypeDef HAL_MMC_GetCardExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pExtCSD, uint32_t Timeout) 02441 { 02442 SDMMC_DataInitTypeDef config; 02443 uint32_t errorstate; 02444 uint32_t tickstart = HAL_GetTick(); 02445 uint32_t count; 02446 uint32_t *tmp_buf; 02447 02448 if(NULL == pExtCSD) 02449 { 02450 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; 02451 return HAL_ERROR; 02452 } 02453 02454 if(hmmc->State == HAL_MMC_STATE_READY) 02455 { 02456 hmmc->ErrorCode = HAL_MMC_ERROR_NONE; 02457 02458 hmmc->State = HAL_MMC_STATE_BUSY; 02459 02460 /* Initialize data control register */ 02461 hmmc->Instance->DCTRL = 0; 02462 02463 /* Initiaize the destination pointer */ 02464 tmp_buf = pExtCSD; 02465 02466 /* Configure the MMC DPSM (Data Path State Machine) */ 02467 config.DataTimeOut = SDMMC_DATATIMEOUT; 02468 config.DataLength = 512; 02469 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; 02470 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; 02471 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; 02472 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 02473 config.DPSM = SDMMC_DPSM_ENABLE; 02474 #else 02475 config.DPSM = SDMMC_DPSM_DISABLE; 02476 #endif 02477 (void)SDMMC_ConfigData(hmmc->Instance, &config); 02478 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 02479 __SDMMC_CMDTRANS_ENABLE( hmmc->Instance); 02480 #endif 02481 02482 /* Send ExtCSD Read command to Card */ 02483 errorstate = SDMMC_CmdSendEXTCSD(hmmc->Instance, 0); 02484 if(errorstate != HAL_MMC_ERROR_NONE) 02485 { 02486 /* Clear all the static flags */ 02487 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 02488 hmmc->ErrorCode |= errorstate; 02489 hmmc->State = HAL_MMC_STATE_READY; 02490 return HAL_ERROR; 02491 } 02492 02493 /* Poll on SDMMC flags */ 02494 while(!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND)) 02495 { 02496 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF)) 02497 { 02498 /* Read data from SDMMC Rx FIFO */ 02499 for(count = 0U; count < 8U; count++) 02500 { 02501 *tmp_buf = SDMMC_ReadFIFO(hmmc->Instance); 02502 tmp_buf++; 02503 } 02504 } 02505 02506 if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U)) 02507 { 02508 /* Clear all the static flags */ 02509 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 02510 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT; 02511 hmmc->State= HAL_MMC_STATE_READY; 02512 return HAL_TIMEOUT; 02513 } 02514 } 02515 02516 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 02517 __SDMMC_CMDTRANS_DISABLE( hmmc->Instance); 02518 #endif 02519 02520 /* Get error state */ 02521 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT)) 02522 { 02523 /* Clear all the static flags */ 02524 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 02525 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT; 02526 hmmc->State = HAL_MMC_STATE_READY; 02527 return HAL_ERROR; 02528 } 02529 else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL)) 02530 { 02531 /* Clear all the static flags */ 02532 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 02533 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL; 02534 hmmc->State = HAL_MMC_STATE_READY; 02535 return HAL_ERROR; 02536 } 02537 else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR)) 02538 { 02539 /* Clear all the static flags */ 02540 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 02541 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN; 02542 hmmc->State = HAL_MMC_STATE_READY; 02543 return HAL_ERROR; 02544 } 02545 else 02546 { 02547 /* Nothing to do */ 02548 } 02549 02550 /* Clear all the static flags */ 02551 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS); 02552 hmmc->State = HAL_MMC_STATE_READY; 02553 } 02554 02555 return HAL_OK; 02556 } 02557 02558 /** 02559 * @brief Enables wide bus operation for the requested card if supported by 02560 * card. 02561 * @param hmmc Pointer to MMC handle 02562 * @param WideMode Specifies the MMC card wide bus mode 02563 * This parameter can be one of the following values: 02564 * @arg SDMMC_BUS_WIDE_8B: 8-bit data transfer 02565 * @arg SDMMC_BUS_WIDE_4B: 4-bit data transfer 02566 * @arg SDMMC_BUS_WIDE_1B: 1-bit data transfer 02567 * @retval HAL status 02568 */ 02569 HAL_StatusTypeDef HAL_MMC_ConfigWideBusOperation(MMC_HandleTypeDef *hmmc, uint32_t WideMode) 02570 { 02571 uint32_t count; 02572 SDMMC_InitTypeDef Init; 02573 uint32_t errorstate; 02574 uint32_t response = 0U; 02575 02576 /* Check the parameters */ 02577 assert_param(IS_SDMMC_BUS_WIDE(WideMode)); 02578 02579 /* Change State */ 02580 hmmc->State = HAL_MMC_STATE_BUSY; 02581 02582 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 02583 /* Check and update the power class if needed */ 02584 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) != 0U) 02585 { 02586 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) != 0U) 02587 { 02588 errorstate = MMC_PwrClassUpdate(hmmc, WideMode, SDMMC_SPEED_MODE_DDR); 02589 } 02590 else 02591 { 02592 errorstate = MMC_PwrClassUpdate(hmmc, WideMode, SDMMC_SPEED_MODE_HIGH); 02593 } 02594 } 02595 else 02596 { 02597 errorstate = MMC_PwrClassUpdate(hmmc, WideMode, SDMMC_SPEED_MODE_DEFAULT); 02598 } 02599 #else 02600 errorstate = MMC_PwrClassUpdate(hmmc, WideMode, 0U); 02601 #endif 02602 02603 if(errorstate == HAL_MMC_ERROR_NONE) 02604 { 02605 if(WideMode == SDMMC_BUS_WIDE_8B) 02606 { 02607 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U); 02608 } 02609 else if(WideMode == SDMMC_BUS_WIDE_4B) 02610 { 02611 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U); 02612 } 02613 else if(WideMode == SDMMC_BUS_WIDE_1B) 02614 { 02615 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70000U); 02616 } 02617 else 02618 { 02619 /* WideMode is not a valid argument*/ 02620 errorstate = HAL_MMC_ERROR_PARAM; 02621 } 02622 02623 /* Check for switch error and violation of the trial number of sending CMD 13 */ 02624 if(errorstate == HAL_MMC_ERROR_NONE) 02625 { 02626 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ 02627 count = SDMMC_MAX_TRIAL; 02628 do 02629 { 02630 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); 02631 if(errorstate != HAL_MMC_ERROR_NONE) 02632 { 02633 break; 02634 } 02635 02636 /* Get command response */ 02637 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1); 02638 count--; 02639 }while(((response & 0x100U) == 0U) && (count != 0U)); 02640 02641 /* Check the status after the switch command execution */ 02642 if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE)) 02643 { 02644 /* Check the bit SWITCH_ERROR of the device status */ 02645 if ((response & 0x80U) != 0U) 02646 { 02647 errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR; 02648 } 02649 else 02650 { 02651 /* Configure the SDMMC peripheral */ 02652 Init = hmmc->Init; 02653 Init.BusWide = WideMode; 02654 (void)SDMMC_Init(hmmc->Instance, Init); 02655 } 02656 } 02657 else if (count == 0U) 02658 { 02659 errorstate = SDMMC_ERROR_TIMEOUT; 02660 } 02661 else 02662 { 02663 /* Nothing to do */ 02664 } 02665 } 02666 } 02667 02668 /* Change State */ 02669 hmmc->State = HAL_MMC_STATE_READY; 02670 02671 if(errorstate != HAL_MMC_ERROR_NONE) 02672 { 02673 /* Clear all the static flags */ 02674 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 02675 hmmc->ErrorCode |= errorstate; 02676 return HAL_ERROR; 02677 } 02678 02679 return HAL_OK; 02680 } 02681 02682 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 02683 /** 02684 * @brief Configure the speed bus mode 02685 * @param hmmc Pointer to the MMC handle 02686 * @param SpeedMode Specifies the MMC card speed bus mode 02687 * This parameter can be one of the following values: 02688 * @arg SDMMC_SPEED_MODE_AUTO: Max speed mode supported by the card 02689 * @arg SDMMC_SPEED_MODE_DEFAULT: Default Speed (MMC @ 26MHz) 02690 * @arg SDMMC_SPEED_MODE_HIGH: High Speed (MMC @ 52 MHz) 02691 * @arg SDMMC_SPEED_MODE_DDR: High Speed DDR (MMC DDR @ 52 MHz) 02692 * @retval HAL status 02693 */ 02694 02695 HAL_StatusTypeDef HAL_MMC_ConfigSpeedBusOperation(MMC_HandleTypeDef *hmmc, uint32_t SpeedMode) 02696 { 02697 uint32_t tickstart; 02698 HAL_StatusTypeDef status = HAL_OK; 02699 uint32_t device_type; 02700 uint32_t errorstate; 02701 02702 /* Check the parameters */ 02703 assert_param(IS_SDMMC_SPEED_MODE(SpeedMode)); 02704 02705 /* Change State */ 02706 hmmc->State = HAL_MMC_STATE_BUSY; 02707 02708 /* Field DEVICE_TYPE [196 = 49*4] of Extended CSD register */ 02709 device_type = (hmmc->Ext_CSD[49] & 0x000000FFU); 02710 02711 switch (SpeedMode) 02712 { 02713 case SDMMC_SPEED_MODE_AUTO: 02714 { 02715 if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS) != 0U) && ((device_type & 0x04U) != 0U)) 02716 { 02717 /* High Speed DDR mode allowed */ 02718 errorstate = MMC_HighSpeed(hmmc, ENABLE); 02719 if(errorstate != HAL_MMC_ERROR_NONE) 02720 { 02721 hmmc->ErrorCode |= errorstate; 02722 } 02723 else 02724 { 02725 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_CLKDIV) != 0U) 02726 { 02727 /* DDR mode not supported with CLKDIV = 0 */ 02728 errorstate = MMC_DDR_Mode(hmmc, ENABLE); 02729 if(errorstate != HAL_MMC_ERROR_NONE) 02730 { 02731 hmmc->ErrorCode |= errorstate; 02732 } 02733 } 02734 } 02735 } 02736 else if ((device_type & 0x02U) != 0U) 02737 { 02738 /* High Speed mode allowed */ 02739 errorstate = MMC_HighSpeed(hmmc, ENABLE); 02740 if(errorstate != HAL_MMC_ERROR_NONE) 02741 { 02742 hmmc->ErrorCode |= errorstate; 02743 } 02744 } 02745 else 02746 { 02747 /* Nothing to do : keep current speed */ 02748 } 02749 break; 02750 } 02751 case SDMMC_SPEED_MODE_DDR: 02752 { 02753 if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS) != 0U) && ((device_type & 0x04U) != 0U)) 02754 { 02755 /* High Speed DDR mode allowed */ 02756 errorstate = MMC_HighSpeed(hmmc, ENABLE); 02757 if(errorstate != HAL_MMC_ERROR_NONE) 02758 { 02759 hmmc->ErrorCode |= errorstate; 02760 } 02761 else 02762 { 02763 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_CLKDIV) != 0U) 02764 { 02765 /* DDR mode not supported with CLKDIV = 0 */ 02766 errorstate = MMC_DDR_Mode(hmmc, ENABLE); 02767 if(errorstate != HAL_MMC_ERROR_NONE) 02768 { 02769 hmmc->ErrorCode |= errorstate; 02770 } 02771 } 02772 } 02773 } 02774 else 02775 { 02776 /* High Speed DDR mode not allowed */ 02777 hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE; 02778 status = HAL_ERROR; 02779 } 02780 break; 02781 } 02782 case SDMMC_SPEED_MODE_HIGH: 02783 { 02784 if ((device_type & 0x02U) != 0U) 02785 { 02786 /* High Speed mode allowed */ 02787 errorstate = MMC_HighSpeed(hmmc, ENABLE); 02788 if(errorstate != HAL_MMC_ERROR_NONE) 02789 { 02790 hmmc->ErrorCode |= errorstate; 02791 } 02792 } 02793 else 02794 { 02795 /* High Speed mode not allowed */ 02796 hmmc->ErrorCode |= HAL_MMC_ERROR_UNSUPPORTED_FEATURE; 02797 status = HAL_ERROR; 02798 } 02799 break; 02800 } 02801 case SDMMC_SPEED_MODE_DEFAULT: 02802 { 02803 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) != 0U) 02804 { 02805 /* High Speed DDR mode activated */ 02806 errorstate = MMC_DDR_Mode(hmmc, DISABLE); 02807 if(errorstate != HAL_MMC_ERROR_NONE) 02808 { 02809 hmmc->ErrorCode |= errorstate; 02810 } 02811 } 02812 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) != 0U) 02813 { 02814 /* High Speed mode activated */ 02815 errorstate = MMC_HighSpeed(hmmc, DISABLE); 02816 if(errorstate != HAL_MMC_ERROR_NONE) 02817 { 02818 hmmc->ErrorCode |= errorstate; 02819 } 02820 } 02821 break; 02822 } 02823 default: 02824 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; 02825 status = HAL_ERROR; 02826 break; 02827 } 02828 02829 /* Verify that MMC card is ready to use after Speed mode switch*/ 02830 tickstart = HAL_GetTick(); 02831 while ((HAL_MMC_GetCardState(hmmc) != HAL_MMC_CARD_TRANSFER)) 02832 { 02833 if ((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT) 02834 { 02835 hmmc->ErrorCode = HAL_MMC_ERROR_TIMEOUT; 02836 hmmc->State = HAL_MMC_STATE_READY; 02837 return HAL_TIMEOUT; 02838 } 02839 } 02840 02841 /* Change State */ 02842 hmmc->State = HAL_MMC_STATE_READY; 02843 return status; 02844 } 02845 #endif 02846 02847 /** 02848 * @brief Gets the current mmc card data state. 02849 * @param hmmc pointer to MMC handle 02850 * @retval Card state 02851 */ 02852 HAL_MMC_CardStateTypeDef HAL_MMC_GetCardState(MMC_HandleTypeDef *hmmc) 02853 { 02854 uint32_t cardstate; 02855 uint32_t errorstate; 02856 uint32_t resp1 = 0U; 02857 02858 errorstate = MMC_SendStatus(hmmc, &resp1); 02859 if(errorstate != HAL_MMC_ERROR_NONE) 02860 { 02861 hmmc->ErrorCode |= errorstate; 02862 } 02863 02864 cardstate = ((resp1 >> 9U) & 0x0FU); 02865 02866 return (HAL_MMC_CardStateTypeDef)cardstate; 02867 } 02868 02869 /** 02870 * @brief Abort the current transfer and disable the MMC. 02871 * @param hmmc pointer to a MMC_HandleTypeDef structure that contains 02872 * the configuration information for MMC module. 02873 * @retval HAL status 02874 */ 02875 HAL_StatusTypeDef HAL_MMC_Abort(MMC_HandleTypeDef *hmmc) 02876 { 02877 HAL_MMC_CardStateTypeDef CardState; 02878 02879 /* DIsable All interrupts */ 02880 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\ 02881 SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR); 02882 02883 /* Clear All flags */ 02884 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS); 02885 02886 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 02887 if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL)) 02888 { 02889 /* Disable the MMC DMA request */ 02890 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN); 02891 02892 /* Abort the MMC DMA Tx Stream */ 02893 if(hmmc->hdmatx != NULL) 02894 { 02895 if(HAL_DMA_Abort(hmmc->hdmatx) != HAL_OK) 02896 { 02897 hmmc->ErrorCode |= HAL_MMC_ERROR_DMA; 02898 } 02899 } 02900 /* Abort the MMC DMA Rx Stream */ 02901 if(hmmc->hdmarx != NULL) 02902 { 02903 if(HAL_DMA_Abort(hmmc->hdmarx) != HAL_OK) 02904 { 02905 hmmc->ErrorCode |= HAL_MMC_ERROR_DMA; 02906 } 02907 } 02908 } 02909 #else 02910 /* If IDMA Context, disable Internal DMA */ 02911 hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA; 02912 #endif 02913 02914 hmmc->State = HAL_MMC_STATE_READY; 02915 02916 /* Initialize the MMC operation */ 02917 hmmc->Context = MMC_CONTEXT_NONE; 02918 02919 CardState = HAL_MMC_GetCardState(hmmc); 02920 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING)) 02921 { 02922 hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance); 02923 } 02924 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE) 02925 { 02926 return HAL_ERROR; 02927 } 02928 return HAL_OK; 02929 } 02930 02931 /** 02932 * @brief Abort the current transfer and disable the MMC (IT mode). 02933 * @param hmmc pointer to a MMC_HandleTypeDef structure that contains 02934 * the configuration information for MMC module. 02935 * @retval HAL status 02936 */ 02937 HAL_StatusTypeDef HAL_MMC_Abort_IT(MMC_HandleTypeDef *hmmc) 02938 { 02939 HAL_MMC_CardStateTypeDef CardState; 02940 02941 /* DIsable All interrupts */ 02942 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\ 02943 SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR); 02944 02945 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 02946 /* If IDMA Context, disable Internal DMA */ 02947 hmmc->Instance->IDMACTRL = SDMMC_DISABLE_IDMA; 02948 #endif 02949 02950 /* Clear All flags */ 02951 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS); 02952 02953 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 02954 if((hmmc->hdmatx != NULL) || (hmmc->hdmarx != NULL)) 02955 { 02956 /* Disable the MMC DMA request */ 02957 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN); 02958 02959 /* Abort the MMC DMA Tx Stream */ 02960 if(hmmc->hdmatx != NULL) 02961 { 02962 hmmc->hdmatx->XferAbortCallback = MMC_DMATxAbort; 02963 if(HAL_DMA_Abort_IT(hmmc->hdmatx) != HAL_OK) 02964 { 02965 hmmc->hdmatx = NULL; 02966 } 02967 } 02968 /* Abort the MMC DMA Rx Stream */ 02969 if(hmmc->hdmarx != NULL) 02970 { 02971 hmmc->hdmarx->XferAbortCallback = MMC_DMARxAbort; 02972 if(HAL_DMA_Abort_IT(hmmc->hdmarx) != HAL_OK) 02973 { 02974 hmmc->hdmarx = NULL; 02975 } 02976 } 02977 } 02978 02979 /* No transfer ongoing on both DMA channels*/ 02980 if((hmmc->hdmatx == NULL) && (hmmc->hdmarx == NULL)) 02981 { 02982 #endif 02983 CardState = HAL_MMC_GetCardState(hmmc); 02984 hmmc->State = HAL_MMC_STATE_READY; 02985 02986 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING)) 02987 { 02988 hmmc->ErrorCode = SDMMC_CmdStopTransfer(hmmc->Instance); 02989 } 02990 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE) 02991 { 02992 return HAL_ERROR; 02993 } 02994 else 02995 { 02996 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 02997 hmmc->AbortCpltCallback(hmmc); 02998 #else 02999 HAL_MMC_AbortCallback(hmmc); 03000 #endif 03001 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 03002 } 03003 #endif 03004 } 03005 03006 return HAL_OK; 03007 } 03008 03009 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 03010 /** 03011 * @brief Perform specific commands sequence for the different type of erase. 03012 * @note This API should be followed by a check on the card state through 03013 * HAL_MMC_GetCardState(). 03014 * @param hmmc Pointer to MMC handle 03015 * @param EraseType Specifies the type of erase to be performed 03016 * This parameter can be one of the following values: 03017 * @arg HAL_MMC_ERASE Erase the erase groups identified by CMD35 & 36 03018 * @arg HAL_MMC_TRIM Erase the write blocks identified by CMD35 & 36 03019 * @arg HAL_MMC_DISCARD Discard the write blocks identified by CMD35 & 36 03020 * @arg HAL_MMC_SECURE_ERASE Perform a secure purge according SRT on the erase groups identified by CMD35 & 36 03021 * @arg HAL_MMC_SECURE_TRIM_STEP1 Mark the write blocks identified by CMD35 & 36 for secure erase 03022 * @arg HAL_MMC_SECURE_TRIM_STEP2 Perform a secure purge according SRT on the write blocks previously identified 03023 * @param BlockStartAdd Start Block address 03024 * @param BlockEndAdd End Block address 03025 * @retval HAL status 03026 */ 03027 HAL_StatusTypeDef HAL_MMC_EraseSequence(MMC_HandleTypeDef *hmmc, uint32_t EraseType, uint32_t BlockStartAdd, uint32_t BlockEndAdd) 03028 { 03029 uint32_t errorstate; 03030 uint32_t start_add = BlockStartAdd; 03031 uint32_t end_add = BlockEndAdd; 03032 uint32_t tickstart = HAL_GetTick(); 03033 03034 /* Check the erase type value is correct */ 03035 assert_param(IS_MMC_ERASE_TYPE(EraseType)); 03036 03037 /* Check the coherence between start and end address */ 03038 if(end_add < start_add) 03039 { 03040 hmmc->ErrorCode |= HAL_MMC_ERROR_PARAM; 03041 return HAL_ERROR; 03042 } 03043 03044 /* Check that the end address is not out of range of device memory */ 03045 if(end_add > (hmmc->MmcCard.LogBlockNbr)) 03046 { 03047 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; 03048 return HAL_ERROR; 03049 } 03050 03051 /* Check if the card command class supports erase command */ 03052 if(((hmmc->MmcCard.Class) & SDMMC_CCCC_ERASE) == 0U) 03053 { 03054 hmmc->ErrorCode |= HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE; 03055 return HAL_ERROR; 03056 } 03057 03058 /* Check the state of the driver */ 03059 if(hmmc->State == HAL_MMC_STATE_READY) 03060 { 03061 /* Change State */ 03062 hmmc->State = HAL_MMC_STATE_BUSY; 03063 03064 /* Check that the card is not locked */ 03065 if((SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED) 03066 { 03067 hmmc->ErrorCode |= HAL_MMC_ERROR_LOCK_UNLOCK_FAILED; 03068 hmmc->State = HAL_MMC_STATE_READY; 03069 return HAL_ERROR; 03070 } 03071 03072 /* In case of low capacity card, the address is not block number but bytes */ 03073 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD) 03074 { 03075 start_add *= 512U; 03076 end_add *= 512U; 03077 } 03078 03079 /* Send CMD35 MMC_ERASE_GRP_START with start address as argument */ 03080 errorstate = SDMMC_CmdEraseStartAdd(hmmc->Instance, start_add); 03081 if(errorstate == HAL_MMC_ERROR_NONE) 03082 { 03083 /* Send CMD36 MMC_ERASE_GRP_END with end address as argument */ 03084 errorstate = SDMMC_CmdEraseEndAdd(hmmc->Instance, end_add); 03085 if(errorstate == HAL_MMC_ERROR_NONE) 03086 { 03087 /* Send CMD38 ERASE with erase type as argument */ 03088 errorstate = SDMMC_CmdErase(hmmc->Instance, EraseType); 03089 if(errorstate == HAL_MMC_ERROR_NONE) 03090 { 03091 if ((EraseType == HAL_MMC_SECURE_ERASE) || (EraseType == HAL_MMC_SECURE_TRIM_STEP2)) 03092 { 03093 /* Wait that the device is ready by checking the D0 line */ 03094 while((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE)) 03095 { 03096 if((HAL_GetTick()-tickstart) >= SDMMC_MAXERASETIMEOUT) 03097 { 03098 errorstate = HAL_MMC_ERROR_TIMEOUT; 03099 } 03100 } 03101 03102 /* Clear the flag corresponding to end D0 bus line */ 03103 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END); 03104 } 03105 } 03106 } 03107 } 03108 03109 /* Change State */ 03110 hmmc->State = HAL_MMC_STATE_READY; 03111 03112 /* Manage errors */ 03113 if(errorstate != HAL_MMC_ERROR_NONE) 03114 { 03115 /* Clear all the static flags */ 03116 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 03117 hmmc->ErrorCode |= errorstate; 03118 03119 if(errorstate != HAL_MMC_ERROR_TIMEOUT) 03120 { 03121 return HAL_ERROR; 03122 } 03123 else 03124 { 03125 return HAL_TIMEOUT; 03126 } 03127 } 03128 else 03129 { 03130 return HAL_OK; 03131 } 03132 } 03133 else 03134 { 03135 return HAL_BUSY; 03136 } 03137 } 03138 03139 /** 03140 * @brief Perform sanitize operation on the device. 03141 * @note This API should be followed by a check on the card state through 03142 * HAL_MMC_GetCardState(). 03143 * @param hmmc Pointer to MMC handle 03144 * @retval HAL status 03145 */ 03146 HAL_StatusTypeDef HAL_MMC_Sanitize(MMC_HandleTypeDef *hmmc) 03147 { 03148 uint32_t errorstate, response = 0U, count; 03149 uint32_t tickstart = HAL_GetTick(); 03150 03151 /* Check the state of the driver */ 03152 if(hmmc->State == HAL_MMC_STATE_READY) 03153 { 03154 /* Change State */ 03155 hmmc->State = HAL_MMC_STATE_BUSY; 03156 03157 /* Index : 165 - Value : 0x01 */ 03158 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03A50100U); 03159 if(errorstate == HAL_MMC_ERROR_NONE) 03160 { 03161 /* Wait that the device is ready by checking the D0 line */ 03162 while((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE)) 03163 { 03164 if((HAL_GetTick()-tickstart) >= SDMMC_MAXERASETIMEOUT) 03165 { 03166 errorstate = HAL_MMC_ERROR_TIMEOUT; 03167 } 03168 } 03169 03170 /* Clear the flag corresponding to end D0 bus line */ 03171 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END); 03172 03173 if(errorstate == HAL_MMC_ERROR_NONE) 03174 { 03175 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ 03176 count = SDMMC_MAX_TRIAL; 03177 do 03178 { 03179 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); 03180 if(errorstate != HAL_MMC_ERROR_NONE) 03181 { 03182 break; 03183 } 03184 03185 /* Get command response */ 03186 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1); 03187 count--; 03188 }while(((response & 0x100U) == 0U) && (count != 0U)); 03189 03190 /* Check the status after the switch command execution */ 03191 if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE)) 03192 { 03193 /* Check the bit SWITCH_ERROR of the device status */ 03194 if ((response & 0x80U) != 0U) 03195 { 03196 errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR; 03197 } 03198 } 03199 else if (count == 0U) 03200 { 03201 errorstate = SDMMC_ERROR_TIMEOUT; 03202 } 03203 else 03204 { 03205 /* Nothing to do */ 03206 } 03207 } 03208 } 03209 03210 /* Change State */ 03211 hmmc->State = HAL_MMC_STATE_READY; 03212 03213 /* Manage errors */ 03214 if(errorstate != HAL_MMC_ERROR_NONE) 03215 { 03216 /* Clear all the static flags */ 03217 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 03218 hmmc->ErrorCode |= errorstate; 03219 03220 if(errorstate != HAL_MMC_ERROR_TIMEOUT) 03221 { 03222 return HAL_ERROR; 03223 } 03224 else 03225 { 03226 return HAL_TIMEOUT; 03227 } 03228 } 03229 else 03230 { 03231 return HAL_OK; 03232 } 03233 } 03234 else 03235 { 03236 return HAL_BUSY; 03237 } 03238 } 03239 03240 /** 03241 * @brief Configure the Secure Removal Type (SRT) in the Extended CSD register. 03242 * @note This API should be followed by a check on the card state through 03243 * HAL_MMC_GetCardState(). 03244 * @param hmmc Pointer to MMC handle 03245 * @param SRTMode Specifies the type of erase to be performed 03246 * This parameter can be one of the following values: 03247 * @arg HAL_MMC_SRT_ERASE Information removed by an erase 03248 * @arg HAL_MMC_SRT_WRITE_CHAR_ERASE Information removed by an overwriting with a character followed by an erase 03249 * @arg HAL_MMC_SRT_WRITE_CHAR_COMPL_RANDOM Information removed by an overwriting with a character, its complement then a random character 03250 * @arg HAL_MMC_SRT_VENDOR_DEFINED Information removed using a vendor defined 03251 * @retval HAL status 03252 */ 03253 HAL_StatusTypeDef HAL_MMC_ConfigSecRemovalType(MMC_HandleTypeDef *hmmc, uint32_t SRTMode) 03254 { 03255 uint32_t srt, errorstate, response = 0U, count; 03256 03257 /* Check the erase type value is correct */ 03258 assert_param(IS_MMC_SRT_TYPE(SRTMode)); 03259 03260 /* Check the state of the driver */ 03261 if(hmmc->State == HAL_MMC_STATE_READY) 03262 { 03263 /* Get the supported values by the device */ 03264 if(HAL_MMC_GetSupportedSecRemovalType(hmmc, &srt) == HAL_OK) 03265 { 03266 /* Change State */ 03267 hmmc->State = HAL_MMC_STATE_BUSY; 03268 03269 /* Check the value passed as parameter is supported by the device */ 03270 if((SRTMode & srt) != 0U) 03271 { 03272 /* Index : 16 - Value : SRTMode */ 03273 srt |= ((POSITION_VAL(SRTMode)) << 4U); 03274 errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03100000U | (srt << 8U))); 03275 if(errorstate == HAL_MMC_ERROR_NONE) 03276 { 03277 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ 03278 count = SDMMC_MAX_TRIAL; 03279 do 03280 { 03281 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); 03282 if(errorstate != HAL_MMC_ERROR_NONE) 03283 { 03284 break; 03285 } 03286 03287 /* Get command response */ 03288 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1); 03289 count--; 03290 }while(((response & 0x100U) == 0U) && (count != 0U)); 03291 03292 /* Check the status after the switch command execution */ 03293 if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE)) 03294 { 03295 /* Check the bit SWITCH_ERROR of the device status */ 03296 if ((response & 0x80U) != 0U) 03297 { 03298 errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR; 03299 } 03300 } 03301 else if (count == 0U) 03302 { 03303 errorstate = SDMMC_ERROR_TIMEOUT; 03304 } 03305 else 03306 { 03307 /* Nothing to do */ 03308 } 03309 } 03310 } 03311 else 03312 { 03313 errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE; 03314 } 03315 03316 /* Change State */ 03317 hmmc->State = HAL_MMC_STATE_READY; 03318 } 03319 else 03320 { 03321 errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR; 03322 } 03323 03324 /* Manage errors */ 03325 if(errorstate != HAL_MMC_ERROR_NONE) 03326 { 03327 /* Clear all the static flags */ 03328 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 03329 hmmc->ErrorCode |= errorstate; 03330 return HAL_ERROR; 03331 } 03332 else 03333 { 03334 return HAL_OK; 03335 } 03336 } 03337 else 03338 { 03339 return HAL_BUSY; 03340 } 03341 } 03342 03343 /** 03344 * @brief Gets the supported values of the the Secure Removal Type (SRT). 03345 * @param hmmc pointer to MMC handle 03346 * @param SupportedSRT pointer for supported SRT value 03347 * This parameter is a bit field of the following values: 03348 * @arg HAL_MMC_SRT_ERASE Information removed by an erase 03349 * @arg HAL_MMC_SRT_WRITE_CHAR_ERASE Information removed by an overwriting with a character followed by an erase 03350 * @arg HAL_MMC_SRT_WRITE_CHAR_COMPL_RANDOM Information removed by an overwriting with a character, its complement then a random character 03351 * @arg HAL_MMC_SRT_VENDOR_DEFINED Information removed using a vendor defined 03352 * @retval HAL status 03353 */ 03354 HAL_StatusTypeDef HAL_MMC_GetSupportedSecRemovalType(MMC_HandleTypeDef *hmmc, uint32_t *SupportedSRT) 03355 { 03356 /* Check the state of the driver */ 03357 if(hmmc->State == HAL_MMC_STATE_READY) 03358 { 03359 /* Change State */ 03360 hmmc->State = HAL_MMC_STATE_BUSY; 03361 03362 /* Read field SECURE_REMOVAL_TYPE [16 = 4*4] of the Extended CSD register */ 03363 *SupportedSRT = (hmmc->Ext_CSD[4] & 0x0000000FU); /* Bits [3:0] of field 16 */ 03364 03365 /* Change State */ 03366 hmmc->State = HAL_MMC_STATE_READY; 03367 03368 return HAL_OK; 03369 } 03370 else 03371 { 03372 return HAL_BUSY; 03373 } 03374 } 03375 03376 /** 03377 * @brief Switch the device from Standby State to Sleep State. 03378 * @param hmmc pointer to MMC handle 03379 * @retval HAL status 03380 */ 03381 HAL_StatusTypeDef HAL_MMC_SleepDevice(MMC_HandleTypeDef *hmmc) 03382 { 03383 uint32_t errorstate, sleep_timeout, timeout, count, response = 0U; 03384 uint32_t tickstart = HAL_GetTick(); 03385 03386 /* Check the state of the driver */ 03387 if(hmmc->State == HAL_MMC_STATE_READY) 03388 { 03389 /* Change State */ 03390 hmmc->State = HAL_MMC_STATE_BUSY; 03391 03392 /* Set the power-off notification to powered-on : Ext_CSD[34] = 1 */ 03393 errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03220100U)); 03394 if (errorstate == HAL_MMC_ERROR_NONE) 03395 { 03396 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ 03397 count = SDMMC_MAX_TRIAL; 03398 do 03399 { 03400 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); 03401 if(errorstate != HAL_MMC_ERROR_NONE) 03402 { 03403 break; 03404 } 03405 03406 /* Get command response */ 03407 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1); 03408 count--; 03409 }while(((response & 0x100U) == 0U) && (count != 0U)); 03410 03411 /* Check the status after the switch command execution */ 03412 if (count == 0U) 03413 { 03414 errorstate = SDMMC_ERROR_TIMEOUT; 03415 } 03416 else if (errorstate == HAL_MMC_ERROR_NONE) 03417 { 03418 /* Check the bit SWITCH_ERROR of the device status */ 03419 if ((response & 0x80U) != 0U) 03420 { 03421 errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE; 03422 } 03423 else 03424 { 03425 /* Set the power-off notification to sleep notification : Ext_CSD[34] = 4 */ 03426 errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03220400U)); 03427 if (errorstate == HAL_MMC_ERROR_NONE) 03428 { 03429 /* Field SLEEP_NOTIFICATION_TIME [216] */ 03430 sleep_timeout = ((hmmc->Ext_CSD[(MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_INDEX/4)] >> MMC_EXT_CSD_SLEEP_NOTIFICATION_TIME_POS) & 0x000000FFU); 03431 03432 /* Sleep/Awake Timeout = 10µs * 2^SLEEP_NOTIFICATION_TIME, max value of SLEEP_NOTIFICATION_TIME is 0x17 */ 03433 /* In HAL, the tick interrupt occurs each ms */ 03434 timeout = (((1UL << (sleep_timeout & 0x1FU)) / 100U) + 1U); 03435 03436 /* Wait that the device is ready by checking the D0 line */ 03437 while((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE)) 03438 { 03439 if((HAL_GetTick() - tickstart) >= timeout) 03440 { 03441 errorstate = SDMMC_ERROR_TIMEOUT; 03442 } 03443 } 03444 03445 /* Clear the flag corresponding to end D0 bus line */ 03446 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END); 03447 03448 if (errorstate == HAL_MMC_ERROR_NONE) 03449 { 03450 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ 03451 count = SDMMC_MAX_TRIAL; 03452 do 03453 { 03454 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); 03455 if(errorstate != HAL_MMC_ERROR_NONE) 03456 { 03457 break; 03458 } 03459 03460 /* Get command response */ 03461 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1); 03462 count--; 03463 }while(((response & 0x100U) == 0U) && (count != 0U)); 03464 03465 /* Check the status after the switch command execution */ 03466 if (count == 0U) 03467 { 03468 errorstate = SDMMC_ERROR_TIMEOUT; 03469 } 03470 else if (errorstate == HAL_MMC_ERROR_NONE) 03471 { 03472 /* Check the bit SWITCH_ERROR of the device status */ 03473 if ((response & 0x80U) != 0U) 03474 { 03475 errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE; 03476 } 03477 else 03478 { 03479 /* Switch the device in stand-by mode */ 03480 (void)SDMMC_CmdSelDesel(hmmc->Instance, 0U); 03481 03482 /* Field S_A_TIEMOUT [217] */ 03483 sleep_timeout = ((hmmc->Ext_CSD[(MMC_EXT_CSD_S_A_TIMEOUT_INDEX/4)] >> MMC_EXT_CSD_S_A_TIMEOUT_POS) & 0x000000FFU); 03484 03485 /* Sleep/Awake Timeout = 100ns * 2^S_A_TIMEOUT, max value of S_A_TIMEOUT is 0x17 */ 03486 /* In HAL, the tick interrupt occurs each ms */ 03487 timeout = (((1UL << (sleep_timeout & 0x1FU)) / 10000U) + 1U); 03488 03489 if (HAL_MMC_GetCardState(hmmc) == HAL_MMC_CARD_STANDBY) 03490 { 03491 /* Send CMD5 CMD_MMC_SLEEP_AWAKE with RCA and SLEEP as argument */ 03492 errorstate = SDMMC_CmdSleepMmc(hmmc->Instance, ((hmmc->MmcCard.RelCardAdd << 16U) | (0x1U << 15U))); 03493 if (errorstate == HAL_MMC_ERROR_NONE) 03494 { 03495 /* Wait that the device is ready by checking the D0 line */ 03496 while((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE)) 03497 { 03498 if((HAL_GetTick() - tickstart) >= timeout) 03499 { 03500 errorstate = SDMMC_ERROR_TIMEOUT; 03501 } 03502 } 03503 03504 /* Clear the flag corresponding to end D0 bus line */ 03505 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END); 03506 } 03507 } 03508 else 03509 { 03510 errorstate = SDMMC_ERROR_REQUEST_NOT_APPLICABLE; 03511 } 03512 } 03513 } 03514 else 03515 { 03516 /* Nothing to do */ 03517 } 03518 } 03519 } 03520 } 03521 } 03522 else 03523 { 03524 /* Nothing to do */ 03525 } 03526 } 03527 03528 /* Change State */ 03529 hmmc->State = HAL_MMC_STATE_READY; 03530 03531 /* Manage errors */ 03532 if (errorstate != HAL_MMC_ERROR_NONE) 03533 { 03534 /* Clear all the static flags */ 03535 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 03536 hmmc->ErrorCode |= errorstate; 03537 03538 if (errorstate != HAL_MMC_ERROR_TIMEOUT) 03539 { 03540 return HAL_ERROR; 03541 } 03542 else 03543 { 03544 return HAL_TIMEOUT; 03545 } 03546 } 03547 else 03548 { 03549 return HAL_OK; 03550 } 03551 } 03552 else 03553 { 03554 return HAL_BUSY; 03555 } 03556 } 03557 03558 /** 03559 * @brief Switch the device from Sleep State to Standby State. 03560 * @param hmmc pointer to MMC handle 03561 * @retval HAL status 03562 */ 03563 HAL_StatusTypeDef HAL_MMC_AwakeDevice(MMC_HandleTypeDef *hmmc) 03564 { 03565 uint32_t errorstate, sleep_timeout, timeout, count, response = 0U; 03566 uint32_t tickstart = HAL_GetTick(); 03567 03568 /* Check the state of the driver */ 03569 if (hmmc->State == HAL_MMC_STATE_READY) 03570 { 03571 /* Change State */ 03572 hmmc->State = HAL_MMC_STATE_BUSY; 03573 03574 /* Field S_A_TIEMOUT [217] */ 03575 sleep_timeout = ((hmmc->Ext_CSD[(MMC_EXT_CSD_S_A_TIMEOUT_INDEX/4)] >> MMC_EXT_CSD_S_A_TIMEOUT_POS) & 0x000000FFU); 03576 03577 /* Sleep/Awake Timeout = 100ns * 2^S_A_TIMEOUT, max value of S_A_TIMEOUT is 0x17 */ 03578 /* In HAL, the tick interrupt occurs each ms */ 03579 timeout = (((1UL << (sleep_timeout & 0x1FU)) / 10000U) + 1U); 03580 03581 /* Send CMD5 CMD_MMC_SLEEP_AWAKE with RCA and AWAKE as argument */ 03582 errorstate = SDMMC_CmdSleepMmc(hmmc->Instance, (hmmc->MmcCard.RelCardAdd << 16U)); 03583 if (errorstate == HAL_MMC_ERROR_NONE) 03584 { 03585 /* Wait that the device is ready by checking the D0 line */ 03586 while ((!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_BUSYD0END)) && (errorstate == HAL_MMC_ERROR_NONE)) 03587 { 03588 if((HAL_GetTick() - tickstart) >= timeout) 03589 { 03590 errorstate = SDMMC_ERROR_TIMEOUT; 03591 } 03592 } 03593 03594 /* Clear the flag corresponding to end D0 bus line */ 03595 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_FLAG_BUSYD0END); 03596 03597 if (errorstate == HAL_MMC_ERROR_NONE) 03598 { 03599 if (HAL_MMC_GetCardState(hmmc) == HAL_MMC_CARD_STANDBY) 03600 { 03601 /* Switch the device in transfer mode */ 03602 errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); 03603 if (errorstate == HAL_MMC_ERROR_NONE) 03604 { 03605 if (HAL_MMC_GetCardState(hmmc) == HAL_MMC_CARD_TRANSFER) 03606 { 03607 /* Set the power-off notification to powered-on : Ext_CSD[34] = 1 */ 03608 errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03220100U)); 03609 if (errorstate == HAL_MMC_ERROR_NONE) 03610 { 03611 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ 03612 count = SDMMC_MAX_TRIAL; 03613 do 03614 { 03615 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); 03616 if(errorstate != HAL_MMC_ERROR_NONE) 03617 { 03618 break; 03619 } 03620 03621 /* Get command response */ 03622 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1); 03623 count--; 03624 }while(((response & 0x100U) == 0U) && (count != 0U)); 03625 03626 /* Check the status after the switch command execution */ 03627 if (count == 0U) 03628 { 03629 errorstate = SDMMC_ERROR_TIMEOUT; 03630 } 03631 else if (errorstate == HAL_MMC_ERROR_NONE) 03632 { 03633 /* Check the bit SWITCH_ERROR of the device status */ 03634 if ((response & 0x80U) != 0U) 03635 { 03636 errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE; 03637 } 03638 } 03639 else 03640 { 03641 /* Nothing to do */ 03642 } 03643 } 03644 } 03645 else 03646 { 03647 errorstate = SDMMC_ERROR_REQUEST_NOT_APPLICABLE; 03648 } 03649 } 03650 } 03651 else 03652 { 03653 errorstate = SDMMC_ERROR_REQUEST_NOT_APPLICABLE; 03654 } 03655 } 03656 } 03657 03658 /* Change State */ 03659 hmmc->State = HAL_MMC_STATE_READY; 03660 03661 /* Manage errors */ 03662 if (errorstate != HAL_MMC_ERROR_NONE) 03663 { 03664 /* Clear all the static flags */ 03665 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 03666 hmmc->ErrorCode |= errorstate; 03667 03668 if (errorstate != HAL_MMC_ERROR_TIMEOUT) 03669 { 03670 return HAL_ERROR; 03671 } 03672 else 03673 { 03674 return HAL_TIMEOUT; 03675 } 03676 } 03677 else 03678 { 03679 return HAL_OK; 03680 } 03681 } 03682 else 03683 { 03684 return HAL_BUSY; 03685 } 03686 } 03687 #endif /* defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) */ 03688 03689 /** 03690 * @} 03691 */ 03692 03693 /** 03694 * @} 03695 */ 03696 03697 /* Private function ----------------------------------------------------------*/ 03698 /** @addtogroup MMC_Private_Functions 03699 * @{ 03700 */ 03701 03702 #if !defined(STM32L4P5xx) && !defined(STM32L4Q5xx) && !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 03703 /** 03704 * @brief DMA MMC transmit process complete callback 03705 * @param hdma DMA handle 03706 * @retval None 03707 */ 03708 static void MMC_DMATransmitCplt(DMA_HandleTypeDef *hdma) 03709 { 03710 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent); 03711 03712 /* Enable DATAEND Interrupt */ 03713 __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DATAEND)); 03714 } 03715 03716 /** 03717 * @brief DMA MMC receive process complete callback 03718 * @param hdma DMA handle 03719 * @retval None 03720 */ 03721 static void MMC_DMAReceiveCplt(DMA_HandleTypeDef *hdma) 03722 { 03723 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent); 03724 uint32_t errorstate; 03725 03726 /* Send stop command in multiblock write */ 03727 if(hmmc->Context == (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA)) 03728 { 03729 errorstate = SDMMC_CmdStopTransfer(hmmc->Instance); 03730 if(errorstate != HAL_MMC_ERROR_NONE) 03731 { 03732 hmmc->ErrorCode |= errorstate; 03733 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 03734 hmmc->ErrorCallback(hmmc); 03735 #else 03736 HAL_MMC_ErrorCallback(hmmc); 03737 #endif 03738 } 03739 } 03740 03741 /* Disable the DMA transfer for transmit request by setting the DMAEN bit 03742 in the MMC DCTRL register */ 03743 hmmc->Instance->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN); 03744 03745 /* Clear all the static flags */ 03746 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS); 03747 03748 hmmc->State = HAL_MMC_STATE_READY; 03749 hmmc->Context = MMC_CONTEXT_NONE; 03750 03751 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 03752 hmmc->RxCpltCallback(hmmc); 03753 #else 03754 HAL_MMC_RxCpltCallback(hmmc); 03755 #endif 03756 } 03757 03758 /** 03759 * @brief DMA MMC communication error callback 03760 * @param hdma DMA handle 03761 * @retval None 03762 */ 03763 static void MMC_DMAError(DMA_HandleTypeDef *hdma) 03764 { 03765 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent); 03766 HAL_MMC_CardStateTypeDef CardState; 03767 uint32_t RxErrorCode, TxErrorCode; 03768 03769 RxErrorCode = hmmc->hdmarx->ErrorCode; 03770 TxErrorCode = hmmc->hdmatx->ErrorCode; 03771 if((RxErrorCode == HAL_DMA_ERROR_TE) || (TxErrorCode == HAL_DMA_ERROR_TE)) 03772 { 03773 /* Clear All flags */ 03774 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 03775 03776 /* Disable All interrupts */ 03777 __HAL_MMC_DISABLE_IT(hmmc, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\ 03778 SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR); 03779 03780 hmmc->ErrorCode |= HAL_MMC_ERROR_DMA; 03781 CardState = HAL_MMC_GetCardState(hmmc); 03782 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING)) 03783 { 03784 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance); 03785 } 03786 03787 hmmc->State= HAL_MMC_STATE_READY; 03788 hmmc->Context = MMC_CONTEXT_NONE; 03789 } 03790 03791 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 03792 hmmc->ErrorCallback(hmmc); 03793 #else 03794 HAL_MMC_ErrorCallback(hmmc); 03795 #endif 03796 } 03797 03798 /** 03799 * @brief DMA MMC Tx Abort callback 03800 * @param hdma DMA handle 03801 * @retval None 03802 */ 03803 static void MMC_DMATxAbort(DMA_HandleTypeDef *hdma) 03804 { 03805 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent); 03806 HAL_MMC_CardStateTypeDef CardState; 03807 03808 if(hmmc->hdmatx != NULL) 03809 { 03810 hmmc->hdmatx = NULL; 03811 } 03812 03813 /* All DMA channels are aborted */ 03814 if(hmmc->hdmarx == NULL) 03815 { 03816 CardState = HAL_MMC_GetCardState(hmmc); 03817 hmmc->ErrorCode = HAL_MMC_ERROR_NONE; 03818 hmmc->State = HAL_MMC_STATE_READY; 03819 hmmc->Context = MMC_CONTEXT_NONE; 03820 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING)) 03821 { 03822 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance); 03823 03824 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE) 03825 { 03826 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 03827 hmmc->AbortCpltCallback(hmmc); 03828 #else 03829 HAL_MMC_AbortCallback(hmmc); 03830 #endif 03831 } 03832 else 03833 { 03834 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 03835 hmmc->ErrorCallback(hmmc); 03836 #else 03837 HAL_MMC_ErrorCallback(hmmc); 03838 #endif 03839 } 03840 } 03841 } 03842 } 03843 03844 /** 03845 * @brief DMA MMC Rx Abort callback 03846 * @param hdma DMA handle 03847 * @retval None 03848 */ 03849 static void MMC_DMARxAbort(DMA_HandleTypeDef *hdma) 03850 { 03851 MMC_HandleTypeDef* hmmc = (MMC_HandleTypeDef* )(hdma->Parent); 03852 HAL_MMC_CardStateTypeDef CardState; 03853 03854 if(hmmc->hdmarx != NULL) 03855 { 03856 hmmc->hdmarx = NULL; 03857 } 03858 03859 /* All DMA channels are aborted */ 03860 if(hmmc->hdmatx == NULL) 03861 { 03862 CardState = HAL_MMC_GetCardState(hmmc); 03863 hmmc->ErrorCode = HAL_MMC_ERROR_NONE; 03864 hmmc->State = HAL_MMC_STATE_READY; 03865 hmmc->Context = MMC_CONTEXT_NONE; 03866 if((CardState == HAL_MMC_CARD_RECEIVING) || (CardState == HAL_MMC_CARD_SENDING)) 03867 { 03868 hmmc->ErrorCode |= SDMMC_CmdStopTransfer(hmmc->Instance); 03869 03870 if(hmmc->ErrorCode != HAL_MMC_ERROR_NONE) 03871 { 03872 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 03873 hmmc->AbortCpltCallback(hmmc); 03874 #else 03875 HAL_MMC_AbortCallback(hmmc); 03876 #endif 03877 } 03878 else 03879 { 03880 #if defined (USE_HAL_MMC_REGISTER_CALLBACKS) && (USE_HAL_MMC_REGISTER_CALLBACKS == 1U) 03881 hmmc->ErrorCallback(hmmc); 03882 #else 03883 HAL_MMC_ErrorCallback(hmmc); 03884 #endif 03885 } 03886 } 03887 } 03888 } 03889 #endif 03890 03891 /** 03892 * @brief Initializes the mmc card. 03893 * @param hmmc Pointer to MMC handle 03894 * @retval MMC Card error state 03895 */ 03896 static uint32_t MMC_InitCard(MMC_HandleTypeDef *hmmc) 03897 { 03898 HAL_MMC_CardCSDTypeDef CSD; 03899 uint32_t errorstate; 03900 uint16_t mmc_rca = 2U; 03901 MMC_InitTypeDef Init; 03902 03903 /* Check the power State */ 03904 if(SDMMC_GetPowerState(hmmc->Instance) == 0U) 03905 { 03906 /* Power off */ 03907 return HAL_MMC_ERROR_REQUEST_NOT_APPLICABLE; 03908 } 03909 03910 /* Send CMD2 ALL_SEND_CID */ 03911 errorstate = SDMMC_CmdSendCID(hmmc->Instance); 03912 if(errorstate != HAL_MMC_ERROR_NONE) 03913 { 03914 return errorstate; 03915 } 03916 else 03917 { 03918 /* Get Card identification number data */ 03919 hmmc->CID[0U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1); 03920 hmmc->CID[1U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2); 03921 hmmc->CID[2U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP3); 03922 hmmc->CID[3U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP4); 03923 } 03924 03925 /* Send CMD3 SET_REL_ADDR with RCA = 2 (should be greater than 1) */ 03926 /* MMC Card publishes its RCA. */ 03927 errorstate = SDMMC_CmdSetRelAddMmc(hmmc->Instance, mmc_rca); 03928 if(errorstate != HAL_MMC_ERROR_NONE) 03929 { 03930 return errorstate; 03931 } 03932 03933 /* Get the MMC card RCA */ 03934 hmmc->MmcCard.RelCardAdd = mmc_rca; 03935 03936 /* Send CMD9 SEND_CSD with argument as card's RCA */ 03937 errorstate = SDMMC_CmdSendCSD(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U)); 03938 if(errorstate != HAL_MMC_ERROR_NONE) 03939 { 03940 return errorstate; 03941 } 03942 else 03943 { 03944 /* Get Card Specific Data */ 03945 hmmc->CSD[0U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1); 03946 hmmc->CSD[1U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2); 03947 hmmc->CSD[2U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP3); 03948 hmmc->CSD[3U] = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP4); 03949 } 03950 03951 /* Get the Card Class */ 03952 hmmc->MmcCard.Class = (SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP2) >> 20U); 03953 03954 /* Select the Card */ 03955 errorstate = SDMMC_CmdSelDesel(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); 03956 if(errorstate != HAL_MMC_ERROR_NONE) 03957 { 03958 return errorstate; 03959 } 03960 03961 /* Get CSD parameters */ 03962 if (HAL_MMC_GetCardCSD(hmmc, &CSD) != HAL_OK) 03963 { 03964 return hmmc->ErrorCode; 03965 } 03966 03967 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ 03968 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); 03969 if(errorstate != HAL_MMC_ERROR_NONE) 03970 { 03971 hmmc->ErrorCode |= errorstate; 03972 } 03973 03974 /* Get Extended CSD parameters */ 03975 if (HAL_MMC_GetCardExtCSD(hmmc, hmmc->Ext_CSD, SDMMC_DATATIMEOUT) != HAL_OK) 03976 { 03977 return hmmc->ErrorCode; 03978 } 03979 03980 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ 03981 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); 03982 if(errorstate != HAL_MMC_ERROR_NONE) 03983 { 03984 hmmc->ErrorCode |= errorstate; 03985 } 03986 03987 /* Configure the SDMMC peripheral */ 03988 Init = hmmc->Init; 03989 Init.BusWide = SDMMC_BUS_WIDE_1B; 03990 (void)SDMMC_Init(hmmc->Instance, Init); 03991 03992 /* All cards are initialized */ 03993 return HAL_MMC_ERROR_NONE; 03994 } 03995 03996 /** 03997 * @brief Enquires cards about their operating voltage and configures clock 03998 * controls and stores MMC information that will be needed in future 03999 * in the MMC handle. 04000 * @param hmmc Pointer to MMC handle 04001 * @retval error state 04002 */ 04003 static uint32_t MMC_PowerON(MMC_HandleTypeDef *hmmc) 04004 { 04005 __IO uint32_t count = 0U; 04006 uint32_t response = 0U, validvoltage = 0U; 04007 uint32_t errorstate; 04008 04009 /* CMD0: GO_IDLE_STATE */ 04010 errorstate = SDMMC_CmdGoIdleState(hmmc->Instance); 04011 if(errorstate != HAL_MMC_ERROR_NONE) 04012 { 04013 return errorstate; 04014 } 04015 04016 while(validvoltage == 0U) 04017 { 04018 if(count++ == SDMMC_MAX_VOLT_TRIAL) 04019 { 04020 return HAL_MMC_ERROR_INVALID_VOLTRANGE; 04021 } 04022 04023 /* SEND CMD1 APP_CMD with voltage range as argument */ 04024 errorstate = SDMMC_CmdOpCondition(hmmc->Instance, MMC_VOLTAGE_RANGE); 04025 if(errorstate != HAL_MMC_ERROR_NONE) 04026 { 04027 return HAL_MMC_ERROR_UNSUPPORTED_FEATURE; 04028 } 04029 04030 /* Get command response */ 04031 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1); 04032 04033 /* Get operating voltage*/ 04034 validvoltage = (((response >> 31U) == 1U) ? 1U : 0U); 04035 } 04036 04037 /* When power routine is finished and command returns valid voltage */ 04038 if (((response & (0xFF000000U)) >> 24) == 0xC0U) 04039 { 04040 hmmc->MmcCard.CardType = MMC_HIGH_CAPACITY_CARD; 04041 } 04042 else 04043 { 04044 hmmc->MmcCard.CardType = MMC_LOW_CAPACITY_CARD; 04045 } 04046 04047 return HAL_MMC_ERROR_NONE; 04048 } 04049 04050 /** 04051 * @brief Turns the SDMMC output signals off. 04052 * @param hmmc Pointer to MMC handle 04053 * @retval None 04054 */ 04055 static void MMC_PowerOFF(MMC_HandleTypeDef *hmmc) 04056 { 04057 /* Set Power State to OFF */ 04058 (void)SDMMC_PowerState_OFF(hmmc->Instance); 04059 } 04060 04061 /** 04062 * @brief Returns the current card's status. 04063 * @param hmmc Pointer to MMC handle 04064 * @param pCardStatus pointer to the buffer that will contain the MMC card 04065 * status (Card Status register) 04066 * @retval error state 04067 */ 04068 static uint32_t MMC_SendStatus(MMC_HandleTypeDef *hmmc, uint32_t *pCardStatus) 04069 { 04070 uint32_t errorstate; 04071 04072 if(pCardStatus == NULL) 04073 { 04074 return HAL_MMC_ERROR_PARAM; 04075 } 04076 04077 /* Send Status command */ 04078 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(hmmc->MmcCard.RelCardAdd << 16U)); 04079 if(errorstate != HAL_MMC_ERROR_NONE) 04080 { 04081 return errorstate; 04082 } 04083 04084 /* Get MMC card status */ 04085 *pCardStatus = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1); 04086 04087 return HAL_MMC_ERROR_NONE; 04088 } 04089 04090 /** 04091 * @brief Reads extended CSD register to get the sectors number of the device 04092 * @param hmmc Pointer to MMC handle 04093 * @param pFieldData Pointer to the read buffer 04094 * @param FieldIndex Index of the field to be read 04095 * @param Timeout Specify timeout value 04096 * @retval HAL status 04097 */ 04098 static HAL_StatusTypeDef MMC_ReadExtCSD(MMC_HandleTypeDef *hmmc, uint32_t *pFieldData, uint16_t FieldIndex, uint32_t Timeout) 04099 { 04100 SDMMC_DataInitTypeDef config; 04101 uint32_t errorstate; 04102 uint32_t tickstart = HAL_GetTick(); 04103 uint32_t count; 04104 uint32_t i = 0; 04105 uint32_t tmp_data; 04106 04107 hmmc->ErrorCode = HAL_MMC_ERROR_NONE; 04108 04109 /* Initialize data control register */ 04110 hmmc->Instance->DCTRL = 0; 04111 04112 /* Configure the MMC DPSM (Data Path State Machine) */ 04113 config.DataTimeOut = SDMMC_DATATIMEOUT; 04114 config.DataLength = 512; 04115 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; 04116 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; 04117 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; 04118 config.DPSM = SDMMC_DPSM_ENABLE; 04119 (void)SDMMC_ConfigData(hmmc->Instance, &config); 04120 04121 /* Set Block Size for Card */ 04122 errorstate = SDMMC_CmdSendEXTCSD(hmmc->Instance, 0); 04123 if(errorstate != HAL_MMC_ERROR_NONE) 04124 { 04125 /* Clear all the static flags */ 04126 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 04127 hmmc->ErrorCode |= errorstate; 04128 hmmc->State = HAL_MMC_STATE_READY; 04129 return HAL_ERROR; 04130 } 04131 04132 /* Poll on SDMMC flags */ 04133 while(!__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND)) 04134 { 04135 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXFIFOHF)) 04136 { 04137 /* Read data from SDMMC Rx FIFO */ 04138 for(count = 0U; count < 8U; count++) 04139 { 04140 tmp_data = SDMMC_ReadFIFO(hmmc->Instance); 04141 /* eg : SEC_COUNT : FieldIndex = 212 => i+count = 53 */ 04142 /* DEVICE_TYPE : FieldIndex = 196 => i+count = 49 */ 04143 if ((i + count) == ((uint32_t)FieldIndex/4U)) 04144 { 04145 *pFieldData = tmp_data; 04146 } 04147 } 04148 i += 8U; 04149 } 04150 04151 if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U)) 04152 { 04153 /* Clear all the static flags */ 04154 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 04155 hmmc->ErrorCode |= HAL_MMC_ERROR_TIMEOUT; 04156 hmmc->State= HAL_MMC_STATE_READY; 04157 return HAL_TIMEOUT; 04158 } 04159 } 04160 04161 /* Get error state */ 04162 if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DTIMEOUT)) 04163 { 04164 /* Clear all the static flags */ 04165 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 04166 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_TIMEOUT; 04167 hmmc->State = HAL_MMC_STATE_READY; 04168 return HAL_ERROR; 04169 } 04170 else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_DCRCFAIL)) 04171 { 04172 /* Clear all the static flags */ 04173 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 04174 hmmc->ErrorCode |= HAL_MMC_ERROR_DATA_CRC_FAIL; 04175 hmmc->State = HAL_MMC_STATE_READY; 04176 return HAL_ERROR; 04177 } 04178 else if(__HAL_MMC_GET_FLAG(hmmc, SDMMC_FLAG_RXOVERR)) 04179 { 04180 /* Clear all the static flags */ 04181 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_FLAGS); 04182 hmmc->ErrorCode |= HAL_MMC_ERROR_RX_OVERRUN; 04183 hmmc->State = HAL_MMC_STATE_READY; 04184 return HAL_ERROR; 04185 } 04186 else 04187 { 04188 /* Nothing to do */ 04189 } 04190 04191 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ 04192 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16)); 04193 if(errorstate != HAL_MMC_ERROR_NONE) 04194 { 04195 hmmc->ErrorCode |= errorstate; 04196 } 04197 04198 /* Clear all the static flags */ 04199 __HAL_MMC_CLEAR_FLAG(hmmc, SDMMC_STATIC_DATA_FLAGS); 04200 04201 hmmc->State = HAL_MMC_STATE_READY; 04202 04203 return HAL_OK; 04204 } 04205 04206 /** 04207 * @brief Wrap up reading in non-blocking mode. 04208 * @param hmmc pointer to a MMC_HandleTypeDef structure that contains 04209 * the configuration information. 04210 * @retval None 04211 */ 04212 static void MMC_Read_IT(MMC_HandleTypeDef *hmmc) 04213 { 04214 uint32_t count, data, dataremaining; 04215 uint8_t* tmp; 04216 04217 tmp = hmmc->pRxBuffPtr; 04218 dataremaining = hmmc->RxXferSize; 04219 04220 if (dataremaining > 0U) 04221 { 04222 /* Read data from SDMMC Rx FIFO */ 04223 for(count = 0U; count < 8U; count++) 04224 { 04225 data = SDMMC_ReadFIFO(hmmc->Instance); 04226 *tmp = (uint8_t)(data & 0xFFU); 04227 tmp++; 04228 dataremaining--; 04229 *tmp = (uint8_t)((data >> 8U) & 0xFFU); 04230 tmp++; 04231 dataremaining--; 04232 *tmp = (uint8_t)((data >> 16U) & 0xFFU); 04233 tmp++; 04234 dataremaining--; 04235 *tmp = (uint8_t)((data >> 24U) & 0xFFU); 04236 tmp++; 04237 dataremaining--; 04238 } 04239 04240 hmmc->pRxBuffPtr = tmp; 04241 hmmc->RxXferSize = dataremaining; 04242 } 04243 } 04244 04245 /** 04246 * @brief Wrap up writing in non-blocking mode. 04247 * @param hmmc pointer to a MMC_HandleTypeDef structure that contains 04248 * the configuration information. 04249 * @retval None 04250 */ 04251 static void MMC_Write_IT(MMC_HandleTypeDef *hmmc) 04252 { 04253 uint32_t count, data, dataremaining; 04254 uint8_t* tmp; 04255 04256 tmp = hmmc->pTxBuffPtr; 04257 dataremaining = hmmc->TxXferSize; 04258 04259 if (dataremaining > 0U) 04260 { 04261 /* Write data to SDMMC Tx FIFO */ 04262 for(count = 0U; count < 8U; count++) 04263 { 04264 data = (uint32_t)(*tmp); 04265 tmp++; 04266 dataremaining--; 04267 data |= ((uint32_t)(*tmp) << 8U); 04268 tmp++; 04269 dataremaining--; 04270 data |= ((uint32_t)(*tmp) << 16U); 04271 tmp++; 04272 dataremaining--; 04273 data |= ((uint32_t)(*tmp) << 24U); 04274 tmp++; 04275 dataremaining--; 04276 (void)SDMMC_WriteFIFO(hmmc->Instance, &data); 04277 } 04278 04279 hmmc->pTxBuffPtr = tmp; 04280 hmmc->TxXferSize = dataremaining; 04281 } 04282 } 04283 04284 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 04285 /** 04286 * @brief Switches the MMC card to high speed mode. 04287 * @param hmmc MMC handle 04288 * @param state State of high speed mode 04289 * @retval MMC Card error state 04290 */ 04291 static uint32_t MMC_HighSpeed(MMC_HandleTypeDef *hmmc, FunctionalState state) 04292 { 04293 uint32_t errorstate = HAL_MMC_ERROR_NONE; 04294 uint32_t response = 0U, count; 04295 uint32_t sdmmc_clk; 04296 SDMMC_InitTypeDef Init; 04297 04298 if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) != 0U) && (state == DISABLE)) 04299 { 04300 errorstate = MMC_PwrClassUpdate(hmmc, (hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS), SDMMC_SPEED_MODE_DEFAULT); 04301 if(errorstate == HAL_MMC_ERROR_NONE) 04302 { 04303 /* Index : 185 - Value : 0 */ 04304 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B90000U); 04305 } 04306 } 04307 04308 if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_BUSSPEED) == 0U) && (state != DISABLE)) 04309 { 04310 errorstate = MMC_PwrClassUpdate(hmmc, (hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS), SDMMC_SPEED_MODE_HIGH); 04311 if(errorstate == HAL_MMC_ERROR_NONE) 04312 { 04313 /* Index : 185 - Value : 1 */ 04314 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B90100U); 04315 } 04316 } 04317 04318 if(errorstate == HAL_MMC_ERROR_NONE) 04319 { 04320 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ 04321 count = SDMMC_MAX_TRIAL; 04322 do 04323 { 04324 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); 04325 if(errorstate != HAL_MMC_ERROR_NONE) 04326 { 04327 break; 04328 } 04329 04330 /* Get command response */ 04331 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1); 04332 count--; 04333 }while(((response & 0x100U) == 0U) && (count != 0U)); 04334 04335 /* Check the status after the switch command execution */ 04336 if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE)) 04337 { 04338 /* Check the bit SWITCH_ERROR of the device status */ 04339 if ((response & 0x80U) != 0U) 04340 { 04341 errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE; 04342 } 04343 else 04344 { 04345 /* Configure high speed */ 04346 Init.ClockEdge = hmmc->Init.ClockEdge; 04347 Init.ClockPowerSave = hmmc->Init.ClockPowerSave; 04348 Init.BusWide = (hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS); 04349 Init.HardwareFlowControl = hmmc->Init.HardwareFlowControl; 04350 04351 if (state == DISABLE) 04352 { 04353 Init.ClockDiv = hmmc->Init.ClockDiv; 04354 (void)SDMMC_Init(hmmc->Instance, Init); 04355 04356 CLEAR_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_BUSSPEED); 04357 } 04358 else 04359 { 04360 /* High Speed Clock should be less or equal to 52MHz*/ 04361 sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC1); 04362 if (sdmmc_clk == 0U) 04363 { 04364 errorstate = SDMMC_ERROR_INVALID_PARAMETER; 04365 } 04366 else 04367 { 04368 Init.ClockDiv = sdmmc_clk/(2U*MMC_HIGH_SPEED_FREQ); 04369 (void)SDMMC_Init(hmmc->Instance, Init); 04370 04371 SET_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_BUSSPEED); 04372 } 04373 } 04374 } 04375 } 04376 else if (count == 0U) 04377 { 04378 errorstate = SDMMC_ERROR_TIMEOUT; 04379 } 04380 else 04381 { 04382 /* Nothing to do */ 04383 } 04384 } 04385 04386 return errorstate; 04387 } 04388 04389 /** 04390 * @brief Switches the MMC card to Double Data Rate (DDR) mode. 04391 * @param hmmc MMC handle 04392 * @param state State of DDR mode 04393 * @retval MMC Card error state 04394 */ 04395 static uint32_t MMC_DDR_Mode(MMC_HandleTypeDef *hmmc, FunctionalState state) 04396 { 04397 uint32_t errorstate = HAL_MMC_ERROR_NONE; 04398 uint32_t response = 0U, count; 04399 04400 if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) != 0U) && (state == DISABLE)) 04401 { 04402 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS_0) != 0U) 04403 { 04404 errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_4B, SDMMC_SPEED_MODE_HIGH); 04405 if(errorstate == HAL_MMC_ERROR_NONE) 04406 { 04407 /* Index : 183 - Value : 1 */ 04408 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70100U); 04409 } 04410 } 04411 else 04412 { 04413 errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_8B, SDMMC_SPEED_MODE_HIGH); 04414 if(errorstate == HAL_MMC_ERROR_NONE) 04415 { 04416 /* Index : 183 - Value : 2 */ 04417 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70200U); 04418 } 04419 } 04420 } 04421 04422 if (((hmmc->Instance->CLKCR & SDMMC_CLKCR_DDR) == 0U) && (state != DISABLE)) 04423 { 04424 if ((hmmc->Instance->CLKCR & SDMMC_CLKCR_WIDBUS_0) != 0U) 04425 { 04426 errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_4B, SDMMC_SPEED_MODE_DDR); 04427 if(errorstate == HAL_MMC_ERROR_NONE) 04428 { 04429 /* Index : 183 - Value : 5 */ 04430 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70500U); 04431 } 04432 } 04433 else 04434 { 04435 errorstate = MMC_PwrClassUpdate(hmmc, SDMMC_BUS_WIDE_8B, SDMMC_SPEED_MODE_DDR); 04436 if(errorstate == HAL_MMC_ERROR_NONE) 04437 { 04438 /* Index : 183 - Value : 6 */ 04439 errorstate = SDMMC_CmdSwitch(hmmc->Instance, 0x03B70600U); 04440 } 04441 } 04442 } 04443 04444 if(errorstate == HAL_MMC_ERROR_NONE) 04445 { 04446 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ 04447 count = SDMMC_MAX_TRIAL; 04448 do 04449 { 04450 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); 04451 if(errorstate != HAL_MMC_ERROR_NONE) 04452 { 04453 break; 04454 } 04455 04456 /* Get command response */ 04457 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1); 04458 count--; 04459 }while(((response & 0x100U) == 0U) && (count != 0U)); 04460 04461 /* Check the status after the switch command execution */ 04462 if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE)) 04463 { 04464 /* Check the bit SWITCH_ERROR of the device status */ 04465 if ((response & 0x80U) != 0U) 04466 { 04467 errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE; 04468 } 04469 else 04470 { 04471 /* Configure DDR mode */ 04472 if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE)) 04473 { 04474 if (state == DISABLE) 04475 { 04476 CLEAR_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_DDR); 04477 } 04478 else 04479 { 04480 SET_BIT(hmmc->Instance->CLKCR, SDMMC_CLKCR_DDR); 04481 } 04482 } 04483 } 04484 } 04485 else if (count == 0U) 04486 { 04487 errorstate = SDMMC_ERROR_TIMEOUT; 04488 } 04489 else 04490 { 04491 /* Nothing to do */ 04492 } 04493 } 04494 04495 return errorstate; 04496 } 04497 #endif 04498 04499 /** 04500 * @brief Update the power class of the device. 04501 * @param hmmc MMC handle 04502 * @param Wide Wide of MMC bus 04503 * @param Speed Speed of the MMC bus 04504 * @retval MMC Card error state 04505 */ 04506 static uint32_t MMC_PwrClassUpdate(MMC_HandleTypeDef *hmmc, uint32_t Wide, uint32_t Speed) 04507 { 04508 uint32_t count; 04509 uint32_t response = 0U; 04510 uint32_t errorstate = HAL_MMC_ERROR_NONE; 04511 uint32_t power_class, supported_pwr_class; 04512 04513 if((Wide == SDMMC_BUS_WIDE_8B) || (Wide == SDMMC_BUS_WIDE_4B)) 04514 { 04515 power_class = 0U; /* Default value after power-on or software reset */ 04516 04517 /* Read the PowerClass field of the Extended CSD register */ 04518 if(MMC_ReadExtCSD(hmmc, &power_class, 187, SDMMC_DATATIMEOUT) != HAL_OK) /* Field POWER_CLASS [187] */ 04519 { 04520 errorstate = SDMMC_ERROR_GENERAL_UNKNOWN_ERR; 04521 } 04522 else 04523 { 04524 power_class = ((power_class >> 24U) & 0x000000FFU); 04525 } 04526 04527 /* Get the supported PowerClass field of the Extended CSD register */ 04528 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 04529 if (Speed == SDMMC_SPEED_MODE_DDR) 04530 { 04531 /* Field PWR_CL_DDR_52_xxx [238 or 239] */ 04532 supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_DDR_52_INDEX/4)] >> MMC_EXT_CSD_PWR_CL_DDR_52_POS) & 0x000000FFU); 04533 } 04534 else if (Speed == SDMMC_SPEED_MODE_HIGH) 04535 { 04536 /* Field PWR_CL_52_xxx [200 or 202] */ 04537 supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_52_INDEX/4)] >> MMC_EXT_CSD_PWR_CL_52_POS) & 0x000000FFU); 04538 } 04539 else 04540 #endif 04541 { 04542 /* Field PWR_CL_26_xxx [201 or 203] */ 04543 supported_pwr_class = ((hmmc->Ext_CSD[(MMC_EXT_CSD_PWR_CL_26_INDEX/4)] >> MMC_EXT_CSD_PWR_CL_26_POS) & 0x000000FFU); 04544 } 04545 04546 if(errorstate == HAL_MMC_ERROR_NONE) 04547 { 04548 if(Wide == SDMMC_BUS_WIDE_8B) 04549 { 04550 /* Bit [7:4] : power class for 8-bits bus configuration - Bit [3:0] : power class for 4-bits bus configuration */ 04551 supported_pwr_class = (supported_pwr_class >> 4U); 04552 } 04553 04554 if ((power_class & 0x0FU) != (supported_pwr_class & 0x0FU)) 04555 { 04556 /* Need to change current power class */ 04557 errorstate = SDMMC_CmdSwitch(hmmc->Instance, (0x03BB0000U | ((supported_pwr_class & 0x0FU) << 8U))); 04558 04559 if(errorstate == HAL_MMC_ERROR_NONE) 04560 { 04561 /* While card is not ready for data and trial number for sending CMD13 is not exceeded */ 04562 count = SDMMC_MAX_TRIAL; 04563 do 04564 { 04565 errorstate = SDMMC_CmdSendStatus(hmmc->Instance, (uint32_t)(((uint32_t)hmmc->MmcCard.RelCardAdd) << 16U)); 04566 if(errorstate != HAL_MMC_ERROR_NONE) 04567 { 04568 break; 04569 } 04570 04571 /* Get command response */ 04572 response = SDMMC_GetResponse(hmmc->Instance, SDMMC_RESP1); 04573 count--; 04574 }while(((response & 0x100U) == 0U) && (count != 0U)); 04575 04576 /* Check the status after the switch command execution */ 04577 if ((count != 0U) && (errorstate == HAL_MMC_ERROR_NONE)) 04578 { 04579 /* Check the bit SWITCH_ERROR of the device status */ 04580 if ((response & 0x80U) != 0U) 04581 { 04582 errorstate = SDMMC_ERROR_UNSUPPORTED_FEATURE; 04583 } 04584 } 04585 else if (count == 0U) 04586 { 04587 errorstate = SDMMC_ERROR_TIMEOUT; 04588 } 04589 else 04590 { 04591 /* Nothing to do */ 04592 } 04593 } 04594 } 04595 } 04596 } 04597 04598 return errorstate; 04599 } 04600 /** 04601 * @} 04602 */ 04603 04604 /** 04605 * @} 04606 */ 04607 04608 /** 04609 * @} 04610 */ 04611 04612 #endif /* HAL_MMC_MODULE_ENABLED */ 04613 04614 #endif /* SDMMC1 */