STM32L443xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32l4xx_ll_dma.c 00004 * @author MCD Application Team 00005 * @brief DMA LL module driver. 00006 ****************************************************************************** 00007 * @attention 00008 * 00009 * Copyright (c) 2017 STMicroelectronics. 00010 * All rights reserved. 00011 * 00012 * This software is licensed under terms that can be found in the LICENSE file 00013 * in the root directory of this software component. 00014 * If no LICENSE file comes with this software, it is provided AS-IS. 00015 * 00016 ****************************************************************************** 00017 */ 00018 #if defined(USE_FULL_LL_DRIVER) 00019 00020 /* Includes ------------------------------------------------------------------*/ 00021 #include "stm32l4xx_ll_dma.h" 00022 #include "stm32l4xx_ll_bus.h" 00023 #ifdef USE_FULL_ASSERT 00024 #include "stm32_assert.h" 00025 #else 00026 #define assert_param(expr) ((void)0U) 00027 #endif 00028 00029 /** @addtogroup STM32L4xx_LL_Driver 00030 * @{ 00031 */ 00032 00033 #if defined (DMA1) || defined (DMA2) 00034 00035 /** @defgroup DMA_LL DMA 00036 * @{ 00037 */ 00038 00039 /* Private types -------------------------------------------------------------*/ 00040 /* Private variables ---------------------------------------------------------*/ 00041 /* Private constants ---------------------------------------------------------*/ 00042 /* Private macros ------------------------------------------------------------*/ 00043 /** @addtogroup DMA_LL_Private_Macros 00044 * @{ 00045 */ 00046 #define IS_LL_DMA_DIRECTION(__VALUE__) (((__VALUE__) == LL_DMA_DIRECTION_PERIPH_TO_MEMORY) || \ 00047 ((__VALUE__) == LL_DMA_DIRECTION_MEMORY_TO_PERIPH) || \ 00048 ((__VALUE__) == LL_DMA_DIRECTION_MEMORY_TO_MEMORY)) 00049 00050 #define IS_LL_DMA_MODE(__VALUE__) (((__VALUE__) == LL_DMA_MODE_NORMAL) || \ 00051 ((__VALUE__) == LL_DMA_MODE_CIRCULAR)) 00052 00053 #define IS_LL_DMA_PERIPHINCMODE(__VALUE__) (((__VALUE__) == LL_DMA_PERIPH_INCREMENT) || \ 00054 ((__VALUE__) == LL_DMA_PERIPH_NOINCREMENT)) 00055 00056 #define IS_LL_DMA_MEMORYINCMODE(__VALUE__) (((__VALUE__) == LL_DMA_MEMORY_INCREMENT) || \ 00057 ((__VALUE__) == LL_DMA_MEMORY_NOINCREMENT)) 00058 00059 #define IS_LL_DMA_PERIPHDATASIZE(__VALUE__) (((__VALUE__) == LL_DMA_PDATAALIGN_BYTE) || \ 00060 ((__VALUE__) == LL_DMA_PDATAALIGN_HALFWORD) || \ 00061 ((__VALUE__) == LL_DMA_PDATAALIGN_WORD)) 00062 00063 #define IS_LL_DMA_MEMORYDATASIZE(__VALUE__) (((__VALUE__) == LL_DMA_MDATAALIGN_BYTE) || \ 00064 ((__VALUE__) == LL_DMA_MDATAALIGN_HALFWORD) || \ 00065 ((__VALUE__) == LL_DMA_MDATAALIGN_WORD)) 00066 00067 #define IS_LL_DMA_NBDATA(__VALUE__) ((__VALUE__) <= 0x0000FFFFU) 00068 00069 #if defined(DMAMUX1) 00070 #define IS_LL_DMA_PERIPHREQUEST(__VALUE__) ((__VALUE__) <= 93U) 00071 #else 00072 #define IS_LL_DMA_PERIPHREQUEST(__VALUE__) (((__VALUE__) == LL_DMA_REQUEST_0) || \ 00073 ((__VALUE__) == LL_DMA_REQUEST_1) || \ 00074 ((__VALUE__) == LL_DMA_REQUEST_2) || \ 00075 ((__VALUE__) == LL_DMA_REQUEST_3) || \ 00076 ((__VALUE__) == LL_DMA_REQUEST_4) || \ 00077 ((__VALUE__) == LL_DMA_REQUEST_5) || \ 00078 ((__VALUE__) == LL_DMA_REQUEST_6) || \ 00079 ((__VALUE__) == LL_DMA_REQUEST_7)) 00080 #endif /* DMAMUX1 */ 00081 00082 #define IS_LL_DMA_PRIORITY(__VALUE__) (((__VALUE__) == LL_DMA_PRIORITY_LOW) || \ 00083 ((__VALUE__) == LL_DMA_PRIORITY_MEDIUM) || \ 00084 ((__VALUE__) == LL_DMA_PRIORITY_HIGH) || \ 00085 ((__VALUE__) == LL_DMA_PRIORITY_VERYHIGH)) 00086 00087 #if defined (DMA2) 00088 #if defined (DMA2_Channel6) && defined (DMA2_Channel7) 00089 #define IS_LL_DMA_ALL_CHANNEL_INSTANCE(INSTANCE, CHANNEL) ((((INSTANCE) == DMA1) && \ 00090 (((CHANNEL) == LL_DMA_CHANNEL_1) || \ 00091 ((CHANNEL) == LL_DMA_CHANNEL_2) || \ 00092 ((CHANNEL) == LL_DMA_CHANNEL_3) || \ 00093 ((CHANNEL) == LL_DMA_CHANNEL_4) || \ 00094 ((CHANNEL) == LL_DMA_CHANNEL_5) || \ 00095 ((CHANNEL) == LL_DMA_CHANNEL_6) || \ 00096 ((CHANNEL) == LL_DMA_CHANNEL_7))) || \ 00097 (((INSTANCE) == DMA2) && \ 00098 (((CHANNEL) == LL_DMA_CHANNEL_1) || \ 00099 ((CHANNEL) == LL_DMA_CHANNEL_2) || \ 00100 ((CHANNEL) == LL_DMA_CHANNEL_3) || \ 00101 ((CHANNEL) == LL_DMA_CHANNEL_4) || \ 00102 ((CHANNEL) == LL_DMA_CHANNEL_5) || \ 00103 ((CHANNEL) == LL_DMA_CHANNEL_6) || \ 00104 ((CHANNEL) == LL_DMA_CHANNEL_7)))) 00105 #else 00106 #define IS_LL_DMA_ALL_CHANNEL_INSTANCE(INSTANCE, CHANNEL) ((((INSTANCE) == DMA1) && \ 00107 (((CHANNEL) == LL_DMA_CHANNEL_1) || \ 00108 ((CHANNEL) == LL_DMA_CHANNEL_2) || \ 00109 ((CHANNEL) == LL_DMA_CHANNEL_3) || \ 00110 ((CHANNEL) == LL_DMA_CHANNEL_4) || \ 00111 ((CHANNEL) == LL_DMA_CHANNEL_5) || \ 00112 ((CHANNEL) == LL_DMA_CHANNEL_6) || \ 00113 ((CHANNEL) == LL_DMA_CHANNEL_7))) || \ 00114 (((INSTANCE) == DMA2) && \ 00115 (((CHANNEL) == LL_DMA_CHANNEL_1) || \ 00116 ((CHANNEL) == LL_DMA_CHANNEL_2) || \ 00117 ((CHANNEL) == LL_DMA_CHANNEL_3) || \ 00118 ((CHANNEL) == LL_DMA_CHANNEL_4) || \ 00119 ((CHANNEL) == LL_DMA_CHANNEL_5)))) 00120 #endif 00121 #else 00122 #define IS_LL_DMA_ALL_CHANNEL_INSTANCE(INSTANCE, CHANNEL) ((((INSTANCE) == DMA1) && \ 00123 (((CHANNEL) == LL_DMA_CHANNEL_1)|| \ 00124 ((CHANNEL) == LL_DMA_CHANNEL_2) || \ 00125 ((CHANNEL) == LL_DMA_CHANNEL_3) || \ 00126 ((CHANNEL) == LL_DMA_CHANNEL_4) || \ 00127 ((CHANNEL) == LL_DMA_CHANNEL_5) || \ 00128 ((CHANNEL) == LL_DMA_CHANNEL_6) || \ 00129 ((CHANNEL) == LL_DMA_CHANNEL_7)))) 00130 #endif 00131 /** 00132 * @} 00133 */ 00134 00135 /* Private function prototypes -----------------------------------------------*/ 00136 00137 /* Exported functions --------------------------------------------------------*/ 00138 /** @addtogroup DMA_LL_Exported_Functions 00139 * @{ 00140 */ 00141 00142 /** @addtogroup DMA_LL_EF_Init 00143 * @{ 00144 */ 00145 00146 /** 00147 * @brief De-initialize the DMA registers to their default reset values. 00148 * @param DMAx DMAx Instance 00149 * @param Channel This parameter can be one of the following values: 00150 * @arg @ref LL_DMA_CHANNEL_1 00151 * @arg @ref LL_DMA_CHANNEL_2 00152 * @arg @ref LL_DMA_CHANNEL_3 00153 * @arg @ref LL_DMA_CHANNEL_4 00154 * @arg @ref LL_DMA_CHANNEL_5 00155 * @arg @ref LL_DMA_CHANNEL_6 00156 * @arg @ref LL_DMA_CHANNEL_7 00157 * @arg @ref LL_DMA_CHANNEL_ALL 00158 * @retval An ErrorStatus enumeration value: 00159 * - SUCCESS: DMA registers are de-initialized 00160 * - ERROR: DMA registers are not de-initialized 00161 */ 00162 ErrorStatus LL_DMA_DeInit(DMA_TypeDef *DMAx, uint32_t Channel) 00163 { 00164 ErrorStatus status = SUCCESS; 00165 DMA_Channel_TypeDef *tmp; 00166 00167 /* Check the DMA Instance DMAx and Channel parameters*/ 00168 assert_param(IS_LL_DMA_ALL_CHANNEL_INSTANCE(DMAx, Channel) || (Channel == LL_DMA_CHANNEL_ALL)); 00169 00170 if (Channel == LL_DMA_CHANNEL_ALL) 00171 { 00172 if (DMAx == DMA1) 00173 { 00174 /* Force reset of DMA clock */ 00175 LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_DMA1); 00176 00177 /* Release reset of DMA clock */ 00178 LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_DMA1); 00179 } 00180 #if defined(DMA2) 00181 else if (DMAx == DMA2) 00182 { 00183 /* Force reset of DMA clock */ 00184 LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_DMA2); 00185 00186 /* Release reset of DMA clock */ 00187 LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_DMA2); 00188 } 00189 #endif 00190 else 00191 { 00192 status = ERROR; 00193 } 00194 } 00195 else 00196 { 00197 tmp = (DMA_Channel_TypeDef *)(__LL_DMA_GET_CHANNEL_INSTANCE(DMAx, Channel)); 00198 00199 /* Disable the selected DMAx_Channely */ 00200 CLEAR_BIT(tmp->CCR, DMA_CCR_EN); 00201 00202 /* Reset DMAx_Channely control register */ 00203 WRITE_REG(tmp->CCR, 0U); 00204 00205 /* Reset DMAx_Channely remaining bytes register */ 00206 WRITE_REG(tmp->CNDTR, 0U); 00207 00208 /* Reset DMAx_Channely peripheral address register */ 00209 WRITE_REG(tmp->CPAR, 0U); 00210 00211 /* Reset DMAx_Channely memory 0 address register */ 00212 WRITE_REG(tmp->CMAR, 0U); 00213 00214 #if defined(DMAMUX1) 00215 /* Reset Request register field for DMAx Channel */ 00216 LL_DMA_SetPeriphRequest(DMAx, Channel, LL_DMAMUX_REQ_MEM2MEM); 00217 #else 00218 /* Reset Request register field for DMAx Channel */ 00219 LL_DMA_SetPeriphRequest(DMAx, Channel, LL_DMA_REQUEST_0); 00220 #endif /* DMAMUX1 */ 00221 00222 if (Channel == LL_DMA_CHANNEL_1) 00223 { 00224 /* Reset interrupt pending bits for DMAx Channel1 */ 00225 LL_DMA_ClearFlag_GI1(DMAx); 00226 } 00227 else if (Channel == LL_DMA_CHANNEL_2) 00228 { 00229 /* Reset interrupt pending bits for DMAx Channel2 */ 00230 LL_DMA_ClearFlag_GI2(DMAx); 00231 } 00232 else if (Channel == LL_DMA_CHANNEL_3) 00233 { 00234 /* Reset interrupt pending bits for DMAx Channel3 */ 00235 LL_DMA_ClearFlag_GI3(DMAx); 00236 } 00237 else if (Channel == LL_DMA_CHANNEL_4) 00238 { 00239 /* Reset interrupt pending bits for DMAx Channel4 */ 00240 LL_DMA_ClearFlag_GI4(DMAx); 00241 } 00242 else if (Channel == LL_DMA_CHANNEL_5) 00243 { 00244 /* Reset interrupt pending bits for DMAx Channel5 */ 00245 LL_DMA_ClearFlag_GI5(DMAx); 00246 } 00247 00248 else if (Channel == LL_DMA_CHANNEL_6) 00249 { 00250 /* Reset interrupt pending bits for DMAx Channel6 */ 00251 LL_DMA_ClearFlag_GI6(DMAx); 00252 } 00253 else if (Channel == LL_DMA_CHANNEL_7) 00254 { 00255 /* Reset interrupt pending bits for DMAx Channel7 */ 00256 LL_DMA_ClearFlag_GI7(DMAx); 00257 } 00258 else 00259 { 00260 status = ERROR; 00261 } 00262 } 00263 00264 return status; 00265 } 00266 00267 /** 00268 * @brief Initialize the DMA registers according to the specified parameters in DMA_InitStruct. 00269 * @note To convert DMAx_Channely Instance to DMAx Instance and Channely, use helper macros : 00270 * @arg @ref __LL_DMA_GET_INSTANCE 00271 * @arg @ref __LL_DMA_GET_CHANNEL 00272 * @param DMAx DMAx Instance 00273 * @param Channel This parameter can be one of the following values: 00274 * @arg @ref LL_DMA_CHANNEL_1 00275 * @arg @ref LL_DMA_CHANNEL_2 00276 * @arg @ref LL_DMA_CHANNEL_3 00277 * @arg @ref LL_DMA_CHANNEL_4 00278 * @arg @ref LL_DMA_CHANNEL_5 00279 * @arg @ref LL_DMA_CHANNEL_6 00280 * @arg @ref LL_DMA_CHANNEL_7 00281 * @param DMA_InitStruct pointer to a @ref LL_DMA_InitTypeDef structure. 00282 * @retval An ErrorStatus enumeration value: 00283 * - SUCCESS: DMA registers are initialized 00284 * - ERROR: Not applicable 00285 */ 00286 ErrorStatus LL_DMA_Init(DMA_TypeDef *DMAx, uint32_t Channel, LL_DMA_InitTypeDef *DMA_InitStruct) 00287 { 00288 /* Check the DMA Instance DMAx and Channel parameters*/ 00289 assert_param(IS_LL_DMA_ALL_CHANNEL_INSTANCE(DMAx, Channel)); 00290 00291 /* Check the DMA parameters from DMA_InitStruct */ 00292 assert_param(IS_LL_DMA_DIRECTION(DMA_InitStruct->Direction)); 00293 assert_param(IS_LL_DMA_MODE(DMA_InitStruct->Mode)); 00294 assert_param(IS_LL_DMA_PERIPHINCMODE(DMA_InitStruct->PeriphOrM2MSrcIncMode)); 00295 assert_param(IS_LL_DMA_MEMORYINCMODE(DMA_InitStruct->MemoryOrM2MDstIncMode)); 00296 assert_param(IS_LL_DMA_PERIPHDATASIZE(DMA_InitStruct->PeriphOrM2MSrcDataSize)); 00297 assert_param(IS_LL_DMA_MEMORYDATASIZE(DMA_InitStruct->MemoryOrM2MDstDataSize)); 00298 assert_param(IS_LL_DMA_NBDATA(DMA_InitStruct->NbData)); 00299 assert_param(IS_LL_DMA_PERIPHREQUEST(DMA_InitStruct->PeriphRequest)); 00300 assert_param(IS_LL_DMA_PRIORITY(DMA_InitStruct->Priority)); 00301 00302 /*---------------------------- DMAx CCR Configuration ------------------------ 00303 * Configure DMAx_Channely: data transfer direction, data transfer mode, 00304 * peripheral and memory increment mode, 00305 * data size alignment and priority level with parameters : 00306 * - Direction: DMA_CCR_DIR and DMA_CCR_MEM2MEM bits 00307 * - Mode: DMA_CCR_CIRC bit 00308 * - PeriphOrM2MSrcIncMode: DMA_CCR_PINC bit 00309 * - MemoryOrM2MDstIncMode: DMA_CCR_MINC bit 00310 * - PeriphOrM2MSrcDataSize: DMA_CCR_PSIZE[1:0] bits 00311 * - MemoryOrM2MDstDataSize: DMA_CCR_MSIZE[1:0] bits 00312 * - Priority: DMA_CCR_PL[1:0] bits 00313 */ 00314 LL_DMA_ConfigTransfer(DMAx, Channel, DMA_InitStruct->Direction | \ 00315 DMA_InitStruct->Mode | \ 00316 DMA_InitStruct->PeriphOrM2MSrcIncMode | \ 00317 DMA_InitStruct->MemoryOrM2MDstIncMode | \ 00318 DMA_InitStruct->PeriphOrM2MSrcDataSize | \ 00319 DMA_InitStruct->MemoryOrM2MDstDataSize | \ 00320 DMA_InitStruct->Priority); 00321 00322 /*-------------------------- DMAx CMAR Configuration ------------------------- 00323 * Configure the memory or destination base address with parameter : 00324 * - MemoryOrM2MDstAddress: DMA_CMAR_MA[31:0] bits 00325 */ 00326 LL_DMA_SetMemoryAddress(DMAx, Channel, DMA_InitStruct->MemoryOrM2MDstAddress); 00327 00328 /*-------------------------- DMAx CPAR Configuration ------------------------- 00329 * Configure the peripheral or source base address with parameter : 00330 * - PeriphOrM2MSrcAddress: DMA_CPAR_PA[31:0] bits 00331 */ 00332 LL_DMA_SetPeriphAddress(DMAx, Channel, DMA_InitStruct->PeriphOrM2MSrcAddress); 00333 00334 /*--------------------------- DMAx CNDTR Configuration ----------------------- 00335 * Configure the peripheral base address with parameter : 00336 * - NbData: DMA_CNDTR_NDT[15:0] bits 00337 */ 00338 LL_DMA_SetDataLength(DMAx, Channel, DMA_InitStruct->NbData); 00339 00340 #if defined(DMAMUX1) 00341 /*--------------------------- DMAMUXx CCR Configuration ---------------------- 00342 * Configure the DMA request for DMA Channels on DMAMUX Channel x with parameter : 00343 * - PeriphRequest: DMA_CxCR[7:0] bits 00344 */ 00345 LL_DMA_SetPeriphRequest(DMAx, Channel, DMA_InitStruct->PeriphRequest); 00346 #else 00347 /*--------------------------- DMAx CSELR Configuration ----------------------- 00348 * Configure the DMA request for DMA instance on Channel x with parameter : 00349 * - PeriphRequest: DMA_CSELR[31:0] bits 00350 */ 00351 LL_DMA_SetPeriphRequest(DMAx, Channel, DMA_InitStruct->PeriphRequest); 00352 #endif /* DMAMUX1 */ 00353 00354 return SUCCESS; 00355 } 00356 00357 /** 00358 * @brief Set each @ref LL_DMA_InitTypeDef field to default value. 00359 * @param DMA_InitStruct Pointer to a @ref LL_DMA_InitTypeDef structure. 00360 * @retval None 00361 */ 00362 void LL_DMA_StructInit(LL_DMA_InitTypeDef *DMA_InitStruct) 00363 { 00364 /* Set DMA_InitStruct fields to default values */ 00365 DMA_InitStruct->PeriphOrM2MSrcAddress = 0x00000000U; 00366 DMA_InitStruct->MemoryOrM2MDstAddress = 0x00000000U; 00367 DMA_InitStruct->Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY; 00368 DMA_InitStruct->Mode = LL_DMA_MODE_NORMAL; 00369 DMA_InitStruct->PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT; 00370 DMA_InitStruct->MemoryOrM2MDstIncMode = LL_DMA_MEMORY_NOINCREMENT; 00371 DMA_InitStruct->PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_BYTE; 00372 DMA_InitStruct->MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_BYTE; 00373 DMA_InitStruct->NbData = 0x00000000U; 00374 #if defined(DMAMUX1) 00375 DMA_InitStruct->PeriphRequest = LL_DMAMUX_REQ_MEM2MEM; 00376 #else 00377 DMA_InitStruct->PeriphRequest = LL_DMA_REQUEST_0; 00378 #endif /* DMAMUX1 */ 00379 DMA_InitStruct->Priority = LL_DMA_PRIORITY_LOW; 00380 } 00381 00382 /** 00383 * @} 00384 */ 00385 00386 /** 00387 * @} 00388 */ 00389 00390 /** 00391 * @} 00392 */ 00393 00394 #endif /* DMA1 || DMA2 */ 00395 00396 /** 00397 * @} 00398 */ 00399 00400 #endif /* USE_FULL_LL_DRIVER */