STM32L486xx 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 * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2> 00010 * 00011 * Redistribution and use in source and binary forms, with or without modification, 00012 * are permitted provided that the following conditions are met: 00013 * 1. Redistributions of source code must retain the above copyright notice, 00014 * this list of conditions and the following disclaimer. 00015 * 2. Redistributions in binary form must reproduce the above copyright notice, 00016 * this list of conditions and the following disclaimer in the documentation 00017 * and/or other materials provided with the distribution. 00018 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00019 * may be used to endorse or promote products derived from this software 00020 * without specific prior written permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00023 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00024 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00025 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00026 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00027 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00028 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00029 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00030 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00031 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00032 * 00033 ****************************************************************************** 00034 */ 00035 #if defined(USE_FULL_LL_DRIVER) 00036 00037 /* Includes ------------------------------------------------------------------*/ 00038 #include "stm32l4xx_ll_dma.h" 00039 #include "stm32l4xx_ll_bus.h" 00040 #ifdef USE_FULL_ASSERT 00041 #include "stm32_assert.h" 00042 #else 00043 #define assert_param(expr) ((void)0U) 00044 #endif 00045 00046 /** @addtogroup STM32L4xx_LL_Driver 00047 * @{ 00048 */ 00049 00050 #if defined (DMA1) || defined (DMA2) 00051 00052 /** @defgroup DMA_LL DMA 00053 * @{ 00054 */ 00055 00056 /* Private types -------------------------------------------------------------*/ 00057 /* Private variables ---------------------------------------------------------*/ 00058 /* Private constants ---------------------------------------------------------*/ 00059 /* Private macros ------------------------------------------------------------*/ 00060 /** @addtogroup DMA_LL_Private_Macros 00061 * @{ 00062 */ 00063 #define IS_LL_DMA_DIRECTION(__VALUE__) (((__VALUE__) == LL_DMA_DIRECTION_PERIPH_TO_MEMORY) || \ 00064 ((__VALUE__) == LL_DMA_DIRECTION_MEMORY_TO_PERIPH) || \ 00065 ((__VALUE__) == LL_DMA_DIRECTION_MEMORY_TO_MEMORY)) 00066 00067 #define IS_LL_DMA_MODE(__VALUE__) (((__VALUE__) == LL_DMA_MODE_NORMAL) || \ 00068 ((__VALUE__) == LL_DMA_MODE_CIRCULAR)) 00069 00070 #define IS_LL_DMA_PERIPHINCMODE(__VALUE__) (((__VALUE__) == LL_DMA_PERIPH_INCREMENT) || \ 00071 ((__VALUE__) == LL_DMA_PERIPH_NOINCREMENT)) 00072 00073 #define IS_LL_DMA_MEMORYINCMODE(__VALUE__) (((__VALUE__) == LL_DMA_MEMORY_INCREMENT) || \ 00074 ((__VALUE__) == LL_DMA_MEMORY_NOINCREMENT)) 00075 00076 #define IS_LL_DMA_PERIPHDATASIZE(__VALUE__) (((__VALUE__) == LL_DMA_PDATAALIGN_BYTE) || \ 00077 ((__VALUE__) == LL_DMA_PDATAALIGN_HALFWORD) || \ 00078 ((__VALUE__) == LL_DMA_PDATAALIGN_WORD)) 00079 00080 #define IS_LL_DMA_MEMORYDATASIZE(__VALUE__) (((__VALUE__) == LL_DMA_MDATAALIGN_BYTE) || \ 00081 ((__VALUE__) == LL_DMA_MDATAALIGN_HALFWORD) || \ 00082 ((__VALUE__) == LL_DMA_MDATAALIGN_WORD)) 00083 00084 #define IS_LL_DMA_NBDATA(__VALUE__) ((__VALUE__) <= 0x0000FFFFU) 00085 00086 #if defined(DMAMUX1) 00087 #define IS_LL_DMA_PERIPHREQUEST(__VALUE__) ((__VALUE__) <= 93U) 00088 #else 00089 #define IS_LL_DMA_PERIPHREQUEST(__VALUE__) (((__VALUE__) == LL_DMA_REQUEST_0) || \ 00090 ((__VALUE__) == LL_DMA_REQUEST_1) || \ 00091 ((__VALUE__) == LL_DMA_REQUEST_2) || \ 00092 ((__VALUE__) == LL_DMA_REQUEST_3) || \ 00093 ((__VALUE__) == LL_DMA_REQUEST_4) || \ 00094 ((__VALUE__) == LL_DMA_REQUEST_5) || \ 00095 ((__VALUE__) == LL_DMA_REQUEST_6) || \ 00096 ((__VALUE__) == LL_DMA_REQUEST_7)) 00097 #endif /* DMAMUX1 */ 00098 00099 #define IS_LL_DMA_PRIORITY(__VALUE__) (((__VALUE__) == LL_DMA_PRIORITY_LOW) || \ 00100 ((__VALUE__) == LL_DMA_PRIORITY_MEDIUM) || \ 00101 ((__VALUE__) == LL_DMA_PRIORITY_HIGH) || \ 00102 ((__VALUE__) == LL_DMA_PRIORITY_VERYHIGH)) 00103 00104 #if defined (DMA2) 00105 #if defined (DMA2_Channel6) && defined (DMA2_Channel7) 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 ((CHANNEL) == LL_DMA_CHANNEL_6) || \ 00121 ((CHANNEL) == LL_DMA_CHANNEL_7)))) 00122 #else 00123 #define IS_LL_DMA_ALL_CHANNEL_INSTANCE(INSTANCE, CHANNEL) ((((INSTANCE) == DMA1) && \ 00124 (((CHANNEL) == LL_DMA_CHANNEL_1) || \ 00125 ((CHANNEL) == LL_DMA_CHANNEL_2) || \ 00126 ((CHANNEL) == LL_DMA_CHANNEL_3) || \ 00127 ((CHANNEL) == LL_DMA_CHANNEL_4) || \ 00128 ((CHANNEL) == LL_DMA_CHANNEL_5) || \ 00129 ((CHANNEL) == LL_DMA_CHANNEL_6) || \ 00130 ((CHANNEL) == LL_DMA_CHANNEL_7))) || \ 00131 (((INSTANCE) == DMA2) && \ 00132 (((CHANNEL) == LL_DMA_CHANNEL_1) || \ 00133 ((CHANNEL) == LL_DMA_CHANNEL_2) || \ 00134 ((CHANNEL) == LL_DMA_CHANNEL_3) || \ 00135 ((CHANNEL) == LL_DMA_CHANNEL_4) || \ 00136 ((CHANNEL) == LL_DMA_CHANNEL_5)))) 00137 #endif 00138 #else 00139 #define IS_LL_DMA_ALL_CHANNEL_INSTANCE(INSTANCE, CHANNEL) ((((INSTANCE) == DMA1) && \ 00140 (((CHANNEL) == LL_DMA_CHANNEL_1)|| \ 00141 ((CHANNEL) == LL_DMA_CHANNEL_2) || \ 00142 ((CHANNEL) == LL_DMA_CHANNEL_3) || \ 00143 ((CHANNEL) == LL_DMA_CHANNEL_4) || \ 00144 ((CHANNEL) == LL_DMA_CHANNEL_5) || \ 00145 ((CHANNEL) == LL_DMA_CHANNEL_6) || \ 00146 ((CHANNEL) == LL_DMA_CHANNEL_7)))) 00147 #endif 00148 /** 00149 * @} 00150 */ 00151 00152 /* Private function prototypes -----------------------------------------------*/ 00153 00154 /* Exported functions --------------------------------------------------------*/ 00155 /** @addtogroup DMA_LL_Exported_Functions 00156 * @{ 00157 */ 00158 00159 /** @addtogroup DMA_LL_EF_Init 00160 * @{ 00161 */ 00162 00163 /** 00164 * @brief De-initialize the DMA registers to their default reset values. 00165 * @param DMAx DMAx Instance 00166 * @param Channel This parameter can be one of the following values: 00167 * @arg @ref LL_DMA_CHANNEL_1 00168 * @arg @ref LL_DMA_CHANNEL_2 00169 * @arg @ref LL_DMA_CHANNEL_3 00170 * @arg @ref LL_DMA_CHANNEL_4 00171 * @arg @ref LL_DMA_CHANNEL_5 00172 * @arg @ref LL_DMA_CHANNEL_6 00173 * @arg @ref LL_DMA_CHANNEL_7 00174 * @arg @ref LL_DMA_CHANNEL_ALL 00175 * @retval An ErrorStatus enumeration value: 00176 * - SUCCESS: DMA registers are de-initialized 00177 * - ERROR: DMA registers are not de-initialized 00178 */ 00179 uint32_t LL_DMA_DeInit(DMA_TypeDef *DMAx, uint32_t Channel) 00180 { 00181 DMA_Channel_TypeDef *tmp = (DMA_Channel_TypeDef *)DMA1_Channel1; 00182 ErrorStatus status = SUCCESS; 00183 00184 /* Check the DMA Instance DMAx and Channel parameters*/ 00185 assert_param(IS_LL_DMA_ALL_CHANNEL_INSTANCE(DMAx, Channel) || (Channel == LL_DMA_CHANNEL_ALL)); 00186 00187 if (Channel == LL_DMA_CHANNEL_ALL) 00188 { 00189 if (DMAx == DMA1) 00190 { 00191 /* Force reset of DMA clock */ 00192 LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_DMA1); 00193 00194 /* Release reset of DMA clock */ 00195 LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_DMA1); 00196 } 00197 #if defined(DMA2) 00198 else if (DMAx == DMA2) 00199 { 00200 /* Force reset of DMA clock */ 00201 LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_DMA2); 00202 00203 /* Release reset of DMA clock */ 00204 LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_DMA2); 00205 } 00206 #endif 00207 else 00208 { 00209 status = ERROR; 00210 } 00211 } 00212 else 00213 { 00214 tmp = (DMA_Channel_TypeDef *)(__LL_DMA_GET_CHANNEL_INSTANCE(DMAx, Channel)); 00215 00216 /* Disable the selected DMAx_Channely */ 00217 CLEAR_BIT(tmp->CCR, DMA_CCR_EN); 00218 00219 /* Reset DMAx_Channely control register */ 00220 LL_DMA_WriteReg(tmp, CCR, 0U); 00221 00222 /* Reset DMAx_Channely remaining bytes register */ 00223 LL_DMA_WriteReg(tmp, CNDTR, 0U); 00224 00225 /* Reset DMAx_Channely peripheral address register */ 00226 LL_DMA_WriteReg(tmp, CPAR, 0U); 00227 00228 /* Reset DMAx_Channely memory address register */ 00229 LL_DMA_WriteReg(tmp, CMAR, 0U); 00230 00231 #if defined(DMAMUX1) 00232 /* Reset Request register field for DMAx Channel */ 00233 LL_DMA_SetPeriphRequest(DMAx, Channel, LL_DMAMUX_REQUEST_MEM2MEM); 00234 #else 00235 /* Reset Request register field for DMAx Channel */ 00236 LL_DMA_SetPeriphRequest(DMAx, Channel, LL_DMA_REQUEST_0); 00237 #endif /* DMAMUX1 */ 00238 00239 if (Channel == LL_DMA_CHANNEL_1) 00240 { 00241 /* Reset interrupt pending bits for DMAx Channel1 */ 00242 LL_DMA_ClearFlag_GI1(DMAx); 00243 } 00244 else if (Channel == LL_DMA_CHANNEL_2) 00245 { 00246 /* Reset interrupt pending bits for DMAx Channel2 */ 00247 LL_DMA_ClearFlag_GI2(DMAx); 00248 } 00249 else if (Channel == LL_DMA_CHANNEL_3) 00250 { 00251 /* Reset interrupt pending bits for DMAx Channel3 */ 00252 LL_DMA_ClearFlag_GI3(DMAx); 00253 } 00254 else if (Channel == LL_DMA_CHANNEL_4) 00255 { 00256 /* Reset interrupt pending bits for DMAx Channel4 */ 00257 LL_DMA_ClearFlag_GI4(DMAx); 00258 } 00259 else if (Channel == LL_DMA_CHANNEL_5) 00260 { 00261 /* Reset interrupt pending bits for DMAx Channel5 */ 00262 LL_DMA_ClearFlag_GI5(DMAx); 00263 } 00264 00265 else if (Channel == LL_DMA_CHANNEL_6) 00266 { 00267 /* Reset interrupt pending bits for DMAx Channel6 */ 00268 LL_DMA_ClearFlag_GI6(DMAx); 00269 } 00270 else if (Channel == LL_DMA_CHANNEL_7) 00271 { 00272 /* Reset interrupt pending bits for DMAx Channel7 */ 00273 LL_DMA_ClearFlag_GI7(DMAx); 00274 } 00275 else 00276 { 00277 status = ERROR; 00278 } 00279 } 00280 00281 return status; 00282 } 00283 00284 /** 00285 * @brief Initialize the DMA registers according to the specified parameters in DMA_InitStruct. 00286 * @note To convert DMAx_Channely Instance to DMAx Instance and Channely, use helper macros : 00287 * @arg @ref __LL_DMA_GET_INSTANCE 00288 * @arg @ref __LL_DMA_GET_CHANNEL 00289 * @param DMAx DMAx Instance 00290 * @param Channel This parameter can be one of the following values: 00291 * @arg @ref LL_DMA_CHANNEL_1 00292 * @arg @ref LL_DMA_CHANNEL_2 00293 * @arg @ref LL_DMA_CHANNEL_3 00294 * @arg @ref LL_DMA_CHANNEL_4 00295 * @arg @ref LL_DMA_CHANNEL_5 00296 * @arg @ref LL_DMA_CHANNEL_6 00297 * @arg @ref LL_DMA_CHANNEL_7 00298 * @param DMA_InitStruct pointer to a @ref LL_DMA_InitTypeDef structure. 00299 * @retval An ErrorStatus enumeration value: 00300 * - SUCCESS: DMA registers are initialized 00301 * - ERROR: Not applicable 00302 */ 00303 uint32_t LL_DMA_Init(DMA_TypeDef *DMAx, uint32_t Channel, LL_DMA_InitTypeDef *DMA_InitStruct) 00304 { 00305 /* Check the DMA Instance DMAx and Channel parameters*/ 00306 assert_param(IS_LL_DMA_ALL_CHANNEL_INSTANCE(DMAx, Channel)); 00307 00308 /* Check the DMA parameters from DMA_InitStruct */ 00309 assert_param(IS_LL_DMA_DIRECTION(DMA_InitStruct->Direction)); 00310 assert_param(IS_LL_DMA_MODE(DMA_InitStruct->Mode)); 00311 assert_param(IS_LL_DMA_PERIPHINCMODE(DMA_InitStruct->PeriphOrM2MSrcIncMode)); 00312 assert_param(IS_LL_DMA_MEMORYINCMODE(DMA_InitStruct->MemoryOrM2MDstIncMode)); 00313 assert_param(IS_LL_DMA_PERIPHDATASIZE(DMA_InitStruct->PeriphOrM2MSrcDataSize)); 00314 assert_param(IS_LL_DMA_MEMORYDATASIZE(DMA_InitStruct->MemoryOrM2MDstDataSize)); 00315 assert_param(IS_LL_DMA_NBDATA(DMA_InitStruct->NbData)); 00316 assert_param(IS_LL_DMA_PERIPHREQUEST(DMA_InitStruct->PeriphRequest)); 00317 assert_param(IS_LL_DMA_PRIORITY(DMA_InitStruct->Priority)); 00318 00319 /*---------------------------- DMAx CCR Configuration ------------------------ 00320 * Configure DMAx_Channely: data transfer direction, data transfer mode, 00321 * peripheral and memory increment mode, 00322 * data size alignment and priority level with parameters : 00323 * - Direction: DMA_CCR_DIR and DMA_CCR_MEM2MEM bits 00324 * - Mode: DMA_CCR_CIRC bit 00325 * - PeriphOrM2MSrcIncMode: DMA_CCR_PINC bit 00326 * - MemoryOrM2MDstIncMode: DMA_CCR_MINC bit 00327 * - PeriphOrM2MSrcDataSize: DMA_CCR_PSIZE[1:0] bits 00328 * - MemoryOrM2MDstDataSize: DMA_CCR_MSIZE[1:0] bits 00329 * - Priority: DMA_CCR_PL[1:0] bits 00330 */ 00331 LL_DMA_ConfigTransfer(DMAx, Channel, DMA_InitStruct->Direction | \ 00332 DMA_InitStruct->Mode | \ 00333 DMA_InitStruct->PeriphOrM2MSrcIncMode | \ 00334 DMA_InitStruct->MemoryOrM2MDstIncMode | \ 00335 DMA_InitStruct->PeriphOrM2MSrcDataSize | \ 00336 DMA_InitStruct->MemoryOrM2MDstDataSize | \ 00337 DMA_InitStruct->Priority); 00338 00339 /*-------------------------- DMAx CMAR Configuration ------------------------- 00340 * Configure the memory or destination base address with parameter : 00341 * - MemoryOrM2MDstAddress: DMA_CMAR_MA[31:0] bits 00342 */ 00343 LL_DMA_SetMemoryAddress(DMAx, Channel, DMA_InitStruct->MemoryOrM2MDstAddress); 00344 00345 /*-------------------------- DMAx CPAR Configuration ------------------------- 00346 * Configure the peripheral or source base address with parameter : 00347 * - PeriphOrM2MSrcAddress: DMA_CPAR_PA[31:0] bits 00348 */ 00349 LL_DMA_SetPeriphAddress(DMAx, Channel, DMA_InitStruct->PeriphOrM2MSrcAddress); 00350 00351 /*--------------------------- DMAx CNDTR Configuration ----------------------- 00352 * Configure the peripheral base address with parameter : 00353 * - NbData: DMA_CNDTR_NDT[15:0] bits 00354 */ 00355 LL_DMA_SetDataLength(DMAx, Channel, DMA_InitStruct->NbData); 00356 00357 #if defined(DMAMUX1) 00358 /*--------------------------- DMAMUXx CCR Configuration ---------------------- 00359 * Configure the DMA request for DMA Channels on DMAMUX Channel x with parameter : 00360 * - PeriphRequest: DMA_CxCR[7:0] bits 00361 */ 00362 LL_DMA_SetPeriphRequest(DMAx, Channel, DMA_InitStruct->PeriphRequest); 00363 #else 00364 /*--------------------------- DMAx CSELR Configuration ----------------------- 00365 * Configure the DMA request for DMA instance on Channel x with parameter : 00366 * - PeriphRequest: DMA_CSELR[31:0] bits 00367 */ 00368 LL_DMA_SetPeriphRequest(DMAx, Channel, DMA_InitStruct->PeriphRequest); 00369 #endif /* DMAMUX1 */ 00370 00371 return SUCCESS; 00372 } 00373 00374 /** 00375 * @brief Set each @ref LL_DMA_InitTypeDef field to default value. 00376 * @param DMA_InitStruct Pointer to a @ref LL_DMA_InitTypeDef structure. 00377 * @retval None 00378 */ 00379 void LL_DMA_StructInit(LL_DMA_InitTypeDef *DMA_InitStruct) 00380 { 00381 /* Set DMA_InitStruct fields to default values */ 00382 DMA_InitStruct->PeriphOrM2MSrcAddress = 0x00000000U; 00383 DMA_InitStruct->MemoryOrM2MDstAddress = 0x00000000U; 00384 DMA_InitStruct->Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY; 00385 DMA_InitStruct->Mode = LL_DMA_MODE_NORMAL; 00386 DMA_InitStruct->PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT; 00387 DMA_InitStruct->MemoryOrM2MDstIncMode = LL_DMA_MEMORY_NOINCREMENT; 00388 DMA_InitStruct->PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_BYTE; 00389 DMA_InitStruct->MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_BYTE; 00390 DMA_InitStruct->NbData = 0x00000000U; 00391 #if defined(DMAMUX1) 00392 DMA_InitStruct->PeriphRequest = LL_DMAMUX_REQUEST_MEM2MEM; 00393 #else 00394 DMA_InitStruct->PeriphRequest = LL_DMA_REQUEST_0; 00395 #endif /* DMAMUX1 */ 00396 DMA_InitStruct->Priority = LL_DMA_PRIORITY_LOW; 00397 } 00398 00399 /** 00400 * @} 00401 */ 00402 00403 /** 00404 * @} 00405 */ 00406 00407 /** 00408 * @} 00409 */ 00410 00411 #endif /* DMA1 || DMA2 */ 00412 00413 /** 00414 * @} 00415 */ 00416 00417 #endif /* USE_FULL_LL_DRIVER */ 00418 00419 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/