STM32L443xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l4xx_hal_mmc_ex.c 00004 * @author MCD Application Team 00005 * @brief MMC card Extended HAL module driver. 00006 * This file provides firmware functions to manage the following 00007 * functionalities of the Secure Digital (MMC) 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 MMC Extension HAL driver can be used as follows: 00027 (+) Configure Buffer0 and Buffer1 start address and Buffer size using HAL_MMCEx_ConfigDMAMultiBuffer() function. 00028 00029 (+) Start Read and Write for multibuffer mode using HAL_MMCEx_ReadBlocksDMAMultiBuffer() and HAL_MMCEx_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 MMCEx MMCEx 00045 * @brief MMC Extended HAL module driver 00046 * @{ 00047 */ 00048 00049 #ifdef HAL_MMC_MODULE_ENABLED 00050 00051 /* Private typedef -----------------------------------------------------------*/ 00052 /* Private define ------------------------------------------------------------*/ 00053 /* Private macro -------------------------------------------------------------*/ 00054 /* Private variables ---------------------------------------------------------*/ 00055 /* Private function prototypes -----------------------------------------------*/ 00056 /* Private functions ---------------------------------------------------------*/ 00057 /* Exported functions --------------------------------------------------------*/ 00058 /** @defgroup MMCEx_Exported_Types MMCEx Exported Types 00059 * @{ 00060 */ 00061 00062 /** @defgroup MMCEx_Exported_Types_Group1 MMC Internal DMA Buffer structure 00063 * @brief Multibuffer functions 00064 * 00065 @verbatim 00066 ============================================================================== 00067 ##### Multibuffer functions ##### 00068 ============================================================================== 00069 [..] 00070 This section provides functions allowing to configure the multibuffer mode and start read and write 00071 multibuffer mode for MMC HAL driver. 00072 00073 @endverbatim 00074 * @{ 00075 */ 00076 00077 /** 00078 * @brief Configure DMA Dual Buffer mode. The Data transfer is managed by an Internal DMA. 00079 * @param hmmc MMC handle 00080 * @param pDataBuffer0 Pointer to the buffer0 that will contain/receive the transfered data 00081 * @param pDataBuffer1 Pointer to the buffer1 that will contain/receive the transfered data 00082 * @param BufferSize Size of Buffer0 in Blocks. Buffer0 and Buffer1 must have the same size. 00083 * @retval HAL status 00084 */ 00085 HAL_StatusTypeDef HAL_MMCEx_ConfigDMAMultiBuffer(MMC_HandleTypeDef *hmmc, uint32_t * pDataBuffer0, uint32_t * pDataBuffer1, uint32_t BufferSize) 00086 { 00087 if(hmmc->State == HAL_MMC_STATE_READY) 00088 { 00089 hmmc->Instance->IDMABASE0= (uint32_t) pDataBuffer0 ; 00090 hmmc->Instance->IDMABASE1= (uint32_t) pDataBuffer1 ; 00091 hmmc->Instance->IDMABSIZE= (uint32_t) (MMC_BLOCKSIZE * BufferSize); 00092 00093 return HAL_OK; 00094 } 00095 else 00096 { 00097 return HAL_BUSY; 00098 } 00099 } 00100 00101 /** 00102 * @brief Reads block(s) from a specified address in a card. The received Data will be stored in Buffer0 and Buffer1. 00103 * Buffer0, Buffer1 and BufferSize need to be configured by function HAL_MMCEx_ConfigDMAMultiBuffer before call this function. 00104 * @param hmmc MMC 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_MMCEx_ReadBlocksDMAMultiBuffer(MMC_HandleTypeDef *hmmc, uint32_t BlockAdd, uint32_t NumberOfBlocks) 00110 { 00111 SDMMC_DataInitTypeDef config; 00112 uint32_t DmaBase0_reg, DmaBase1_reg; 00113 uint32_t errorstate; 00114 uint32_t add = BlockAdd; 00115 00116 if(hmmc->State == HAL_MMC_STATE_READY) 00117 { 00118 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr)) 00119 { 00120 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; 00121 return HAL_ERROR; 00122 } 00123 00124 DmaBase0_reg = hmmc->Instance->IDMABASE0; 00125 DmaBase1_reg = hmmc->Instance->IDMABASE1; 00126 if ((hmmc->Instance->IDMABSIZE == 0U) || (DmaBase0_reg == 0U) || (DmaBase1_reg == 0U)) 00127 { 00128 hmmc->ErrorCode = HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; 00129 return HAL_ERROR; 00130 } 00131 00132 /* Initialize data control register */ 00133 hmmc->Instance->DCTRL = 0; 00134 00135 hmmc->ErrorCode = HAL_MMC_ERROR_NONE; 00136 hmmc->State = HAL_MMC_STATE_BUSY; 00137 00138 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD) 00139 { 00140 add *= 512U; 00141 } 00142 00143 /* Configure the MMC DPSM (Data Path State Machine) */ 00144 config.DataTimeOut = SDMMC_DATATIMEOUT; 00145 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks; 00146 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; 00147 config.TransferDir = SDMMC_TRANSFER_DIR_TO_SDMMC; 00148 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; 00149 config.DPSM = SDMMC_DPSM_DISABLE; 00150 (void)SDMMC_ConfigData(hmmc->Instance, &config); 00151 00152 hmmc->Instance->DCTRL |= SDMMC_DCTRL_FIFORST; 00153 00154 __SDMMC_CMDTRANS_ENABLE( hmmc->Instance); 00155 00156 hmmc->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_DOUBLE_BUFF0; 00157 00158 /* Read Blocks in DMA mode */ 00159 hmmc->Context = (MMC_CONTEXT_READ_MULTIPLE_BLOCK | MMC_CONTEXT_DMA); 00160 00161 /* Read Multi Block command */ 00162 errorstate = SDMMC_CmdReadMultiBlock(hmmc->Instance, add); 00163 if(errorstate != HAL_MMC_ERROR_NONE) 00164 { 00165 hmmc->State = HAL_MMC_STATE_READY; 00166 hmmc->ErrorCode |= errorstate; 00167 return HAL_ERROR; 00168 } 00169 00170 __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_RXOVERR | SDMMC_IT_DATAEND | SDMMC_FLAG_IDMATE | SDMMC_FLAG_IDMABTC)); 00171 00172 return HAL_OK; 00173 } 00174 else 00175 { 00176 return HAL_BUSY; 00177 } 00178 00179 } 00180 00181 /** 00182 * @brief Write block(s) to a specified address in a card. The transfered Data are stored in Buffer0 and Buffer1. 00183 * Buffer0, Buffer1 and BufferSize need to be configured by function HAL_MMCEx_ConfigDMAMultiBuffer before call this function. 00184 * @param hmmc MMC handle 00185 * @param BlockAdd Block Address from where data is to be read 00186 * @param NumberOfBlocks Total number of blocks to read 00187 * @retval HAL status 00188 */ 00189 HAL_StatusTypeDef HAL_MMCEx_WriteBlocksDMAMultiBuffer(MMC_HandleTypeDef *hmmc, uint32_t BlockAdd, uint32_t NumberOfBlocks) 00190 { 00191 SDMMC_DataInitTypeDef config; 00192 uint32_t errorstate; 00193 uint32_t DmaBase0_reg, DmaBase1_reg; 00194 uint32_t add = BlockAdd; 00195 00196 if(hmmc->State == HAL_MMC_STATE_READY) 00197 { 00198 if((BlockAdd + NumberOfBlocks) > (hmmc->MmcCard.LogBlockNbr)) 00199 { 00200 hmmc->ErrorCode |= HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; 00201 return HAL_ERROR; 00202 } 00203 00204 DmaBase0_reg = hmmc->Instance->IDMABASE0; 00205 DmaBase1_reg = hmmc->Instance->IDMABASE1; 00206 if ((hmmc->Instance->IDMABSIZE == 0U) || (DmaBase0_reg == 0U) || (DmaBase1_reg == 0U)) 00207 { 00208 hmmc->ErrorCode = HAL_MMC_ERROR_ADDR_OUT_OF_RANGE; 00209 return HAL_ERROR; 00210 } 00211 00212 /* Initialize data control register */ 00213 hmmc->Instance->DCTRL = 0; 00214 00215 hmmc->ErrorCode = HAL_MMC_ERROR_NONE; 00216 00217 hmmc->State = HAL_MMC_STATE_BUSY; 00218 00219 if ((hmmc->MmcCard.CardType) != MMC_HIGH_CAPACITY_CARD) 00220 { 00221 add *= 512U; 00222 } 00223 00224 /* Configure the MMC DPSM (Data Path State Machine) */ 00225 config.DataTimeOut = SDMMC_DATATIMEOUT; 00226 config.DataLength = MMC_BLOCKSIZE * NumberOfBlocks; 00227 config.DataBlockSize = SDMMC_DATABLOCK_SIZE_512B; 00228 config.TransferDir = SDMMC_TRANSFER_DIR_TO_CARD; 00229 config.TransferMode = SDMMC_TRANSFER_MODE_BLOCK; 00230 config.DPSM = SDMMC_DPSM_DISABLE; 00231 (void)SDMMC_ConfigData(hmmc->Instance, &config); 00232 00233 __SDMMC_CMDTRANS_ENABLE( hmmc->Instance); 00234 00235 hmmc->Instance->IDMACTRL = SDMMC_ENABLE_IDMA_DOUBLE_BUFF0; 00236 00237 /* Write Blocks in DMA mode */ 00238 hmmc->Context = (MMC_CONTEXT_WRITE_MULTIPLE_BLOCK | MMC_CONTEXT_DMA); 00239 00240 /* Write Multi Block command */ 00241 errorstate = SDMMC_CmdWriteMultiBlock(hmmc->Instance, add); 00242 if(errorstate != HAL_MMC_ERROR_NONE) 00243 { 00244 hmmc->State = HAL_MMC_STATE_READY; 00245 hmmc->ErrorCode |= errorstate; 00246 return HAL_ERROR; 00247 } 00248 00249 __HAL_MMC_ENABLE_IT(hmmc, (SDMMC_IT_DCRCFAIL | SDMMC_IT_DTIMEOUT | SDMMC_IT_TXUNDERR | SDMMC_IT_DATAEND | SDMMC_FLAG_IDMATE | SDMMC_FLAG_IDMABTC)); 00250 00251 return HAL_OK; 00252 } 00253 else 00254 { 00255 return HAL_BUSY; 00256 } 00257 } 00258 00259 00260 /** 00261 * @brief Change the DMA Buffer0 or Buffer1 address on the fly. 00262 * @param hmmc pointer to a MMC_HandleTypeDef structure. 00263 * @param Buffer the buffer to be changed, This parameter can be one of 00264 * the following values: MMC_DMA_BUFFER0 or MMC_DMA_BUFFER1 00265 * @param pDataBuffer The new address 00266 * @note The BUFFER0 address can be changed only when the current transfer use 00267 * BUFFER1 and the BUFFER1 address can be changed only when the current 00268 * transfer use BUFFER0. 00269 * @retval HAL status 00270 */ 00271 HAL_StatusTypeDef HAL_MMCEx_ChangeDMABuffer(MMC_HandleTypeDef *hmmc, HAL_MMCEx_DMABuffer_MemoryTypeDef Buffer, uint32_t *pDataBuffer) 00272 { 00273 if(Buffer == MMC_DMA_BUFFER0) 00274 { 00275 /* change the buffer0 address */ 00276 hmmc->Instance->IDMABASE0 = (uint32_t)pDataBuffer; 00277 } 00278 else 00279 { 00280 /* change the memory1 address */ 00281 hmmc->Instance->IDMABASE1 = (uint32_t)pDataBuffer; 00282 } 00283 00284 return HAL_OK; 00285 } 00286 00287 /** 00288 * @brief Read DMA Buffer 0 Transfer completed callbacks 00289 * @param hmmc MMC handle 00290 * @retval None 00291 */ 00292 __weak void HAL_MMCEx_Read_DMADoubleBuffer0CpltCallback(MMC_HandleTypeDef *hmmc) 00293 { 00294 /* Prevent unused argument(s) compilation warning */ 00295 UNUSED(hmmc); 00296 00297 /* NOTE : This function should not be modified, when the callback is needed, 00298 the HAL_MMCEx_Read_DMADoubleBuffer0CpltCallback can be implemented in the user file 00299 */ 00300 } 00301 00302 /** 00303 * @brief Read DMA Buffer 1 Transfer completed callbacks 00304 * @param hmmc MMC handle 00305 * @retval None 00306 */ 00307 __weak void HAL_MMCEx_Read_DMADoubleBuffer1CpltCallback(MMC_HandleTypeDef *hmmc) 00308 { 00309 /* Prevent unused argument(s) compilation warning */ 00310 UNUSED(hmmc); 00311 00312 /* NOTE : This function should not be modified, when the callback is needed, 00313 the HAL_MMCEx_Read_DMADoubleBuffer1CpltCallback can be implemented in the user file 00314 */ 00315 } 00316 00317 /** 00318 * @brief Write DMA Buffer 0 Transfer completed callbacks 00319 * @param hmmc MMC handle 00320 * @retval None 00321 */ 00322 __weak void HAL_MMCEx_Write_DMADoubleBuffer0CpltCallback(MMC_HandleTypeDef *hmmc) 00323 { 00324 /* Prevent unused argument(s) compilation warning */ 00325 UNUSED(hmmc); 00326 00327 /* NOTE : This function should not be modified, when the callback is needed, 00328 the HAL_MMCEx_Write_DMADoubleBuffer0CpltCallback can be implemented in the user file 00329 */ 00330 } 00331 00332 /** 00333 * @brief Write DMA Buffer 1 Transfer completed callbacks 00334 * @param hmmc MMC handle 00335 * @retval None 00336 */ 00337 __weak void HAL_MMCEx_Write_DMADoubleBuffer1CpltCallback(MMC_HandleTypeDef *hmmc) 00338 { 00339 /* Prevent unused argument(s) compilation warning */ 00340 UNUSED(hmmc); 00341 00342 /* NOTE : This function should not be modified, when the callback is needed, 00343 the HAL_MMCEx_Write_DMADoubleBuffer0CpltCallback can be implemented in the user file 00344 */ 00345 } 00346 00347 /** 00348 * @} 00349 */ 00350 00351 /** 00352 * @} 00353 */ 00354 00355 #endif /* HAL_MMC_MODULE_ENABLED */ 00356 00357 /** 00358 * @} 00359 */ 00360 00361 /** 00362 * @} 00363 */ 00364 00365 #endif /* STM32L4P5xx || STM32L4Q5xx || STM32L4R5xx || STM32L4R7xx || STM32L4R9xx || STM32L4S5xx || STM32L4S7xx || STM32L4S9xx */