amiro-blt / Target / Demo / ARMCM4_STM32F405_Power_Management_GCC / Boot / lib / stdperiphlib / STM32F4xx_StdPeriph_Driver / src / stm32f4xx_dma.c @ 69661903
History | View | Annotate | Download (51.7 KB)
1 |
/**
|
---|---|
2 |
******************************************************************************
|
3 |
* @file stm32f4xx_dma.c
|
4 |
* @author MCD Application Team
|
5 |
* @version V1.1.0
|
6 |
* @date 11-January-2013
|
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>© COPYRIGHT 2013 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 |
*/
|
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 |
*/
|
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 |
*/
|
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 |
*/
|
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 |
*/
|
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 |
*/
|
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 |
*/
|
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 |
*/
|
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 |
*/
|
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 |
*/
|
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 |
*/
|
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 |
*/
|
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 |
*/
|
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 |
*/
|
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 |
*/
|
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 |
*/
|
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 |
*/
|
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 |
*/
|
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 |
*/
|
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****/
|