Merge pull request #11198 from SteveCEvans/sce_rc2
[betaflight.git] / lib / main / STM32F4 / Drivers / STM32F4xx_HAL_Driver / Src / stm32f4xx_ll_dma.c
blobc9c3a0e84cd89ca43f5dd820e0b2c6a3caa6f656
1 /**
2 ******************************************************************************
3 * @file stm32f4xx_ll_dma.c
4 * @author MCD Application Team
5 * @version V1.7.1
6 * @date 14-April-2017
7 * @brief DMA LL module driver.
8 ******************************************************************************
9 * @attention
11 * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
13 * Redistribution and use in source and binary forms, with or without modification,
14 * are permitted provided that the following conditions are met:
15 * 1. Redistributions of source code must retain the above copyright notice,
16 * this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright notice,
18 * this list of conditions and the following disclaimer in the documentation
19 * and/or other materials provided with the distribution.
20 * 3. Neither the name of STMicroelectronics nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 ******************************************************************************
37 #if defined(USE_FULL_LL_DRIVER)
39 /* Includes ------------------------------------------------------------------*/
40 #include "stm32f4xx_ll_dma.h"
41 #include "stm32f4xx_ll_bus.h"
42 #ifdef USE_FULL_ASSERT
43 #include "stm32_assert.h"
44 #else
45 #define assert_param(expr) ((void)0U)
46 #endif
48 /** @addtogroup STM32F4xx_LL_Driver
49 * @{
52 #if defined (DMA1) || defined (DMA2)
54 /** @defgroup DMA_LL DMA
55 * @{
58 /* Private types -------------------------------------------------------------*/
59 /* Private variables ---------------------------------------------------------*/
60 /* Private constants ---------------------------------------------------------*/
61 /* Private macros ------------------------------------------------------------*/
62 /** @addtogroup DMA_LL_Private_Macros
63 * @{
65 #define IS_LL_DMA_DIRECTION(__VALUE__) (((__VALUE__) == LL_DMA_DIRECTION_PERIPH_TO_MEMORY) || \
66 ((__VALUE__) == LL_DMA_DIRECTION_MEMORY_TO_PERIPH) || \
67 ((__VALUE__) == LL_DMA_DIRECTION_MEMORY_TO_MEMORY))
69 #define IS_LL_DMA_MODE(__VALUE__) (((__VALUE__) == LL_DMA_MODE_NORMAL) || \
70 ((__VALUE__) == LL_DMA_MODE_CIRCULAR) || \
71 ((__VALUE__) == LL_DMA_MODE_PFCTRL))
73 #define IS_LL_DMA_PERIPHINCMODE(__VALUE__) (((__VALUE__) == LL_DMA_PERIPH_INCREMENT) || \
74 ((__VALUE__) == LL_DMA_PERIPH_NOINCREMENT))
76 #define IS_LL_DMA_MEMORYINCMODE(__VALUE__) (((__VALUE__) == LL_DMA_MEMORY_INCREMENT) || \
77 ((__VALUE__) == LL_DMA_MEMORY_NOINCREMENT))
79 #define IS_LL_DMA_PERIPHDATASIZE(__VALUE__) (((__VALUE__) == LL_DMA_PDATAALIGN_BYTE) || \
80 ((__VALUE__) == LL_DMA_PDATAALIGN_HALFWORD) || \
81 ((__VALUE__) == LL_DMA_PDATAALIGN_WORD))
83 #define IS_LL_DMA_MEMORYDATASIZE(__VALUE__) (((__VALUE__) == LL_DMA_MDATAALIGN_BYTE) || \
84 ((__VALUE__) == LL_DMA_MDATAALIGN_HALFWORD) || \
85 ((__VALUE__) == LL_DMA_MDATAALIGN_WORD))
87 #define IS_LL_DMA_NBDATA(__VALUE__) ((__VALUE__) <= 0x0000FFFFU)
89 #define IS_LL_DMA_CHANNEL(__VALUE__) (((__VALUE__) == LL_DMA_CHANNEL_0) || \
90 ((__VALUE__) == LL_DMA_CHANNEL_1) || \
91 ((__VALUE__) == LL_DMA_CHANNEL_2) || \
92 ((__VALUE__) == LL_DMA_CHANNEL_3) || \
93 ((__VALUE__) == LL_DMA_CHANNEL_4) || \
94 ((__VALUE__) == LL_DMA_CHANNEL_5) || \
95 ((__VALUE__) == LL_DMA_CHANNEL_6) || \
96 ((__VALUE__) == LL_DMA_CHANNEL_7))
98 #define IS_LL_DMA_PRIORITY(__VALUE__) (((__VALUE__) == LL_DMA_PRIORITY_LOW) || \
99 ((__VALUE__) == LL_DMA_PRIORITY_MEDIUM) || \
100 ((__VALUE__) == LL_DMA_PRIORITY_HIGH) || \
101 ((__VALUE__) == LL_DMA_PRIORITY_VERYHIGH))
103 #define IS_LL_DMA_ALL_STREAM_INSTANCE(INSTANCE, STREAM) ((((INSTANCE) == DMA1) && \
104 (((STREAM) == LL_DMA_STREAM_0) || \
105 ((STREAM) == LL_DMA_STREAM_1) || \
106 ((STREAM) == LL_DMA_STREAM_2) || \
107 ((STREAM) == LL_DMA_STREAM_3) || \
108 ((STREAM) == LL_DMA_STREAM_4) || \
109 ((STREAM) == LL_DMA_STREAM_5) || \
110 ((STREAM) == LL_DMA_STREAM_6) || \
111 ((STREAM) == LL_DMA_STREAM_7) || \
112 ((STREAM) == LL_DMA_STREAM_ALL))) ||\
113 (((INSTANCE) == DMA2) && \
114 (((STREAM) == LL_DMA_STREAM_0) || \
115 ((STREAM) == LL_DMA_STREAM_1) || \
116 ((STREAM) == LL_DMA_STREAM_2) || \
117 ((STREAM) == LL_DMA_STREAM_3) || \
118 ((STREAM) == LL_DMA_STREAM_4) || \
119 ((STREAM) == LL_DMA_STREAM_5) || \
120 ((STREAM) == LL_DMA_STREAM_6) || \
121 ((STREAM) == LL_DMA_STREAM_7) || \
122 ((STREAM) == LL_DMA_STREAM_ALL))))
124 #define IS_LL_DMA_FIFO_MODE_STATE(STATE) (((STATE) == LL_DMA_FIFOMODE_DISABLE ) || \
125 ((STATE) == LL_DMA_FIFOMODE_ENABLE))
127 #define IS_LL_DMA_FIFO_THRESHOLD(THRESHOLD) (((THRESHOLD) == LL_DMA_FIFOTHRESHOLD_1_4) || \
128 ((THRESHOLD) == LL_DMA_FIFOTHRESHOLD_1_2) || \
129 ((THRESHOLD) == LL_DMA_FIFOTHRESHOLD_3_4) || \
130 ((THRESHOLD) == LL_DMA_FIFOTHRESHOLD_FULL))
132 #define IS_LL_DMA_MEMORY_BURST(BURST) (((BURST) == LL_DMA_MBURST_SINGLE) || \
133 ((BURST) == LL_DMA_MBURST_INC4) || \
134 ((BURST) == LL_DMA_MBURST_INC8) || \
135 ((BURST) == LL_DMA_MBURST_INC16))
137 #define IS_LL_DMA_PERIPHERAL_BURST(BURST) (((BURST) == LL_DMA_PBURST_SINGLE) || \
138 ((BURST) == LL_DMA_PBURST_INC4) || \
139 ((BURST) == LL_DMA_PBURST_INC8) || \
140 ((BURST) == LL_DMA_PBURST_INC16))
143 * @}
146 /* Private function prototypes -----------------------------------------------*/
148 /* Exported functions --------------------------------------------------------*/
149 /** @addtogroup DMA_LL_Exported_Functions
150 * @{
153 /** @addtogroup DMA_LL_EF_Init
154 * @{
158 * @brief De-initialize the DMA registers to their default reset values.
159 * @param DMAx DMAx Instance
160 * @param Stream This parameter can be one of the following values:
161 * @arg @ref LL_DMA_STREAM_0
162 * @arg @ref LL_DMA_STREAM_1
163 * @arg @ref LL_DMA_STREAM_2
164 * @arg @ref LL_DMA_STREAM_3
165 * @arg @ref LL_DMA_STREAM_4
166 * @arg @ref LL_DMA_STREAM_5
167 * @arg @ref LL_DMA_STREAM_6
168 * @arg @ref LL_DMA_STREAM_7
169 * @arg @ref LL_DMA_STREAM_ALL
170 * @retval An ErrorStatus enumeration value:
171 * - SUCCESS: DMA registers are de-initialized
172 * - ERROR: DMA registers are not de-initialized
174 uint32_t LL_DMA_DeInit(DMA_TypeDef *DMAx, uint32_t Stream)
176 DMA_Stream_TypeDef *tmp = (DMA_Stream_TypeDef *)DMA1_Stream0;
177 ErrorStatus status = SUCCESS;
179 /* Check the DMA Instance DMAx and Stream parameters*/
180 assert_param(IS_LL_DMA_ALL_STREAM_INSTANCE(DMAx, Stream));
182 if (Stream == LL_DMA_STREAM_ALL)
184 if (DMAx == DMA1)
186 /* Force reset of DMA clock */
187 LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_DMA1);
189 /* Release reset of DMA clock */
190 LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_DMA1);
192 else if (DMAx == DMA2)
194 /* Force reset of DMA clock */
195 LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_DMA2);
197 /* Release reset of DMA clock */
198 LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_DMA2);
200 else
202 status = ERROR;
205 else
207 /* Disable the selected Stream */
208 LL_DMA_DisableStream(DMAx,Stream);
210 /* Get the DMA Stream Instance */
211 tmp = (DMA_Stream_TypeDef *)(__LL_DMA_GET_STREAM_INSTANCE(DMAx, Stream));
213 /* Reset DMAx_Streamy configuration register */
214 LL_DMA_WriteReg(tmp, CR, 0U);
216 /* Reset DMAx_Streamy remaining bytes register */
217 LL_DMA_WriteReg(tmp, NDTR, 0U);
219 /* Reset DMAx_Streamy peripheral address register */
220 LL_DMA_WriteReg(tmp, PAR, 0U);
222 /* Reset DMAx_Streamy memory address register */
223 LL_DMA_WriteReg(tmp, M0AR, 0U);
225 /* Reset DMAx_Streamy memory address register */
226 LL_DMA_WriteReg(tmp, M1AR, 0U);
228 /* Reset DMAx_Streamy FIFO control register */
229 LL_DMA_WriteReg(tmp, FCR, 0x00000021U);
231 /* Reset Channel register field for DMAx Stream*/
232 LL_DMA_SetChannelSelection(DMAx, Stream, LL_DMA_CHANNEL_0);
234 if(Stream == LL_DMA_STREAM_0)
236 /* Reset the Stream0 pending flags */
237 DMAx->LIFCR = 0x0000003FU;
239 else if(Stream == LL_DMA_STREAM_1)
241 /* Reset the Stream1 pending flags */
242 DMAx->LIFCR = 0x00000F40U;
244 else if(Stream == LL_DMA_STREAM_2)
246 /* Reset the Stream2 pending flags */
247 DMAx->LIFCR = 0x003F0000U;
249 else if(Stream == LL_DMA_STREAM_3)
251 /* Reset the Stream3 pending flags */
252 DMAx->LIFCR = 0x0F400000U;
254 else if(Stream == LL_DMA_STREAM_4)
256 /* Reset the Stream4 pending flags */
257 DMAx->HIFCR = 0x0000003FU;
259 else if(Stream == LL_DMA_STREAM_5)
261 /* Reset the Stream5 pending flags */
262 DMAx->HIFCR = 0x00000F40U;
264 else if(Stream == LL_DMA_STREAM_6)
266 /* Reset the Stream6 pending flags */
267 DMAx->HIFCR = 0x003F0000U;
269 else if(Stream == LL_DMA_STREAM_7)
271 /* Reset the Stream7 pending flags */
272 DMAx->HIFCR = 0x0F400000U;
274 else
276 status = ERROR;
280 return status;
284 * @brief Initialize the DMA registers according to the specified parameters in DMA_InitStruct.
285 * @note To convert DMAx_Streamy Instance to DMAx Instance and Streamy, use helper macros :
286 * @arg @ref __LL_DMA_GET_INSTANCE
287 * @arg @ref __LL_DMA_GET_STREAM
288 * @param DMAx DMAx Instance
289 * @param Stream This parameter can be one of the following values:
290 * @arg @ref LL_DMA_STREAM_0
291 * @arg @ref LL_DMA_STREAM_1
292 * @arg @ref LL_DMA_STREAM_2
293 * @arg @ref LL_DMA_STREAM_3
294 * @arg @ref LL_DMA_STREAM_4
295 * @arg @ref LL_DMA_STREAM_5
296 * @arg @ref LL_DMA_STREAM_6
297 * @arg @ref LL_DMA_STREAM_7
298 * @param DMA_InitStruct pointer to a @ref LL_DMA_InitTypeDef structure.
299 * @retval An ErrorStatus enumeration value:
300 * - SUCCESS: DMA registers are initialized
301 * - ERROR: Not applicable
303 uint32_t LL_DMA_Init(DMA_TypeDef *DMAx, uint32_t Stream, LL_DMA_InitTypeDef *DMA_InitStruct)
305 /* Check the DMA Instance DMAx and Stream parameters*/
306 assert_param(IS_LL_DMA_ALL_STREAM_INSTANCE(DMAx, Stream));
308 /* Check the DMA parameters from DMA_InitStruct */
309 assert_param(IS_LL_DMA_DIRECTION(DMA_InitStruct->Direction));
310 assert_param(IS_LL_DMA_MODE(DMA_InitStruct->Mode));
311 assert_param(IS_LL_DMA_PERIPHINCMODE(DMA_InitStruct->PeriphOrM2MSrcIncMode));
312 assert_param(IS_LL_DMA_MEMORYINCMODE(DMA_InitStruct->MemoryOrM2MDstIncMode));
313 assert_param(IS_LL_DMA_PERIPHDATASIZE(DMA_InitStruct->PeriphOrM2MSrcDataSize));
314 assert_param(IS_LL_DMA_MEMORYDATASIZE(DMA_InitStruct->MemoryOrM2MDstDataSize));
315 assert_param(IS_LL_DMA_NBDATA(DMA_InitStruct->NbData));
316 assert_param(IS_LL_DMA_CHANNEL(DMA_InitStruct->Channel));
317 assert_param(IS_LL_DMA_PRIORITY(DMA_InitStruct->Priority));
318 assert_param(IS_LL_DMA_FIFO_MODE_STATE(DMA_InitStruct->FIFOMode));
319 /* Check the memory burst, peripheral burst and FIFO threshold parameters only
320 when FIFO mode is enabled */
321 if(DMA_InitStruct->FIFOMode != LL_DMA_FIFOMODE_DISABLE)
323 assert_param(IS_LL_DMA_FIFO_THRESHOLD(DMA_InitStruct->FIFOThreshold));
324 assert_param(IS_LL_DMA_MEMORY_BURST(DMA_InitStruct->MemBurst));
325 assert_param(IS_LL_DMA_PERIPHERAL_BURST(DMA_InitStruct->PeriphBurst));
328 /*---------------------------- DMAx SxCR Configuration ------------------------
329 * Configure DMAx_Streamy: data transfer direction, data transfer mode,
330 * peripheral and memory increment mode,
331 * data size alignment and priority level with parameters :
332 * - Direction: DMA_SxCR_DIR[1:0] bits
333 * - Mode: DMA_SxCR_CIRC bit
334 * - PeriphOrM2MSrcIncMode: DMA_SxCR_PINC bit
335 * - MemoryOrM2MDstIncMode: DMA_SxCR_MINC bit
336 * - PeriphOrM2MSrcDataSize: DMA_SxCR_PSIZE[1:0] bits
337 * - MemoryOrM2MDstDataSize: DMA_SxCR_MSIZE[1:0] bits
338 * - Priority: DMA_SxCR_PL[1:0] bits
340 LL_DMA_ConfigTransfer(DMAx, Stream, DMA_InitStruct->Direction | \
341 DMA_InitStruct->Mode | \
342 DMA_InitStruct->PeriphOrM2MSrcIncMode | \
343 DMA_InitStruct->MemoryOrM2MDstIncMode | \
344 DMA_InitStruct->PeriphOrM2MSrcDataSize | \
345 DMA_InitStruct->MemoryOrM2MDstDataSize | \
346 DMA_InitStruct->Priority
349 if(DMA_InitStruct->FIFOMode != LL_DMA_FIFOMODE_DISABLE)
351 /*---------------------------- DMAx SxFCR Configuration ------------------------
352 * Configure DMAx_Streamy: fifo mode and fifo threshold with parameters :
353 * - FIFOMode: DMA_SxFCR_DMDIS bit
354 * - FIFOThreshold: DMA_SxFCR_FTH[1:0] bits
356 LL_DMA_ConfigFifo(DMAx, Stream, DMA_InitStruct->FIFOMode, DMA_InitStruct->FIFOThreshold);
358 /*---------------------------- DMAx SxCR Configuration --------------------------
359 * Configure DMAx_Streamy: memory burst transfer with parameters :
360 * - MemBurst: DMA_SxCR_MBURST[1:0] bits
362 LL_DMA_SetMemoryBurstxfer(DMAx,Stream,DMA_InitStruct->MemBurst);
364 /*---------------------------- DMAx SxCR Configuration --------------------------
365 * Configure DMAx_Streamy: peripheral burst transfer with parameters :
366 * - PeriphBurst: DMA_SxCR_PBURST[1:0] bits
368 LL_DMA_SetPeriphBurstxfer(DMAx,Stream,DMA_InitStruct->PeriphBurst);
371 /*-------------------------- DMAx SxM0AR Configuration --------------------------
372 * Configure the memory or destination base address with parameter :
373 * - MemoryOrM2MDstAddress: DMA_SxM0AR_M0A[31:0] bits
375 LL_DMA_SetMemoryAddress(DMAx, Stream, DMA_InitStruct->MemoryOrM2MDstAddress);
377 /*-------------------------- DMAx SxPAR Configuration ---------------------------
378 * Configure the peripheral or source base address with parameter :
379 * - PeriphOrM2MSrcAddress: DMA_SxPAR_PA[31:0] bits
381 LL_DMA_SetPeriphAddress(DMAx, Stream, DMA_InitStruct->PeriphOrM2MSrcAddress);
383 /*--------------------------- DMAx SxNDTR Configuration -------------------------
384 * Configure the peripheral base address with parameter :
385 * - NbData: DMA_SxNDT[15:0] bits
387 LL_DMA_SetDataLength(DMAx, Stream, DMA_InitStruct->NbData);
389 /*--------------------------- DMA SxCR_CHSEL Configuration ----------------------
390 * Configure the peripheral base address with parameter :
391 * - PeriphRequest: DMA_SxCR_CHSEL[2:0] bits
393 LL_DMA_SetChannelSelection(DMAx, Stream, DMA_InitStruct->Channel);
395 return SUCCESS;
399 * @brief Set each @ref LL_DMA_InitTypeDef field to default value.
400 * @param DMA_InitStruct Pointer to a @ref LL_DMA_InitTypeDef structure.
401 * @retval None
403 void LL_DMA_StructInit(LL_DMA_InitTypeDef *DMA_InitStruct)
405 /* Set DMA_InitStruct fields to default values */
406 DMA_InitStruct->PeriphOrM2MSrcAddress = 0x00000000U;
407 DMA_InitStruct->MemoryOrM2MDstAddress = 0x00000000U;
408 DMA_InitStruct->Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
409 DMA_InitStruct->Mode = LL_DMA_MODE_NORMAL;
410 DMA_InitStruct->PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT;
411 DMA_InitStruct->MemoryOrM2MDstIncMode = LL_DMA_MEMORY_NOINCREMENT;
412 DMA_InitStruct->PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_BYTE;
413 DMA_InitStruct->MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_BYTE;
414 DMA_InitStruct->NbData = 0x00000000U;
415 DMA_InitStruct->Channel = LL_DMA_CHANNEL_0;
416 DMA_InitStruct->Priority = LL_DMA_PRIORITY_LOW;
417 DMA_InitStruct->FIFOMode = LL_DMA_FIFOMODE_DISABLE;
418 DMA_InitStruct->FIFOThreshold = LL_DMA_FIFOTHRESHOLD_1_4;
419 DMA_InitStruct->MemBurst = LL_DMA_MBURST_SINGLE;
420 DMA_InitStruct->PeriphBurst = LL_DMA_PBURST_SINGLE;
424 * @}
428 * @}
432 * @}
435 #endif /* DMA1 || DMA2 */
438 * @}
441 #endif /* USE_FULL_LL_DRIVER */
443 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/