STM32L486xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l4xx_hal_sd.c 00004 * @author MCD Application Team 00005 * @brief SD card HAL module driver. 00006 * This file provides firmware functions to manage the following 00007 * functionalities of the Secure Digital (SD) peripheral: 00008 * + Initialization and de-initialization functions 00009 * + IO operation functions 00010 * + Peripheral Control functions 00011 * + SD card Control functions 00012 * 00013 @verbatim 00014 ============================================================================== 00015 ##### How to use this driver ##### 00016 ============================================================================== 00017 [..] 00018 This driver implements a high level communication layer for read and write from/to 00019 this memory. The needed STM32 hardware resources (SDMMC1 and GPIO) are performed by 00020 the user in HAL_SD_MspInit() function (MSP layer). 00021 Basically, the MSP layer configuration should be the same as we provide in the 00022 examples. 00023 You can easily tailor this configuration according to hardware resources. 00024 00025 [..] 00026 This driver is a generic layered driver for SDMMC memories which uses the HAL 00027 SDMMC driver functions to interface with SD and uSD cards devices. 00028 It is used as follows: 00029 00030 (#)Initialize the SDMMC1 low level resources by implementing the HAL_SD_MspInit() API: 00031 (##) Call the function HAL_RCCEx_PeriphCLKConfig with RCC_PERIPHCLK_SDMMC1 for 00032 PeriphClockSelection and select SDMMC1 clock source (MSI, main PLL or PLLSAI1) 00033 (##) Enable the SDMMC1 interface clock using __HAL_RCC_SDMMC1_CLK_ENABLE(); 00034 (##) SDMMC pins configuration for SD card 00035 (+++) Enable the clock for the SDMMC GPIOs using the functions __HAL_RCC_GPIOx_CLK_ENABLE(); 00036 (+++) Configure these SDMMC pins as alternate function pull-up using HAL_GPIO_Init() 00037 and according to your pin assignment; 00038 (##) On STM32L4Rx/STM32L4Sxx devices, no DMA configuration is need, an internal DMA for SDMMC IP is used. 00039 (##) On other devices, perform DMA configuration if you need to use DMA process (HAL_SD_ReadBlocks_DMA() 00040 and HAL_SD_WriteBlocks_DMA() APIs). 00041 (+++) Enable the DMAx interface clock using __HAL_RCC_DMAx_CLK_ENABLE(); 00042 (+++) Configure the DMA using the function HAL_DMA_Init() with predeclared and filled. 00043 (##) NVIC configuration if you need to use interrupt process when using DMA transfer. 00044 (+++) Configure the SDMMC and DMA interrupt priorities using functions 00045 HAL_NVIC_SetPriority(); DMA priority is superior to SDMMC's priority 00046 (+++) Enable the NVIC DMA and SDMMC IRQs using function HAL_NVIC_EnableIRQ() 00047 (+++) SDMMC interrupts are managed using the macros __HAL_SD_ENABLE_IT() 00048 and __HAL_SD_DISABLE_IT() inside the communication process. 00049 (+++) SDMMC interrupts pending bits are managed using the macros __HAL_SD_GET_IT() 00050 and __HAL_SD_CLEAR_IT() 00051 (##) NVIC configuration if you need to use interrupt process (HAL_SD_ReadBlocks_IT() 00052 and HAL_SD_WriteBlocks_IT() APIs). 00053 (+++) Configure the SDMMC interrupt priorities using function 00054 HAL_NVIC_SetPriority(); 00055 (+++) Enable the NVIC SDMMC IRQs using function HAL_NVIC_EnableIRQ() 00056 (+++) SDMMC interrupts are managed using the macros __HAL_SD_ENABLE_IT() 00057 and __HAL_SD_DISABLE_IT() inside the communication process. 00058 (+++) SDMMC interrupts pending bits are managed using the macros __HAL_SD_GET_IT() 00059 and __HAL_SD_CLEAR_IT() 00060 (#) At this stage, you can perform SD read/write/erase operations after SD card initialization 00061 00062 00063 *** SD Card Initialization and configuration *** 00064 ================================================ 00065 [..] 00066 To initialize the SD Card, use the HAL_SD_Init() function. It Initializes 00067 SDMMC IP(STM32 side) and the SD Card, and put it into StandBy State (Ready for data transfer). 00068 This function provide the following operations: 00069 00070 (#) Initialize the SDMMC peripheral interface with defaullt configuration. 00071 The initialization process is done at 400KHz. You can change or adapt 00072 this frequency by adjusting the "ClockDiv" field. 00073 The SD Card frequency (SDMMC_CK) is computed as follows: 00074 00075 SDMMC_CK = SDMMCCLK / (ClockDiv + 2) 00076 00077 In initialization mode and according to the SD Card standard, 00078 make sure that the SDMMC_CK frequency doesn't exceed 400KHz. 00079 00080 This phase of initialization is done through SDMMC_Init() and 00081 SDMMC_PowerState_ON() SDMMC low level APIs. 00082 00083 (#) Initialize the SD card. The API used is HAL_SD_InitCard(). 00084 This phase allows the card initialization and identification 00085 and check the SD Card type (Standard Capacity or High Capacity) 00086 The initialization flow is compatible with SD standard. 00087 00088 This API (HAL_SD_InitCard()) could be used also to reinitialize the card in case 00089 of plug-off plug-in. 00090 00091 (#) Configure the SD Card Data transfer frequency. By Default, the card transfer 00092 frequency is set to 24MHz. You can change or adapt this frequency by adjusting 00093 the "ClockDiv" field. 00094 In transfer mode and according to the SD Card standard, make sure that the 00095 SDMMC_CK frequency doesn't exceed 25MHz and 50MHz in High-speed mode switch. 00096 To be able to use a frequency higher than 24MHz, you should use the SDMMC 00097 peripheral in bypass mode. Refer to the corresponding reference manual 00098 for more details. 00099 00100 (#) Select the corresponding SD Card according to the address read with the step 2. 00101 00102 (#) Configure the SD Card in wide bus mode: 4-bits data. 00103 00104 *** SD Card Read operation *** 00105 ============================== 00106 [..] 00107 (+) You can read from SD card in polling mode by using function HAL_SD_ReadBlocks(). 00108 This function allows the read of 512 bytes blocks. 00109 You can choose either one block read operation or multiple block read operation 00110 by adjusting the "NumberOfBlocks" parameter. 00111 After this, you have to ensure that the transfer is done correctly. The check is done 00112 through HAL_SD_GetCardState() function for SD card state. 00113 00114 (+) You can read from SD card in DMA mode by using function HAL_SD_ReadBlocks_DMA(). 00115 This function allows the read of 512 bytes blocks. 00116 You can choose either one block read operation or multiple block read operation 00117 by adjusting the "NumberOfBlocks" parameter. 00118 After this, you have to ensure that the transfer is done correctly. The check is done 00119 through HAL_SD_GetCardState() function for SD card state. 00120 You could also check the DMA transfer process through the SD Rx interrupt event. 00121 00122 (+) You can read from SD card in Interrupt mode by using function HAL_SD_ReadBlocks_IT(). 00123 This function allows the read of 512 bytes blocks. 00124 You can choose either one block read operation or multiple block read operation 00125 by adjusting the "NumberOfBlocks" parameter. 00126 After this, you have to ensure that the transfer is done correctly. The check is done 00127 through HAL_SD_GetCardState() function for SD card state. 00128 You could also check the IT transfer process through the SD Rx interrupt event. 00129 00130 *** SD Card Write operation *** 00131 =============================== 00132 [..] 00133 (+) You can write to SD card in polling mode by using function HAL_SD_WriteBlocks(). 00134 This function allows the read of 512 bytes blocks. 00135 You can choose either one block read operation or multiple block read operation 00136 by adjusting the "NumberOfBlocks" parameter. 00137 After this, you have to ensure that the transfer is done correctly. The check is done 00138 through HAL_SD_GetCardState() function for SD card state. 00139 00140 (+) You can write to SD card in DMA mode by using function HAL_SD_WriteBlocks_DMA(). 00141 This function allows the read of 512 bytes blocks. 00142 You can choose either one block read operation or multiple block read operation 00143 by adjusting the "NumberOfBlocks" parameter. 00144 After this, you have to ensure that the transfer is done correctly. The check is done 00145 through HAL_SD_GetCardState() function for SD card state. 00146 You could also check the DMA transfer process through the SD Tx interrupt event. 00147 00148 (+) You can write to SD card in Interrupt mode by using function HAL_SD_WriteBlocks_IT(). 00149 This function allows the read of 512 bytes blocks. 00150 You can choose either one block read operation or multiple block read operation 00151 by adjusting the "NumberOfBlocks" parameter. 00152 After this, you have to ensure that the transfer is done correctly. The check is done 00153 through HAL_SD_GetCardState() function for SD card state. 00154 You could also check the IT transfer process through the SD Tx interrupt event. 00155 00156 *** SD card status *** 00157 ====================== 00158 [..] 00159 (+) The SD Status contains status bits that are related to the SD Memory 00160 Card proprietary features. To get SD card status use the HAL_SD_GetCardStatus(). 00161 00162 *** SD card information *** 00163 =========================== 00164 [..] 00165 (+) To get SD card information, you can use the function HAL_SD_GetCardInfo(). 00166 It returns useful information about the SD card such as block size, card type, 00167 block number ... 00168 00169 *** SD card CSD register *** 00170 ============================ 00171 (+) The HAL_SD_GetCardCSD() API allows to get the parameters of the CSD register. 00172 Some of the CSD parameters are useful for card initialization and identification. 00173 00174 *** SD card CID register *** 00175 ============================ 00176 (+) The HAL_SD_GetCardCID() API allows to get the parameters of the CID register. 00177 Some of the CSD parameters are useful for card initialization and identification. 00178 00179 *** SD HAL driver macros list *** 00180 ================================== 00181 [..] 00182 Below the list of most used macros in SD HAL driver. 00183 00184 (+) __HAL_SD_ENABLE : Enable the SD device 00185 (+) __HAL_SD_DISABLE : Disable the SD device 00186 (+) __HAL_SD_DMA_ENABLE: Enable the SDMMC DMA transfer 00187 (+) __HAL_SD_DMA_DISABLE: Disable the SDMMC DMA transfer 00188 (+) __HAL_SD_ENABLE_IT: Enable the SD device interrupt 00189 (+) __HAL_SD_DISABLE_IT: Disable the SD device interrupt 00190 (+) __HAL_SD_GET_FLAG:Check whether the specified SD flag is set or not 00191 (+) __HAL_SD_CLEAR_FLAG: Clear the SD's pending flags 00192 00193 (@) You can refer to the SD HAL driver header file for more useful macros 00194 00195 *** Callback registration *** 00196 ============================================= 00197 [..] 00198 The compilation define USE_HAL_SD_REGISTER_CALLBACKS when set to 1 00199 allows the user to configure dynamically the driver callbacks. 00200 00201 Use Functions @ref HAL_SD_RegisterCallback() to register a user callback, 00202 it allows to register following callbacks: 00203 (+) TxCpltCallback : callback when a transmission transfer is completed. 00204 (+) RxCpltCallback : callback when a reception transfer is completed. 00205 (+) ErrorCallback : callback when error occurs. 00206 (+) AbortCpltCallback : callback when abort is completed. 00207 (+) Read_DMADblBuf0CpltCallback : callback when the DMA reception of first buffer is completed. 00208 (+) Read_DMADblBuf1CpltCallback : callback when the DMA reception of second buffer is completed. 00209 (+) Write_DMADblBuf0CpltCallback : callback when the DMA transmission of first buffer is completed. 00210 (+) Write_DMADblBuf1CpltCallback : callback when the DMA transmission of second buffer is completed. 00211 (+) MspInitCallback : SD MspInit. 00212 (+) MspDeInitCallback : SD MspDeInit. 00213 This function takes as parameters the HAL peripheral handle, the Callback ID 00214 and a pointer to the user callback function. 00215 For specific callbacks TransceiverCallback use dedicated register callbacks: 00216 respectively @ref HAL_SD_RegisterTransceiverCallback(). 00217 00218 Use function @ref HAL_SD_UnRegisterCallback() to reset a callback to the default 00219 weak (surcharged) function. It allows to reset following callbacks: 00220 (+) TxCpltCallback : callback when a transmission transfer is completed. 00221 (+) RxCpltCallback : callback when a reception transfer is completed. 00222 (+) ErrorCallback : callback when error occurs. 00223 (+) AbortCpltCallback : callback when abort is completed. 00224 (+) Read_DMADblBuf0CpltCallback : callback when the DMA reception of first buffer is completed. 00225 (+) Read_DMADblBuf1CpltCallback : callback when the DMA reception of second buffer is completed. 00226 (+) Write_DMADblBuf0CpltCallback : callback when the DMA transmission of first buffer is completed. 00227 (+) Write_DMADblBuf1CpltCallback : callback when the DMA transmission of second buffer is completed. 00228 (+) MspInitCallback : SD MspInit. 00229 (+) MspDeInitCallback : SD MspDeInit. 00230 This function) takes as parameters the HAL peripheral handle and the Callback ID. 00231 For specific callbacks TransceiverCallback use dedicated unregister callbacks: 00232 respectively @ref HAL_SD_UnRegisterTransceiverCallback(). 00233 00234 By default, after the @ref HAL_SD_Init and if the state is HAL_SD_STATE_RESET 00235 all callbacks are reset to the corresponding legacy weak (surcharged) functions. 00236 Exception done for MspInit and MspDeInit callbacks that are respectively 00237 reset to the legacy weak (surcharged) functions in the @ref HAL_SD_Init 00238 and @ref HAL_SD_DeInit only when these callbacks are null (not registered beforehand). 00239 If not, MspInit or MspDeInit are not null, the @ref HAL_SD_Init and @ref HAL_SD_DeInit 00240 keep and use the user MspInit/MspDeInit callbacks (registered beforehand) 00241 00242 Callbacks can be registered/unregistered in READY state only. 00243 Exception done for MspInit/MspDeInit callbacks that can be registered/unregistered 00244 in READY or RESET state, thus registered (user) MspInit/DeInit callbacks can be used 00245 during the Init/DeInit. 00246 In that case first register the MspInit/MspDeInit user callbacks 00247 using @ref HAL_SD_RegisterCallback before calling @ref HAL_SD_DeInit 00248 or @ref HAL_SD_Init function. 00249 00250 When The compilation define USE_HAL_SD_REGISTER_CALLBACKS is set to 0 or 00251 not defined, the callback registering feature is not available 00252 and weak (surcharged) callbacks are used. 00253 00254 @endverbatim 00255 ****************************************************************************** 00256 * @attention 00257 * 00258 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2> 00259 * 00260 * Redistribution and use in source and binary forms, with or without modification, 00261 * are permitted provided that the following conditions are met: 00262 * 1. Redistributions of source code must retain the above copyright notice, 00263 * this list of conditions and the following disclaimer. 00264 * 2. Redistributions in binary form must reproduce the above copyright notice, 00265 * this list of conditions and the following disclaimer in the documentation 00266 * and/or other materials provided with the distribution. 00267 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00268 * may be used to endorse or promote products derived from this software 00269 * without specific prior written permission. 00270 * 00271 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00272 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00273 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00274 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00275 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00276 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00277 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00278 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00279 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00280 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00281 * 00282 ****************************************************************************** 00283 */ 00284 00285 /* Includes ------------------------------------------------------------------*/ 00286 #include "stm32l4xx_hal.h" 00287 00288 #if defined(SDMMC1) 00289 00290 /** @addtogroup STM32L4xx_HAL_Driver 00291 * @{ 00292 */ 00293 00294 /** @defgroup SD SD 00295 * @brief SD HAL module driver 00296 * @{ 00297 */ 00298 00299 #ifdef HAL_SD_MODULE_ENABLED 00300 00301 /* Private typedef -----------------------------------------------------------*/ 00302 /* Private define ------------------------------------------------------------*/ 00303 /** @addtogroup SD_Private_Defines 00304 * @{ 00305 */ 00306 00307 /** 00308 * @} 00309 */ 00310 00311 /* Private macro -------------------------------------------------------------*/ 00312 /* Private variables ---------------------------------------------------------*/ 00313 /* Private function prototypes -----------------------------------------------*/ 00314 /* Private functions ---------------------------------------------------------*/ 00315 /** @defgroup SD_Private_Functions SD Private Functions 00316 * @{ 00317 */ 00318 static uint32_t SD_InitCard (SD_HandleTypeDef *hsd); 00319 static uint32_t SD_PowerON (SD_HandleTypeDef *hsd); 00320 static uint32_t SD_SendSDStatus (SD_HandleTypeDef *hsd, uint32_t *pSDstatus); 00321 static uint32_t SD_SendStatus (SD_HandleTypeDef *hsd, uint32_t *pCardStatus); 00322 static uint32_t SD_WideBus_Enable (SD_HandleTypeDef *hsd); 00323 static uint32_t SD_WideBus_Disable(SD_HandleTypeDef *hsd); 00324 static uint32_t SD_FindSCR (SD_HandleTypeDef *hsd, uint32_t *pSCR); 00325 static void SD_PowerOFF (SD_HandleTypeDef *hsd); 00326 static void SD_Write_IT (SD_HandleTypeDef *hsd); 00327 static void SD_Read_IT (SD_HandleTypeDef *hsd); 00328 #if !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 00329 static void SD_DMATransmitCplt(DMA_HandleTypeDef *hdma); 00330 static void SD_DMAReceiveCplt (DMA_HandleTypeDef *hdma); 00331 static void SD_DMAError (DMA_HandleTypeDef *hdma); 00332 static void SD_DMATxAbort (DMA_HandleTypeDef *hdma); 00333 static void SD_DMARxAbort (DMA_HandleTypeDef *hdma); 00334 #endif /* !STM32L4R5xx && !STM32L4R7xx && !STM32L4R9xx && !STM32L4S5xx && !STM32L4S7xx && !STM32L4S9xx */ 00335 /** 00336 * @} 00337 */ 00338 00339 /* Exported functions --------------------------------------------------------*/ 00340 /** @addtogroup SD_Exported_Functions 00341 * @{ 00342 */ 00343 00344 /** @addtogroup SD_Exported_Functions_Group1 00345 * @brief Initialization and de-initialization functions 00346 * 00347 @verbatim 00348 ============================================================================== 00349 ##### Initialization and de-initialization functions ##### 00350 ============================================================================== 00351 [..] 00352 This section provides functions allowing to initialize/de-initialize the SD 00353 card device to be ready for use. 00354 00355 @endverbatim 00356 * @{ 00357 */ 00358 00359 /** 00360 * @brief Initializes the SD according to the specified parameters in the 00361 SD_HandleTypeDef and create the associated handle. 00362 * @param hsd: Pointer to the SD handle 00363 * @retval HAL status 00364 */ 00365 HAL_StatusTypeDef HAL_SD_Init(SD_HandleTypeDef *hsd) 00366 { 00367 /* Check the SD handle allocation */ 00368 if(hsd == NULL) 00369 { 00370 return HAL_ERROR; 00371 } 00372 00373 /* Check the parameters */ 00374 assert_param(IS_SDMMC_ALL_INSTANCE(hsd->Instance)); 00375 assert_param(IS_SDMMC_CLOCK_EDGE(hsd->Init.ClockEdge)); 00376 #if !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 00377 assert_param(IS_SDMMC_CLOCK_BYPASS(hsd->Init.ClockBypass)); 00378 #endif /* !STM32L4R5xx && !STM32L4R7xx && !STM32L4R9xx && !STM32L4S5xx && !STM32L4S7xx && !STM32L4S9xx */ 00379 assert_param(IS_SDMMC_CLOCK_POWER_SAVE(hsd->Init.ClockPowerSave)); 00380 assert_param(IS_SDMMC_BUS_WIDE(hsd->Init.BusWide)); 00381 assert_param(IS_SDMMC_HARDWARE_FLOW_CONTROL(hsd->Init.HardwareFlowControl)); 00382 assert_param(IS_SDMMC_CLKDIV(hsd->Init.ClockDiv)); 00383 00384 if(hsd->State == HAL_SD_STATE_RESET) 00385 { 00386 /* Allocate lock resource and initialize it */ 00387 hsd->Lock = HAL_UNLOCKED; 00388 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1) 00389 /* Reset Callback pointers in HAL_SD_STATE_RESET only */ 00390 hsd->TxCpltCallback = HAL_SD_TxCpltCallback; 00391 hsd->RxCpltCallback = HAL_SD_RxCpltCallback; 00392 hsd->ErrorCallback = HAL_SD_ErrorCallback; 00393 hsd->AbortCpltCallback = HAL_SD_AbortCallback; 00394 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 00395 hsd->Read_DMADblBuf0CpltCallback = HAL_SDEx_Read_DMADoubleBuffer0CpltCallback; 00396 hsd->Read_DMADblBuf1CpltCallback = HAL_SDEx_Read_DMADoubleBuffer1CpltCallback; 00397 hsd->Write_DMADblBuf0CpltCallback = HAL_SDEx_Write_DMADoubleBuffer0CpltCallback; 00398 hsd->Write_DMADblBuf1CpltCallback = HAL_SDEx_Write_DMADoubleBuffer1CpltCallback; 00399 hsd->DriveTransceiver_1_8V_Callback = HAL_SDEx_DriveTransceiver_1_8V_Callback; 00400 #endif 00401 00402 if(hsd->MspInitCallback == NULL) 00403 { 00404 hsd->MspInitCallback = HAL_SD_MspInit; 00405 } 00406 00407 /* Init the low level hardware */ 00408 hsd->MspInitCallback(hsd); 00409 #else 00410 /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */ 00411 HAL_SD_MspInit(hsd); 00412 #endif 00413 } 00414 00415 hsd->State = HAL_SD_STATE_BUSY; 00416 00417 /* Initialize the Card parameters */ 00418 if (HAL_SD_InitCard(hsd) != HAL_OK) 00419 { 00420 return HAL_ERROR; 00421 } 00422 00423 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 00424 /* Configure the bus wide */ 00425 if(HAL_SD_ConfigWideBusOperation(hsd, hsd->Init.BusWide) != HAL_OK) 00426 { 00427 return HAL_ERROR; 00428 } 00429 00430 if(hsd->Init.Transceiver == SDMMC_TRANSCEIVER_ENABLE) 00431 { 00432 if((hsd->SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED) || 00433 (hsd->SdCard.CardType == CARD_SDHC_SDXC)) 00434 { 00435 hsd->Instance->CLKCR |= 0x00100000U; 00436 /* Enable High Speed */ 00437 if(HAL_SDEx_HighSpeed(hsd) != HAL_SD_ERROR_NONE) 00438 { 00439 return HAL_ERROR; 00440 } 00441 } 00442 } 00443 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 00444 00445 /* Initialize the error code */ 00446 hsd->ErrorCode = HAL_SD_ERROR_NONE; 00447 00448 /* Initialize the SD operation */ 00449 hsd->Context = SD_CONTEXT_NONE; 00450 00451 /* Initialize the SD state */ 00452 hsd->State = HAL_SD_STATE_READY; 00453 00454 return HAL_OK; 00455 } 00456 00457 /** 00458 * @brief Initializes the SD Card. 00459 * @param hsd: Pointer to SD handle 00460 * @note This function initializes the SD card. It could be used when a card 00461 re-initialization is needed. 00462 * @retval HAL status 00463 */ 00464 HAL_StatusTypeDef HAL_SD_InitCard(SD_HandleTypeDef *hsd) 00465 { 00466 uint32_t errorstate; 00467 HAL_StatusTypeDef status; 00468 SD_InitTypeDef Init; 00469 00470 /* Default SDMMC peripheral configuration for SD card initialization */ 00471 Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING; 00472 #if !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 00473 Init.ClockBypass = SDMMC_CLOCK_BYPASS_DISABLE; 00474 #endif /* !STM32L4R5xx && !STM32L4R7xx && !STM32L4R9xx && !STM32L4S5xx && !STM32L4S7xx && !STM32L4S9xx */ 00475 Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE; 00476 Init.BusWide = SDMMC_BUS_WIDE_1B; 00477 Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE; 00478 Init.ClockDiv = SDMMC_INIT_CLK_DIV; 00479 00480 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 00481 if(hsd->Init.Transceiver == SDMMC_TRANSCEIVER_ENABLE) 00482 { 00483 /* Set Transceiver polarity */ 00484 hsd->Instance->POWER |= SDMMC_POWER_DIRPOL; 00485 } 00486 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 00487 00488 /* Initialize SDMMC peripheral interface with default configuration */ 00489 status = SDMMC_Init(hsd->Instance, Init); 00490 if(status != HAL_OK) 00491 { 00492 return HAL_ERROR; 00493 } 00494 00495 #if !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 00496 /* Disable SDMMC Clock */ 00497 __HAL_SD_DISABLE(hsd); 00498 #endif /* !STM32L4R5xx && !STM32L4R7xx && !STM32L4R9xx && !STM32L4S5xx && !STM32L4S7xx && !STM32L4S9xx */ 00499 00500 /* Set Power State to ON */ 00501 status = SDMMC_PowerState_ON(hsd->Instance); 00502 if(status != HAL_OK) 00503 { 00504 return HAL_ERROR; 00505 } 00506 00507 #if !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 00508 /* Enable SDMMC Clock */ 00509 __HAL_SD_ENABLE(hsd); 00510 #endif /* !STM32L4R5xx && !STM32L4R7xx && !STM32L4R9xx && !STM32L4S5xx && !STM32L4S7xx && !STM32L4S9xx */ 00511 00512 /* Required power up waiting time before starting the SD initialization sequence */ 00513 HAL_Delay(2U); 00514 00515 /* Identify card operating voltage */ 00516 errorstate = SD_PowerON(hsd); 00517 if(errorstate != HAL_SD_ERROR_NONE) 00518 { 00519 hsd->State = HAL_SD_STATE_READY; 00520 hsd->ErrorCode |= errorstate; 00521 return HAL_ERROR; 00522 } 00523 00524 /* Card initialization */ 00525 errorstate = SD_InitCard(hsd); 00526 if(errorstate != HAL_SD_ERROR_NONE) 00527 { 00528 hsd->State = HAL_SD_STATE_READY; 00529 hsd->ErrorCode |= errorstate; 00530 return HAL_ERROR; 00531 } 00532 00533 return HAL_OK; 00534 } 00535 00536 /** 00537 * @brief De-Initializes the SD card. 00538 * @param hsd: Pointer to SD handle 00539 * @retval HAL status 00540 */ 00541 HAL_StatusTypeDef HAL_SD_DeInit(SD_HandleTypeDef *hsd) 00542 { 00543 /* Check the SD handle allocation */ 00544 if(hsd == NULL) 00545 { 00546 return HAL_ERROR; 00547 } 00548 00549 /* Check the parameters */ 00550 assert_param(IS_SDMMC_ALL_INSTANCE(hsd->Instance)); 00551 00552 hsd->State = HAL_SD_STATE_BUSY; 00553 00554 /* Set SD power state to off */ 00555 SD_PowerOFF(hsd); 00556 00557 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1) 00558 if(hsd->MspDeInitCallback == NULL) 00559 { 00560 hsd->MspDeInitCallback = HAL_SD_MspDeInit; 00561 } 00562 00563 /* DeInit the low level hardware */ 00564 hsd->MspDeInitCallback(hsd); 00565 #else 00566 /* De-Initialize the MSP layer */ 00567 HAL_SD_MspDeInit(hsd); 00568 #endif 00569 00570 hsd->ErrorCode = HAL_SD_ERROR_NONE; 00571 hsd->State = HAL_SD_STATE_RESET; 00572 00573 return HAL_OK; 00574 } 00575 00576 00577 /** 00578 * @brief Initializes the SD MSP. 00579 * @param hsd: Pointer to SD handle 00580 * @retval None 00581 */ 00582 __weak void HAL_SD_MspInit(SD_HandleTypeDef *hsd) 00583 { 00584 /* Prevent unused argument(s) compilation warning */ 00585 UNUSED(hsd); 00586 00587 /* NOTE : This function should not be modified, when the callback is needed, 00588 the HAL_SD_MspInit could be implemented in the user file 00589 */ 00590 } 00591 00592 /** 00593 * @brief De-Initialize SD MSP. 00594 * @param hsd: Pointer to SD handle 00595 * @retval None 00596 */ 00597 __weak void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd) 00598 { 00599 /* Prevent unused argument(s) compilation warning */ 00600 UNUSED(hsd); 00601 00602 /* NOTE : This function should not be modified, when the callback is needed, 00603 the HAL_SD_MspDeInit could be implemented in the user file 00604 */ 00605 } 00606 00607 /** 00608 * @} 00609 */ 00610 00611 /** @addtogroup SD_Exported_Functions_Group2 00612 * @brief Data transfer functions 00613 * 00614 @verbatim 00615 ============================================================================== 00616 ##### IO operation functions ##### 00617 ============================================================================== 00618 [..] 00619 This subsection provides a set of functions allowing to manage the data 00620 transfer from/to SD card. 00621 00622 @endverbatim 00623 * @{ 00624 */ 00625 00626 /** 00627 * @brief Reads block(s) from a specified address in a card. The Data transfer 00628 * is managed by polling mode. 00629 * @note This API should be followed by a check on the card state through 00630 * HAL_SD_GetCardState(). 00631 * @param hsd: Pointer to SD handle 00632 * @param pData: pointer to the buffer that will contain the received data 00633 * @param BlockAdd: Block Address from where data is to be read 00634 * @param NumberOfBlocks: Number of SD blocks to read 00635 * @param Timeout: Specify timeout value 00636 * @retval HAL status 00637 */ 00638 HAL_StatusTypeDef HAL_SD_ReadBlocks(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout) 00639 { 00640 SDMMC_DataInitTypeDef config; 00641 uint32_t errorstate; 00642 uint32_t tickstart = HAL_GetTick(); 00643 uint32_t count, data; 00644 uint32_t add = BlockAdd; 00645 uint8_t *tempbuff = pData; 00646 00647 if(NULL == pData) 00648 { 00649 hsd->ErrorCode |= HAL_SD_ERROR_PARAM; 00650 return HAL_ERROR; 00651 } 00652 00653 if(hsd->State == HAL_SD_STATE_READY) 00654 { 00655 hsd->ErrorCode = HAL_SD_ERROR_NONE; 00656 00657 if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)) 00658 { 00659 hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE; 00660 return HAL_ERROR; 00661 } 00662 00663 hsd->State = HAL_SD_STATE_BUSY; 00664 00665 /* Initialize data control register */ 00666 hsd->Instance->DCTRL = 0U; 00667 00668 if(hsd->SdCard.CardType != CARD_SDHC_SDXC) 00669 { 00670 add *= 512U; 00671 } 00672 00673 /* Set Block Size for Card */ 00674 errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE); 00675 if(errorstate != HAL_SD_ERROR_NONE) 00676 { 00677 /* Clear all the static flags */ 00678 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 00679 hsd->ErrorCode |= errorstate; 00680 hsd->State = HAL_SD_STATE_READY; 00681 return HAL_ERROR; 00682 } 00683 00684 /* Configure the SD DPSM (Data Path State Machine) */ 00685 config.DataTimeOut = SDMMC_DATATIMEOUT; 00686 config.DataLength = NumberOfBlocks * BLOCKSIZE; 00687 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; 00688 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; 00689 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; 00690 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 00691 config.DPSM = SDMMC_DPSM_DISABLE; 00692 #else 00693 config.DPSM = SDMMC_DPSM_ENABLE; 00694 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 00695 (void)SDMMC_ConfigData(hsd->Instance, &config); 00696 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 00697 __SDMMC_CMDTRANS_ENABLE( hsd->Instance); 00698 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 00699 00700 /* Read block(s) in polling mode */ 00701 if(NumberOfBlocks > 1U) 00702 { 00703 hsd->Context = SD_CONTEXT_READ_MULTIPLE_BLOCK; 00704 00705 /* Read Multi Block command */ 00706 errorstate = SDMMC_CmdReadMultiBlock(hsd->Instance, add); 00707 } 00708 else 00709 { 00710 hsd->Context = SD_CONTEXT_READ_SINGLE_BLOCK; 00711 00712 /* Read Single Block command */ 00713 errorstate = SDMMC_CmdReadSingleBlock(hsd->Instance, add); 00714 } 00715 if(errorstate != HAL_SD_ERROR_NONE) 00716 { 00717 /* Clear all the static flags */ 00718 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 00719 hsd->ErrorCode |= errorstate; 00720 hsd->State = HAL_SD_STATE_READY; 00721 return HAL_ERROR; 00722 } 00723 00724 /* Poll on SDMMC flags */ 00725 while(!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND)) 00726 { 00727 if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOHF)) 00728 { 00729 /* Read data from SDMMC Rx FIFO */ 00730 for(count = 0U; count < 8U; count++) 00731 { 00732 data = SDMMC_ReadFIFO(hsd->Instance); 00733 *tempbuff = (uint8_t)(data & 0xFFU); 00734 tempbuff++; 00735 *tempbuff = (uint8_t)((data >> 8U) & 0xFFU); 00736 tempbuff++; 00737 *tempbuff = (uint8_t)((data >> 16U) & 0xFFU); 00738 tempbuff++; 00739 *tempbuff = (uint8_t)((data >> 24U) & 0xFFU); 00740 tempbuff++; 00741 } 00742 } 00743 00744 if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U)) 00745 { 00746 /* Clear all the static flags */ 00747 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 00748 hsd->ErrorCode |= HAL_SD_ERROR_TIMEOUT; 00749 hsd->State= HAL_SD_STATE_READY; 00750 return HAL_TIMEOUT; 00751 } 00752 } 00753 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 00754 __SDMMC_CMDTRANS_DISABLE( hsd->Instance); 00755 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 00756 00757 /* Send stop transmission command in case of multiblock read */ 00758 if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U)) 00759 { 00760 if(hsd->SdCard.CardType != CARD_SECURED) 00761 { 00762 /* Send stop transmission command */ 00763 errorstate = SDMMC_CmdStopTransfer(hsd->Instance); 00764 if(errorstate != HAL_SD_ERROR_NONE) 00765 { 00766 /* Clear all the static flags */ 00767 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 00768 hsd->ErrorCode |= errorstate; 00769 hsd->State = HAL_SD_STATE_READY; 00770 return HAL_ERROR; 00771 } 00772 } 00773 } 00774 00775 /* Get error state */ 00776 if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT)) 00777 { 00778 /* Clear all the static flags */ 00779 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 00780 hsd->ErrorCode |= HAL_SD_ERROR_DATA_TIMEOUT; 00781 hsd->State = HAL_SD_STATE_READY; 00782 return HAL_ERROR; 00783 } 00784 else if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL)) 00785 { 00786 /* Clear all the static flags */ 00787 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 00788 hsd->ErrorCode |= HAL_SD_ERROR_DATA_CRC_FAIL; 00789 hsd->State = HAL_SD_STATE_READY; 00790 return HAL_ERROR; 00791 } 00792 else if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR)) 00793 { 00794 /* Clear all the static flags */ 00795 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 00796 hsd->ErrorCode |= HAL_SD_ERROR_RX_OVERRUN; 00797 hsd->State = HAL_SD_STATE_READY; 00798 return HAL_ERROR; 00799 } 00800 else 00801 { 00802 /* Nothing to do */ 00803 } 00804 00805 #if !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 00806 /* Empty FIFO if there is still any data */ 00807 while ((__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXDAVL))) 00808 { 00809 data = SDMMC_ReadFIFO(hsd->Instance); 00810 *tempbuff = (uint8_t)(data & 0xFFU); 00811 tempbuff++; 00812 *tempbuff = (uint8_t)((data >> 8U) & 0xFFU); 00813 tempbuff++; 00814 *tempbuff = (uint8_t)((data >> 16U) & 0xFFU); 00815 tempbuff++; 00816 *tempbuff = (uint8_t)((data >> 24U) & 0xFFU); 00817 tempbuff++; 00818 00819 if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U)) 00820 { 00821 /* Clear all the static flags */ 00822 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 00823 hsd->ErrorCode |= HAL_SD_ERROR_TIMEOUT; 00824 hsd->State= HAL_SD_STATE_READY; 00825 return HAL_ERROR; 00826 } 00827 } 00828 #endif /* !STM32L4R5xx && !STM32L4R7xx && !STM32L4R9xx && !STM32L4S5xx && !STM32L4S7xx && !STM32L4S9xx */ 00829 00830 /* Clear all the static flags */ 00831 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); 00832 00833 hsd->State = HAL_SD_STATE_READY; 00834 00835 return HAL_OK; 00836 } 00837 else 00838 { 00839 hsd->ErrorCode |= HAL_SD_ERROR_BUSY; 00840 return HAL_ERROR; 00841 } 00842 } 00843 00844 /** 00845 * @brief Allows to write block(s) to a specified address in a card. The Data 00846 * transfer is managed by polling mode. 00847 * @note This API should be followed by a check on the card state through 00848 * HAL_SD_GetCardState(). 00849 * @param hsd: Pointer to SD handle 00850 * @param pData: pointer to the buffer that will contain the data to transmit 00851 * @param BlockAdd: Block Address where data will be written 00852 * @param NumberOfBlocks: Number of SD blocks to write 00853 * @param Timeout: Specify timeout value 00854 * @retval HAL status 00855 */ 00856 HAL_StatusTypeDef HAL_SD_WriteBlocks(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks, uint32_t Timeout) 00857 { 00858 SDMMC_DataInitTypeDef config; 00859 uint32_t errorstate; 00860 uint32_t tickstart = HAL_GetTick(); 00861 uint32_t count, data; 00862 uint32_t add = BlockAdd; 00863 uint8_t *tempbuff = pData; 00864 00865 if(NULL == pData) 00866 { 00867 hsd->ErrorCode |= HAL_SD_ERROR_PARAM; 00868 return HAL_ERROR; 00869 } 00870 00871 if(hsd->State == HAL_SD_STATE_READY) 00872 { 00873 hsd->ErrorCode = HAL_SD_ERROR_NONE; 00874 00875 if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)) 00876 { 00877 hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE; 00878 return HAL_ERROR; 00879 } 00880 00881 hsd->State = HAL_SD_STATE_BUSY; 00882 00883 /* Initialize data control register */ 00884 hsd->Instance->DCTRL = 0U; 00885 00886 if(hsd->SdCard.CardType != CARD_SDHC_SDXC) 00887 { 00888 add *= 512U; 00889 } 00890 00891 /* Set Block Size for Card */ 00892 errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE); 00893 if(errorstate != HAL_SD_ERROR_NONE) 00894 { 00895 /* Clear all the static flags */ 00896 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 00897 hsd->ErrorCode |= errorstate; 00898 hsd->State = HAL_SD_STATE_READY; 00899 return HAL_ERROR; 00900 } 00901 00902 /* Configure the SD DPSM (Data Path State Machine) */ 00903 config.DataTimeOut = SDMMC_DATATIMEOUT; 00904 config.DataLength = NumberOfBlocks * BLOCKSIZE; 00905 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; 00906 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD; 00907 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; 00908 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 00909 config.DPSM = SDMMC_DPSM_DISABLE; 00910 #else 00911 config.DPSM = SDMMC_DPSM_ENABLE; 00912 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 00913 (void)SDMMC_ConfigData(hsd->Instance, &config); 00914 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 00915 __SDMMC_CMDTRANS_ENABLE( hsd->Instance); 00916 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 00917 00918 /* Write Blocks in Polling mode */ 00919 if(NumberOfBlocks > 1U) 00920 { 00921 hsd->Context = SD_CONTEXT_WRITE_MULTIPLE_BLOCK; 00922 00923 /* Write Multi Block command */ 00924 errorstate = SDMMC_CmdWriteMultiBlock(hsd->Instance, add); 00925 } 00926 else 00927 { 00928 hsd->Context = SD_CONTEXT_WRITE_SINGLE_BLOCK; 00929 00930 /* Write Single Block command */ 00931 errorstate = SDMMC_CmdWriteSingleBlock(hsd->Instance, add); 00932 } 00933 if(errorstate != HAL_SD_ERROR_NONE) 00934 { 00935 /* Clear all the static flags */ 00936 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 00937 hsd->ErrorCode |= errorstate; 00938 hsd->State = HAL_SD_STATE_READY; 00939 return HAL_ERROR; 00940 } 00941 00942 /* Write block(s) in polling mode */ 00943 while(!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_TXUNDERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND)) 00944 { 00945 if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_TXFIFOHE)) 00946 { 00947 /* Write data to SDMMC Tx FIFO */ 00948 for(count = 0U; count < 8U; count++) 00949 { 00950 data = (uint32_t)(*tempbuff); 00951 tempbuff++; 00952 data |= ((uint32_t)(*tempbuff) << 8U); 00953 tempbuff++; 00954 data |= ((uint32_t)(*tempbuff) << 16U); 00955 tempbuff++; 00956 data |= ((uint32_t)(*tempbuff) << 24U); 00957 tempbuff++; 00958 (void)SDMMC_WriteFIFO(hsd->Instance, &data); 00959 } 00960 } 00961 00962 if(((HAL_GetTick()-tickstart) >= Timeout) || (Timeout == 0U)) 00963 { 00964 /* Clear all the static flags */ 00965 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 00966 hsd->ErrorCode |= errorstate; 00967 hsd->State = HAL_SD_STATE_READY; 00968 return HAL_TIMEOUT; 00969 } 00970 } 00971 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 00972 __SDMMC_CMDTRANS_DISABLE( hsd->Instance); 00973 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 00974 00975 /* Send stop transmission command in case of multiblock write */ 00976 if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DATAEND) && (NumberOfBlocks > 1U)) 00977 { 00978 if(hsd->SdCard.CardType != CARD_SECURED) 00979 { 00980 /* Send stop transmission command */ 00981 errorstate = SDMMC_CmdStopTransfer(hsd->Instance); 00982 if(errorstate != HAL_SD_ERROR_NONE) 00983 { 00984 /* Clear all the static flags */ 00985 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 00986 hsd->ErrorCode |= errorstate; 00987 hsd->State = HAL_SD_STATE_READY; 00988 return HAL_ERROR; 00989 } 00990 } 00991 } 00992 00993 /* Get error state */ 00994 if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT)) 00995 { 00996 /* Clear all the static flags */ 00997 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 00998 hsd->ErrorCode |= HAL_SD_ERROR_DATA_TIMEOUT; 00999 hsd->State = HAL_SD_STATE_READY; 01000 return HAL_ERROR; 01001 } 01002 else if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL)) 01003 { 01004 /* Clear all the static flags */ 01005 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 01006 hsd->ErrorCode |= HAL_SD_ERROR_DATA_CRC_FAIL; 01007 hsd->State = HAL_SD_STATE_READY; 01008 return HAL_ERROR; 01009 } 01010 else if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_TXUNDERR)) 01011 { 01012 /* Clear all the static flags */ 01013 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 01014 hsd->ErrorCode |= HAL_SD_ERROR_TX_UNDERRUN; 01015 hsd->State = HAL_SD_STATE_READY; 01016 return HAL_ERROR; 01017 } 01018 else 01019 { 01020 /* Nothing to do */ 01021 } 01022 01023 /* Clear all the static flags */ 01024 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); 01025 01026 hsd->State = HAL_SD_STATE_READY; 01027 01028 return HAL_OK; 01029 } 01030 else 01031 { 01032 hsd->ErrorCode |= HAL_SD_ERROR_BUSY; 01033 return HAL_ERROR; 01034 } 01035 } 01036 01037 /** 01038 * @brief Reads block(s) from a specified address in a card. The Data transfer 01039 * is managed in interrupt mode. 01040 * @note This API should be followed by a check on the card state through 01041 * HAL_SD_GetCardState(). 01042 * @note You could also check the IT transfer process through the SD Rx 01043 * interrupt event. 01044 * @param hsd: Pointer to SD handle 01045 * @param pData: Pointer to the buffer that will contain the received data 01046 * @param BlockAdd: Block Address from where data is to be read 01047 * @param NumberOfBlocks: Number of blocks to read. 01048 * @retval HAL status 01049 */ 01050 HAL_StatusTypeDef HAL_SD_ReadBlocks_IT(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks) 01051 { 01052 SDMMC_DataInitTypeDef config; 01053 uint32_t errorstate; 01054 uint32_t add = BlockAdd; 01055 01056 if(NULL == pData) 01057 { 01058 hsd->ErrorCode |= HAL_SD_ERROR_PARAM; 01059 return HAL_ERROR; 01060 } 01061 01062 if(hsd->State == HAL_SD_STATE_READY) 01063 { 01064 hsd->ErrorCode = HAL_SD_ERROR_NONE; 01065 01066 if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)) 01067 { 01068 hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE; 01069 return HAL_ERROR; 01070 } 01071 01072 hsd->State = HAL_SD_STATE_BUSY; 01073 01074 /* Initialize data control register */ 01075 hsd->Instance->DCTRL = 0U; 01076 01077 hsd->pRxBuffPtr = pData; 01078 hsd->RxXferSize = BLOCKSIZE * NumberOfBlocks; 01079 01080 __HAL_SD_ENABLE_IT(hsd, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND | SDMMC_FLAG_RXFIFOHF)); 01081 01082 if(hsd->SdCard.CardType != CARD_SDHC_SDXC) 01083 { 01084 add *= 512U; 01085 } 01086 01087 /* Set Block Size for Card */ 01088 errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE); 01089 if(errorstate != HAL_SD_ERROR_NONE) 01090 { 01091 /* Clear all the static flags */ 01092 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 01093 hsd->ErrorCode |= errorstate; 01094 hsd->State = HAL_SD_STATE_READY; 01095 return HAL_ERROR; 01096 } 01097 01098 /* Configure the SD DPSM (Data Path State Machine) */ 01099 config.DataTimeOut = SDMMC_DATATIMEOUT; 01100 config.DataLength = BLOCKSIZE * NumberOfBlocks; 01101 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; 01102 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; 01103 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; 01104 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 01105 config.DPSM = SDMMC_DPSM_DISABLE; 01106 #else 01107 config.DPSM = SDMMC_DPSM_ENABLE; 01108 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 01109 (void)SDMMC_ConfigData(hsd->Instance, &config); 01110 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 01111 __SDMMC_CMDTRANS_ENABLE( hsd->Instance); 01112 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 01113 01114 /* Read Blocks in IT mode */ 01115 if(NumberOfBlocks > 1U) 01116 { 01117 hsd->Context = (SD_CONTEXT_READ_MULTIPLE_BLOCK | SD_CONTEXT_IT); 01118 01119 /* Read Multi Block command */ 01120 errorstate = SDMMC_CmdReadMultiBlock(hsd->Instance, add); 01121 } 01122 else 01123 { 01124 hsd->Context = (SD_CONTEXT_READ_SINGLE_BLOCK | SD_CONTEXT_IT); 01125 01126 /* Read Single Block command */ 01127 errorstate = SDMMC_CmdReadSingleBlock(hsd->Instance, add); 01128 } 01129 if(errorstate != HAL_SD_ERROR_NONE) 01130 { 01131 /* Clear all the static flags */ 01132 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 01133 hsd->ErrorCode |= errorstate; 01134 hsd->State = HAL_SD_STATE_READY; 01135 return HAL_ERROR; 01136 } 01137 01138 return HAL_OK; 01139 } 01140 else 01141 { 01142 return HAL_BUSY; 01143 } 01144 } 01145 01146 /** 01147 * @brief Writes block(s) to a specified address in a card. The Data transfer 01148 * is managed in interrupt mode. 01149 * @note This API should be followed by a check on the card state through 01150 * HAL_SD_GetCardState(). 01151 * @note You could also check the IT transfer process through the SD Tx 01152 * interrupt event. 01153 * @param hsd: Pointer to SD handle 01154 * @param pData: Pointer to the buffer that will contain the data to transmit 01155 * @param BlockAdd: Block Address where data will be written 01156 * @param NumberOfBlocks: Number of blocks to write 01157 * @retval HAL status 01158 */ 01159 HAL_StatusTypeDef HAL_SD_WriteBlocks_IT(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks) 01160 { 01161 SDMMC_DataInitTypeDef config; 01162 uint32_t errorstate; 01163 uint32_t add = BlockAdd; 01164 01165 if(NULL == pData) 01166 { 01167 hsd->ErrorCode |= HAL_SD_ERROR_PARAM; 01168 return HAL_ERROR; 01169 } 01170 01171 if(hsd->State == HAL_SD_STATE_READY) 01172 { 01173 hsd->ErrorCode = HAL_SD_ERROR_NONE; 01174 01175 if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)) 01176 { 01177 hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE; 01178 return HAL_ERROR; 01179 } 01180 01181 hsd->State = HAL_SD_STATE_BUSY; 01182 01183 /* Initialize data control register */ 01184 hsd->Instance->DCTRL = 0U; 01185 01186 hsd->pTxBuffPtr = pData; 01187 hsd->TxXferSize = BLOCKSIZE * NumberOfBlocks; 01188 01189 /* Enable transfer interrupts */ 01190 __HAL_SD_ENABLE_IT(hsd, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND | SDMMC_FLAG_TXFIFOHE)); 01191 01192 if(hsd->SdCard.CardType != CARD_SDHC_SDXC) 01193 { 01194 add *= 512U; 01195 } 01196 01197 /* Set Block Size for Card */ 01198 errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE); 01199 if(errorstate != HAL_SD_ERROR_NONE) 01200 { 01201 /* Clear all the static flags */ 01202 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 01203 hsd->ErrorCode |= errorstate; 01204 hsd->State = HAL_SD_STATE_READY; 01205 return HAL_ERROR; 01206 } 01207 01208 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 01209 /* Configure the SD DPSM (Data Path State Machine) */ 01210 config.DataTimeOut = SDMMC_DATATIMEOUT; 01211 config.DataLength = BLOCKSIZE * NumberOfBlocks; 01212 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; 01213 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD; 01214 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; 01215 config.DPSM = SDMMC_DPSM_DISABLE; 01216 (void)SDMMC_ConfigData(hsd->Instance, &config); 01217 01218 __SDMMC_CMDTRANS_ENABLE( hsd->Instance); 01219 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 01220 01221 /* Write Blocks in Polling mode */ 01222 if(NumberOfBlocks > 1U) 01223 { 01224 hsd->Context = (SD_CONTEXT_WRITE_MULTIPLE_BLOCK| SD_CONTEXT_IT); 01225 01226 /* Write Multi Block command */ 01227 errorstate = SDMMC_CmdWriteMultiBlock(hsd->Instance, add); 01228 } 01229 else 01230 { 01231 hsd->Context = (SD_CONTEXT_WRITE_SINGLE_BLOCK | SD_CONTEXT_IT); 01232 01233 /* Write Single Block command */ 01234 errorstate = SDMMC_CmdWriteSingleBlock(hsd->Instance, add); 01235 } 01236 if(errorstate != HAL_SD_ERROR_NONE) 01237 { 01238 /* Clear all the static flags */ 01239 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 01240 hsd->ErrorCode |= errorstate; 01241 hsd->State = HAL_SD_STATE_READY; 01242 return HAL_ERROR; 01243 } 01244 01245 #if !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 01246 /* Configure the SD DPSM (Data Path State Machine) */ 01247 config.DataTimeOut = SDMMC_DATATIMEOUT; 01248 config.DataLength = BLOCKSIZE * NumberOfBlocks; 01249 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; 01250 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD; 01251 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; 01252 config.DPSM = SDMMC_DPSM_ENABLE; 01253 (void)SDMMC_ConfigData(hsd->Instance, &config); 01254 #endif /* !STM32L4R5xx && !STM32L4R7xx && !STM32L4R9xx && !STM32L4S5xx && !STM32L4S7xx && !STM32L4S9xx */ 01255 01256 return HAL_OK; 01257 } 01258 else 01259 { 01260 return HAL_BUSY; 01261 } 01262 } 01263 01264 /** 01265 * @brief Reads block(s) from a specified address in a card. The Data transfer 01266 * is managed by DMA mode. 01267 * @note This API should be followed by a check on the card state through 01268 * HAL_SD_GetCardState(). 01269 * @note You could also check the DMA transfer process through the SD Rx 01270 * interrupt event. 01271 * @param hsd: Pointer SD handle 01272 * @param pData: Pointer to the buffer that will contain the received data 01273 * @param BlockAdd: Block Address from where data is to be read 01274 * @param NumberOfBlocks: Number of blocks to read. 01275 * @retval HAL status 01276 */ 01277 HAL_StatusTypeDef HAL_SD_ReadBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks) 01278 { 01279 SDMMC_DataInitTypeDef config; 01280 uint32_t errorstate; 01281 uint32_t add = BlockAdd; 01282 01283 if(NULL == pData) 01284 { 01285 hsd->ErrorCode |= HAL_SD_ERROR_PARAM; 01286 return HAL_ERROR; 01287 } 01288 01289 if(hsd->State == HAL_SD_STATE_READY) 01290 { 01291 hsd->ErrorCode = HAL_SD_ERROR_NONE; 01292 01293 if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)) 01294 { 01295 hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE; 01296 return HAL_ERROR; 01297 } 01298 01299 hsd->State = HAL_SD_STATE_BUSY; 01300 01301 /* Initialize data control register */ 01302 hsd->Instance->DCTRL = 0U; 01303 01304 #if !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 01305 __HAL_SD_ENABLE_IT(hsd, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND)); 01306 01307 /* Set the DMA transfer complete callback */ 01308 hsd->hdmarx->XferCpltCallback = SD_DMAReceiveCplt; 01309 01310 /* Set the DMA error callback */ 01311 hsd->hdmarx->XferErrorCallback = SD_DMAError; 01312 01313 /* Set the DMA Abort callback */ 01314 hsd->hdmarx->XferAbortCallback = NULL; 01315 01316 /* Enable the DMA Channel */ 01317 if(HAL_DMA_Start_IT(hsd->hdmarx, (uint32_t)&hsd->Instance->FIFO, (uint32_t)pData, (uint32_t)(BLOCKSIZE * NumberOfBlocks)/4U) != HAL_OK) 01318 { 01319 __HAL_SD_DISABLE_IT(hsd, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND)); 01320 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 01321 hsd->ErrorCode |= HAL_SD_ERROR_DMA; 01322 hsd->State = HAL_SD_STATE_READY; 01323 return HAL_ERROR; 01324 } 01325 else 01326 { 01327 /* Enable SD DMA transfer */ 01328 __HAL_SD_DMA_ENABLE(hsd); 01329 #else 01330 hsd->pRxBuffPtr = pData; 01331 hsd->RxXferSize = BLOCKSIZE * NumberOfBlocks; 01332 #endif /* !STM32L4R5xx && !STM32L4R7xx && !STM32L4R9xx && !STM32L4S5xx && !STM32L4S7xx && !STM32L4S9xx */ 01333 01334 if(hsd->SdCard.CardType != CARD_SDHC_SDXC) 01335 { 01336 add *= 512U; 01337 } 01338 01339 /* Set Block Size for Card */ 01340 errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE); 01341 if(errorstate != HAL_SD_ERROR_NONE) 01342 { 01343 /* Clear all the static flags */ 01344 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 01345 hsd->ErrorCode |= errorstate; 01346 hsd->State = HAL_SD_STATE_READY; 01347 return HAL_ERROR; 01348 } 01349 01350 /* Configure the SD DPSM (Data Path State Machine) */ 01351 config.DataTimeOut = SDMMC_DATATIMEOUT; 01352 config.DataLength = BLOCKSIZE * NumberOfBlocks; 01353 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; 01354 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; 01355 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; 01356 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 01357 config.DPSM = SDMMC_DPSM_DISABLE; 01358 #else 01359 config.DPSM = SDMMC_DPSM_ENABLE; 01360 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 01361 (void)SDMMC_ConfigData(hsd->Instance, &config); 01362 01363 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 01364 /* Enable transfer interrupts */ 01365 __HAL_SD_ENABLE_IT(hsd, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND)); 01366 01367 __SDMMC_CMDTRANS_ENABLE( hsd->Instance); 01368 hsd->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_SINGLE_BUFF; 01369 hsd->Instance->IDMABASE0 = (uint32_t) pData ; 01370 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 01371 01372 /* Read Blocks in DMA mode */ 01373 if(NumberOfBlocks > 1U) 01374 { 01375 hsd->Context = (SD_CONTEXT_READ_MULTIPLE_BLOCK | SD_CONTEXT_DMA); 01376 01377 /* Read Multi Block command */ 01378 errorstate = SDMMC_CmdReadMultiBlock(hsd->Instance, add); 01379 } 01380 else 01381 { 01382 hsd->Context = (SD_CONTEXT_READ_SINGLE_BLOCK | SD_CONTEXT_DMA); 01383 01384 /* Read Single Block command */ 01385 errorstate = SDMMC_CmdReadSingleBlock(hsd->Instance, add); 01386 } 01387 if(errorstate != HAL_SD_ERROR_NONE) 01388 { 01389 /* Clear all the static flags */ 01390 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 01391 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 01392 __HAL_SD_DISABLE_IT(hsd, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND)); 01393 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 01394 hsd->ErrorCode |= errorstate; 01395 hsd->State = HAL_SD_STATE_READY; 01396 return HAL_ERROR; 01397 } 01398 01399 return HAL_OK; 01400 #if !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 01401 } 01402 #endif 01403 } 01404 else 01405 { 01406 return HAL_BUSY; 01407 } 01408 } 01409 01410 /** 01411 * @brief Writes block(s) to a specified address in a card. The Data transfer 01412 * is managed by DMA mode. 01413 * @note This API should be followed by a check on the card state through 01414 * HAL_SD_GetCardState(). 01415 * @note You could also check the DMA transfer process through the SD Tx 01416 * interrupt event. 01417 * @param hsd: Pointer to SD handle 01418 * @param pData: Pointer to the buffer that will contain the data to transmit 01419 * @param BlockAdd: Block Address where data will be written 01420 * @param NumberOfBlocks: Number of blocks to write 01421 * @retval HAL status 01422 */ 01423 HAL_StatusTypeDef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks) 01424 { 01425 SDMMC_DataInitTypeDef config; 01426 uint32_t errorstate; 01427 uint32_t add = BlockAdd; 01428 01429 if(NULL == pData) 01430 { 01431 hsd->ErrorCode |= HAL_SD_ERROR_PARAM; 01432 return HAL_ERROR; 01433 } 01434 01435 if(hsd->State == HAL_SD_STATE_READY) 01436 { 01437 hsd->ErrorCode = HAL_SD_ERROR_NONE; 01438 01439 if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)) 01440 { 01441 hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE; 01442 return HAL_ERROR; 01443 } 01444 01445 hsd->State = HAL_SD_STATE_BUSY; 01446 01447 /* Initialize data control register */ 01448 hsd->Instance->DCTRL = 0U; 01449 01450 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 01451 hsd->pTxBuffPtr = pData; 01452 hsd->TxXferSize = BLOCKSIZE * NumberOfBlocks; 01453 #else 01454 /* Enable SD Error interrupts */ 01455 __HAL_SD_ENABLE_IT(hsd, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR)); 01456 01457 /* Set the DMA transfer complete callback */ 01458 hsd->hdmatx->XferCpltCallback = SD_DMATransmitCplt; 01459 01460 /* Set the DMA error callback */ 01461 hsd->hdmatx->XferErrorCallback = SD_DMAError; 01462 01463 /* Set the DMA Abort callback */ 01464 hsd->hdmatx->XferAbortCallback = NULL; 01465 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 01466 01467 if(hsd->SdCard.CardType != CARD_SDHC_SDXC) 01468 { 01469 add *= 512U; 01470 } 01471 01472 /* Set Block Size for Card */ 01473 errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE); 01474 if(errorstate != HAL_SD_ERROR_NONE) 01475 { 01476 /* Clear all the static flags */ 01477 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 01478 hsd->ErrorCode |= errorstate; 01479 hsd->State = HAL_SD_STATE_READY; 01480 return HAL_ERROR; 01481 } 01482 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 01483 /* Configure the SD DPSM (Data Path State Machine) */ 01484 config.DataTimeOut = SDMMC_DATATIMEOUT; 01485 config.DataLength = BLOCKSIZE * NumberOfBlocks; 01486 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; 01487 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD; 01488 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; 01489 config.DPSM = SDMMC_DPSM_DISABLE; 01490 (void)SDMMC_ConfigData(hsd->Instance, &config); 01491 01492 /* Enable transfer interrupts */ 01493 __HAL_SD_ENABLE_IT(hsd, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND)); 01494 01495 __SDMMC_CMDTRANS_ENABLE( hsd->Instance); 01496 01497 hsd->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_SINGLE_BUFF; 01498 hsd->Instance->IDMABASE0 = (uint32_t) pData ; 01499 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 01500 01501 /* Write Blocks in Polling mode */ 01502 if(NumberOfBlocks > 1U) 01503 { 01504 hsd->Context = (SD_CONTEXT_WRITE_MULTIPLE_BLOCK | SD_CONTEXT_DMA); 01505 01506 /* Write Multi Block command */ 01507 errorstate = SDMMC_CmdWriteMultiBlock(hsd->Instance, add); 01508 } 01509 else 01510 { 01511 hsd->Context = (SD_CONTEXT_WRITE_SINGLE_BLOCK | SD_CONTEXT_DMA); 01512 01513 /* Write Single Block command */ 01514 errorstate = SDMMC_CmdWriteSingleBlock(hsd->Instance, add); 01515 } 01516 if(errorstate != HAL_SD_ERROR_NONE) 01517 { 01518 /* Clear all the static flags */ 01519 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 01520 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 01521 __HAL_SD_DISABLE_IT(hsd, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND)); 01522 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 01523 hsd->ErrorCode |= errorstate; 01524 hsd->State = HAL_SD_STATE_READY; 01525 return HAL_ERROR; 01526 } 01527 01528 #if !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 01529 /* Enable SDMMC DMA transfer */ 01530 __HAL_SD_DMA_ENABLE(hsd); 01531 01532 /* Enable the DMA Channel */ 01533 if(HAL_DMA_Start_IT(hsd->hdmatx, (uint32_t)pData, (uint32_t)&hsd->Instance->FIFO, (uint32_t)(BLOCKSIZE * NumberOfBlocks)/4U) != HAL_OK) 01534 { 01535 __HAL_SD_DISABLE_IT(hsd, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND)); 01536 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 01537 hsd->ErrorCode |= HAL_SD_ERROR_DMA; 01538 hsd->State = HAL_SD_STATE_READY; 01539 return HAL_ERROR; 01540 } 01541 else 01542 { 01543 /* Configure the SD DPSM (Data Path State Machine) */ 01544 config.DataTimeOut = SDMMC_DATATIMEOUT; 01545 config.DataLength = BLOCKSIZE * NumberOfBlocks; 01546 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; 01547 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD; 01548 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; 01549 config.DPSM = SDMMC_DPSM_ENABLE; 01550 (void)SDMMC_ConfigData(hsd->Instance, &config); 01551 #endif /* !STM32L4R5xx && !STM32L4R7xx && !STM32L4R9xx && !STM32L4S5xx && !STM32L4S7xx && !STM32L4S9xx */ 01552 01553 return HAL_OK; 01554 #if !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 01555 } 01556 #endif 01557 } 01558 else 01559 { 01560 return HAL_BUSY; 01561 } 01562 } 01563 01564 /** 01565 * @brief Erases the specified memory area of the given SD card. 01566 * @note This API should be followed by a check on the card state through 01567 * HAL_SD_GetCardState(). 01568 * @param hsd: Pointer to SD handle 01569 * @param BlockStartAdd: Start Block address 01570 * @param BlockEndAdd: End Block address 01571 * @retval HAL status 01572 */ 01573 HAL_StatusTypeDef HAL_SD_Erase(SD_HandleTypeDef *hsd, uint32_t BlockStartAdd, uint32_t BlockEndAdd) 01574 { 01575 uint32_t errorstate; 01576 uint32_t start_add = BlockStartAdd; 01577 uint32_t end_add = BlockEndAdd; 01578 01579 if(hsd->State == HAL_SD_STATE_READY) 01580 { 01581 hsd->ErrorCode = HAL_SD_ERROR_NONE; 01582 01583 if(end_add < start_add) 01584 { 01585 hsd->ErrorCode |= HAL_SD_ERROR_PARAM; 01586 return HAL_ERROR; 01587 } 01588 01589 if(end_add > (hsd->SdCard.LogBlockNbr)) 01590 { 01591 hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE; 01592 return HAL_ERROR; 01593 } 01594 01595 hsd->State = HAL_SD_STATE_BUSY; 01596 01597 /* Check if the card command class supports erase command */ 01598 if(((hsd->SdCard.Class) & SDMMC_CCCC_ERASE) == 0U) 01599 { 01600 /* Clear all the static flags */ 01601 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 01602 hsd->ErrorCode |= HAL_SD_ERROR_REQUEST_NOT_APPLICABLE; 01603 hsd->State = HAL_SD_STATE_READY; 01604 return HAL_ERROR; 01605 } 01606 01607 if((SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED) 01608 { 01609 /* Clear all the static flags */ 01610 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 01611 hsd->ErrorCode |= HAL_SD_ERROR_LOCK_UNLOCK_FAILED; 01612 hsd->State = HAL_SD_STATE_READY; 01613 return HAL_ERROR; 01614 } 01615 01616 /* Get start and end block for high capacity cards */ 01617 if(hsd->SdCard.CardType != CARD_SDHC_SDXC) 01618 { 01619 start_add *= 512U; 01620 end_add *= 512U; 01621 } 01622 01623 /* According to sd-card spec 1.0 ERASE_GROUP_START (CMD32) and erase_group_end(CMD33) */ 01624 if(hsd->SdCard.CardType != CARD_SECURED) 01625 { 01626 /* Send CMD32 SD_ERASE_GRP_START with argument as addr */ 01627 errorstate = SDMMC_CmdSDEraseStartAdd(hsd->Instance, start_add); 01628 if(errorstate != HAL_SD_ERROR_NONE) 01629 { 01630 /* Clear all the static flags */ 01631 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 01632 hsd->ErrorCode |= errorstate; 01633 hsd->State = HAL_SD_STATE_READY; 01634 return HAL_ERROR; 01635 } 01636 01637 /* Send CMD33 SD_ERASE_GRP_END with argument as addr */ 01638 errorstate = SDMMC_CmdSDEraseEndAdd(hsd->Instance, end_add); 01639 if(errorstate != HAL_SD_ERROR_NONE) 01640 { 01641 /* Clear all the static flags */ 01642 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 01643 hsd->ErrorCode |= errorstate; 01644 hsd->State = HAL_SD_STATE_READY; 01645 return HAL_ERROR; 01646 } 01647 } 01648 01649 /* Send CMD38 ERASE */ 01650 errorstate = SDMMC_CmdErase(hsd->Instance); 01651 if(errorstate != HAL_SD_ERROR_NONE) 01652 { 01653 /* Clear all the static flags */ 01654 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 01655 hsd->ErrorCode |= errorstate; 01656 hsd->State = HAL_SD_STATE_READY; 01657 return HAL_ERROR; 01658 } 01659 01660 hsd->State = HAL_SD_STATE_READY; 01661 01662 return HAL_OK; 01663 } 01664 else 01665 { 01666 return HAL_BUSY; 01667 } 01668 } 01669 01670 /** 01671 * @brief This function handles SD card interrupt request. 01672 * @param hsd: Pointer to SD handle 01673 * @retval None 01674 */ 01675 void HAL_SD_IRQHandler(SD_HandleTypeDef *hsd) 01676 { 01677 uint32_t errorstate; 01678 uint32_t context = hsd->Context; 01679 01680 /* Check for SDMMC interrupt flags */ 01681 if(__HAL_SD_GET_FLAG(hsd, SDMMC_IT_DATAEND) != RESET) 01682 { 01683 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_DATAEND); 01684 01685 __HAL_SD_DISABLE_IT(hsd, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT |\ 01686 SDMMC_IT_TXUNDERR | SDMMC_IT_RXOVERR | SDMMC_IT_TXFIFOHE |\ 01687 SDMMC_IT_RXFIFOHF); 01688 01689 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 01690 __HAL_SD_DISABLE_IT(hsd, SDMMC_IT_IDMABTC); 01691 __SDMMC_CMDTRANS_DISABLE( hsd->Instance); 01692 #else 01693 hsd->Instance->DCTRL &= ~(SDMMC_DCTRL_DTEN); 01694 01695 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 01696 01697 if((context & SD_CONTEXT_IT) != 0U) 01698 { 01699 if(((context & SD_CONTEXT_READ_MULTIPLE_BLOCK) != 0U) || ((context & SD_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)) 01700 { 01701 errorstate = SDMMC_CmdStopTransfer(hsd->Instance); 01702 if(errorstate != HAL_SD_ERROR_NONE) 01703 { 01704 hsd->ErrorCode |= errorstate; 01705 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1) 01706 hsd->ErrorCallback(hsd); 01707 #else 01708 HAL_SD_ErrorCallback(hsd); 01709 #endif 01710 } 01711 } 01712 01713 /* Clear all the static flags */ 01714 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); 01715 01716 hsd->State = HAL_SD_STATE_READY; 01717 if(((context & SD_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & SD_CONTEXT_READ_MULTIPLE_BLOCK) != 0U)) 01718 { 01719 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1) 01720 hsd->RxCpltCallback(hsd); 01721 #else 01722 HAL_SD_RxCpltCallback(hsd); 01723 #endif 01724 } 01725 else 01726 { 01727 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1) 01728 hsd->TxCpltCallback(hsd); 01729 #else 01730 HAL_SD_TxCpltCallback(hsd); 01731 #endif 01732 } 01733 } 01734 else if((context & SD_CONTEXT_DMA) != 0U) 01735 { 01736 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 01737 hsd->Instance->DLEN = 0; 01738 hsd->Instance->DCTRL = 0; 01739 hsd->Instance->IDMACTRL = SDMMC_DISABLE_IDMA; 01740 01741 /* Stop Transfer for Write Single/Multi blocks or Read Multi blocks */ 01742 if((context & SD_CONTEXT_READ_SINGLE_BLOCK) == 0U) 01743 { 01744 errorstate = SDMMC_CmdStopTransfer(hsd->Instance); 01745 if(errorstate != HAL_SD_ERROR_NONE) 01746 { 01747 hsd->ErrorCode |= errorstate; 01748 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1) 01749 hsd->ErrorCallback(hsd); 01750 #else 01751 HAL_SD_ErrorCallback(hsd); 01752 #endif 01753 } 01754 } 01755 01756 hsd->State = HAL_SD_STATE_READY; 01757 if(((context & SD_CONTEXT_WRITE_SINGLE_BLOCK) != 0U) || ((context & SD_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U)) 01758 { 01759 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1) 01760 hsd->TxCpltCallback(hsd); 01761 #else 01762 HAL_SD_TxCpltCallback(hsd); 01763 #endif 01764 } 01765 if(((context & SD_CONTEXT_READ_SINGLE_BLOCK) != 0U) || ((context & SD_CONTEXT_READ_MULTIPLE_BLOCK) != 0U)) 01766 { 01767 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1) 01768 hsd->RxCpltCallback(hsd); 01769 #else 01770 HAL_SD_RxCpltCallback(hsd); 01771 #endif 01772 } 01773 #else 01774 if((context & SD_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U) 01775 { 01776 errorstate = SDMMC_CmdStopTransfer(hsd->Instance); 01777 if(errorstate != HAL_SD_ERROR_NONE) 01778 { 01779 hsd->ErrorCode |= errorstate; 01780 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1) 01781 hsd->ErrorCallback(hsd); 01782 #else 01783 HAL_SD_ErrorCallback(hsd); 01784 #endif 01785 } 01786 } 01787 if(((context & SD_CONTEXT_READ_SINGLE_BLOCK) == 0U) && ((context & SD_CONTEXT_READ_MULTIPLE_BLOCK) == 0U)) 01788 { 01789 /* Disable the DMA transfer for transmit request by setting the DMAEN bit 01790 in the SD DCTRL register */ 01791 hsd->Instance->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN); 01792 01793 hsd->State = HAL_SD_STATE_READY; 01794 01795 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1) 01796 hsd->TxCpltCallback(hsd); 01797 #else 01798 HAL_SD_TxCpltCallback(hsd); 01799 #endif 01800 } 01801 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 01802 } 01803 else 01804 { 01805 /* Nothing to do */ 01806 } 01807 } 01808 01809 else if(__HAL_SD_GET_FLAG(hsd, SDMMC_IT_TXFIFOHE) != RESET) 01810 { 01811 SD_Write_IT(hsd); 01812 } 01813 01814 else if(__HAL_SD_GET_FLAG(hsd, SDMMC_IT_RXFIFOHF) != RESET) 01815 { 01816 SD_Read_IT(hsd); 01817 } 01818 01819 else if(__HAL_SD_GET_FLAG(hsd, SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_TXUNDERR) != RESET) 01820 { 01821 /* Set Error code */ 01822 if(__HAL_SD_GET_FLAG(hsd, SDMMC_IT_DCRCFAIL) != RESET) 01823 { 01824 hsd->ErrorCode |= HAL_SD_ERROR_DATA_CRC_FAIL; 01825 } 01826 if(__HAL_SD_GET_FLAG(hsd, SDMMC_IT_DTIMEOUT) != RESET) 01827 { 01828 hsd->ErrorCode |= HAL_SD_ERROR_DATA_TIMEOUT; 01829 } 01830 if(__HAL_SD_GET_FLAG(hsd, SDMMC_IT_RXOVERR) != RESET) 01831 { 01832 hsd->ErrorCode |= HAL_SD_ERROR_RX_OVERRUN; 01833 } 01834 if(__HAL_SD_GET_FLAG(hsd, SDMMC_IT_TXUNDERR) != RESET) 01835 { 01836 hsd->ErrorCode |= HAL_SD_ERROR_TX_UNDERRUN; 01837 } 01838 01839 /* Clear All flags */ 01840 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); 01841 01842 /* Disable all interrupts */ 01843 __HAL_SD_DISABLE_IT(hsd, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\ 01844 SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR); 01845 01846 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 01847 __SDMMC_CMDTRANS_DISABLE( hsd->Instance); 01848 hsd->Instance->DCTRL |= SDMMC_DCTRL_FIFORST; 01849 hsd->Instance->CMD |= SDMMC_CMD_CMDSTOP; 01850 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 01851 hsd->ErrorCode |= SDMMC_CmdStopTransfer(hsd->Instance); 01852 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 01853 hsd->Instance->CMD &= ~(SDMMC_CMD_CMDSTOP); 01854 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_DABORT); 01855 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 01856 01857 if((context & SD_CONTEXT_IT) != 0U) 01858 { 01859 /* Set the SD state to ready to be able to start again the process */ 01860 hsd->State = HAL_SD_STATE_READY; 01861 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1) 01862 hsd->ErrorCallback(hsd); 01863 #else 01864 HAL_SD_ErrorCallback(hsd); 01865 #endif 01866 } 01867 else if((context & SD_CONTEXT_DMA) != 0U) 01868 { 01869 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 01870 if(hsd->ErrorCode != HAL_SD_ERROR_NONE) 01871 { 01872 /* Disable Internal DMA */ 01873 __HAL_SD_DISABLE_IT(hsd, SDMMC_IT_IDMABTC); 01874 hsd->Instance->IDMACTRL = SDMMC_DISABLE_IDMA; 01875 01876 /* Set the SD state to ready to be able to start again the process */ 01877 hsd->State = HAL_SD_STATE_READY; 01878 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1) 01879 hsd->ErrorCallback(hsd); 01880 #else 01881 HAL_SD_ErrorCallback(hsd); 01882 #endif 01883 } 01884 #else 01885 /* Abort the SD DMA channel */ 01886 if(hsd->hdmatx != NULL) 01887 { 01888 /* Set the DMA Tx abort callback */ 01889 hsd->hdmatx->XferAbortCallback = SD_DMATxAbort; 01890 /* Abort DMA in IT mode */ 01891 if(HAL_DMA_Abort_IT(hsd->hdmatx) != HAL_OK) 01892 { 01893 SD_DMATxAbort(hsd->hdmatx); 01894 } 01895 } 01896 else if(hsd->hdmarx != NULL) 01897 { 01898 /* Set the DMA Rx abort callback */ 01899 hsd->hdmarx->XferAbortCallback = SD_DMARxAbort; 01900 /* Abort DMA in IT mode */ 01901 if(HAL_DMA_Abort_IT(hsd->hdmarx) != HAL_OK) 01902 { 01903 SD_DMARxAbort(hsd->hdmarx); 01904 } 01905 } 01906 else 01907 { 01908 hsd->ErrorCode = HAL_SD_ERROR_NONE; 01909 hsd->State = HAL_SD_STATE_READY; 01910 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1) 01911 hsd->AbortCpltCallback(hsd); 01912 #else 01913 HAL_SD_AbortCallback(hsd); 01914 #endif 01915 } 01916 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 01917 } 01918 else 01919 { 01920 /* Nothing to do */ 01921 } 01922 } 01923 01924 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 01925 else if(__HAL_SD_GET_FLAG(hsd, SDMMC_IT_IDMABTC) != RESET) 01926 { 01927 if(READ_BIT(hsd->Instance->IDMACTRL, SDMMC_IDMA_IDMABACT) == 0U) 01928 { 01929 /* Current buffer is buffer0, Transfer complete for buffer1 */ 01930 if((hsd->Context & SD_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U) 01931 { 01932 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1) 01933 hsd->Write_DMADblBuf1CpltCallback(hsd); 01934 #else 01935 HAL_SDEx_Write_DMADoubleBuffer1CpltCallback(hsd); 01936 #endif 01937 } 01938 else /* SD_CONTEXT_READ_MULTIPLE_BLOCK */ 01939 { 01940 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1) 01941 hsd->Read_DMADblBuf1CpltCallback(hsd); 01942 #else 01943 HAL_SDEx_Read_DMADoubleBuffer1CpltCallback(hsd); 01944 #endif 01945 } 01946 } 01947 else /* SD_DMA_BUFFER1 */ 01948 { 01949 /* Current buffer is buffer1, Transfer complete for buffer0 */ 01950 if((context & SD_CONTEXT_WRITE_MULTIPLE_BLOCK) != 0U) 01951 { 01952 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1) 01953 hsd->Write_DMADblBuf0CpltCallback(hsd); 01954 #else 01955 HAL_SDEx_Write_DMADoubleBuffer0CpltCallback(hsd); 01956 #endif 01957 } 01958 else /* SD_CONTEXT_READ_MULTIPLE_BLOCK */ 01959 { 01960 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1) 01961 hsd->Read_DMADblBuf0CpltCallback(hsd); 01962 #else 01963 HAL_SDEx_Read_DMADoubleBuffer0CpltCallback(hsd); 01964 #endif 01965 } 01966 } 01967 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_IDMABTC); 01968 } 01969 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 01970 else 01971 { 01972 /* Nothing to do */ 01973 } 01974 } 01975 01976 /** 01977 * @brief return the SD state 01978 * @param hsd: Pointer to sd handle 01979 * @retval HAL state 01980 */ 01981 HAL_SD_StateTypeDef HAL_SD_GetState(SD_HandleTypeDef *hsd) 01982 { 01983 return hsd->State; 01984 } 01985 01986 /** 01987 * @brief Return the SD error code 01988 * @param hsd : Pointer to a SD_HandleTypeDef structure that contains 01989 * the configuration information. 01990 * @retval SD Error Code 01991 */ 01992 uint32_t HAL_SD_GetError(SD_HandleTypeDef *hsd) 01993 { 01994 return hsd->ErrorCode; 01995 } 01996 01997 /** 01998 * @brief Tx Transfer completed callbacks 01999 * @param hsd: Pointer to SD handle 02000 * @retval None 02001 */ 02002 __weak void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd) 02003 { 02004 /* Prevent unused argument(s) compilation warning */ 02005 UNUSED(hsd); 02006 02007 /* NOTE : This function should not be modified, when the callback is needed, 02008 the HAL_SD_TxCpltCallback can be implemented in the user file 02009 */ 02010 } 02011 02012 /** 02013 * @brief Rx Transfer completed callbacks 02014 * @param hsd: Pointer SD handle 02015 * @retval None 02016 */ 02017 __weak void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd) 02018 { 02019 /* Prevent unused argument(s) compilation warning */ 02020 UNUSED(hsd); 02021 02022 /* NOTE : This function should not be modified, when the callback is needed, 02023 the HAL_SD_RxCpltCallback can be implemented in the user file 02024 */ 02025 } 02026 02027 /** 02028 * @brief SD error callbacks 02029 * @param hsd: Pointer SD handle 02030 * @retval None 02031 */ 02032 __weak void HAL_SD_ErrorCallback(SD_HandleTypeDef *hsd) 02033 { 02034 /* Prevent unused argument(s) compilation warning */ 02035 UNUSED(hsd); 02036 02037 /* NOTE : This function should not be modified, when the callback is needed, 02038 the HAL_SD_ErrorCallback can be implemented in the user file 02039 */ 02040 } 02041 02042 /** 02043 * @brief SD Abort callbacks 02044 * @param hsd: Pointer SD handle 02045 * @retval None 02046 */ 02047 __weak void HAL_SD_AbortCallback(SD_HandleTypeDef *hsd) 02048 { 02049 /* Prevent unused argument(s) compilation warning */ 02050 UNUSED(hsd); 02051 02052 /* NOTE : This function should not be modified, when the callback is needed, 02053 the HAL_SD_AbortCallback can be implemented in the user file 02054 */ 02055 } 02056 02057 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1) 02058 /** 02059 * @brief Register a User SD Callback 02060 * To be used instead of the weak (surcharged) predefined callback 02061 * @param hsd : SD handle 02062 * @param CallbackID : ID of the callback to be registered 02063 * This parameter can be one of the following values: 02064 * @arg @ref HAL_SD_TX_CPLT_CB_ID SD Tx Complete Callback ID 02065 * @arg @ref HAL_SD_RX_CPLT_CB_ID SD Rx Complete Callback ID 02066 * @arg @ref HAL_SD_ERROR_CB_ID SD Error Callback ID 02067 * @arg @ref HAL_SD_ABORT_CB_ID SD Abort Callback ID 02068 * @arg @ref HAL_SD_MSP_INIT_CB_ID SD MspInit Callback ID 02069 * @arg @ref HAL_SD_MSP_DEINIT_CB_ID SD MspDeInit Callback ID 02070 * @param pCallback : pointer to the Callback function 02071 * @retval status 02072 */ 02073 HAL_StatusTypeDef HAL_SD_RegisterCallback(SD_HandleTypeDef *hsd, HAL_SD_CallbackIDTypeDef CallbackID, pSD_CallbackTypeDef pCallback) 02074 { 02075 HAL_StatusTypeDef status = HAL_OK; 02076 02077 if(pCallback == NULL) 02078 { 02079 /* Update the error code */ 02080 hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK; 02081 return HAL_ERROR; 02082 } 02083 02084 /* Process locked */ 02085 __HAL_LOCK(hsd); 02086 02087 if(hsd->State == HAL_SD_STATE_READY) 02088 { 02089 switch (CallbackID) 02090 { 02091 case HAL_SD_TX_CPLT_CB_ID : 02092 hsd->TxCpltCallback = pCallback; 02093 break; 02094 case HAL_SD_RX_CPLT_CB_ID : 02095 hsd->RxCpltCallback = pCallback; 02096 break; 02097 case HAL_SD_ERROR_CB_ID : 02098 hsd->ErrorCallback = pCallback; 02099 break; 02100 case HAL_SD_ABORT_CB_ID : 02101 hsd->AbortCpltCallback = pCallback; 02102 break; 02103 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 02104 case HAL_SD_READ_DMA_DBL_BUF0_CPLT_CB_ID : 02105 hsd->Read_DMADblBuf0CpltCallback = pCallback; 02106 break; 02107 case HAL_SD_READ_DMA_DBL_BUF1_CPLT_CB_ID : 02108 hsd->Read_DMADblBuf1CpltCallback = pCallback; 02109 break; 02110 case HAL_SD_WRITE_DMA_DBL_BUF0_CPLT_CB_ID : 02111 hsd->Write_DMADblBuf0CpltCallback = pCallback; 02112 break; 02113 case HAL_SD_WRITE_DMA_DBL_BUF1_CPLT_CB_ID : 02114 hsd->Write_DMADblBuf1CpltCallback = pCallback; 02115 break; 02116 #endif 02117 case HAL_SD_MSP_INIT_CB_ID : 02118 hsd->MspInitCallback = pCallback; 02119 break; 02120 case HAL_SD_MSP_DEINIT_CB_ID : 02121 hsd->MspDeInitCallback = pCallback; 02122 break; 02123 default : 02124 /* Update the error code */ 02125 hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK; 02126 /* update return status */ 02127 status = HAL_ERROR; 02128 break; 02129 } 02130 } 02131 else if (hsd->State == HAL_SD_STATE_RESET) 02132 { 02133 switch (CallbackID) 02134 { 02135 case HAL_SD_MSP_INIT_CB_ID : 02136 hsd->MspInitCallback = pCallback; 02137 break; 02138 case HAL_SD_MSP_DEINIT_CB_ID : 02139 hsd->MspDeInitCallback = pCallback; 02140 break; 02141 default : 02142 /* Update the error code */ 02143 hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK; 02144 /* update return status */ 02145 status = HAL_ERROR; 02146 break; 02147 } 02148 } 02149 else 02150 { 02151 /* Update the error code */ 02152 hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK; 02153 /* update return status */ 02154 status = HAL_ERROR; 02155 } 02156 02157 /* Release Lock */ 02158 __HAL_UNLOCK(hsd); 02159 return status; 02160 } 02161 02162 /** 02163 * @brief Unregister a User SD Callback 02164 * SD Callback is redirected to the weak (surcharged) predefined callback 02165 * @param hsd : SD handle 02166 * @param CallbackID : ID of the callback to be unregistered 02167 * This parameter can be one of the following values: 02168 * @arg @ref HAL_SD_TX_CPLT_CB_ID SD Tx Complete Callback ID 02169 * @arg @ref HAL_SD_RX_CPLT_CB_ID SD Rx Complete Callback ID 02170 * @arg @ref HAL_SD_ERROR_CB_ID SD Error Callback ID 02171 * @arg @ref HAL_SD_ABORT_CB_ID SD Abort Callback ID 02172 * @arg @ref HAL_SD_MSP_INIT_CB_ID SD MspInit Callback ID 02173 * @arg @ref HAL_SD_MSP_DEINIT_CB_ID SD MspDeInit Callback ID 02174 * @retval status 02175 */ 02176 HAL_StatusTypeDef HAL_SD_UnRegisterCallback(SD_HandleTypeDef *hsd, HAL_SD_CallbackIDTypeDef CallbackID) 02177 { 02178 HAL_StatusTypeDef status = HAL_OK; 02179 02180 /* Process locked */ 02181 __HAL_LOCK(hsd); 02182 02183 if(hsd->State == HAL_SD_STATE_READY) 02184 { 02185 switch (CallbackID) 02186 { 02187 case HAL_SD_TX_CPLT_CB_ID : 02188 hsd->TxCpltCallback = HAL_SD_TxCpltCallback; 02189 break; 02190 case HAL_SD_RX_CPLT_CB_ID : 02191 hsd->RxCpltCallback = HAL_SD_RxCpltCallback; 02192 break; 02193 case HAL_SD_ERROR_CB_ID : 02194 hsd->ErrorCallback = HAL_SD_ErrorCallback; 02195 break; 02196 case HAL_SD_ABORT_CB_ID : 02197 hsd->AbortCpltCallback = HAL_SD_AbortCallback; 02198 break; 02199 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 02200 case HAL_SD_READ_DMA_DBL_BUF0_CPLT_CB_ID : 02201 hsd->Read_DMADblBuf0CpltCallback = HAL_SDEx_Read_DMADoubleBuffer0CpltCallback; 02202 break; 02203 case HAL_SD_READ_DMA_DBL_BUF1_CPLT_CB_ID : 02204 hsd->Read_DMADblBuf1CpltCallback = HAL_SDEx_Read_DMADoubleBuffer1CpltCallback; 02205 break; 02206 case HAL_SD_WRITE_DMA_DBL_BUF0_CPLT_CB_ID : 02207 hsd->Write_DMADblBuf0CpltCallback = HAL_SDEx_Write_DMADoubleBuffer0CpltCallback; 02208 break; 02209 case HAL_SD_WRITE_DMA_DBL_BUF1_CPLT_CB_ID : 02210 hsd->Write_DMADblBuf1CpltCallback = HAL_SDEx_Write_DMADoubleBuffer1CpltCallback; 02211 break; 02212 #endif 02213 case HAL_SD_MSP_INIT_CB_ID : 02214 hsd->MspInitCallback = HAL_SD_MspInit; 02215 break; 02216 case HAL_SD_MSP_DEINIT_CB_ID : 02217 hsd->MspDeInitCallback = HAL_SD_MspDeInit; 02218 break; 02219 default : 02220 /* Update the error code */ 02221 hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK; 02222 /* update return status */ 02223 status = HAL_ERROR; 02224 break; 02225 } 02226 } 02227 else if (hsd->State == HAL_SD_STATE_RESET) 02228 { 02229 switch (CallbackID) 02230 { 02231 case HAL_SD_MSP_INIT_CB_ID : 02232 hsd->MspInitCallback = HAL_SD_MspInit; 02233 break; 02234 case HAL_SD_MSP_DEINIT_CB_ID : 02235 hsd->MspDeInitCallback = HAL_SD_MspDeInit; 02236 break; 02237 default : 02238 /* Update the error code */ 02239 hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK; 02240 /* update return status */ 02241 status = HAL_ERROR; 02242 break; 02243 } 02244 } 02245 else 02246 { 02247 /* Update the error code */ 02248 hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK; 02249 /* update return status */ 02250 status = HAL_ERROR; 02251 } 02252 02253 /* Release Lock */ 02254 __HAL_UNLOCK(hsd); 02255 return status; 02256 } 02257 02258 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 02259 /** 02260 * @brief Register a User SD Transceiver Callback 02261 * To be used instead of the weak (surcharged) predefined callback 02262 * @param hsd : SD handle 02263 * @param pCallback : pointer to the Callback function 02264 * @retval status 02265 */ 02266 HAL_StatusTypeDef HAL_SD_RegisterTransceiverCallback(SD_HandleTypeDef *hsd, pSD_TransceiverCallbackTypeDef pCallback) 02267 { 02268 HAL_StatusTypeDef status = HAL_OK; 02269 02270 if(pCallback == NULL) 02271 { 02272 /* Update the error code */ 02273 hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK; 02274 return HAL_ERROR; 02275 } 02276 02277 /* Process locked */ 02278 __HAL_LOCK(hsd); 02279 02280 if(hsd->State == HAL_SD_STATE_READY) 02281 { 02282 hsd->DriveTransceiver_1_8V_Callback = pCallback; 02283 } 02284 else 02285 { 02286 /* Update the error code */ 02287 hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK; 02288 /* update return status */ 02289 status = HAL_ERROR; 02290 } 02291 02292 /* Release Lock */ 02293 __HAL_UNLOCK(hsd); 02294 return status; 02295 } 02296 02297 /** 02298 * @brief Unregister a User SD Transceiver Callback 02299 * SD Callback is redirected to the weak (surcharged) predefined callback 02300 * @param hsd : SD handle 02301 * @retval status 02302 */ 02303 HAL_StatusTypeDef HAL_SD_UnRegisterTransceiverCallback(SD_HandleTypeDef *hsd) 02304 { 02305 HAL_StatusTypeDef status = HAL_OK; 02306 02307 /* Process locked */ 02308 __HAL_LOCK(hsd); 02309 02310 if(hsd->State == HAL_SD_STATE_READY) 02311 { 02312 hsd->DriveTransceiver_1_8V_Callback = HAL_SDEx_DriveTransceiver_1_8V_Callback; 02313 } 02314 else 02315 { 02316 /* Update the error code */ 02317 hsd->ErrorCode |= HAL_SD_ERROR_INVALID_CALLBACK; 02318 /* update return status */ 02319 status = HAL_ERROR; 02320 } 02321 02322 /* Release Lock */ 02323 __HAL_UNLOCK(hsd); 02324 return status; 02325 } 02326 #endif 02327 #endif 02328 02329 /** 02330 * @} 02331 */ 02332 02333 /** @addtogroup SD_Exported_Functions_Group3 02334 * @brief management functions 02335 * 02336 @verbatim 02337 ============================================================================== 02338 ##### Peripheral Control functions ##### 02339 ============================================================================== 02340 [..] 02341 This subsection provides a set of functions allowing to control the SD card 02342 operations and get the related information 02343 02344 @endverbatim 02345 * @{ 02346 */ 02347 02348 /** 02349 * @brief Returns information the information of the card which are stored on 02350 * the CID register. 02351 * @param hsd: Pointer to SD handle 02352 * @param pCID: Pointer to a HAL_SD_CIDTypedef structure that 02353 * contains all CID register parameters 02354 * @retval HAL status 02355 */ 02356 HAL_StatusTypeDef HAL_SD_GetCardCID(SD_HandleTypeDef *hsd, HAL_SD_CardCIDTypedef *pCID) 02357 { 02358 pCID->ManufacturerID = (uint8_t)((hsd->CID[0] & 0xFF000000U) >> 24U); 02359 02360 pCID->OEM_AppliID = (uint16_t)((hsd->CID[0] & 0x00FFFF00U) >> 8U); 02361 02362 pCID->ProdName1 = (((hsd->CID[0] & 0x000000FFU) << 24U) | ((hsd->CID[1] & 0xFFFFFF00U) >> 8U)); 02363 02364 pCID->ProdName2 = (uint8_t)(hsd->CID[1] & 0x000000FFU); 02365 02366 pCID->ProdRev = (uint8_t)((hsd->CID[2] & 0xFF000000U) >> 24U); 02367 02368 pCID->ProdSN = (((hsd->CID[2] & 0x00FFFFFFU) << 8U) | ((hsd->CID[3] & 0xFF000000U) >> 24U)); 02369 02370 pCID->Reserved1 = (uint8_t)((hsd->CID[3] & 0x00F00000U) >> 20U); 02371 02372 pCID->ManufactDate = (uint16_t)((hsd->CID[3] & 0x000FFF00U) >> 8U); 02373 02374 pCID->CID_CRC = (uint8_t)((hsd->CID[3] & 0x000000FEU) >> 1U); 02375 02376 pCID->Reserved2 = 1U; 02377 02378 return HAL_OK; 02379 } 02380 02381 /** 02382 * @brief Returns information the information of the card which are stored on 02383 * the CSD register. 02384 * @param hsd: Pointer to SD handle 02385 * @param pCSD: Pointer to a HAL_SD_CardInfoTypedef structure that 02386 * contains all CSD register parameters 02387 * @retval HAL status 02388 */ 02389 HAL_StatusTypeDef HAL_SD_GetCardCSD(SD_HandleTypeDef *hsd, HAL_SD_CardCSDTypedef *pCSD) 02390 { 02391 pCSD->CSDStruct = (uint8_t)((hsd->CSD[0] & 0xC0000000U) >> 30U); 02392 02393 pCSD->SysSpecVersion = (uint8_t)((hsd->CSD[0] & 0x3C000000U) >> 26U); 02394 02395 pCSD->Reserved1 = (uint8_t)((hsd->CSD[0] & 0x03000000U) >> 24U); 02396 02397 pCSD->TAAC = (uint8_t)((hsd->CSD[0] & 0x00FF0000U) >> 16U); 02398 02399 pCSD->NSAC = (uint8_t)((hsd->CSD[0] & 0x0000FF00U) >> 8U); 02400 02401 pCSD->MaxBusClkFrec = (uint8_t)(hsd->CSD[0] & 0x000000FFU); 02402 02403 pCSD->CardComdClasses = (uint16_t)((hsd->CSD[1] & 0xFFF00000U) >> 20U); 02404 02405 pCSD->RdBlockLen = (uint8_t)((hsd->CSD[1] & 0x000F0000U) >> 16U); 02406 02407 pCSD->PartBlockRead = (uint8_t)((hsd->CSD[1] & 0x00008000U) >> 15U); 02408 02409 pCSD->WrBlockMisalign = (uint8_t)((hsd->CSD[1] & 0x00004000U) >> 14U); 02410 02411 pCSD->RdBlockMisalign = (uint8_t)((hsd->CSD[1] & 0x00002000U) >> 13U); 02412 02413 pCSD->DSRImpl = (uint8_t)((hsd->CSD[1] & 0x00001000U) >> 12U); 02414 02415 pCSD->Reserved2 = 0U; /*!< Reserved */ 02416 02417 if(hsd->SdCard.CardType == CARD_SDSC) 02418 { 02419 pCSD->DeviceSize = (((hsd->CSD[1] & 0x000003FFU) << 2U) | ((hsd->CSD[2] & 0xC0000000U) >> 30U)); 02420 02421 pCSD->MaxRdCurrentVDDMin = (uint8_t)((hsd->CSD[2] & 0x38000000U) >> 27U); 02422 02423 pCSD->MaxRdCurrentVDDMax = (uint8_t)((hsd->CSD[2] & 0x07000000U) >> 24U); 02424 02425 pCSD->MaxWrCurrentVDDMin = (uint8_t)((hsd->CSD[2] & 0x00E00000U) >> 21U); 02426 02427 pCSD->MaxWrCurrentVDDMax = (uint8_t)((hsd->CSD[2] & 0x001C0000U) >> 18U); 02428 02429 pCSD->DeviceSizeMul = (uint8_t)((hsd->CSD[2] & 0x00038000U) >> 15U); 02430 02431 hsd->SdCard.BlockNbr = (pCSD->DeviceSize + 1U) ; 02432 hsd->SdCard.BlockNbr *= (1UL << ((pCSD->DeviceSizeMul & 0x07U) + 2U)); 02433 hsd->SdCard.BlockSize = (1UL << (pCSD->RdBlockLen & 0x0FU)); 02434 02435 hsd->SdCard.LogBlockNbr = (hsd->SdCard.BlockNbr) * ((hsd->SdCard.BlockSize) / 512U); 02436 hsd->SdCard.LogBlockSize = 512U; 02437 } 02438 else if(hsd->SdCard.CardType == CARD_SDHC_SDXC) 02439 { 02440 /* Byte 7 */ 02441 pCSD->DeviceSize = (((hsd->CSD[1] & 0x0000003FU) << 16U) | ((hsd->CSD[2] & 0xFFFF0000U) >> 16U)); 02442 02443 hsd->SdCard.BlockNbr = ((pCSD->DeviceSize + 1U) * 1024U); 02444 hsd->SdCard.LogBlockNbr = hsd->SdCard.BlockNbr; 02445 hsd->SdCard.BlockSize = 512U; 02446 hsd->SdCard.LogBlockSize = hsd->SdCard.BlockSize; 02447 } 02448 else 02449 { 02450 /* Clear all the static flags */ 02451 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 02452 hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; 02453 hsd->State = HAL_SD_STATE_READY; 02454 return HAL_ERROR; 02455 } 02456 02457 pCSD->EraseGrSize = (uint8_t)((hsd->CSD[2] & 0x00004000U) >> 14U); 02458 02459 pCSD->EraseGrMul = (uint8_t)((hsd->CSD[2] & 0x00003F80U) >> 7U); 02460 02461 pCSD->WrProtectGrSize = (uint8_t)(hsd->CSD[2] & 0x0000007FU); 02462 02463 pCSD->WrProtectGrEnable = (uint8_t)((hsd->CSD[3] & 0x80000000U) >> 31U); 02464 02465 pCSD->ManDeflECC = (uint8_t)((hsd->CSD[3] & 0x60000000U) >> 29U); 02466 02467 pCSD->WrSpeedFact = (uint8_t)((hsd->CSD[3] & 0x1C000000U) >> 26U); 02468 02469 pCSD->MaxWrBlockLen= (uint8_t)((hsd->CSD[3] & 0x03C00000U) >> 22U); 02470 02471 pCSD->WriteBlockPaPartial = (uint8_t)((hsd->CSD[3] & 0x00200000U) >> 21U); 02472 02473 pCSD->Reserved3 = 0; 02474 02475 pCSD->ContentProtectAppli = (uint8_t)((hsd->CSD[3] & 0x00010000U) >> 16U); 02476 02477 pCSD->FileFormatGroup = (uint8_t)((hsd->CSD[3] & 0x00008000U) >> 15U); 02478 02479 pCSD->CopyFlag = (uint8_t)((hsd->CSD[3] & 0x00004000U) >> 14U); 02480 02481 pCSD->PermWrProtect = (uint8_t)((hsd->CSD[3] & 0x00002000U) >> 13U); 02482 02483 pCSD->TempWrProtect = (uint8_t)((hsd->CSD[3] & 0x00001000U) >> 12U); 02484 02485 pCSD->FileFormat = (uint8_t)((hsd->CSD[3] & 0x00000C00U) >> 10U); 02486 02487 pCSD->ECC= (uint8_t)((hsd->CSD[3] & 0x00000300U) >> 8U); 02488 02489 pCSD->CSD_CRC = (uint8_t)((hsd->CSD[3] & 0x000000FEU) >> 1U); 02490 02491 pCSD->Reserved4 = 1; 02492 02493 return HAL_OK; 02494 } 02495 02496 /** 02497 * @brief Gets the SD status info. 02498 * @param hsd: Pointer to SD handle 02499 * @param pStatus: Pointer to the HAL_SD_CardStatusTypedef structure that 02500 * will contain the SD card status information 02501 * @retval HAL status 02502 */ 02503 HAL_StatusTypeDef HAL_SD_GetCardStatus(SD_HandleTypeDef *hsd, HAL_SD_CardStatusTypedef *pStatus) 02504 { 02505 uint32_t sd_status[16]; 02506 uint32_t errorstate; 02507 02508 errorstate = SD_SendSDStatus(hsd, sd_status); 02509 if(errorstate != HAL_SD_ERROR_NONE) 02510 { 02511 /* Clear all the static flags */ 02512 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 02513 hsd->ErrorCode |= errorstate; 02514 hsd->State = HAL_SD_STATE_READY; 02515 return HAL_ERROR; 02516 } 02517 else 02518 { 02519 pStatus->DataBusWidth = (uint8_t)((sd_status[0] & 0xC0U) >> 6U); 02520 02521 pStatus->SecuredMode = (uint8_t)((sd_status[0] & 0x20U) >> 5U); 02522 02523 pStatus->CardType = (uint16_t)(((sd_status[0] & 0x00FF0000U) >> 8U) | ((sd_status[0] & 0xFF000000U) >> 24U)); 02524 02525 pStatus->ProtectedAreaSize = (((sd_status[1] & 0xFFU) << 24U) | ((sd_status[1] & 0xFF00U) << 8U) | 02526 ((sd_status[1] & 0xFF0000U) >> 8U) | ((sd_status[1] & 0xFF000000U) >> 24U)); 02527 02528 pStatus->SpeedClass = (uint8_t)(sd_status[2] & 0xFFU); 02529 02530 pStatus->PerformanceMove = (uint8_t)((sd_status[2] & 0xFF00U) >> 8U); 02531 02532 pStatus->AllocationUnitSize = (uint8_t)((sd_status[2] & 0xF00000U) >> 20U); 02533 02534 pStatus->EraseSize = (uint16_t)(((sd_status[2] & 0xFF000000U) >> 16U) | (sd_status[3] & 0xFFU)); 02535 02536 pStatus->EraseTimeout = (uint8_t)((sd_status[3] & 0xFC00U) >> 10U); 02537 02538 pStatus->EraseOffset = (uint8_t)((sd_status[3] & 0x0300U) >> 8U); 02539 } 02540 02541 return HAL_OK; 02542 } 02543 02544 /** 02545 * @brief Gets the SD card info. 02546 * @param hsd: Pointer to SD handle 02547 * @param pCardInfo: Pointer to the HAL_SD_CardInfoTypeDef structure that 02548 * will contain the SD card status information 02549 * @retval HAL status 02550 */ 02551 HAL_StatusTypeDef HAL_SD_GetCardInfo(SD_HandleTypeDef *hsd, HAL_SD_CardInfoTypeDef *pCardInfo) 02552 { 02553 pCardInfo->CardType = (uint32_t)(hsd->SdCard.CardType); 02554 pCardInfo->CardVersion = (uint32_t)(hsd->SdCard.CardVersion); 02555 pCardInfo->Class = (uint32_t)(hsd->SdCard.Class); 02556 pCardInfo->RelCardAdd = (uint32_t)(hsd->SdCard.RelCardAdd); 02557 pCardInfo->BlockNbr = (uint32_t)(hsd->SdCard.BlockNbr); 02558 pCardInfo->BlockSize = (uint32_t)(hsd->SdCard.BlockSize); 02559 pCardInfo->LogBlockNbr = (uint32_t)(hsd->SdCard.LogBlockNbr); 02560 pCardInfo->LogBlockSize = (uint32_t)(hsd->SdCard.LogBlockSize); 02561 02562 return HAL_OK; 02563 } 02564 02565 /** 02566 * @brief Enables wide bus operation for the requested card if supported by 02567 * card. 02568 * @param hsd: Pointer to SD handle 02569 * @param WideMode: Specifies the SD card wide bus mode 02570 * This parameter can be one of the following values: 02571 * @arg SDMMC_BUS_WIDE_8B: 8-bit data transfer 02572 * @arg SDMMC_BUS_WIDE_4B: 4-bit data transfer 02573 * @arg SDMMC_BUS_WIDE_1B: 1-bit data transfer 02574 * @retval HAL status 02575 */ 02576 HAL_StatusTypeDef HAL_SD_ConfigWideBusOperation(SD_HandleTypeDef *hsd, uint32_t WideMode) 02577 { 02578 SDMMC_InitTypeDef Init; 02579 uint32_t errorstate; 02580 02581 /* Check the parameters */ 02582 assert_param(IS_SDMMC_BUS_WIDE(WideMode)); 02583 02584 /* Change State */ 02585 hsd->State = HAL_SD_STATE_BUSY; 02586 02587 if(hsd->SdCard.CardType != CARD_SECURED) 02588 { 02589 if(WideMode == SDMMC_BUS_WIDE_8B) 02590 { 02591 hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; 02592 } 02593 else if(WideMode == SDMMC_BUS_WIDE_4B) 02594 { 02595 errorstate = SD_WideBus_Enable(hsd); 02596 02597 hsd->ErrorCode |= errorstate; 02598 } 02599 else if(WideMode == SDMMC_BUS_WIDE_1B) 02600 { 02601 errorstate = SD_WideBus_Disable(hsd); 02602 02603 hsd->ErrorCode |= errorstate; 02604 } 02605 else 02606 { 02607 /* WideMode is not a valid argument*/ 02608 hsd->ErrorCode |= HAL_SD_ERROR_PARAM; 02609 } 02610 } 02611 else 02612 { 02613 /* MMC Card does not support this feature */ 02614 hsd->ErrorCode |= HAL_SD_ERROR_UNSUPPORTED_FEATURE; 02615 } 02616 02617 if(hsd->ErrorCode != HAL_SD_ERROR_NONE) 02618 { 02619 /* Clear all the static flags */ 02620 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 02621 hsd->State = HAL_SD_STATE_READY; 02622 return HAL_ERROR; 02623 } 02624 else 02625 { 02626 /* Configure the SDMMC peripheral */ 02627 Init.ClockEdge = hsd->Init.ClockEdge; 02628 #if !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 02629 Init.ClockBypass = hsd->Init.ClockBypass; 02630 #endif /* !STM32L4R5xx && !STM32L4R7xx && !STM32L4R9xx && !STM32L4S5xx && !STM32L4S7xx && !STM32L4S9xx */ 02631 Init.ClockPowerSave = hsd->Init.ClockPowerSave; 02632 Init.BusWide = WideMode; 02633 Init.HardwareFlowControl = hsd->Init.HardwareFlowControl; 02634 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 02635 #if 0 02636 /* Check if user Clock div < Normal speed 25Mhz, no change in Clockdiv */ 02637 // if(hsd->Init.ClockDiv >= SDMMC_NSpeed_CLK_DIV) 02638 if(hsd->Init.ClockDiv >= SDMMC_TRANSFER_CLK_DIV) 02639 { 02640 Init.ClockDiv = hsd->Init.ClockDiv; 02641 } 02642 else 02643 { 02644 if(hsd->SdCard.CardSpeed == CARD_ULTRA_HIGH_SPEED) 02645 { 02646 Init.ClockDiv = hsd->Init.ClockDiv; 02647 } 02648 else 02649 { 02650 /* No High speed SD card */ 02651 // Init.ClockDiv = SDMMC_NSpeed_CLK_DIV; 02652 Init.ClockDiv = SDMMC_TRANSFER_CLK_DIV; 02653 } 02654 } 02655 #else 02656 Init.ClockDiv = hsd->Init.ClockDiv; 02657 #endif 02658 #else 02659 Init.ClockDiv = hsd->Init.ClockDiv; 02660 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 02661 02662 (void)SDMMC_Init(hsd->Instance, Init); 02663 } 02664 02665 /* Change State */ 02666 hsd->State = HAL_SD_STATE_READY; 02667 02668 return HAL_OK; 02669 } 02670 02671 /** 02672 * @brief Gets the current sd card data state. 02673 * @param hsd: pointer to SD handle 02674 * @retval Card state 02675 */ 02676 HAL_SD_CardStateTypedef HAL_SD_GetCardState(SD_HandleTypeDef *hsd) 02677 { 02678 uint32_t cardstate; 02679 uint32_t errorstate; 02680 uint32_t resp1 = 0; 02681 02682 errorstate = SD_SendStatus(hsd, &resp1); 02683 if(errorstate != HAL_SD_ERROR_NONE) 02684 { 02685 hsd->ErrorCode |= errorstate; 02686 } 02687 02688 cardstate = ((resp1 >> 9U) & 0x0FU); 02689 02690 return (HAL_SD_CardStateTypedef)cardstate; 02691 } 02692 02693 /** 02694 * @brief Abort the current transfer and disable the SD. 02695 * @param hsd: pointer to a SD_HandleTypeDef structure that contains 02696 * the configuration information for SD module. 02697 * @retval HAL status 02698 */ 02699 HAL_StatusTypeDef HAL_SD_Abort(SD_HandleTypeDef *hsd) 02700 { 02701 HAL_SD_CardStateTypedef CardState; 02702 02703 /* DIsable All interrupts */ 02704 __HAL_SD_DISABLE_IT(hsd, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\ 02705 SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR); 02706 02707 /* Clear All flags */ 02708 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 02709 02710 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 02711 /* If IDMA Context, disable Internal DMA */ 02712 hsd->Instance->IDMACTRL = SDMMC_DISABLE_IDMA; 02713 #else 02714 CLEAR_BIT(hsd->Instance->DCTRL, SDMMC_DCTRL_DTEN); 02715 02716 if((hsd->hdmatx != NULL) || (hsd->hdmarx != NULL)) 02717 { 02718 /* Disable the SD DMA request */ 02719 hsd->Instance->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN); 02720 02721 /* Abort the SD DMA Tx channel */ 02722 if(hsd->hdmatx != NULL) 02723 { 02724 if(HAL_DMA_Abort(hsd->hdmatx) != HAL_OK) 02725 { 02726 hsd->ErrorCode |= HAL_SD_ERROR_DMA; 02727 } 02728 } 02729 /* Abort the SD DMA Rx channel */ 02730 if(hsd->hdmarx != NULL) 02731 { 02732 if(HAL_DMA_Abort(hsd->hdmarx) != HAL_OK) 02733 { 02734 hsd->ErrorCode |= HAL_SD_ERROR_DMA; 02735 } 02736 } 02737 } 02738 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 02739 02740 hsd->State = HAL_SD_STATE_READY; 02741 CardState = HAL_SD_GetCardState(hsd); 02742 if((CardState == HAL_SD_CARD_RECEIVING) || (CardState == HAL_SD_CARD_SENDING)) 02743 { 02744 hsd->ErrorCode |= SDMMC_CmdStopTransfer(hsd->Instance); 02745 } 02746 if(hsd->ErrorCode != HAL_SD_ERROR_NONE) 02747 { 02748 return HAL_ERROR; 02749 } 02750 return HAL_OK; 02751 } 02752 02753 /** 02754 * @brief Abort the current transfer and disable the SD (IT mode). 02755 * @param hsd: pointer to a SD_HandleTypeDef structure that contains 02756 * the configuration information for SD module. 02757 * @retval HAL status 02758 */ 02759 HAL_StatusTypeDef HAL_SD_Abort_IT(SD_HandleTypeDef *hsd) 02760 { 02761 HAL_SD_CardStateTypedef CardState; 02762 02763 /* Disable All interrupts */ 02764 __HAL_SD_DISABLE_IT(hsd, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\ 02765 SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR); 02766 02767 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 02768 /* If IDMA Context, disable Internal DMA */ 02769 hsd->Instance->IDMACTRL = SDMMC_DISABLE_IDMA; 02770 02771 /* Clear All flags */ 02772 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); 02773 02774 CardState = HAL_SD_GetCardState(hsd); 02775 hsd->State = HAL_SD_STATE_READY; 02776 02777 if((CardState == HAL_SD_CARD_RECEIVING) || (CardState == HAL_SD_CARD_SENDING)) 02778 { 02779 hsd->ErrorCode = SDMMC_CmdStopTransfer(hsd->Instance); 02780 } 02781 02782 if(hsd->ErrorCode != HAL_SD_ERROR_NONE) 02783 { 02784 return HAL_ERROR; 02785 } 02786 else 02787 { 02788 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1) 02789 hsd->AbortCpltCallback(hsd); 02790 #else 02791 HAL_SD_AbortCallback(hsd); 02792 #endif 02793 } 02794 #else 02795 CLEAR_BIT(hsd->Instance->DCTRL, SDMMC_DCTRL_DTEN); 02796 02797 if((hsd->hdmatx != NULL) || (hsd->hdmarx != NULL)) 02798 { 02799 /* Disable the SD DMA request */ 02800 hsd->Instance->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN); 02801 02802 /* Abort the SD DMA Tx channel */ 02803 if(hsd->hdmatx != NULL) 02804 { 02805 hsd->hdmatx->XferAbortCallback = SD_DMATxAbort; 02806 if(HAL_DMA_Abort_IT(hsd->hdmatx) != HAL_OK) 02807 { 02808 hsd->hdmatx = NULL; 02809 } 02810 } 02811 /* Abort the SD DMA Rx channel */ 02812 if(hsd->hdmarx != NULL) 02813 { 02814 hsd->hdmarx->XferAbortCallback = SD_DMARxAbort; 02815 if(HAL_DMA_Abort_IT(hsd->hdmarx) != HAL_OK) 02816 { 02817 hsd->hdmarx = NULL; 02818 } 02819 } 02820 } 02821 02822 /* No transfer ongoing on both DMA channels*/ 02823 if((hsd->hdmatx == NULL) && (hsd->hdmarx == NULL)) 02824 { 02825 /* Clear All flags */ 02826 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); 02827 02828 CardState = HAL_SD_GetCardState(hsd); 02829 hsd->State = HAL_SD_STATE_READY; 02830 if((CardState == HAL_SD_CARD_RECEIVING) || (CardState == HAL_SD_CARD_SENDING)) 02831 { 02832 hsd->ErrorCode = SDMMC_CmdStopTransfer(hsd->Instance); 02833 } 02834 if(hsd->ErrorCode != HAL_SD_ERROR_NONE) 02835 { 02836 return HAL_ERROR; 02837 } 02838 else 02839 { 02840 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1) 02841 hsd->AbortCpltCallback(hsd); 02842 #else 02843 HAL_SD_AbortCallback(hsd); 02844 #endif 02845 } 02846 } 02847 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 02848 02849 return HAL_OK; 02850 } 02851 02852 /** 02853 * @} 02854 */ 02855 02856 /** 02857 * @} 02858 */ 02859 02860 /* Private function ----------------------------------------------------------*/ 02861 /** @addtogroup SD_Private_Functions 02862 * @{ 02863 */ 02864 02865 #if !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 02866 /** 02867 * @brief DMA SD transmit process complete callback 02868 * @param hdma: DMA handle 02869 * @retval None 02870 */ 02871 static void SD_DMATransmitCplt(DMA_HandleTypeDef *hdma) 02872 { 02873 SD_HandleTypeDef* hsd = (SD_HandleTypeDef* )(hdma->Parent); 02874 02875 /* Enable DATAEND Interrupt */ 02876 __HAL_SD_ENABLE_IT(hsd, (SDMMC_IT_DATAEND)); 02877 } 02878 02879 /** 02880 * @brief DMA SD receive process complete callback 02881 * @param hdma: DMA handle 02882 * @retval None 02883 */ 02884 static void SD_DMAReceiveCplt(DMA_HandleTypeDef *hdma) 02885 { 02886 SD_HandleTypeDef* hsd = (SD_HandleTypeDef* )(hdma->Parent); 02887 uint32_t errorstate; 02888 02889 /* Send stop command in multiblock write */ 02890 if(hsd->Context == (SD_CONTEXT_READ_MULTIPLE_BLOCK | SD_CONTEXT_DMA)) 02891 { 02892 errorstate = SDMMC_CmdStopTransfer(hsd->Instance); 02893 if(errorstate != HAL_SD_ERROR_NONE) 02894 { 02895 hsd->ErrorCode |= errorstate; 02896 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1) 02897 hsd->ErrorCallback(hsd); 02898 #else 02899 HAL_SD_ErrorCallback(hsd); 02900 #endif 02901 } 02902 } 02903 02904 /* Disable the DMA transfer for transmit request by setting the DMAEN bit 02905 in the SD DCTRL register */ 02906 hsd->Instance->DCTRL &= (uint32_t)~((uint32_t)SDMMC_DCTRL_DMAEN); 02907 02908 /* Clear all the static flags */ 02909 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); 02910 02911 hsd->State = HAL_SD_STATE_READY; 02912 02913 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1) 02914 hsd->RxCpltCallback(hsd); 02915 #else 02916 HAL_SD_RxCpltCallback(hsd); 02917 #endif 02918 } 02919 02920 /** 02921 * @brief DMA SD communication error callback 02922 * @param hdma: DMA handle 02923 * @retval None 02924 */ 02925 static void SD_DMAError(DMA_HandleTypeDef *hdma) 02926 { 02927 SD_HandleTypeDef* hsd = (SD_HandleTypeDef* )(hdma->Parent); 02928 HAL_SD_CardStateTypedef CardState; 02929 uint32_t RxErrorCode, TxErrorCode; 02930 02931 RxErrorCode = hsd->hdmarx->ErrorCode; 02932 TxErrorCode = hsd->hdmatx->ErrorCode; 02933 if((RxErrorCode == HAL_DMA_ERROR_TE) || (TxErrorCode == HAL_DMA_ERROR_TE)) 02934 { 02935 /* Clear All flags */ 02936 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_FLAGS); 02937 02938 /* Disable All interrupts */ 02939 __HAL_SD_DISABLE_IT(hsd, SDMMC_IT_DATAEND | SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT|\ 02940 SDMMC_IT_TXUNDERR| SDMMC_IT_RXOVERR); 02941 02942 hsd->ErrorCode |= HAL_SD_ERROR_DMA; 02943 CardState = HAL_SD_GetCardState(hsd); 02944 if((CardState == HAL_SD_CARD_RECEIVING) || (CardState == HAL_SD_CARD_SENDING)) 02945 { 02946 hsd->ErrorCode |= SDMMC_CmdStopTransfer(hsd->Instance); 02947 } 02948 02949 hsd->State= HAL_SD_STATE_READY; 02950 } 02951 02952 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1) 02953 hsd->ErrorCallback(hsd); 02954 #else 02955 HAL_SD_ErrorCallback(hsd); 02956 #endif 02957 } 02958 02959 /** 02960 * @brief DMA SD Tx Abort callback 02961 * @param hdma: DMA handle 02962 * @retval None 02963 */ 02964 static void SD_DMATxAbort(DMA_HandleTypeDef *hdma) 02965 { 02966 SD_HandleTypeDef* hsd = (SD_HandleTypeDef* )(hdma->Parent); 02967 HAL_SD_CardStateTypedef CardState; 02968 02969 if(hsd->hdmatx != NULL) 02970 { 02971 hsd->hdmatx = NULL; 02972 } 02973 02974 /* All DMA channels are aborted */ 02975 if((hsd->hdmatx == NULL) && (hsd->hdmarx == NULL)) 02976 { 02977 /* Clear All flags */ 02978 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); 02979 02980 CardState = HAL_SD_GetCardState(hsd); 02981 hsd->State = HAL_SD_STATE_READY; 02982 if((CardState == HAL_SD_CARD_RECEIVING) || (CardState == HAL_SD_CARD_SENDING)) 02983 { 02984 hsd->ErrorCode |= SDMMC_CmdStopTransfer(hsd->Instance); 02985 02986 if(hsd->ErrorCode == HAL_SD_ERROR_NONE) 02987 { 02988 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1) 02989 hsd->AbortCpltCallback(hsd); 02990 #else 02991 HAL_SD_AbortCallback(hsd); 02992 #endif 02993 } 02994 else 02995 { 02996 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1) 02997 hsd->ErrorCallback(hsd); 02998 #else 02999 HAL_SD_ErrorCallback(hsd); 03000 #endif 03001 } 03002 } 03003 } 03004 } 03005 03006 /** 03007 * @brief DMA SD Rx Abort callback 03008 * @param hdma: DMA handle 03009 * @retval None 03010 */ 03011 static void SD_DMARxAbort(DMA_HandleTypeDef *hdma) 03012 { 03013 SD_HandleTypeDef* hsd = (SD_HandleTypeDef* )(hdma->Parent); 03014 HAL_SD_CardStateTypedef CardState; 03015 03016 if(hsd->hdmarx != NULL) 03017 { 03018 hsd->hdmarx = NULL; 03019 } 03020 03021 /* All DMA channels are aborted */ 03022 if((hsd->hdmatx == NULL) && (hsd->hdmarx == NULL)) 03023 { 03024 /* Clear All flags */ 03025 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); 03026 03027 CardState = HAL_SD_GetCardState(hsd); 03028 hsd->State = HAL_SD_STATE_READY; 03029 if((CardState == HAL_SD_CARD_RECEIVING) || (CardState == HAL_SD_CARD_SENDING)) 03030 { 03031 hsd->ErrorCode |= SDMMC_CmdStopTransfer(hsd->Instance); 03032 03033 if(hsd->ErrorCode == HAL_SD_ERROR_NONE) 03034 { 03035 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1) 03036 hsd->AbortCpltCallback(hsd); 03037 #else 03038 HAL_SD_AbortCallback(hsd); 03039 #endif 03040 } 03041 else 03042 { 03043 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1) 03044 hsd->ErrorCallback(hsd); 03045 #else 03046 HAL_SD_ErrorCallback(hsd); 03047 #endif 03048 } 03049 } 03050 } 03051 } 03052 #endif /* !STM32L4R5xx && !STM32L4R7xx && !STM32L4R9xx && !STM32L4S5xx && !STM32L4S7xx && !STM32L4S9xx */ 03053 03054 /** 03055 * @brief Initializes the sd card. 03056 * @param hsd: Pointer to SD handle 03057 * @retval SD Card error state 03058 */ 03059 static uint32_t SD_InitCard(SD_HandleTypeDef *hsd) 03060 { 03061 HAL_SD_CardCSDTypedef CSD; 03062 uint32_t errorstate; 03063 uint16_t sd_rca = 1; 03064 03065 /* Check the power State */ 03066 if(SDMMC_GetPowerState(hsd->Instance) == 0U) 03067 { 03068 /* Power off */ 03069 return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE; 03070 } 03071 03072 if(hsd->SdCard.CardType != CARD_SECURED) 03073 { 03074 /* Send CMD2 ALL_SEND_CID */ 03075 errorstate = SDMMC_CmdSendCID(hsd->Instance); 03076 if(errorstate != HAL_SD_ERROR_NONE) 03077 { 03078 return errorstate; 03079 } 03080 else 03081 { 03082 /* Get Card identification number data */ 03083 hsd->CID[0] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1); 03084 hsd->CID[1] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP2); 03085 hsd->CID[2] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP3); 03086 hsd->CID[3] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP4); 03087 } 03088 } 03089 03090 if(hsd->SdCard.CardType != CARD_SECURED) 03091 { 03092 /* Send CMD3 SET_REL_ADDR with argument 0 */ 03093 /* SD Card publishes its RCA. */ 03094 errorstate = SDMMC_CmdSetRelAdd(hsd->Instance, &sd_rca); 03095 if(errorstate != HAL_SD_ERROR_NONE) 03096 { 03097 return errorstate; 03098 } 03099 } 03100 if(hsd->SdCard.CardType != CARD_SECURED) 03101 { 03102 /* Get the SD card RCA */ 03103 hsd->SdCard.RelCardAdd = sd_rca; 03104 03105 /* Send CMD9 SEND_CSD with argument as card's RCA */ 03106 errorstate = SDMMC_CmdSendCSD(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16U)); 03107 if(errorstate != HAL_SD_ERROR_NONE) 03108 { 03109 return errorstate; 03110 } 03111 else 03112 { 03113 /* Get Card Specific Data */ 03114 hsd->CSD[0] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1); 03115 hsd->CSD[1] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP2); 03116 hsd->CSD[2] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP3); 03117 hsd->CSD[3] = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP4); 03118 } 03119 } 03120 03121 /* Get the Card Class */ 03122 hsd->SdCard.Class = (SDMMC_GetResponse(hsd->Instance, SDMMC_RESP2) >> 20); 03123 03124 /* Get CSD parameters */ 03125 if (HAL_SD_GetCardCSD(hsd, &CSD) != HAL_OK) 03126 { 03127 return HAL_SD_ERROR_UNSUPPORTED_FEATURE; 03128 } 03129 03130 /* Select the Card */ 03131 errorstate = SDMMC_CmdSelDesel(hsd->Instance, (uint32_t)(((uint32_t)hsd->SdCard.RelCardAdd) << 16)); 03132 if(errorstate != HAL_SD_ERROR_NONE) 03133 { 03134 return errorstate; 03135 } 03136 03137 #if !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 03138 /* Configure SDMMC peripheral interface */ 03139 (void)SDMMC_Init(hsd->Instance, hsd->Init); 03140 #endif /* !STM32L4R5xx && !STM32L4R7xx && !STM32L4R9xx && !STM32L4S5xx && !STM32L4S7xx && !STM32L4S9xx */ 03141 03142 /* All cards are initialized */ 03143 return HAL_SD_ERROR_NONE; 03144 } 03145 03146 /** 03147 * @brief Enquires cards about their operating voltage and configures clock 03148 * controls and stores SD information that will be needed in future 03149 * in the SD handle. 03150 * @param hsd: Pointer to SD handle 03151 * @retval error state 03152 */ 03153 static uint32_t SD_PowerON(SD_HandleTypeDef *hsd) 03154 { 03155 __IO uint32_t count = 0; 03156 uint32_t response = 0, validvoltage = 0; 03157 uint32_t errorstate; 03158 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 03159 uint32_t tickstart = HAL_GetTick(); 03160 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 03161 03162 /* CMD0: GO_IDLE_STATE */ 03163 errorstate = SDMMC_CmdGoIdleState(hsd->Instance); 03164 if(errorstate != HAL_SD_ERROR_NONE) 03165 { 03166 return errorstate; 03167 } 03168 03169 /* CMD8: SEND_IF_COND: Command available only on V2.0 cards */ 03170 errorstate = SDMMC_CmdOperCond(hsd->Instance); 03171 if(errorstate != HAL_SD_ERROR_NONE) 03172 { 03173 hsd->SdCard.CardVersion = CARD_V1_X; 03174 03175 #if !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 03176 /* Send ACMD41 SD_APP_OP_COND with Argument 0x80100000 */ 03177 while(validvoltage == 0U) 03178 { 03179 if(count++ == SDMMC_MAX_VOLT_TRIAL) 03180 { 03181 return HAL_SD_ERROR_INVALID_VOLTRANGE; 03182 } 03183 03184 /* SEND CMD55 APP_CMD with RCA as 0 */ 03185 errorstate = SDMMC_CmdAppCommand(hsd->Instance, 0); 03186 if(errorstate != HAL_SD_ERROR_NONE) 03187 { 03188 return HAL_SD_ERROR_UNSUPPORTED_FEATURE; 03189 } 03190 03191 /* Send CMD41 */ 03192 errorstate = SDMMC_CmdAppOperCommand(hsd->Instance, SDMMC_STD_CAPACITY); 03193 if(errorstate != HAL_SD_ERROR_NONE) 03194 { 03195 return HAL_SD_ERROR_UNSUPPORTED_FEATURE; 03196 } 03197 03198 /* Get command response */ 03199 response = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1); 03200 03201 /* Get operating voltage*/ 03202 validvoltage = (((response >> 31U) == 1U) ? 1U : 0U); 03203 } 03204 /* Card type is SDSC */ 03205 hsd->SdCard.CardType = CARD_SDSC; 03206 #endif /* !STM32L4R5xx && !STM32L4R7xx && !STM32L4R9xx && !STM32L4S5xx && !STM32L4S7xx && !STM32L4S9xx */ 03207 } 03208 else 03209 { 03210 hsd->SdCard.CardVersion = CARD_V2_X; 03211 03212 #if !defined(STM32L4R5xx) && !defined(STM32L4R7xx) && !defined(STM32L4R9xx) && !defined(STM32L4S5xx) && !defined(STM32L4S7xx) && !defined(STM32L4S9xx) 03213 /* Send ACMD41 SD_APP_OP_COND with Argument 0x80100000 */ 03214 while(validvoltage == 0U) 03215 { 03216 if(count++ == SDMMC_MAX_VOLT_TRIAL) 03217 { 03218 return HAL_SD_ERROR_INVALID_VOLTRANGE; 03219 } 03220 03221 /* SEND CMD55 APP_CMD with RCA as 0 */ 03222 errorstate = SDMMC_CmdAppCommand(hsd->Instance, 0); 03223 if(errorstate != HAL_SD_ERROR_NONE) 03224 { 03225 return errorstate; 03226 } 03227 03228 /* Send CMD41 */ 03229 errorstate = SDMMC_CmdAppOperCommand(hsd->Instance, SDMMC_HIGH_CAPACITY); 03230 if(errorstate != HAL_SD_ERROR_NONE) 03231 { 03232 return errorstate; 03233 } 03234 03235 /* Get command response */ 03236 response = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1); 03237 03238 /* Get operating voltage*/ 03239 validvoltage = (((response >> 31U) == 1U) ? 1U : 0U); 03240 } 03241 03242 if((response & SDMMC_HIGH_CAPACITY) == SDMMC_HIGH_CAPACITY) /* (response &= SD_HIGH_CAPACITY) */ 03243 { 03244 hsd->SdCard.CardType = CARD_SDHC_SDXC; 03245 } 03246 else 03247 { 03248 hsd->SdCard.CardType = CARD_SDSC; 03249 } 03250 #endif /* !STM32L4R5xx && !STM32L4R7xx && !STM32L4R9xx && !STM32L4S5xx && !STM32L4S7xx && !STM32L4S9xx */ 03251 } 03252 03253 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 03254 /* SEND CMD55 APP_CMD with RCA as 0 */ 03255 errorstate = SDMMC_CmdAppCommand(hsd->Instance, 0); 03256 if(errorstate != HAL_SD_ERROR_NONE) 03257 { 03258 return HAL_SD_ERROR_UNSUPPORTED_FEATURE; 03259 } 03260 else 03261 { 03262 /* SD CARD */ 03263 /* Send ACMD41 SD_APP_OP_COND with Argument 0x80100000 */ 03264 while((count < SDMMC_MAX_VOLT_TRIAL) && (validvoltage == 0U)) 03265 { 03266 /* SEND CMD55 APP_CMD with RCA as 0 */ 03267 errorstate = SDMMC_CmdAppCommand(hsd->Instance, 0); 03268 if(errorstate != HAL_SD_ERROR_NONE) 03269 { 03270 return errorstate; 03271 } 03272 03273 /* Send CMD41 */ 03274 errorstate = SDMMC_CmdAppOperCommand(hsd->Instance, SDMMC_VOLTAGE_WINDOW_SD | SDMMC_HIGH_CAPACITY | SD_SWITCH_1_8V_CAPACITY); 03275 if(errorstate != HAL_SD_ERROR_NONE) 03276 { 03277 return HAL_SD_ERROR_UNSUPPORTED_FEATURE; 03278 } 03279 03280 /* Get command response */ 03281 response = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1); 03282 03283 /* Get operating voltage*/ 03284 validvoltage = (((response >> 31U) == 1U) ? 1U : 0U); 03285 03286 count++; 03287 } 03288 03289 if(count >= SDMMC_MAX_VOLT_TRIAL) 03290 { 03291 return HAL_SD_ERROR_INVALID_VOLTRANGE; 03292 } 03293 03294 if((response & SDMMC_HIGH_CAPACITY) == SDMMC_HIGH_CAPACITY) /* (response &= SD_HIGH_CAPACITY) */ 03295 { 03296 hsd->SdCard.CardType = CARD_SDHC_SDXC; 03297 03298 if(hsd->Init.Transceiver == SDMMC_TRANSCEIVER_ENABLE) 03299 { 03300 if((response & SD_SWITCH_1_8V_CAPACITY) == SD_SWITCH_1_8V_CAPACITY) 03301 { 03302 hsd->SdCard.CardSpeed = CARD_ULTRA_HIGH_SPEED; 03303 03304 /* Start switching procedue */ 03305 hsd->Instance->POWER |= SDMMC_POWER_VSWITCHEN; 03306 03307 /* Send CMD11 to switch 1.8V mode */ 03308 errorstate = SDMMC_CmdVoltageSwitch(hsd->Instance); 03309 if(errorstate != HAL_SD_ERROR_NONE) 03310 { 03311 return errorstate; 03312 } 03313 03314 /* Check to CKSTOP */ 03315 while(( hsd->Instance->STA & SDMMC_FLAG_CKSTOP) != SDMMC_FLAG_CKSTOP) 03316 { 03317 if((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT) 03318 { 03319 return HAL_SD_ERROR_TIMEOUT; 03320 } 03321 } 03322 03323 /* Clear CKSTOP Flag */ 03324 hsd->Instance->ICR = SDMMC_FLAG_CKSTOP; 03325 03326 /* Check to BusyD0 */ 03327 if(( hsd->Instance->STA & SDMMC_FLAG_BUSYD0) != SDMMC_FLAG_BUSYD0) 03328 { 03329 /* Error when activate Voltage Switch in SDMMC IP */ 03330 return SDMMC_ERROR_UNSUPPORTED_FEATURE; 03331 } 03332 else 03333 { 03334 /* Enable Transceiver Switch PIN */ 03335 #if (USE_HAL_SD_REGISTER_CALLBACKS == 1) 03336 hsd->DriveTransceiver_1_8V_Callback(SET); 03337 #else 03338 HAL_SDEx_DriveTransceiver_1_8V_Callback(SET); 03339 #endif 03340 03341 /* Switch ready */ 03342 hsd->Instance->POWER |= SDMMC_POWER_VSWITCH; 03343 03344 /* Check VSWEND Flag */ 03345 while(( hsd->Instance->STA & SDMMC_FLAG_VSWEND) != SDMMC_FLAG_VSWEND) 03346 { 03347 if((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT) 03348 { 03349 return HAL_SD_ERROR_TIMEOUT; 03350 } 03351 } 03352 03353 /* Clear VSWEND Flag */ 03354 hsd->Instance->ICR = SDMMC_FLAG_VSWEND; 03355 03356 /* Check BusyD0 status */ 03357 if(( hsd->Instance->STA & SDMMC_FLAG_BUSYD0) == SDMMC_FLAG_BUSYD0) 03358 { 03359 /* Error when enabling 1.8V mode */ 03360 return HAL_SD_ERROR_INVALID_VOLTRANGE; 03361 } 03362 /* Switch to 1.8V OK */ 03363 03364 /* Disable VSWITCH FLAG from SDMMC IP */ 03365 hsd->Instance->POWER = 0x13U; 03366 03367 /* Clean Status flags */ 03368 hsd->Instance->ICR = 0xFFFFFFFFU; 03369 } 03370 } 03371 } 03372 } 03373 } 03374 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 03375 03376 return HAL_SD_ERROR_NONE; 03377 } 03378 03379 /** 03380 * @brief Turns the SDMMC output signals off. 03381 * @param hsd: Pointer to SD handle 03382 * @retval None 03383 */ 03384 static void SD_PowerOFF(SD_HandleTypeDef *hsd) 03385 { 03386 /* Set Power State to OFF */ 03387 (void)SDMMC_PowerState_OFF(hsd->Instance); 03388 } 03389 03390 /** 03391 * @brief Send Status info command. 03392 * @param hsd: pointer to SD handle 03393 * @param pSDstatus: Pointer to the buffer that will contain the SD card status 03394 * SD Status register) 03395 * @retval error state 03396 */ 03397 static uint32_t SD_SendSDStatus(SD_HandleTypeDef *hsd, uint32_t *pSDstatus) 03398 { 03399 SDMMC_DataInitTypeDef config; 03400 uint32_t errorstate; 03401 uint32_t tickstart = HAL_GetTick(); 03402 uint32_t count; 03403 uint32_t *pData = pSDstatus; 03404 03405 /* Check SD response */ 03406 if((SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED) 03407 { 03408 return HAL_SD_ERROR_LOCK_UNLOCK_FAILED; 03409 } 03410 03411 /* Set block size for card if it is not equal to current block size for card */ 03412 errorstate = SDMMC_CmdBlockLength(hsd->Instance, 64); 03413 if(errorstate != HAL_SD_ERROR_NONE) 03414 { 03415 hsd->ErrorCode |= HAL_SD_ERROR_NONE; 03416 return errorstate; 03417 } 03418 03419 /* Send CMD55 */ 03420 errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16)); 03421 if(errorstate != HAL_SD_ERROR_NONE) 03422 { 03423 hsd->ErrorCode |= HAL_SD_ERROR_NONE; 03424 return errorstate; 03425 } 03426 03427 /* Configure the SD DPSM (Data Path State Machine) */ 03428 config.DataTimeOut = SDMMC_DATATIMEOUT; 03429 config.DataLength = 64; 03430 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_64B; 03431 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; 03432 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; 03433 config.DPSM = SDMMC_DPSM_ENABLE; 03434 (void)SDMMC_ConfigData(hsd->Instance, &config); 03435 03436 /* Send ACMD13 (SD_APP_STAUS) with argument as card's RCA */ 03437 errorstate = SDMMC_CmdStatusRegister(hsd->Instance); 03438 if(errorstate != HAL_SD_ERROR_NONE) 03439 { 03440 hsd->ErrorCode |= HAL_SD_ERROR_NONE; 03441 return errorstate; 03442 } 03443 03444 /* Get status data */ 03445 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 03446 while(!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DATAEND)) 03447 #else 03448 while(!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND)) 03449 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 03450 { 03451 if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOHF)) 03452 { 03453 for(count = 0U; count < 8U; count++) 03454 { 03455 *pData = SDMMC_ReadFIFO(hsd->Instance); 03456 pData++; 03457 } 03458 } 03459 03460 if((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT) 03461 { 03462 return HAL_SD_ERROR_TIMEOUT; 03463 } 03464 } 03465 03466 if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT)) 03467 { 03468 return HAL_SD_ERROR_DATA_TIMEOUT; 03469 } 03470 else if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL)) 03471 { 03472 return HAL_SD_ERROR_DATA_CRC_FAIL; 03473 } 03474 else if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR)) 03475 { 03476 return HAL_SD_ERROR_RX_OVERRUN; 03477 } 03478 else 03479 { 03480 /* Nothing to do */ 03481 } 03482 03483 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 03484 while ((__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DPSMACT))) 03485 #else 03486 while ((__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXDAVL))) 03487 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 03488 { 03489 *pData = SDMMC_ReadFIFO(hsd->Instance); 03490 pData++; 03491 03492 if((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT) 03493 { 03494 return HAL_SD_ERROR_TIMEOUT; 03495 } 03496 } 03497 03498 /* Clear all the static status flags*/ 03499 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); 03500 03501 return HAL_SD_ERROR_NONE; 03502 } 03503 03504 /** 03505 * @brief Returns the current card's status. 03506 * @param hsd: Pointer to SD handle 03507 * @param pCardStatus: pointer to the buffer that will contain the SD card 03508 * status (Card Status register) 03509 * @retval error state 03510 */ 03511 static uint32_t SD_SendStatus(SD_HandleTypeDef *hsd, uint32_t *pCardStatus) 03512 { 03513 uint32_t errorstate; 03514 03515 if(pCardStatus == NULL) 03516 { 03517 return HAL_SD_ERROR_PARAM; 03518 } 03519 03520 /* Send Status command */ 03521 errorstate = SDMMC_CmdSendStatus(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16)); 03522 if(errorstate != HAL_SD_ERROR_NONE) 03523 { 03524 return errorstate; 03525 } 03526 03527 /* Get SD card status */ 03528 *pCardStatus = SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1); 03529 03530 return HAL_SD_ERROR_NONE; 03531 } 03532 03533 /** 03534 * @brief Enables the SDMMC wide bus mode. 03535 * @param hsd: pointer to SD handle 03536 * @retval error state 03537 */ 03538 static uint32_t SD_WideBus_Enable(SD_HandleTypeDef *hsd) 03539 { 03540 uint32_t scr[2] = {0, 0}; 03541 uint32_t errorstate; 03542 03543 if((SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED) 03544 { 03545 return HAL_SD_ERROR_LOCK_UNLOCK_FAILED; 03546 } 03547 03548 /* Get SCR Register */ 03549 errorstate = SD_FindSCR(hsd, scr); 03550 if(errorstate != HAL_SD_ERROR_NONE) 03551 { 03552 return errorstate; 03553 } 03554 03555 /* If requested card supports wide bus operation */ 03556 if((scr[1] & SDMMC_WIDE_BUS_SUPPORT) != SDMMC_ALLZERO) 03557 { 03558 /* Send CMD55 APP_CMD with argument as card's RCA.*/ 03559 errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16)); 03560 if(errorstate != HAL_SD_ERROR_NONE) 03561 { 03562 return errorstate; 03563 } 03564 03565 /* Send ACMD6 APP_CMD with argument as 2 for wide bus mode */ 03566 errorstate = SDMMC_CmdBusWidth(hsd->Instance, 2); 03567 if(errorstate != HAL_SD_ERROR_NONE) 03568 { 03569 return errorstate; 03570 } 03571 03572 return HAL_SD_ERROR_NONE; 03573 } 03574 else 03575 { 03576 return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE; 03577 } 03578 } 03579 03580 /** 03581 * @brief Disables the SDMMC wide bus mode. 03582 * @param hsd: Pointer to SD handle 03583 * @retval error state 03584 */ 03585 static uint32_t SD_WideBus_Disable(SD_HandleTypeDef *hsd) 03586 { 03587 uint32_t scr[2] = {0, 0}; 03588 uint32_t errorstate; 03589 03590 if((SDMMC_GetResponse(hsd->Instance, SDMMC_RESP1) & SDMMC_CARD_LOCKED) == SDMMC_CARD_LOCKED) 03591 { 03592 return HAL_SD_ERROR_LOCK_UNLOCK_FAILED; 03593 } 03594 03595 /* Get SCR Register */ 03596 errorstate = SD_FindSCR(hsd, scr); 03597 if(errorstate != HAL_SD_ERROR_NONE) 03598 { 03599 return errorstate; 03600 } 03601 03602 /* If requested card supports 1 bit mode operation */ 03603 if((scr[1] & SDMMC_SINGLE_BUS_SUPPORT) != SDMMC_ALLZERO) 03604 { 03605 /* Send CMD55 APP_CMD with argument as card's RCA */ 03606 errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)(hsd->SdCard.RelCardAdd << 16)); 03607 if(errorstate != HAL_SD_ERROR_NONE) 03608 { 03609 return errorstate; 03610 } 03611 03612 /* Send ACMD6 APP_CMD with argument as 0 for single bus mode */ 03613 errorstate = SDMMC_CmdBusWidth(hsd->Instance, 0); 03614 if(errorstate != HAL_SD_ERROR_NONE) 03615 { 03616 return errorstate; 03617 } 03618 03619 return HAL_SD_ERROR_NONE; 03620 } 03621 else 03622 { 03623 return HAL_SD_ERROR_REQUEST_NOT_APPLICABLE; 03624 } 03625 } 03626 03627 03628 /** 03629 * @brief Finds the SD card SCR register value. 03630 * @param hsd: Pointer to SD handle 03631 * @param pSCR: pointer to the buffer that will contain the SCR value 03632 * @retval error state 03633 */ 03634 static uint32_t SD_FindSCR(SD_HandleTypeDef *hsd, uint32_t *pSCR) 03635 { 03636 SDMMC_DataInitTypeDef config; 03637 uint32_t errorstate; 03638 uint32_t tickstart = HAL_GetTick(); 03639 uint32_t index = 0; 03640 uint32_t tempscr[2] = {0, 0}; 03641 uint32_t *scr = pSCR; 03642 03643 /* Set Block Size To 8 Bytes */ 03644 errorstate = SDMMC_CmdBlockLength(hsd->Instance, 8); 03645 if(errorstate != HAL_SD_ERROR_NONE) 03646 { 03647 return errorstate; 03648 } 03649 03650 /* Send CMD55 APP_CMD with argument as card's RCA */ 03651 errorstate = SDMMC_CmdAppCommand(hsd->Instance, (uint32_t)((hsd->SdCard.RelCardAdd) << 16)); 03652 if(errorstate != HAL_SD_ERROR_NONE) 03653 { 03654 return errorstate; 03655 } 03656 03657 config.DataTimeOut = SDMMC_DATATIMEOUT; 03658 config.DataLength = 8; 03659 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_8B; 03660 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; 03661 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; 03662 config.DPSM = SDMMC_DPSM_ENABLE; 03663 (void)SDMMC_ConfigData(hsd->Instance, &config); 03664 03665 /* Send ACMD51 SD_APP_SEND_SCR with argument as 0 */ 03666 errorstate = SDMMC_CmdSendSCR(hsd->Instance); 03667 if(errorstate != HAL_SD_ERROR_NONE) 03668 { 03669 return errorstate; 03670 } 03671 03672 #if defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 03673 while(!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND | SDMMC_FLAG_DATAEND)) 03674 { 03675 if((!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXFIFOE)) && (index == 0U)) 03676 { 03677 tempscr[0] = SDMMC_ReadFIFO(hsd->Instance); 03678 tempscr[1] = SDMMC_ReadFIFO(hsd->Instance); 03679 index++; 03680 } 03681 03682 03683 if((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT) 03684 { 03685 return HAL_SD_ERROR_TIMEOUT; 03686 } 03687 } 03688 #else 03689 while(!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND)) 03690 { 03691 if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXDAVL)) 03692 { 03693 *(tempscr + index) = SDMMC_ReadFIFO(hsd->Instance); 03694 index++; 03695 } 03696 03697 if((HAL_GetTick() - tickstart) >= SDMMC_DATATIMEOUT) 03698 { 03699 return HAL_SD_ERROR_TIMEOUT; 03700 } 03701 } 03702 #endif /* STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */ 03703 03704 if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DTIMEOUT)) 03705 { 03706 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_DTIMEOUT); 03707 03708 return HAL_SD_ERROR_DATA_TIMEOUT; 03709 } 03710 else if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_DCRCFAIL)) 03711 { 03712 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_DCRCFAIL); 03713 03714 return HAL_SD_ERROR_DATA_CRC_FAIL; 03715 } 03716 else if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR)) 03717 { 03718 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_FLAG_RXOVERR); 03719 03720 return HAL_SD_ERROR_RX_OVERRUN; 03721 } 03722 else 03723 { 03724 /* No error flag set */ 03725 /* Clear all the static flags */ 03726 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); 03727 03728 *scr = (((tempscr[1] & SDMMC_0TO7BITS) << 24) | ((tempscr[1] & SDMMC_8TO15BITS) << 8) |\ 03729 ((tempscr[1] & SDMMC_16TO23BITS) >> 8) | ((tempscr[1] & SDMMC_24TO31BITS) >> 24)); 03730 scr++; 03731 *scr = (((tempscr[0] & SDMMC_0TO7BITS) << 24) | ((tempscr[0] & SDMMC_8TO15BITS) << 8) |\ 03732 ((tempscr[0] & SDMMC_16TO23BITS) >> 8) | ((tempscr[0] & SDMMC_24TO31BITS) >> 24)); 03733 03734 } 03735 03736 return HAL_SD_ERROR_NONE; 03737 } 03738 03739 /** 03740 * @brief Wrap up reading in non-blocking mode. 03741 * @param hsd: pointer to a SD_HandleTypeDef structure that contains 03742 * the configuration information. 03743 * @retval None 03744 */ 03745 static void SD_Read_IT(SD_HandleTypeDef *hsd) 03746 { 03747 uint32_t count, data; 03748 uint8_t* tmp; 03749 03750 tmp = hsd->pRxBuffPtr; 03751 03752 /* Read data from SDMMC Rx FIFO */ 03753 for(count = 0U; count < 8U; count++) 03754 { 03755 data = SDMMC_ReadFIFO(hsd->Instance); 03756 *tmp = (uint8_t)(data & 0xFFU); 03757 tmp++; 03758 *tmp = (uint8_t)((data >> 8U) & 0xFFU); 03759 tmp++; 03760 *tmp = (uint8_t)((data >> 16U) & 0xFFU); 03761 tmp++; 03762 *tmp = (uint8_t)((data >> 24U) & 0xFFU); 03763 tmp++; 03764 } 03765 03766 hsd->pRxBuffPtr = tmp; 03767 } 03768 03769 /** 03770 * @brief Wrap up writing in non-blocking mode. 03771 * @param hsd: pointer to a SD_HandleTypeDef structure that contains 03772 * the configuration information. 03773 * @retval None 03774 */ 03775 static void SD_Write_IT(SD_HandleTypeDef *hsd) 03776 { 03777 uint32_t count, data; 03778 uint8_t* tmp; 03779 03780 tmp = hsd->pTxBuffPtr; 03781 03782 /* Write data to SDMMC Tx FIFO */ 03783 for(count = 0U; count < 8U; count++) 03784 { 03785 data = (uint32_t)(*tmp); 03786 tmp++; 03787 data |= ((uint32_t)(*tmp) << 8U); 03788 tmp++; 03789 data |= ((uint32_t)(*tmp) << 16U); 03790 tmp++; 03791 data |= ((uint32_t)(*tmp) << 24U); 03792 tmp++; 03793 (void)SDMMC_WriteFIFO(hsd->Instance, &data); 03794 } 03795 03796 hsd->pTxBuffPtr = tmp; 03797 } 03798 03799 03800 /** 03801 * @} 03802 */ 03803 03804 #endif /* HAL_SD_MODULE_ENABLED */ 03805 03806 /** 03807 * @} 03808 */ 03809 03810 /** 03811 * @} 03812 */ 03813 03814 #endif /* SDMMC1 */ 03815 03816 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/