STM32H735xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32h7xx_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 (+) Configure Buffer0 and Buffer1 start address and Buffer size using HAL_SDEx_ConfigDMAMultiBuffer() function. 00028 (+) Start Read and Write for multibuffer mode using HAL_SDEx_ReadBlocksDMAMultiBuffer() 00029 and HAL_SDEx_WriteBlocksDMAMultiBuffer() functions. 00030 00031 @endverbatim 00032 ****************************************************************************** 00033 */ 00034 00035 /* Includes ------------------------------------------------------------------*/ 00036 #include "stm32h7xx_hal.h" 00037 00038 /** @addtogroup STM32H7xx_HAL_Driver 00039 * @{ 00040 */ 00041 00042 /** @defgroup SDEx SDEx 00043 * @brief SD Extended HAL module driver 00044 * @{ 00045 */ 00046 00047 #ifdef HAL_SD_MODULE_ENABLED 00048 00049 /* Private typedef -----------------------------------------------------------*/ 00050 /* Private define ------------------------------------------------------------*/ 00051 /* Private macro -------------------------------------------------------------*/ 00052 /* Private variables ---------------------------------------------------------*/ 00053 /* Private function prototypes -----------------------------------------------*/ 00054 /* Private functions ---------------------------------------------------------*/ 00055 /* Exported functions --------------------------------------------------------*/ 00056 /** @addtogroup SDEx_Exported_Functions 00057 * @{ 00058 */ 00059 00060 /** @addtogroup SDEx_Exported_Functions_Group1 00061 * @brief Multibuffer functions 00062 * 00063 @verbatim 00064 ============================================================================== 00065 ##### Multibuffer functions ##### 00066 ============================================================================== 00067 [..] 00068 This section provides functions allowing to configure the multibuffer mode and start read and write 00069 multibuffer mode for SD HAL driver. 00070 00071 @endverbatim 00072 * @{ 00073 */ 00074 00075 /** 00076 * @brief Configure DMA Dual Buffer mode. The Data transfer is managed by an Internal DMA. 00077 * @param hsd: SD handle 00078 * @param pDataBuffer0: Pointer to the buffer0 that will contain/receive the transferred data 00079 * @param pDataBuffer1: Pointer to the buffer1 that will contain/receive the transferred data 00080 * @param BufferSize: Size of Buffer0 in Blocks. Buffer0 and Buffer1 must have the same size. 00081 * @retval HAL status 00082 */ 00083 HAL_StatusTypeDef HAL_SDEx_ConfigDMAMultiBuffer(SD_HandleTypeDef *hsd, uint32_t *pDataBuffer0, uint32_t *pDataBuffer1, 00084 uint32_t BufferSize) 00085 { 00086 if (hsd->State == HAL_SD_STATE_READY) 00087 { 00088 hsd->Instance->IDMABASE0 = (uint32_t) pDataBuffer0; 00089 hsd->Instance->IDMABASE1 = (uint32_t) pDataBuffer1; 00090 hsd->Instance->IDMABSIZE = (uint32_t)(BLOCKSIZE * BufferSize); 00091 00092 return HAL_OK; 00093 } 00094 else 00095 { 00096 return HAL_BUSY; 00097 } 00098 } 00099 00100 /** 00101 * @brief Reads block(s) from a specified address in a card. The received Data will be stored in Buffer0 and Buffer1. 00102 * Buffer0, Buffer1 and BufferSize need to be configured by function HAL_SDEx_ConfigDMAMultiBuffer before 00103 * call this function. 00104 * @param hsd: SD handle 00105 * @param BlockAdd: Block Address from where data is to be read 00106 * @param NumberOfBlocks: Total number of blocks to read 00107 * @retval HAL status 00108 */ 00109 HAL_StatusTypeDef HAL_SDEx_ReadBlocksDMAMultiBuffer(SD_HandleTypeDef *hsd, uint32_t BlockAdd, uint32_t NumberOfBlocks) 00110 { 00111 SDMMC_DataInitTypeDef config; 00112 uint32_t errorstate; 00113 uint32_t DmaBase0_reg; 00114 uint32_t DmaBase1_reg; 00115 uint32_t add = BlockAdd; 00116 00117 if (hsd->State == HAL_SD_STATE_READY) 00118 { 00119 if ((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)) 00120 { 00121 hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE; 00122 return HAL_ERROR; 00123 } 00124 00125 DmaBase0_reg = hsd->Instance->IDMABASE0; 00126 DmaBase1_reg = hsd->Instance->IDMABASE1; 00127 00128 if ((hsd->Instance->IDMABSIZE == 0U) || (DmaBase0_reg == 0U) || (DmaBase1_reg == 0U)) 00129 { 00130 hsd->ErrorCode = HAL_SD_ERROR_ADDR_OUT_OF_RANGE; 00131 return HAL_ERROR; 00132 } 00133 00134 /* Initialize data control register */ 00135 hsd->Instance->DCTRL = 0; 00136 /* Clear old Flags*/ 00137 __HAL_SD_CLEAR_FLAG(hsd, SDMMC_STATIC_DATA_FLAGS); 00138 00139 hsd->ErrorCode = HAL_SD_ERROR_NONE; 00140 hsd->State = HAL_SD_STATE_BUSY; 00141 00142 if (hsd->SdCard.CardType != CARD_SDHC_SDXC) 00143 { 00144 add *= 512U; 00145 } 00146 00147 /* Configure the SD DPSM (Data Path State Machine) */ 00148 config.DataTimeOut = SDMMC_DATATIMEOUT; 00149 config.DataLength = BLOCKSIZE * NumberOfBlocks; 00150 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; 00151 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; 00152 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; 00153 config.DPSM = SDMMC_DPSM_DISABLE; 00154 (void)SDMMC_ConfigData(hsd->Instance, &config); 00155 00156 hsd->Instance->DCTRL |= SDMMC_DCTRL_FIFORST; 00157 00158 __SDMMC_CMDTRANS_ENABLE(hsd->Instance); 00159 00160 hsd->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_DOUBLE_BUFF0; 00161 00162 /* Read Blocks in DMA mode */ 00163 hsd->Context = (SD_CONTEXT_READ_MULTIPLE_BLOCK | SD_CONTEXT_DMA); 00164 00165 /* Read Multi Block command */ 00166 errorstate = SDMMC_CmdReadMultiBlock(hsd->Instance, add); 00167 if (errorstate != HAL_SD_ERROR_NONE) 00168 { 00169 hsd->State = HAL_SD_STATE_READY; 00170 hsd->ErrorCode |= errorstate; 00171 return HAL_ERROR; 00172 } 00173 00174 __HAL_SD_ENABLE_IT(hsd, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND | 00175 SDMMC_IT_IDMABTC)); 00176 00177 return HAL_OK; 00178 } 00179 else 00180 { 00181 return HAL_BUSY; 00182 } 00183 00184 } 00185 00186 /** 00187 * @brief Write block(s) to a specified address in a card. The transferred Data are stored in Buffer0 and Buffer1. 00188 * Buffer0, Buffer1 and BufferSize need to be configured by function HAL_SDEx_ConfigDMAMultiBuffer before 00189 * call this function. 00190 * @param hsd: SD handle 00191 * @param BlockAdd: Block Address from where data is to be read 00192 * @param NumberOfBlocks: Total number of blocks to read 00193 * @retval HAL status 00194 */ 00195 HAL_StatusTypeDef HAL_SDEx_WriteBlocksDMAMultiBuffer(SD_HandleTypeDef *hsd, uint32_t BlockAdd, uint32_t NumberOfBlocks) 00196 { 00197 SDMMC_DataInitTypeDef config; 00198 uint32_t errorstate; 00199 uint32_t DmaBase0_reg; 00200 uint32_t DmaBase1_reg; 00201 uint32_t add = BlockAdd; 00202 00203 if (hsd->State == HAL_SD_STATE_READY) 00204 { 00205 if ((add + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr)) 00206 { 00207 hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE; 00208 return HAL_ERROR; 00209 } 00210 00211 DmaBase0_reg = hsd->Instance->IDMABASE0; 00212 DmaBase1_reg = hsd->Instance->IDMABASE1; 00213 if ((hsd->Instance->IDMABSIZE == 0U) || (DmaBase0_reg == 0U) || (DmaBase1_reg == 0U)) 00214 { 00215 hsd->ErrorCode = HAL_SD_ERROR_ADDR_OUT_OF_RANGE; 00216 return HAL_ERROR; 00217 } 00218 00219 /* Initialize data control register */ 00220 hsd->Instance->DCTRL = 0; 00221 00222 hsd->ErrorCode = HAL_SD_ERROR_NONE; 00223 00224 hsd->State = HAL_SD_STATE_BUSY; 00225 00226 if (hsd->SdCard.CardType != CARD_SDHC_SDXC) 00227 { 00228 add *= 512U; 00229 } 00230 00231 /* Configure the SD DPSM (Data Path State Machine) */ 00232 config.DataTimeOut = SDMMC_DATATIMEOUT; 00233 config.DataLength = BLOCKSIZE * NumberOfBlocks; 00234 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; 00235 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD; 00236 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; 00237 config.DPSM = SDMMC_DPSM_DISABLE; 00238 (void)SDMMC_ConfigData(hsd->Instance, &config); 00239 00240 __SDMMC_CMDTRANS_ENABLE(hsd->Instance); 00241 00242 hsd->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_DOUBLE_BUFF0; 00243 00244 /* Write Blocks in DMA mode */ 00245 hsd->Context = (SD_CONTEXT_WRITE_MULTIPLE_BLOCK | SD_CONTEXT_DMA); 00246 00247 /* Write Multi Block command */ 00248 errorstate = SDMMC_CmdWriteMultiBlock(hsd->Instance, add); 00249 if (errorstate != HAL_SD_ERROR_NONE) 00250 { 00251 hsd->State = HAL_SD_STATE_READY; 00252 hsd->ErrorCode |= errorstate; 00253 return HAL_ERROR; 00254 } 00255 00256 __HAL_SD_ENABLE_IT(hsd, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND | 00257 SDMMC_IT_IDMABTC)); 00258 00259 return HAL_OK; 00260 } 00261 else 00262 { 00263 return HAL_BUSY; 00264 } 00265 } 00266 00267 00268 /** 00269 * @brief Change the DMA Buffer0 or Buffer1 address on the fly. 00270 * @param hsd: pointer to a SD_HandleTypeDef structure. 00271 * @param Buffer: the buffer to be changed, This parameter can be one of 00272 * the following values: SD_DMA_BUFFER0 or SD_DMA_BUFFER1 00273 * @param pDataBuffer: The new address 00274 * @note The BUFFER0 address can be changed only when the current transfer use 00275 * BUFFER1 and the BUFFER1 address can be changed only when the current 00276 * transfer use BUFFER0. 00277 * @retval HAL status 00278 */ 00279 HAL_StatusTypeDef HAL_SDEx_ChangeDMABuffer(SD_HandleTypeDef *hsd, HAL_SDEx_DMABuffer_MemoryTypeDef Buffer, 00280 uint32_t *pDataBuffer) 00281 { 00282 if (Buffer == SD_DMA_BUFFER0) 00283 { 00284 /* change the buffer0 address */ 00285 hsd->Instance->IDMABASE0 = (uint32_t)pDataBuffer; 00286 } 00287 else 00288 { 00289 /* change the memory1 address */ 00290 hsd->Instance->IDMABASE1 = (uint32_t)pDataBuffer; 00291 } 00292 00293 return HAL_OK; 00294 } 00295 00296 00297 /** 00298 * @} 00299 */ 00300 00301 /** 00302 * @} 00303 */ 00304 00305 #endif /* HAL_SD_MODULE_ENABLED */ 00306 00307 /** 00308 * @} 00309 */ 00310 00311 /** 00312 * @} 00313 */