STM32L443xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l4xx_hal_sd_ex.c 00004 * @author MCD Application Team 00005 * @brief SD card Extended HAL module driver. 00006 * This file provides firmware functions to manage the following 00007 * functionalities of the Secure Digital (SD) peripheral: 00008 * + Extended features functions 00009 * 00010 ****************************************************************************** 00011 * @attention 00012 * 00013 * Copyright (c) 2017 STMicroelectronics. 00014 * All rights reserved. 00015 * 00016 * This software is licensed under terms that can be found in the LICENSE file 00017 * in the root directory of this software component. 00018 * If no LICENSE file comes with this software, it is provided AS-IS. 00019 * 00020 ****************************************************************************** 00021 @verbatim 00022 ============================================================================== 00023 ##### How to use this driver ##### 00024 ============================================================================== 00025 [..] 00026 The SD Extension HAL driver can be used as follows: 00027 (+) Set card in High Speed mode using HAL_SDEx_HighSpeed() function. 00028 (+) Configure Buffer0 and Buffer1 start address and Buffer size using HAL_SDEx_ConfigDMAMultiBuffer() function. 00029 (+) Start Read and Write for multibuffer mode using HAL_SDEx_ReadBlocksDMAMultiBuffer() and HAL_SDEx_WriteBlocksDMAMultiBuffer() functions. 00030 00031 @endverbatim 00032 ****************************************************************************** 00033 */ 00034 00035 /* Includes ------------------------------------------------------------------*/ 00036 #include "stm32l4xx_hal.h" 00037 00038 #if defined(STM32L4P5xx) || defined(STM32L4Q5xx) || defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || defined(STM32L4S7xx) || defined(STM32L4S9xx) 00039 00040 /** @addtogroup STM32L4xx_HAL_Driver 00041 * @{ 00042 */ 00043 00044 /** @defgroup SDEx SDEx 00045 * @brief SD Extended HAL module driver 00046 * @{ 00047 */ 00048 00049 #ifdef HAL_SD_MODULE_ENABLED 00050 00051 /* Private typedef -----------------------------------------------------------*/ 00052 /* Private define ------------------------------------------------------------*/ 00053 /* Private macro -------------------------------------------------------------*/ 00054 /* Private variables ---------------------------------------------------------*/ 00055 /* Private function prototypes -----------------------------------------------*/ 00056 /* Private functions ---------------------------------------------------------*/ 00057 extern uint32_t SD_HighSpeed(SD_HandleTypeDef *hsd); 00058 /* Exported functions --------------------------------------------------------*/ 00059 /** @addtogroup SDEx_Exported_Functions 00060 * @{ 00061 */ 00062 00063 /** @addtogroup SDEx_Exported_Functions_Group1 00064 * @brief High Speed function 00065 * 00066 @verbatim 00067 ============================================================================== 00068 ##### High Speed function ##### 00069 ============================================================================== 00070 [..] 00071 This section provides function allowing to configure the card in High Speed mode. 00072 00073 @endverbatim 00074 * @{ 00075 */ 00076 00077 /** 00078 * @brief Switches the SD card to High Speed mode. 00079 * This API must be used after "Transfer State" 00080 * @note This operation should be followed by the configuration 00081 * of PLL to have SDMMCCK clock between 50 and 120 MHz 00082 * @param hsd SD handle 00083 * @retval SD Card error state 00084 */ 00085 uint32_t HAL_SDEx_HighSpeed(SD_HandleTypeDef *hsd) 00086 { 00087 return SD_HighSpeed (hsd); 00088 } 00089 00090 /** 00091 * @brief Enable/Disable the SD Transceiver 1.8V Mode Callback. 00092 * @param status Voltage Switch State 00093 * @retval None 00094 */ 00095 __weak void HAL_SDEx_DriveTransceiver_1_8V_Callback(FlagStatus status) 00096 { 00097 /* Prevent unused argument(s) compilation warning */ 00098 UNUSED(status); 00099 00100 /* NOTE : This function Should not be modified, when the callback is needed, 00101 the HAL_SD_EnableTransciver could be implemented in the user file 00102 */ 00103 } 00104 00105 /** 00106 * @} 00107 */ 00108 00109 /** @addtogroup SDEx_Exported_Functions_Group2 00110 * @brief Multibuffer functions 00111 * 00112 @verbatim 00113 ============================================================================== 00114 ##### Multibuffer functions ##### 00115 ============================================================================== 00116 [..] 00117 This section provides functions allowing to configure the multibuffer mode and start read and write 00118 multibuffer mode for SD HAL driver. 00119 00120 @endverbatim 00121 * @{ 00122 */ 00123 00124 /** 00125 * @brief Configure DMA Dual Buffer mode. The Data transfer is managed by an Internal DMA. 00126 * @param hsd SD handle 00127 * @param pDataBuffer0 Pointer to the buffer0 that will contain/receive the transfered data 00128 * @param pDataBuffer1 Pointer to the buffer1 that will contain/receive the transfered data 00129 * @param BufferSize Size of Buffer0 in Blocks. Buffer0 and Buffer1 must have the same size. 00130 * @retval HAL status 00131 */ 00132 HAL_StatusTypeDef HAL_SDEx_ConfigDMAMultiBuffer(SD_HandleTypeDef *hsd, uint32_t *pDataBuffer0, uint32_t *pDataBuffer1, uint32_t BufferSize) 00133 { 00134 if(hsd->State == HAL_SD_STATE_READY) 00135 { 00136 hsd->Instance->IDMABASE0= (uint32_t) pDataBuffer0; 00137 hsd->Instance->IDMABASE1= (uint32_t) pDataBuffer1; 00138 hsd->Instance->IDMABSIZE= (uint32_t) (BLOCKSIZE * BufferSize); 00139 00140 return HAL_OK; 00141 } 00142 else 00143 { 00144 return HAL_BUSY; 00145 } 00146 } 00147 00148 /** 00149 * @brief Reads block(s) from a specified address in a card. The received Data will be stored in Buffer0 and Buffer1. 00150 * Buffer0, Buffer1 and BufferSize need to be configured by function HAL_SDEx_ConfigDMAMultiBuffer before call this function. 00151 * @param hsd SD handle 00152 * @param BlockAdd Block Address from where data is to be read 00153 * @param NumberOfBlocks Total number of blocks to read 00154 * @retval HAL status 00155 */ 00156 HAL_StatusTypeDef HAL_SDEx_ReadBlocksDMAMultiBuffer(SD_HandleTypeDef *hsd, uint32_t BlockAdd, uint32_t NumberOfBlocks) 00157 { 00158 SDMMC_DataInitTypeDef config; 00159 uint32_t errorstate; 00160 uint32_t DmaBase0_reg, DmaBase1_reg; 00161 uint32_t add = BlockAdd; 00162 00163 if(hsd->State == HAL_SD_STATE_READY) 00164 { 00165 if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)) 00166 { 00167 hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE; 00168 return HAL_ERROR; 00169 } 00170 00171 DmaBase0_reg = hsd->Instance->IDMABASE0; 00172 DmaBase1_reg = hsd->Instance->IDMABASE1; 00173 if ((hsd->Instance->IDMABSIZE == 0U) || (DmaBase0_reg == 0U) || (DmaBase1_reg == 0U)) 00174 { 00175 hsd->ErrorCode = HAL_SD_ERROR_ADDR_OUT_OF_RANGE; 00176 return HAL_ERROR; 00177 } 00178 00179 /* Initialize data control register */ 00180 hsd->Instance->DCTRL = 0; 00181 /* Clear old Flags*/ 00182 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); 00183 00184 hsd->ErrorCode = HAL_SD_ERROR_NONE; 00185 hsd->State = HAL_SD_STATE_BUSY; 00186 00187 if(hsd->SdCard.CardType != CARD_SDHC_SDXC) 00188 { 00189 add *= 512U; 00190 } 00191 00192 /* Configure the SD DPSM (Data Path State Machine) */ 00193 config.DataTimeOut = SDMMC_DATATIMEOUT; 00194 config.DataLength = BLOCKSIZE * NumberOfBlocks; 00195 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; 00196 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; 00197 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; 00198 config.DPSM = SDMMC_DPSM_DISABLE; 00199 (void)SDMMC_ConfigData(hsd->Instance, &config); 00200 00201 hsd->Instance->DCTRL |= SDMMC_DCTRL_FIFORST; 00202 00203 __SDMMC_CMDTRANS_ENABLE( hsd->Instance); 00204 00205 hsd->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_DOUBLE_BUFF0; 00206 00207 /* Read Blocks in DMA mode */ 00208 hsd->Context = (SD_CONTEXT_READ_MULTIPLE_BLOCK | SD_CONTEXT_DMA); 00209 00210 /* Read Multi Block command */ 00211 errorstate = SDMMC_CmdReadMultiBlock(hsd->Instance, add); 00212 if(errorstate != HAL_SD_ERROR_NONE) 00213 { 00214 hsd->State = HAL_SD_STATE_READY; 00215 hsd->ErrorCode |= errorstate; 00216 return HAL_ERROR; 00217 } 00218 00219 __HAL_SD_ENABLE_IT(hsd, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND | SDMMC_IT_IDMABTC)); 00220 00221 return HAL_OK; 00222 } 00223 else 00224 { 00225 return HAL_BUSY; 00226 } 00227 00228 } 00229 00230 /** 00231 * @brief Write block(s) to a specified address in a card. The transfered Data are stored in Buffer0 and Buffer1. 00232 * Buffer0, Buffer1 and BufferSize need to be configured by function HAL_SDEx_ConfigDMAMultiBuffer before call this function. 00233 * @param hsd SD handle 00234 * @param BlockAdd Block Address from where data is to be read 00235 * @param NumberOfBlocks Total number of blocks to read 00236 * @retval HAL status 00237 */ 00238 HAL_StatusTypeDef HAL_SDEx_WriteBlocksDMAMultiBuffer(SD_HandleTypeDef *hsd, uint32_t BlockAdd, uint32_t NumberOfBlocks) 00239 { 00240 SDMMC_DataInitTypeDef config; 00241 uint32_t errorstate; 00242 uint32_t DmaBase0_reg, DmaBase1_reg; 00243 uint32_t add = BlockAdd; 00244 00245 if(hsd->State == HAL_SD_STATE_READY) 00246 { 00247 if((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)) 00248 { 00249 hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE; 00250 return HAL_ERROR; 00251 } 00252 00253 DmaBase0_reg = hsd->Instance->IDMABASE0; 00254 DmaBase1_reg = hsd->Instance->IDMABASE1; 00255 if ((hsd->Instance->IDMABSIZE == 0U) || (DmaBase0_reg == 0U) || (DmaBase1_reg == 0U)) 00256 { 00257 hsd->ErrorCode = HAL_SD_ERROR_ADDR_OUT_OF_RANGE; 00258 return HAL_ERROR; 00259 } 00260 00261 /* Initialize data control register */ 00262 hsd->Instance->DCTRL = 0; 00263 00264 hsd->ErrorCode = HAL_SD_ERROR_NONE; 00265 00266 hsd->State = HAL_SD_STATE_BUSY; 00267 00268 if(hsd->SdCard.CardType != CARD_SDHC_SDXC) 00269 { 00270 add *= 512U; 00271 } 00272 00273 /* Configure the SD DPSM (Data Path State Machine) */ 00274 config.DataTimeOut = SDMMC_DATATIMEOUT; 00275 config.DataLength = BLOCKSIZE * NumberOfBlocks; 00276 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; 00277 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD; 00278 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; 00279 config.DPSM = SDMMC_DPSM_DISABLE; 00280 (void)SDMMC_ConfigData(hsd->Instance, &config); 00281 00282 __SDMMC_CMDTRANS_ENABLE( hsd->Instance); 00283 00284 hsd->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_DOUBLE_BUFF0; 00285 00286 /* Write Blocks in DMA mode */ 00287 hsd->Context = (SD_CONTEXT_WRITE_MULTIPLE_BLOCK | SD_CONTEXT_DMA); 00288 00289 /* Write Multi Block command */ 00290 errorstate = SDMMC_CmdWriteMultiBlock(hsd->Instance, add); 00291 if(errorstate != HAL_SD_ERROR_NONE) 00292 { 00293 hsd->State = HAL_SD_STATE_READY; 00294 hsd->ErrorCode |= errorstate; 00295 return HAL_ERROR; 00296 } 00297 00298 __HAL_SD_ENABLE_IT(hsd, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND | SDMMC_IT_IDMABTC)); 00299 00300 return HAL_OK; 00301 } 00302 else 00303 { 00304 return HAL_BUSY; 00305 } 00306 } 00307 00308 00309 /** 00310 * @brief Change the DMA Buffer0 or Buffer1 address on the fly. 00311 * @param hsd pointer to a SD_HandleTypeDef structure. 00312 * @param Buffer the buffer to be changed, This parameter can be one of 00313 * the following values: SD_DMA_BUFFER0 or SD_DMA_BUFFER1 00314 * @param pDataBuffer The new address 00315 * @note The BUFFER0 address can be changed only when the current transfer use 00316 * BUFFER1 and the BUFFER1 address can be changed only when the current 00317 * transfer use BUFFER0. 00318 * @retval HAL status 00319 */ 00320 HAL_StatusTypeDef HAL_SDEx_ChangeDMABuffer(SD_HandleTypeDef *hsd, HAL_SDEx_DMABuffer_MemoryTypeDef Buffer, uint32_t *pDataBuffer) 00321 { 00322 if(Buffer == SD_DMA_BUFFER0) 00323 { 00324 /* change the buffer0 address */ 00325 hsd->Instance->IDMABASE0 = (uint32_t)pDataBuffer; 00326 } 00327 else 00328 { 00329 /* change the memory1 address */ 00330 hsd->Instance->IDMABASE1 = (uint32_t)pDataBuffer; 00331 } 00332 00333 return HAL_OK; 00334 } 00335 00336 /** 00337 * @brief Read DMA Buffer 0 Transfer completed callbacks 00338 * @param hsd: SD handle 00339 * @retval None 00340 */ 00341 __weak void HAL_SDEx_Read_DMADoubleBuffer0CpltCallback(SD_HandleTypeDef *hsd) 00342 { 00343 /* Prevent unused argument(s) compilation warning */ 00344 UNUSED(hsd); 00345 00346 /* NOTE : This function should not be modified, when the callback is needed, 00347 the HAL_SDEx_Read_DMADoubleBuffer0CpltCallback can be implemented in the user file 00348 */ 00349 } 00350 00351 /** 00352 * @brief Read DMA Buffer 1 Transfer completed callbacks 00353 * @param hsd: SD handle 00354 * @retval None 00355 */ 00356 __weak void HAL_SDEx_Read_DMADoubleBuffer1CpltCallback(SD_HandleTypeDef *hsd) 00357 { 00358 /* Prevent unused argument(s) compilation warning */ 00359 UNUSED(hsd); 00360 00361 /* NOTE : This function should not be modified, when the callback is needed, 00362 the HAL_SDEx_Read_DMADoubleBuffer1CpltCallback can be implemented in the user file 00363 */ 00364 } 00365 00366 /** 00367 * @brief Write DMA Buffer 0 Transfer completed callbacks 00368 * @param hsd: SD handle 00369 * @retval None 00370 */ 00371 __weak void HAL_SDEx_Write_DMADoubleBuffer0CpltCallback(SD_HandleTypeDef *hsd) 00372 { 00373 /* Prevent unused argument(s) compilation warning */ 00374 UNUSED(hsd); 00375 00376 /* NOTE : This function should not be modified, when the callback is needed, 00377 the HAL_SDEx_Write_DMADoubleBuffer0CpltCallback can be implemented in the user file 00378 */ 00379 } 00380 00381 /** 00382 * @brief Write DMA Buffer 1 Transfer completed callbacks 00383 * @param hsd: SD handle 00384 * @retval None 00385 */ 00386 __weak void HAL_SDEx_Write_DMADoubleBuffer1CpltCallback(SD_HandleTypeDef *hsd) 00387 { 00388 /* Prevent unused argument(s) compilation warning */ 00389 UNUSED(hsd); 00390 00391 /* NOTE : This function should not be modified, when the callback is needed, 00392 the HAL_SDEx_Write_DMADoubleBuffer0CpltCallback can be implemented in the user file 00393 */ 00394 } 00395 00396 /** 00397 * @} 00398 */ 00399 00400 /** 00401 * @} 00402 */ 00403 00404 #endif /* HAL_SD_MODULE_ENABLED */ 00405 00406 /** 00407 * @} 00408 */ 00409 00410 /** 00411 * @} 00412 */ 00413 00414 #endif /* STM32L4P5xx || STM32L4Q5xx || STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */