• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2   ******************************************************************************
3   * @file    stm32f4xx_dma.c
4   * @author  MCD Application Team
5   * @version V1.4.0
6   * @date    04-August-2014
7   * @brief   This file provides firmware functions to manage the following
8   *          functionalities of the Direct Memory Access controller (DMA):
9   *           + Initialization and Configuration
10   *           + Data Counter
11   *           + Double Buffer mode configuration and command
12   *           + Interrupts and flags management
13   *
14   @verbatim
15  ===============================================================================
16                        ##### How to use this driver #####
17  ===============================================================================
18     [..]
19       (#) Enable The DMA controller clock using RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_DMA1, ENABLE)
20           function for DMA1 or using RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_DMA2, ENABLE)
21           function for DMA2.
22 
23       (#) Enable and configure the peripheral to be connected to the DMA Stream
24           (except for internal SRAM / FLASH memories: no initialization is
25           necessary).
26 
27       (#) For a given Stream, program the required configuration through following parameters:
28           Source and Destination addresses, Transfer Direction, Transfer size, Source and Destination
29           data formats, Circular or Normal mode, Stream Priority level, Source and Destination
30           Incrementation mode, FIFO mode and its Threshold (if needed), Burst
31           mode for Source and/or Destination (if needed) using the DMA_Init() function.
32           To avoid filling unneccessary fields, you can call DMA_StructInit() function
33           to initialize a given structure with default values (reset values), the modify
34           only necessary fields
35           (ie. Source and Destination addresses, Transfer size and Data Formats).
36 
37       (#) Enable the NVIC and the corresponding interrupt(s) using the function
38           DMA_ITConfig() if you need to use DMA interrupts.
39 
40       (#) Optionally, if the Circular mode is enabled, you can use the Double buffer mode by configuring
41           the second Memory address and the first Memory to be used through the function
42           DMA_DoubleBufferModeConfig(). Then enable the Double buffer mode through the function
43           DMA_DoubleBufferModeCmd(). These operations must be done before step 6.
44 
45       (#) Enable the DMA stream using the DMA_Cmd() function.
46 
47       (#) Activate the needed Stream Request using PPP_DMACmd() function for
48           any PPP peripheral except internal SRAM and FLASH (ie. SPI, USART ...)
49           The function allowing this operation is provided in each PPP peripheral
50           driver (ie. SPI_DMACmd for SPI peripheral).
51           Once the Stream is enabled, it is not possible to modify its configuration
52           unless the stream is stopped and disabled.
53           After enabling the Stream, it is advised to monitor the EN bit status using
54           the function DMA_GetCmdStatus(). In case of configuration errors or bus errors
55           this bit will remain reset and all transfers on this Stream will remain on hold.
56 
57       (#) Optionally, you can configure the number of data to be transferred
58           when the Stream is disabled (ie. after each Transfer Complete event
59           or when a Transfer Error occurs) using the function DMA_SetCurrDataCounter().
60           And you can get the number of remaining data to be transferred using
61           the function DMA_GetCurrDataCounter() at run time (when the DMA Stream is
62           enabled and running).
63 
64       (#) To control DMA events you can use one of the following two methods:
65         (##) Check on DMA Stream flags using the function DMA_GetFlagStatus().
66         (##) Use DMA interrupts through the function DMA_ITConfig() at initialization
67              phase and DMA_GetITStatus() function into interrupt routines in
68              communication phase.
69     [..]
70           After checking on a flag you should clear it using DMA_ClearFlag()
71           function. And after checking on an interrupt event you should
72           clear it using DMA_ClearITPendingBit() function.
73 
74       (#) Optionally, if Circular mode and Double Buffer mode are enabled, you can modify
75           the Memory Addresses using the function DMA_MemoryTargetConfig(). Make sure that
76           the Memory Address to be modified is not the one currently in use by DMA Stream.
77           This condition can be monitored using the function DMA_GetCurrentMemoryTarget().
78 
79       (#) Optionally, Pause-Resume operations may be performed:
80           The DMA_Cmd() function may be used to perform Pause-Resume operation.
81           When a transfer is ongoing, calling this function to disable the
82           Stream will cause the transfer to be paused. All configuration registers
83           and the number of remaining data will be preserved. When calling again
84           this function to re-enable the Stream, the transfer will be resumed from
85           the point where it was paused.
86 
87       -@- Memory-to-Memory transfer is possible by setting the address of the memory into
88            the Peripheral registers. In this mode, Circular mode and Double Buffer mode
89            are not allowed.
90 
91       -@- The FIFO is used mainly to reduce bus usage and to allow data
92            packing/unpacking: it is possible to set different Data Sizes for
93            the Peripheral and the Memory (ie. you can set Half-Word data size
94            for the peripheral to access its data register and set Word data size
95            for the Memory to gain in access time. Each two Half-words will be
96            packed and written in a single access to a Word in the Memory).
97 
98       -@- When FIFO is disabled, it is not allowed to configure different
99            Data Sizes for Source and Destination. In this case the Peripheral
100            Data Size will be applied to both Source and Destination.
101 
102   @endverbatim
103   ******************************************************************************
104   * @attention
105   *
106   * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
107   *
108   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
109   * You may not use this file except in compliance with the License.
110   * You may obtain a copy of the License at:
111   *
112   *        http://www.st.com/software_license_agreement_liberty_v2
113   *
114   * Unless required by applicable law or agreed to in writing, software
115   * distributed under the License is distributed on an "AS IS" BASIS,
116   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
117   * See the License for the specific language governing permissions and
118   * limitations under the License.
119   *
120   ******************************************************************************
121   */
122 
123 /* Includes ------------------------------------------------------------------*/
124 #include "stm32f4xx_dma.h"
125 #include "stm32f4xx_rcc.h"
126 
127 /** @addtogroup STM32F4xx_StdPeriph_Driver
128   * @{
129   */
130 
131 /** @defgroup DMA
132   * @brief DMA driver modules
133   * @{
134   */
135 
136 /* Private typedef -----------------------------------------------------------*/
137 /* Private define ------------------------------------------------------------*/
138 
139 /* Masks Definition */
140 #define TRANSFER_IT_ENABLE_MASK (uint32_t)(DMA_SxCR_TCIE | DMA_SxCR_HTIE | \
141                                            DMA_SxCR_TEIE | DMA_SxCR_DMEIE)
142 
143 #define DMA_Stream0_IT_MASK     (uint32_t)(DMA_LISR_FEIF0 | DMA_LISR_DMEIF0 | \
144                                            DMA_LISR_TEIF0 | DMA_LISR_HTIF0 | \
145                                            DMA_LISR_TCIF0)
146 
147 #define DMA_Stream1_IT_MASK     (uint32_t)(DMA_Stream0_IT_MASK << 6)
148 #define DMA_Stream2_IT_MASK     (uint32_t)(DMA_Stream0_IT_MASK << 16)
149 #define DMA_Stream3_IT_MASK     (uint32_t)(DMA_Stream0_IT_MASK << 22)
150 #define DMA_Stream4_IT_MASK     (uint32_t)(DMA_Stream0_IT_MASK | (uint32_t)0x20000000)
151 #define DMA_Stream5_IT_MASK     (uint32_t)(DMA_Stream1_IT_MASK | (uint32_t)0x20000000)
152 #define DMA_Stream6_IT_MASK     (uint32_t)(DMA_Stream2_IT_MASK | (uint32_t)0x20000000)
153 #define DMA_Stream7_IT_MASK     (uint32_t)(DMA_Stream3_IT_MASK | (uint32_t)0x20000000)
154 #define TRANSFER_IT_MASK        (uint32_t)0x0F3C0F3C
155 #define HIGH_ISR_MASK           (uint32_t)0x20000000
156 #define RESERVED_MASK           (uint32_t)0x0F7D0F7D
157 
158 /* Private macro -------------------------------------------------------------*/
159 /* Private variables ---------------------------------------------------------*/
160 /* Private function prototypes -----------------------------------------------*/
161 /* Private functions ---------------------------------------------------------*/
162 
163 
164 /** @defgroup DMA_Private_Functions
165   * @{
166   */
167 
168 /** @defgroup DMA_Group1 Initialization and Configuration functions
169  *  @brief   Initialization and Configuration functions
170  *
171 @verbatim
172  ===============================================================================
173                 ##### Initialization and Configuration functions #####
174  ===============================================================================
175     [..]
176     This subsection provides functions allowing to initialize the DMA Stream source
177     and destination addresses, incrementation and data sizes, transfer direction,
178     buffer size, circular/normal mode selection, memory-to-memory mode selection
179     and Stream priority value.
180     [..]
181     The DMA_Init() function follows the DMA configuration procedures as described in
182     reference manual (RM0090) except the first point: waiting on EN bit to be reset.
183     This condition should be checked by user application using the function DMA_GetCmdStatus()
184     before calling the DMA_Init() function.
185 
186 @endverbatim
187   * @{
188   */
189 
190 /**
191   * @brief  Deinitialize the DMAy Streamx registers to their default reset values.
192   * @param  DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
193   *         to 7 to select the DMA Stream.
194   * @retval None
195   */
DMA_DeInit(DMA_Stream_TypeDef * DMAy_Streamx)196 void DMA_DeInit(DMA_Stream_TypeDef* DMAy_Streamx)
197 {
198   /* Check the parameters */
199   assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
200 
201   /* Disable the selected DMAy Streamx */
202   DMAy_Streamx->CR &= ~((uint32_t)DMA_SxCR_EN);
203 
204   /* Reset DMAy Streamx control register */
205   DMAy_Streamx->CR  = 0;
206 
207   /* Reset DMAy Streamx Number of Data to Transfer register */
208   DMAy_Streamx->NDTR = 0;
209 
210   /* Reset DMAy Streamx peripheral address register */
211   DMAy_Streamx->PAR  = 0;
212 
213   /* Reset DMAy Streamx memory 0 address register */
214   DMAy_Streamx->M0AR = 0;
215 
216   /* Reset DMAy Streamx memory 1 address register */
217   DMAy_Streamx->M1AR = 0;
218 
219   /* Reset DMAy Streamx FIFO control register */
220   DMAy_Streamx->FCR = (uint32_t)0x00000021;
221 
222   /* Reset interrupt pending bits for the selected stream */
223   if (DMAy_Streamx == DMA1_Stream0)
224   {
225     /* Reset interrupt pending bits for DMA1 Stream0 */
226     DMA1->LIFCR = DMA_Stream0_IT_MASK;
227   }
228   else if (DMAy_Streamx == DMA1_Stream1)
229   {
230     /* Reset interrupt pending bits for DMA1 Stream1 */
231     DMA1->LIFCR = DMA_Stream1_IT_MASK;
232   }
233   else if (DMAy_Streamx == DMA1_Stream2)
234   {
235     /* Reset interrupt pending bits for DMA1 Stream2 */
236     DMA1->LIFCR = DMA_Stream2_IT_MASK;
237   }
238   else if (DMAy_Streamx == DMA1_Stream3)
239   {
240     /* Reset interrupt pending bits for DMA1 Stream3 */
241     DMA1->LIFCR = DMA_Stream3_IT_MASK;
242   }
243   else if (DMAy_Streamx == DMA1_Stream4)
244   {
245     /* Reset interrupt pending bits for DMA1 Stream4 */
246     DMA1->HIFCR = DMA_Stream4_IT_MASK;
247   }
248   else if (DMAy_Streamx == DMA1_Stream5)
249   {
250     /* Reset interrupt pending bits for DMA1 Stream5 */
251     DMA1->HIFCR = DMA_Stream5_IT_MASK;
252   }
253   else if (DMAy_Streamx == DMA1_Stream6)
254   {
255     /* Reset interrupt pending bits for DMA1 Stream6 */
256     DMA1->HIFCR = (uint32_t)DMA_Stream6_IT_MASK;
257   }
258   else if (DMAy_Streamx == DMA1_Stream7)
259   {
260     /* Reset interrupt pending bits for DMA1 Stream7 */
261     DMA1->HIFCR = DMA_Stream7_IT_MASK;
262   }
263   else if (DMAy_Streamx == DMA2_Stream0)
264   {
265     /* Reset interrupt pending bits for DMA2 Stream0 */
266     DMA2->LIFCR = DMA_Stream0_IT_MASK;
267   }
268   else if (DMAy_Streamx == DMA2_Stream1)
269   {
270     /* Reset interrupt pending bits for DMA2 Stream1 */
271     DMA2->LIFCR = DMA_Stream1_IT_MASK;
272   }
273   else if (DMAy_Streamx == DMA2_Stream2)
274   {
275     /* Reset interrupt pending bits for DMA2 Stream2 */
276     DMA2->LIFCR = DMA_Stream2_IT_MASK;
277   }
278   else if (DMAy_Streamx == DMA2_Stream3)
279   {
280     /* Reset interrupt pending bits for DMA2 Stream3 */
281     DMA2->LIFCR = DMA_Stream3_IT_MASK;
282   }
283   else if (DMAy_Streamx == DMA2_Stream4)
284   {
285     /* Reset interrupt pending bits for DMA2 Stream4 */
286     DMA2->HIFCR = DMA_Stream4_IT_MASK;
287   }
288   else if (DMAy_Streamx == DMA2_Stream5)
289   {
290     /* Reset interrupt pending bits for DMA2 Stream5 */
291     DMA2->HIFCR = DMA_Stream5_IT_MASK;
292   }
293   else if (DMAy_Streamx == DMA2_Stream6)
294   {
295     /* Reset interrupt pending bits for DMA2 Stream6 */
296     DMA2->HIFCR = DMA_Stream6_IT_MASK;
297   }
298   else
299   {
300     if (DMAy_Streamx == DMA2_Stream7)
301     {
302       /* Reset interrupt pending bits for DMA2 Stream7 */
303       DMA2->HIFCR = DMA_Stream7_IT_MASK;
304     }
305   }
306 }
307 
308 /**
309   * @brief  Initializes the DMAy Streamx according to the specified parameters in
310   *         the DMA_InitStruct structure.
311   * @note   Before calling this function, it is recommended to check that the Stream
312   *         is actually disabled using the function DMA_GetCmdStatus().
313   * @param  DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
314   *         to 7 to select the DMA Stream.
315   * @param  DMA_InitStruct: pointer to a DMA_InitTypeDef structure that contains
316   *         the configuration information for the specified DMA Stream.
317   * @retval None
318   */
DMA_Init(DMA_Stream_TypeDef * DMAy_Streamx,DMA_InitTypeDef * DMA_InitStruct)319 void DMA_Init(DMA_Stream_TypeDef* DMAy_Streamx, DMA_InitTypeDef* DMA_InitStruct)
320 {
321   uint32_t tmpreg = 0;
322 
323   /* Check the parameters */
324   assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
325   assert_param(IS_DMA_CHANNEL(DMA_InitStruct->DMA_Channel));
326   assert_param(IS_DMA_DIRECTION(DMA_InitStruct->DMA_DIR));
327   assert_param(IS_DMA_BUFFER_SIZE(DMA_InitStruct->DMA_BufferSize));
328   assert_param(IS_DMA_PERIPHERAL_INC_STATE(DMA_InitStruct->DMA_PeripheralInc));
329   assert_param(IS_DMA_MEMORY_INC_STATE(DMA_InitStruct->DMA_MemoryInc));
330   assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(DMA_InitStruct->DMA_PeripheralDataSize));
331   assert_param(IS_DMA_MEMORY_DATA_SIZE(DMA_InitStruct->DMA_MemoryDataSize));
332   assert_param(IS_DMA_MODE(DMA_InitStruct->DMA_Mode));
333   assert_param(IS_DMA_PRIORITY(DMA_InitStruct->DMA_Priority));
334   assert_param(IS_DMA_FIFO_MODE_STATE(DMA_InitStruct->DMA_FIFOMode));
335   assert_param(IS_DMA_FIFO_THRESHOLD(DMA_InitStruct->DMA_FIFOThreshold));
336   assert_param(IS_DMA_MEMORY_BURST(DMA_InitStruct->DMA_MemoryBurst));
337   assert_param(IS_DMA_PERIPHERAL_BURST(DMA_InitStruct->DMA_PeripheralBurst));
338 
339   /*------------------------- DMAy Streamx CR Configuration ------------------*/
340   /* Get the DMAy_Streamx CR value */
341   tmpreg = DMAy_Streamx->CR;
342 
343   /* Clear CHSEL, MBURST, PBURST, PL, MSIZE, PSIZE, MINC, PINC, CIRC and DIR bits */
344   tmpreg &= ((uint32_t)~(DMA_SxCR_CHSEL | DMA_SxCR_MBURST | DMA_SxCR_PBURST | \
345                          DMA_SxCR_PL | DMA_SxCR_MSIZE | DMA_SxCR_PSIZE | \
346                          DMA_SxCR_MINC | DMA_SxCR_PINC | DMA_SxCR_CIRC | \
347                          DMA_SxCR_DIR));
348 
349   /* Configure DMAy Streamx: */
350   /* Set CHSEL bits according to DMA_CHSEL value */
351   /* Set DIR bits according to DMA_DIR value */
352   /* Set PINC bit according to DMA_PeripheralInc value */
353   /* Set MINC bit according to DMA_MemoryInc value */
354   /* Set PSIZE bits according to DMA_PeripheralDataSize value */
355   /* Set MSIZE bits according to DMA_MemoryDataSize value */
356   /* Set CIRC bit according to DMA_Mode value */
357   /* Set PL bits according to DMA_Priority value */
358   /* Set MBURST bits according to DMA_MemoryBurst value */
359   /* Set PBURST bits according to DMA_PeripheralBurst value */
360   tmpreg |= DMA_InitStruct->DMA_Channel | DMA_InitStruct->DMA_DIR |
361             DMA_InitStruct->DMA_PeripheralInc | DMA_InitStruct->DMA_MemoryInc |
362             DMA_InitStruct->DMA_PeripheralDataSize | DMA_InitStruct->DMA_MemoryDataSize |
363             DMA_InitStruct->DMA_Mode | DMA_InitStruct->DMA_Priority |
364             DMA_InitStruct->DMA_MemoryBurst | DMA_InitStruct->DMA_PeripheralBurst;
365 
366   /* Write to DMAy Streamx CR register */
367   DMAy_Streamx->CR = tmpreg;
368 
369   /*------------------------- DMAy Streamx FCR Configuration -----------------*/
370   /* Get the DMAy_Streamx FCR value */
371   tmpreg = DMAy_Streamx->FCR;
372 
373   /* Clear DMDIS and FTH bits */
374   tmpreg &= (uint32_t)~(DMA_SxFCR_DMDIS | DMA_SxFCR_FTH);
375 
376   /* Configure DMAy Streamx FIFO:
377     Set DMDIS bits according to DMA_FIFOMode value
378     Set FTH bits according to DMA_FIFOThreshold value */
379   tmpreg |= DMA_InitStruct->DMA_FIFOMode | DMA_InitStruct->DMA_FIFOThreshold;
380 
381   /* Write to DMAy Streamx CR */
382   DMAy_Streamx->FCR = tmpreg;
383 
384   /*------------------------- DMAy Streamx NDTR Configuration ----------------*/
385   /* Write to DMAy Streamx NDTR register */
386   DMAy_Streamx->NDTR = DMA_InitStruct->DMA_BufferSize;
387 
388   /*------------------------- DMAy Streamx PAR Configuration -----------------*/
389   /* Write to DMAy Streamx PAR */
390   DMAy_Streamx->PAR = DMA_InitStruct->DMA_PeripheralBaseAddr;
391 
392   /*------------------------- DMAy Streamx M0AR Configuration ----------------*/
393   /* Write to DMAy Streamx M0AR */
394   DMAy_Streamx->M0AR = DMA_InitStruct->DMA_Memory0BaseAddr;
395 }
396 
397 /**
398   * @brief  Fills each DMA_InitStruct member with its default value.
399   * @param  DMA_InitStruct : pointer to a DMA_InitTypeDef structure which will
400   *         be initialized.
401   * @retval None
402   */
DMA_StructInit(DMA_InitTypeDef * DMA_InitStruct)403 void DMA_StructInit(DMA_InitTypeDef* DMA_InitStruct)
404 {
405   /*-------------- Reset DMA init structure parameters values ----------------*/
406   /* Initialize the DMA_Channel member */
407   DMA_InitStruct->DMA_Channel = 0;
408 
409   /* Initialize the DMA_PeripheralBaseAddr member */
410   DMA_InitStruct->DMA_PeripheralBaseAddr = 0;
411 
412   /* Initialize the DMA_Memory0BaseAddr member */
413   DMA_InitStruct->DMA_Memory0BaseAddr = 0;
414 
415   /* Initialize the DMA_DIR member */
416   DMA_InitStruct->DMA_DIR = DMA_DIR_PeripheralToMemory;
417 
418   /* Initialize the DMA_BufferSize member */
419   DMA_InitStruct->DMA_BufferSize = 0;
420 
421   /* Initialize the DMA_PeripheralInc member */
422   DMA_InitStruct->DMA_PeripheralInc = DMA_PeripheralInc_Disable;
423 
424   /* Initialize the DMA_MemoryInc member */
425   DMA_InitStruct->DMA_MemoryInc = DMA_MemoryInc_Disable;
426 
427   /* Initialize the DMA_PeripheralDataSize member */
428   DMA_InitStruct->DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
429 
430   /* Initialize the DMA_MemoryDataSize member */
431   DMA_InitStruct->DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
432 
433   /* Initialize the DMA_Mode member */
434   DMA_InitStruct->DMA_Mode = DMA_Mode_Normal;
435 
436   /* Initialize the DMA_Priority member */
437   DMA_InitStruct->DMA_Priority = DMA_Priority_Low;
438 
439   /* Initialize the DMA_FIFOMode member */
440   DMA_InitStruct->DMA_FIFOMode = DMA_FIFOMode_Disable;
441 
442   /* Initialize the DMA_FIFOThreshold member */
443   DMA_InitStruct->DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
444 
445   /* Initialize the DMA_MemoryBurst member */
446   DMA_InitStruct->DMA_MemoryBurst = DMA_MemoryBurst_Single;
447 
448   /* Initialize the DMA_PeripheralBurst member */
449   DMA_InitStruct->DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
450 }
451 
452 /**
453   * @brief  Enables or disables the specified DMAy Streamx.
454   * @param  DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
455   *         to 7 to select the DMA Stream.
456   * @param  NewState: new state of the DMAy Streamx.
457   *          This parameter can be: ENABLE or DISABLE.
458   *
459   * @note  This function may be used to perform Pause-Resume operation. When a
460   *        transfer is ongoing, calling this function to disable the Stream will
461   *        cause the transfer to be paused. All configuration registers and the
462   *        number of remaining data will be preserved. When calling again this
463   *        function to re-enable the Stream, the transfer will be resumed from
464   *        the point where it was paused.
465   *
466   * @note  After configuring the DMA Stream (DMA_Init() function) and enabling the
467   *        stream, it is recommended to check (or wait until) the DMA Stream is
468   *        effectively enabled. A Stream may remain disabled if a configuration
469   *        parameter is wrong.
470   *        After disabling a DMA Stream, it is also recommended to check (or wait
471   *        until) the DMA Stream is effectively disabled. If a Stream is disabled
472   *        while a data transfer is ongoing, the current data will be transferred
473   *        and the Stream will be effectively disabled only after the transfer of
474   *        this single data is finished.
475   *
476   * @retval None
477   */
DMA_Cmd(DMA_Stream_TypeDef * DMAy_Streamx,FunctionalState NewState)478 void DMA_Cmd(DMA_Stream_TypeDef* DMAy_Streamx, FunctionalState NewState)
479 {
480   /* Check the parameters */
481   assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
482   assert_param(IS_FUNCTIONAL_STATE(NewState));
483 
484   if (NewState != DISABLE)
485   {
486     /* Enable the selected DMAy Streamx by setting EN bit */
487     DMAy_Streamx->CR |= (uint32_t)DMA_SxCR_EN;
488   }
489   else
490   {
491     /* Disable the selected DMAy Streamx by clearing EN bit */
492     DMAy_Streamx->CR &= ~(uint32_t)DMA_SxCR_EN;
493   }
494 }
495 
496 /**
497   * @brief  Configures, when the PINC (Peripheral Increment address mode) bit is
498   *         set, if the peripheral address should be incremented with the data
499   *         size (configured with PSIZE bits) or by a fixed offset equal to 4
500   *         (32-bit aligned addresses).
501   *
502   * @note   This function has no effect if the Peripheral Increment mode is disabled.
503   *
504   * @param  DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
505   *          to 7 to select the DMA Stream.
506   * @param  DMA_Pincos: specifies the Peripheral increment offset size.
507   *          This parameter can be one of the following values:
508   *            @arg DMA_PINCOS_Psize: Peripheral address increment is done
509   *                                   accordingly to PSIZE parameter.
510   *            @arg DMA_PINCOS_WordAligned: Peripheral address increment offset is
511   *                                         fixed to 4 (32-bit aligned addresses).
512   * @retval None
513   */
DMA_PeriphIncOffsetSizeConfig(DMA_Stream_TypeDef * DMAy_Streamx,uint32_t DMA_Pincos)514 void DMA_PeriphIncOffsetSizeConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_Pincos)
515 {
516   /* Check the parameters */
517   assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
518   assert_param(IS_DMA_PINCOS_SIZE(DMA_Pincos));
519 
520   /* Check the needed Peripheral increment offset */
521   if(DMA_Pincos != DMA_PINCOS_Psize)
522   {
523     /* Configure DMA_SxCR_PINCOS bit with the input parameter */
524     DMAy_Streamx->CR |= (uint32_t)DMA_SxCR_PINCOS;
525   }
526   else
527   {
528     /* Clear the PINCOS bit: Peripheral address incremented according to PSIZE */
529     DMAy_Streamx->CR &= ~(uint32_t)DMA_SxCR_PINCOS;
530   }
531 }
532 
533 /**
534   * @brief  Configures, when the DMAy Streamx is disabled, the flow controller for
535   *         the next transactions (Peripheral or Memory).
536   *
537   * @note   Before enabling this feature, check if the used peripheral supports
538   *         the Flow Controller mode or not.
539   *
540   * @param  DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
541   *          to 7 to select the DMA Stream.
542   * @param  DMA_FlowCtrl: specifies the DMA flow controller.
543   *          This parameter can be one of the following values:
544   *            @arg DMA_FlowCtrl_Memory: DMAy_Streamx transactions flow controller is
545   *                                      the DMA controller.
546   *            @arg DMA_FlowCtrl_Peripheral: DMAy_Streamx transactions flow controller
547   *                                          is the peripheral.
548   * @retval None
549   */
DMA_FlowControllerConfig(DMA_Stream_TypeDef * DMAy_Streamx,uint32_t DMA_FlowCtrl)550 void DMA_FlowControllerConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FlowCtrl)
551 {
552   /* Check the parameters */
553   assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
554   assert_param(IS_DMA_FLOW_CTRL(DMA_FlowCtrl));
555 
556   /* Check the needed flow controller  */
557   if(DMA_FlowCtrl != DMA_FlowCtrl_Memory)
558   {
559     /* Configure DMA_SxCR_PFCTRL bit with the input parameter */
560     DMAy_Streamx->CR |= (uint32_t)DMA_SxCR_PFCTRL;
561   }
562   else
563   {
564     /* Clear the PFCTRL bit: Memory is the flow controller */
565     DMAy_Streamx->CR &= ~(uint32_t)DMA_SxCR_PFCTRL;
566   }
567 }
568 /**
569   * @}
570   */
571 
572 /** @defgroup DMA_Group2 Data Counter functions
573  *  @brief   Data Counter functions
574  *
575 @verbatim
576  ===============================================================================
577                       ##### Data Counter functions #####
578  ===============================================================================
579     [..]
580     This subsection provides function allowing to configure and read the buffer size
581     (number of data to be transferred).
582     [..]
583     The DMA data counter can be written only when the DMA Stream is disabled
584     (ie. after transfer complete event).
585     [..]
586     The following function can be used to write the Stream data counter value:
587       (+) void DMA_SetCurrDataCounter(DMA_Stream_TypeDef* DMAy_Streamx, uint16_t Counter);
588       -@- It is advised to use this function rather than DMA_Init() in situations
589           where only the Data buffer needs to be reloaded.
590       -@- If the Source and Destination Data Sizes are different, then the value
591           written in data counter, expressing the number of transfers, is relative
592           to the number of transfers from the Peripheral point of view.
593           ie. If Memory data size is Word, Peripheral data size is Half-Words,
594           then the value to be configured in the data counter is the number
595           of Half-Words to be transferred from/to the peripheral.
596     [..]
597     The DMA data counter can be read to indicate the number of remaining transfers for
598     the relative DMA Stream. This counter is decremented at the end of each data
599     transfer and when the transfer is complete:
600       (+) If Normal mode is selected: the counter is set to 0.
601       (+) If Circular mode is selected: the counter is reloaded with the initial value
602           (configured before enabling the DMA Stream)
603      [..]
604      The following function can be used to read the Stream data counter value:
605        (+) uint16_t DMA_GetCurrDataCounter(DMA_Stream_TypeDef* DMAy_Streamx);
606 
607 @endverbatim
608   * @{
609   */
610 
611 /**
612   * @brief  Writes the number of data units to be transferred on the DMAy Streamx.
613   * @param  DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
614   *          to 7 to select the DMA Stream.
615   * @param  Counter: Number of data units to be transferred (from 0 to 65535)
616   *          Number of data items depends only on the Peripheral data format.
617   *
618   * @note   If Peripheral data format is Bytes: number of data units is equal
619   *         to total number of bytes to be transferred.
620   *
621   * @note   If Peripheral data format is Half-Word: number of data units is
622   *         equal to total number of bytes to be transferred / 2.
623   *
624   * @note   If Peripheral data format is Word: number of data units is equal
625   *         to total  number of bytes to be transferred / 4.
626   *
627   * @note   In Memory-to-Memory transfer mode, the memory buffer pointed by
628   *         DMAy_SxPAR register is considered as Peripheral.
629   *
630   * @retval The number of remaining data units in the current DMAy Streamx transfer.
631   */
DMA_SetCurrDataCounter(DMA_Stream_TypeDef * DMAy_Streamx,uint16_t Counter)632 void DMA_SetCurrDataCounter(DMA_Stream_TypeDef* DMAy_Streamx, uint16_t Counter)
633 {
634   /* Check the parameters */
635   assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
636 
637   /* Write the number of data units to be transferred */
638   DMAy_Streamx->NDTR = (uint16_t)Counter;
639 }
640 
641 /**
642   * @brief  Returns the number of remaining data units in the current DMAy Streamx transfer.
643   * @param  DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
644   *          to 7 to select the DMA Stream.
645   * @retval The number of remaining data units in the current DMAy Streamx transfer.
646   */
DMA_GetCurrDataCounter(DMA_Stream_TypeDef * DMAy_Streamx)647 uint16_t DMA_GetCurrDataCounter(DMA_Stream_TypeDef* DMAy_Streamx)
648 {
649   /* Check the parameters */
650   assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
651 
652   /* Return the number of remaining data units for DMAy Streamx */
653   return ((uint16_t)(DMAy_Streamx->NDTR));
654 }
655 /**
656   * @}
657   */
658 
659 /** @defgroup DMA_Group3 Double Buffer mode functions
660  *  @brief   Double Buffer mode functions
661  *
662 @verbatim
663  ===============================================================================
664                     ##### Double Buffer mode functions #####
665  ===============================================================================
666     [..]
667     This subsection provides function allowing to configure and control the double
668     buffer mode parameters.
669 
670     [..]
671     The Double Buffer mode can be used only when Circular mode is enabled.
672     The Double Buffer mode cannot be used when transferring data from Memory to Memory.
673 
674     [..]
675     The Double Buffer mode allows to set two different Memory addresses from/to which
676     the DMA controller will access alternatively (after completing transfer to/from
677     target memory 0, it will start transfer to/from target memory 1).
678     This allows to reduce software overhead for double buffering and reduce the CPU
679     access time.
680 
681     [..]
682     Two functions must be called before calling the DMA_Init() function:
683       (+) void DMA_DoubleBufferModeConfig(DMA_Stream_TypeDef* DMAy_Streamx,
684           uint32_t Memory1BaseAddr, uint32_t DMA_CurrentMemory);
685       (+) void DMA_DoubleBufferModeCmd(DMA_Stream_TypeDef* DMAy_Streamx, FunctionalState NewState);
686 
687     [..]
688     DMA_DoubleBufferModeConfig() is called to configure the Memory 1 base address
689     and the first Memory target from/to which the transfer will start after
690     enabling the DMA Stream. Then DMA_DoubleBufferModeCmd() must be called
691     to enable the Double Buffer mode (or disable it when it should not be used).
692 
693     [..]
694     Two functions can be called dynamically when the transfer is ongoing (or when the DMA Stream is
695     stopped) to modify on of the target Memories addresses or to check wich Memory target is currently
696     used:
697       (+) void DMA_MemoryTargetConfig(DMA_Stream_TypeDef* DMAy_Streamx,
698                 uint32_t MemoryBaseAddr, uint32_t DMA_MemoryTarget);
699       (+) uint32_t DMA_GetCurrentMemoryTarget(DMA_Stream_TypeDef* DMAy_Streamx);
700 
701     [..]
702     DMA_MemoryTargetConfig() can be called to modify the base address of one of
703     the two target Memories.
704     The Memory of which the base address will be modified must not be currently
705     be used by the DMA Stream (ie. if the DMA Stream is currently transferring
706     from Memory 1 then you can only modify base address of target Memory 0 and vice versa).
707     To check this condition, it is recommended to use the function DMA_GetCurrentMemoryTarget() which
708     returns the index of the Memory target currently in use by the DMA Stream.
709 
710 @endverbatim
711   * @{
712   */
713 
714 /**
715   * @brief  Configures, when the DMAy Streamx is disabled, the double buffer mode
716   *         and the current memory target.
717   * @param  DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
718   *          to 7 to select the DMA Stream.
719   * @param  Memory1BaseAddr: the base address of the second buffer (Memory 1)
720   * @param  DMA_CurrentMemory: specifies which memory will be first buffer for
721   *         the transactions when the Stream will be enabled.
722   *          This parameter can be one of the following values:
723   *            @arg DMA_Memory_0: Memory 0 is the current buffer.
724   *            @arg DMA_Memory_1: Memory 1 is the current buffer.
725   *
726   * @note   Memory0BaseAddr is set by the DMA structure configuration in DMA_Init().
727   *
728   * @retval None
729   */
DMA_DoubleBufferModeConfig(DMA_Stream_TypeDef * DMAy_Streamx,uint32_t Memory1BaseAddr,uint32_t DMA_CurrentMemory)730 void DMA_DoubleBufferModeConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t Memory1BaseAddr,
731                                 uint32_t DMA_CurrentMemory)
732 {
733   /* Check the parameters */
734   assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
735   assert_param(IS_DMA_CURRENT_MEM(DMA_CurrentMemory));
736 
737   if (DMA_CurrentMemory != DMA_Memory_0)
738   {
739     /* Set Memory 1 as current memory address */
740     DMAy_Streamx->CR |= (uint32_t)(DMA_SxCR_CT);
741   }
742   else
743   {
744     /* Set Memory 0 as current memory address */
745     DMAy_Streamx->CR &= ~(uint32_t)(DMA_SxCR_CT);
746   }
747 
748   /* Write to DMAy Streamx M1AR */
749   DMAy_Streamx->M1AR = Memory1BaseAddr;
750 }
751 
752 /**
753   * @brief  Enables or disables the double buffer mode for the selected DMA stream.
754   * @note   This function can be called only when the DMA Stream is disabled.
755   * @param  DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
756   *          to 7 to select the DMA Stream.
757   * @param  NewState: new state of the DMAy Streamx double buffer mode.
758   *          This parameter can be: ENABLE or DISABLE.
759   * @retval None
760   */
DMA_DoubleBufferModeCmd(DMA_Stream_TypeDef * DMAy_Streamx,FunctionalState NewState)761 void DMA_DoubleBufferModeCmd(DMA_Stream_TypeDef* DMAy_Streamx, FunctionalState NewState)
762 {
763   /* Check the parameters */
764   assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
765   assert_param(IS_FUNCTIONAL_STATE(NewState));
766 
767   /* Configure the Double Buffer mode */
768   if (NewState != DISABLE)
769   {
770     /* Enable the Double buffer mode */
771     DMAy_Streamx->CR |= (uint32_t)DMA_SxCR_DBM;
772   }
773   else
774   {
775     /* Disable the Double buffer mode */
776     DMAy_Streamx->CR &= ~(uint32_t)DMA_SxCR_DBM;
777   }
778 }
779 
780 /**
781   * @brief  Configures the Memory address for the next buffer transfer in double
782   *         buffer mode (for dynamic use). This function can be called when the
783   *         DMA Stream is enabled and when the transfer is ongoing.
784   * @param  DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
785   *          to 7 to select the DMA Stream.
786   * @param  MemoryBaseAddr: The base address of the target memory buffer
787   * @param  DMA_MemoryTarget: Next memory target to be used.
788   *         This parameter can be one of the following values:
789   *            @arg DMA_Memory_0: To use the memory address 0
790   *            @arg DMA_Memory_1: To use the memory address 1
791   *
792   * @note    It is not allowed to modify the Base Address of a target Memory when
793   *          this target is involved in the current transfer. ie. If the DMA Stream
794   *          is currently transferring to/from Memory 1, then it not possible to
795   *          modify Base address of Memory 1, but it is possible to modify Base
796   *          address of Memory 0.
797   *          To know which Memory is currently used, you can use the function
798   *          DMA_GetCurrentMemoryTarget().
799   *
800   * @retval None
801   */
DMA_MemoryTargetConfig(DMA_Stream_TypeDef * DMAy_Streamx,uint32_t MemoryBaseAddr,uint32_t DMA_MemoryTarget)802 void DMA_MemoryTargetConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t MemoryBaseAddr,
803                            uint32_t DMA_MemoryTarget)
804 {
805   /* Check the parameters */
806   assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
807   assert_param(IS_DMA_CURRENT_MEM(DMA_MemoryTarget));
808 
809   /* Check the Memory target to be configured */
810   if (DMA_MemoryTarget != DMA_Memory_0)
811   {
812     /* Write to DMAy Streamx M1AR */
813     DMAy_Streamx->M1AR = MemoryBaseAddr;
814   }
815   else
816   {
817     /* Write to DMAy Streamx M0AR */
818     DMAy_Streamx->M0AR = MemoryBaseAddr;
819   }
820 }
821 
822 /**
823   * @brief  Returns the current memory target used by double buffer transfer.
824   * @param  DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
825   *          to 7 to select the DMA Stream.
826   * @retval The memory target number: 0 for Memory0 or 1 for Memory1.
827   */
DMA_GetCurrentMemoryTarget(DMA_Stream_TypeDef * DMAy_Streamx)828 uint32_t DMA_GetCurrentMemoryTarget(DMA_Stream_TypeDef* DMAy_Streamx)
829 {
830   uint32_t tmp = 0;
831 
832   /* Check the parameters */
833   assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
834 
835   /* Get the current memory target */
836   if ((DMAy_Streamx->CR & DMA_SxCR_CT) != 0)
837   {
838     /* Current memory buffer used is Memory 1 */
839     tmp = 1;
840   }
841   else
842   {
843     /* Current memory buffer used is Memory 0 */
844     tmp = 0;
845   }
846   return tmp;
847 }
848 /**
849   * @}
850   */
851 
852 /** @defgroup DMA_Group4 Interrupts and flags management functions
853  *  @brief   Interrupts and flags management functions
854  *
855 @verbatim
856  ===============================================================================
857               ##### Interrupts and flags management functions #####
858  ===============================================================================
859     [..]
860     This subsection provides functions allowing to
861       (+) Check the DMA enable status
862       (+) Check the FIFO status
863       (+) Configure the DMA Interrupts sources and check or clear the flags or
864           pending bits status.
865 
866     [..]
867       (#) DMA Enable status:
868           After configuring the DMA Stream (DMA_Init() function) and enabling
869           the stream, it is recommended to check (or wait until) the DMA Stream
870           is effectively enabled. A Stream may remain disabled if a configuration
871           parameter is wrong. After disabling a DMA Stream, it is also recommended
872           to check (or wait until) the DMA Stream is effectively disabled.
873           If a Stream is disabled while a data transfer is ongoing, the current
874           data will be transferred and the Stream will be effectively disabled
875           only after this data transfer completion.
876           To monitor this state it is possible to use the following function:
877         (++) FunctionalState DMA_GetCmdStatus(DMA_Stream_TypeDef* DMAy_Streamx);
878 
879       (#) FIFO Status:
880           It is possible to monitor the FIFO status when a transfer is ongoing
881           using the following function:
882         (++) uint32_t DMA_GetFIFOStatus(DMA_Stream_TypeDef* DMAy_Streamx);
883 
884       (#) DMA Interrupts and Flags:
885           The user should identify which mode will be used in his application
886           to manage the DMA controller events: Polling mode or Interrupt mode.
887 
888     *** Polling Mode ***
889     ====================
890     [..]
891     Each DMA stream can be managed through 4 event Flags:
892     (x : DMA Stream number )
893       (#) DMA_FLAG_FEIFx  : to indicate that a FIFO Mode Transfer Error event occurred.
894       (#) DMA_FLAG_DMEIFx : to indicate that a Direct Mode Transfer Error event occurred.
895       (#) DMA_FLAG_TEIFx  : to indicate that a Transfer Error event occurred.
896       (#) DMA_FLAG_HTIFx  : to indicate that a Half-Transfer Complete event occurred.
897       (#) DMA_FLAG_TCIFx  : to indicate that a Transfer Complete event occurred .
898     [..]
899     In this Mode it is advised to use the following functions:
900       (+) FlagStatus DMA_GetFlagStatus(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FLAG);
901       (+) void DMA_ClearFlag(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FLAG);
902 
903     *** Interrupt Mode ***
904     ======================
905     [..]
906     Each DMA Stream can be managed through 4 Interrupts:
907 
908     *** Interrupt Source ***
909     ========================
910     [..]
911       (#) DMA_IT_FEIFx  : specifies the interrupt source for the  FIFO Mode Transfer Error event.
912       (#) DMA_IT_DMEIFx : specifies the interrupt source for the Direct Mode Transfer Error event.
913       (#) DMA_IT_TEIFx  : specifies the interrupt source for the Transfer Error event.
914       (#) DMA_IT_HTIFx  : specifies the interrupt source for the Half-Transfer Complete event.
915       (#) DMA_IT_TCIFx  : specifies the interrupt source for the a Transfer Complete event.
916     [..]
917     In this Mode it is advised to use the following functions:
918       (+) void DMA_ITConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT, FunctionalState NewState);
919       (+) ITStatus DMA_GetITStatus(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT);
920       (+) void DMA_ClearITPendingBit(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT);
921 
922 @endverbatim
923   * @{
924   */
925 
926 /**
927   * @brief  Returns the status of EN bit for the specified DMAy Streamx.
928   * @param  DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
929   *          to 7 to select the DMA Stream.
930   *
931   * @note    After configuring the DMA Stream (DMA_Init() function) and enabling
932   *          the stream, it is recommended to check (or wait until) the DMA Stream
933   *          is effectively enabled. A Stream may remain disabled if a configuration
934   *          parameter is wrong.
935   *          After disabling a DMA Stream, it is also recommended to check (or wait
936   *          until) the DMA Stream is effectively disabled. If a Stream is disabled
937   *          while a data transfer is ongoing, the current data will be transferred
938   *          and the Stream will be effectively disabled only after the transfer
939   *          of this single data is finished.
940   *
941   * @retval Current state of the DMAy Streamx (ENABLE or DISABLE).
942   */
DMA_GetCmdStatus(DMA_Stream_TypeDef * DMAy_Streamx)943 FunctionalState DMA_GetCmdStatus(DMA_Stream_TypeDef* DMAy_Streamx)
944 {
945   FunctionalState state = DISABLE;
946 
947   /* Check the parameters */
948   assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
949 
950   if ((DMAy_Streamx->CR & (uint32_t)DMA_SxCR_EN) != 0)
951   {
952     /* The selected DMAy Streamx EN bit is set (DMA is still transferring) */
953     state = ENABLE;
954   }
955   else
956   {
957     /* The selected DMAy Streamx EN bit is cleared (DMA is disabled and
958         all transfers are complete) */
959     state = DISABLE;
960   }
961   return state;
962 }
963 
964 /**
965   * @brief  Returns the current DMAy Streamx FIFO filled level.
966   * @param  DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
967   *         to 7 to select the DMA Stream.
968   * @retval The FIFO filling state.
969   *           - DMA_FIFOStatus_Less1QuarterFull: when FIFO is less than 1 quarter-full
970   *                                               and not empty.
971   *           - DMA_FIFOStatus_1QuarterFull: if more than 1 quarter-full.
972   *           - DMA_FIFOStatus_HalfFull: if more than 1 half-full.
973   *           - DMA_FIFOStatus_3QuartersFull: if more than 3 quarters-full.
974   *           - DMA_FIFOStatus_Empty: when FIFO is empty
975   *           - DMA_FIFOStatus_Full: when FIFO is full
976   */
DMA_GetFIFOStatus(DMA_Stream_TypeDef * DMAy_Streamx)977 uint32_t DMA_GetFIFOStatus(DMA_Stream_TypeDef* DMAy_Streamx)
978 {
979   uint32_t tmpreg = 0;
980 
981   /* Check the parameters */
982   assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
983 
984   /* Get the FIFO level bits */
985   tmpreg = (uint32_t)((DMAy_Streamx->FCR & DMA_SxFCR_FS));
986 
987   return tmpreg;
988 }
989 
990 /**
991   * @brief  Checks whether the specified DMAy Streamx flag is set or not.
992   * @param  DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
993   *          to 7 to select the DMA Stream.
994   * @param  DMA_FLAG: specifies the flag to check.
995   *          This parameter can be one of the following values:
996   *            @arg DMA_FLAG_TCIFx:  Streamx transfer complete flag
997   *            @arg DMA_FLAG_HTIFx:  Streamx half transfer complete flag
998   *            @arg DMA_FLAG_TEIFx:  Streamx transfer error flag
999   *            @arg DMA_FLAG_DMEIFx: Streamx direct mode error flag
1000   *            @arg DMA_FLAG_FEIFx:  Streamx FIFO error flag
1001   *         Where x can be 0 to 7 to select the DMA Stream.
1002   * @retval The new state of DMA_FLAG (SET or RESET).
1003   */
DMA_GetFlagStatus(DMA_Stream_TypeDef * DMAy_Streamx,uint32_t DMA_FLAG)1004 FlagStatus DMA_GetFlagStatus(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FLAG)
1005 {
1006   FlagStatus bitstatus = RESET;
1007   DMA_TypeDef* DMAy;
1008   uint32_t tmpreg = 0;
1009 
1010   /* Check the parameters */
1011   assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
1012   assert_param(IS_DMA_GET_FLAG(DMA_FLAG));
1013 
1014   /* Determine the DMA to which belongs the stream */
1015   if (DMAy_Streamx < DMA2_Stream0)
1016   {
1017     /* DMAy_Streamx belongs to DMA1 */
1018     DMAy = DMA1;
1019   }
1020   else
1021   {
1022     /* DMAy_Streamx belongs to DMA2 */
1023     DMAy = DMA2;
1024   }
1025 
1026   /* Check if the flag is in HISR or LISR */
1027   if ((DMA_FLAG & HIGH_ISR_MASK) != (uint32_t)RESET)
1028   {
1029     /* Get DMAy HISR register value */
1030     tmpreg = DMAy->HISR;
1031   }
1032   else
1033   {
1034     /* Get DMAy LISR register value */
1035     tmpreg = DMAy->LISR;
1036   }
1037 
1038   /* Mask the reserved bits */
1039   tmpreg &= (uint32_t)RESERVED_MASK;
1040 
1041   /* Check the status of the specified DMA flag */
1042   if ((tmpreg & DMA_FLAG) != (uint32_t)RESET)
1043   {
1044     /* DMA_FLAG is set */
1045     bitstatus = SET;
1046   }
1047   else
1048   {
1049     /* DMA_FLAG is reset */
1050     bitstatus = RESET;
1051   }
1052 
1053   /* Return the DMA_FLAG status */
1054   return  bitstatus;
1055 }
1056 
1057 /**
1058   * @brief  Clears the DMAy Streamx's pending flags.
1059   * @param  DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
1060   *          to 7 to select the DMA Stream.
1061   * @param  DMA_FLAG: specifies the flag to clear.
1062   *          This parameter can be any combination of the following values:
1063   *            @arg DMA_FLAG_TCIFx:  Streamx transfer complete flag
1064   *            @arg DMA_FLAG_HTIFx:  Streamx half transfer complete flag
1065   *            @arg DMA_FLAG_TEIFx:  Streamx transfer error flag
1066   *            @arg DMA_FLAG_DMEIFx: Streamx direct mode error flag
1067   *            @arg DMA_FLAG_FEIFx:  Streamx FIFO error flag
1068   *         Where x can be 0 to 7 to select the DMA Stream.
1069   * @retval None
1070   */
DMA_ClearFlag(DMA_Stream_TypeDef * DMAy_Streamx,uint32_t DMA_FLAG)1071 void DMA_ClearFlag(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_FLAG)
1072 {
1073   DMA_TypeDef* DMAy;
1074 
1075   /* Check the parameters */
1076   assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
1077   assert_param(IS_DMA_CLEAR_FLAG(DMA_FLAG));
1078 
1079   /* Determine the DMA to which belongs the stream */
1080   if (DMAy_Streamx < DMA2_Stream0)
1081   {
1082     /* DMAy_Streamx belongs to DMA1 */
1083     DMAy = DMA1;
1084   }
1085   else
1086   {
1087     /* DMAy_Streamx belongs to DMA2 */
1088     DMAy = DMA2;
1089   }
1090 
1091   /* Check if LIFCR or HIFCR register is targeted */
1092   if ((DMA_FLAG & HIGH_ISR_MASK) != (uint32_t)RESET)
1093   {
1094     /* Set DMAy HIFCR register clear flag bits */
1095     DMAy->HIFCR = (uint32_t)(DMA_FLAG & RESERVED_MASK);
1096   }
1097   else
1098   {
1099     /* Set DMAy LIFCR register clear flag bits */
1100     DMAy->LIFCR = (uint32_t)(DMA_FLAG & RESERVED_MASK);
1101   }
1102 }
1103 
1104 /**
1105   * @brief  Enables or disables the specified DMAy Streamx interrupts.
1106   * @param  DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
1107   *          to 7 to select the DMA Stream.
1108   * @param DMA_IT: specifies the DMA interrupt sources to be enabled or disabled.
1109   *          This parameter can be any combination of the following values:
1110   *            @arg DMA_IT_TC:  Transfer complete interrupt mask
1111   *            @arg DMA_IT_HT:  Half transfer complete interrupt mask
1112   *            @arg DMA_IT_TE:  Transfer error interrupt mask
1113   *            @arg DMA_IT_FE:  FIFO error interrupt mask
1114   * @param  NewState: new state of the specified DMA interrupts.
1115   *          This parameter can be: ENABLE or DISABLE.
1116   * @retval None
1117   */
DMA_ITConfig(DMA_Stream_TypeDef * DMAy_Streamx,uint32_t DMA_IT,FunctionalState NewState)1118 void DMA_ITConfig(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT, FunctionalState NewState)
1119 {
1120   /* Check the parameters */
1121   assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
1122   assert_param(IS_DMA_CONFIG_IT(DMA_IT));
1123   assert_param(IS_FUNCTIONAL_STATE(NewState));
1124 
1125   /* Check if the DMA_IT parameter contains a FIFO interrupt */
1126   if ((DMA_IT & DMA_IT_FE) != 0)
1127   {
1128     if (NewState != DISABLE)
1129     {
1130       /* Enable the selected DMA FIFO interrupts */
1131       DMAy_Streamx->FCR |= (uint32_t)DMA_IT_FE;
1132     }
1133     else
1134     {
1135       /* Disable the selected DMA FIFO interrupts */
1136       DMAy_Streamx->FCR &= ~(uint32_t)DMA_IT_FE;
1137     }
1138   }
1139 
1140   /* Check if the DMA_IT parameter contains a Transfer interrupt */
1141   if (DMA_IT != DMA_IT_FE)
1142   {
1143     if (NewState != DISABLE)
1144     {
1145       /* Enable the selected DMA transfer interrupts */
1146       DMAy_Streamx->CR |= (uint32_t)(DMA_IT  & TRANSFER_IT_ENABLE_MASK);
1147     }
1148     else
1149     {
1150       /* Disable the selected DMA transfer interrupts */
1151       DMAy_Streamx->CR &= ~(uint32_t)(DMA_IT & TRANSFER_IT_ENABLE_MASK);
1152     }
1153   }
1154 }
1155 
1156 /**
1157   * @brief  Checks whether the specified DMAy Streamx interrupt has occurred or not.
1158   * @param  DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
1159   *          to 7 to select the DMA Stream.
1160   * @param  DMA_IT: specifies the DMA interrupt source to check.
1161   *          This parameter can be one of the following values:
1162   *            @arg DMA_IT_TCIFx:  Streamx transfer complete interrupt
1163   *            @arg DMA_IT_HTIFx:  Streamx half transfer complete interrupt
1164   *            @arg DMA_IT_TEIFx:  Streamx transfer error interrupt
1165   *            @arg DMA_IT_DMEIFx: Streamx direct mode error interrupt
1166   *            @arg DMA_IT_FEIFx:  Streamx FIFO error interrupt
1167   *         Where x can be 0 to 7 to select the DMA Stream.
1168   * @retval The new state of DMA_IT (SET or RESET).
1169   */
DMA_GetITStatus(DMA_Stream_TypeDef * DMAy_Streamx,uint32_t DMA_IT)1170 ITStatus DMA_GetITStatus(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT)
1171 {
1172   ITStatus bitstatus = RESET;
1173   DMA_TypeDef* DMAy;
1174   uint32_t tmpreg = 0, enablestatus = 0;
1175 
1176   /* Check the parameters */
1177   assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
1178   assert_param(IS_DMA_GET_IT(DMA_IT));
1179 
1180   /* Determine the DMA to which belongs the stream */
1181   if (DMAy_Streamx < DMA2_Stream0)
1182   {
1183     /* DMAy_Streamx belongs to DMA1 */
1184     DMAy = DMA1;
1185   }
1186   else
1187   {
1188     /* DMAy_Streamx belongs to DMA2 */
1189     DMAy = DMA2;
1190   }
1191 
1192   /* Check if the interrupt enable bit is in the CR or FCR register */
1193   if ((DMA_IT & TRANSFER_IT_MASK) != (uint32_t)RESET)
1194   {
1195     /* Get the interrupt enable position mask in CR register */
1196     tmpreg = (uint32_t)((DMA_IT >> 11) & TRANSFER_IT_ENABLE_MASK);
1197 
1198     /* Check the enable bit in CR register */
1199     enablestatus = (uint32_t)(DMAy_Streamx->CR & tmpreg);
1200   }
1201   else
1202   {
1203     /* Check the enable bit in FCR register */
1204     enablestatus = (uint32_t)(DMAy_Streamx->FCR & DMA_IT_FE);
1205   }
1206 
1207   /* Check if the interrupt pending flag is in LISR or HISR */
1208   if ((DMA_IT & HIGH_ISR_MASK) != (uint32_t)RESET)
1209   {
1210     /* Get DMAy HISR register value */
1211     tmpreg = DMAy->HISR ;
1212   }
1213   else
1214   {
1215     /* Get DMAy LISR register value */
1216     tmpreg = DMAy->LISR ;
1217   }
1218 
1219   /* mask all reserved bits */
1220   tmpreg &= (uint32_t)RESERVED_MASK;
1221 
1222   /* Check the status of the specified DMA interrupt */
1223   if (((tmpreg & DMA_IT) != (uint32_t)RESET) && (enablestatus != (uint32_t)RESET))
1224   {
1225     /* DMA_IT is set */
1226     bitstatus = SET;
1227   }
1228   else
1229   {
1230     /* DMA_IT is reset */
1231     bitstatus = RESET;
1232   }
1233 
1234   /* Return the DMA_IT status */
1235   return  bitstatus;
1236 }
1237 
1238 /**
1239   * @brief  Clears the DMAy Streamx's interrupt pending bits.
1240   * @param  DMAy_Streamx: where y can be 1 or 2 to select the DMA and x can be 0
1241   *          to 7 to select the DMA Stream.
1242   * @param  DMA_IT: specifies the DMA interrupt pending bit to clear.
1243   *          This parameter can be any combination of the following values:
1244   *            @arg DMA_IT_TCIFx:  Streamx transfer complete interrupt
1245   *            @arg DMA_IT_HTIFx:  Streamx half transfer complete interrupt
1246   *            @arg DMA_IT_TEIFx:  Streamx transfer error interrupt
1247   *            @arg DMA_IT_DMEIFx: Streamx direct mode error interrupt
1248   *            @arg DMA_IT_FEIFx:  Streamx FIFO error interrupt
1249   *         Where x can be 0 to 7 to select the DMA Stream.
1250   * @retval None
1251   */
DMA_ClearITPendingBit(DMA_Stream_TypeDef * DMAy_Streamx,uint32_t DMA_IT)1252 void DMA_ClearITPendingBit(DMA_Stream_TypeDef* DMAy_Streamx, uint32_t DMA_IT)
1253 {
1254   DMA_TypeDef* DMAy;
1255 
1256   /* Check the parameters */
1257   assert_param(IS_DMA_ALL_PERIPH(DMAy_Streamx));
1258   assert_param(IS_DMA_CLEAR_IT(DMA_IT));
1259 
1260   /* Determine the DMA to which belongs the stream */
1261   if (DMAy_Streamx < DMA2_Stream0)
1262   {
1263     /* DMAy_Streamx belongs to DMA1 */
1264     DMAy = DMA1;
1265   }
1266   else
1267   {
1268     /* DMAy_Streamx belongs to DMA2 */
1269     DMAy = DMA2;
1270   }
1271 
1272   /* Check if LIFCR or HIFCR register is targeted */
1273   if ((DMA_IT & HIGH_ISR_MASK) != (uint32_t)RESET)
1274   {
1275     /* Set DMAy HIFCR register clear interrupt bits */
1276     DMAy->HIFCR = (uint32_t)(DMA_IT & RESERVED_MASK);
1277   }
1278   else
1279   {
1280     /* Set DMAy LIFCR register clear interrupt bits */
1281     DMAy->LIFCR = (uint32_t)(DMA_IT & RESERVED_MASK);
1282   }
1283 }
1284 
1285 /**
1286   * @}
1287   */
1288 
1289 /**
1290   * @}
1291   */
1292 
1293 /**
1294   * @}
1295   */
1296 
1297 /**
1298   * @}
1299   */
1300 
1301 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1302