aboutsummaryrefslogtreecommitdiff
path: root/lib/chibios/os/hal/ports/STM32/LLD/DMAv1
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chibios/os/hal/ports/STM32/LLD/DMAv1')
-rw-r--r--lib/chibios/os/hal/ports/STM32/LLD/DMAv1/driver.mk2
-rw-r--r--lib/chibios/os/hal/ports/STM32/LLD/DMAv1/notes.txt26
-rw-r--r--lib/chibios/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c816
-rw-r--r--lib/chibios/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.h554
-rw-r--r--lib/chibios/os/hal/ports/STM32/LLD/DMAv1/stm32_dma1_ch23.inc78
-rw-r--r--lib/chibios/os/hal/ports/STM32/LLD/DMAv1/stm32_dma1_ch4567.inc90
6 files changed, 1566 insertions, 0 deletions
diff --git a/lib/chibios/os/hal/ports/STM32/LLD/DMAv1/driver.mk b/lib/chibios/os/hal/ports/STM32/LLD/DMAv1/driver.mk
new file mode 100644
index 000000000..b4be3ab9d
--- /dev/null
+++ b/lib/chibios/os/hal/ports/STM32/LLD/DMAv1/driver.mk
@@ -0,0 +1,2 @@
1PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c
2PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1
diff --git a/lib/chibios/os/hal/ports/STM32/LLD/DMAv1/notes.txt b/lib/chibios/os/hal/ports/STM32/LLD/DMAv1/notes.txt
new file mode 100644
index 000000000..562f45fb5
--- /dev/null
+++ b/lib/chibios/os/hal/ports/STM32/LLD/DMAv1/notes.txt
@@ -0,0 +1,26 @@
1STM32 DMAv1 driver.
2
3Driver capability:
4
5- The driver supports the STM32 traditional DMA controller in the following
6 configurations: 5ch, 7ch, 7ch+5ch, 7ch+7ch.
7- Support for automatic the channel selection through the CSELR register.
8- For devices without CSELR register it is possible to select channels but
9 the SYSCFG CFGR register is not configured, the user has to configure it
10 before starting the DMA driver.
11- The driver supports shared ISR handlers with a quirk: the IRQ priority is
12 established by the first allocated channel among the channels sharing the
13 ISR.
14
15The file registry must export:
16
17STM32_ADVANCED_DMA - TRUE not used by the DMA drivers but other
18 drivers use it to enable checks on DMA
19 channels. Probably will be removed in the
20 future.
21STM32_DMA_SUPPORTS_CSELR - TRUE if the DMA have a CSELR register.
22STM32_DMA_SUPPORTS_DMAMUX - TRUE if the DMA is riven by a DMAMUX.
23STM32_DMAn_NUM_CHANNELS - Number of channels in DMAs "n" (1..2).
24STM32_DMAn_CHx_HANDLER - Vector name for IRQ "x" (1..7). If the macro
25 is not exported then the ISR is not declared.
26STM32_DMAn_CHx_NUMBER - Vector number for IRQ "x" (1..7).
diff --git a/lib/chibios/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c b/lib/chibios/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c
new file mode 100644
index 000000000..65fa5e8bc
--- /dev/null
+++ b/lib/chibios/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c
@@ -0,0 +1,816 @@
1/*
2 ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/**
18 * @file DMAv1/stm32_dma.c
19 * @brief DMA helper driver code.
20 *
21 * @addtogroup STM32_DMA
22 * @details DMA sharing helper driver. In the STM32 the DMA streams are a
23 * shared resource, this driver allows to allocate and free DMA
24 * streams at runtime in order to allow all the other device
25 * drivers to coordinate the access to the resource.
26 * @note The DMA ISR handlers are all declared into this module because
27 * sharing, the various device drivers can associate a callback to
28 * ISRs when allocating streams.
29 * @{
30 */
31
32#include "hal.h"
33
34/* The following macro is only defined if some driver requiring DMA services
35 has been enabled.*/
36#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__)
37
38/*===========================================================================*/
39/* Driver local definitions. */
40/*===========================================================================*/
41
42/**
43 * @brief Mask of the DMA1 streams in @p dma_streams_mask.
44 */
45#define STM32_DMA1_STREAMS_MASK ((1U << STM32_DMA1_NUM_CHANNELS) - 1U)
46
47/**
48 * @brief Mask of the DMA2 streams in @p dma_streams_mask.
49 */
50#define STM32_DMA2_STREAMS_MASK (((1U << STM32_DMA2_NUM_CHANNELS) - \
51 1U) << STM32_DMA1_NUM_CHANNELS)
52
53#if STM32_DMA_SUPPORTS_CSELR == TRUE
54
55#if defined(DMA1_CSELR)
56#define __DMA1_CSELR &DMA1_CSELR->CSELR
57#else
58#define __DMA1_CSELR &DMA1->CSELR
59#endif
60
61#if defined(DMA2_CSELR)
62#define __DMA2_CSELR &DMA2_CSELR->CSELR
63#else
64#define __DMA2_CSELR &DMA2->CSELR
65#endif
66
67#define DMA1_CH1_VARIANT __DMA1_CSELR
68#define DMA1_CH2_VARIANT __DMA1_CSELR
69#define DMA1_CH3_VARIANT __DMA1_CSELR
70#define DMA1_CH4_VARIANT __DMA1_CSELR
71#define DMA1_CH5_VARIANT __DMA1_CSELR
72#define DMA1_CH6_VARIANT __DMA1_CSELR
73#define DMA1_CH7_VARIANT __DMA1_CSELR
74#define DMA1_CH8_VARIANT __DMA1_CSELR
75#define DMA2_CH1_VARIANT __DMA2_CSELR
76#define DMA2_CH2_VARIANT __DMA2_CSELR
77#define DMA2_CH3_VARIANT __DMA2_CSELR
78#define DMA2_CH4_VARIANT __DMA2_CSELR
79#define DMA2_CH5_VARIANT __DMA2_CSELR
80#define DMA2_CH6_VARIANT __DMA2_CSELR
81#define DMA2_CH7_VARIANT __DMA2_CSELR
82#define DMA2_CH8_VARIANT __DMA2_CSELR
83
84#elif STM32_DMA_SUPPORTS_DMAMUX == TRUE
85
86#define DMAMUX1_CHANNEL(id) (DMAMUX1_BASE + ((id) * 4U))
87
88#define DMA1_CH1_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(0))
89#define DMA1_CH2_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(1))
90#define DMA1_CH3_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(2))
91#define DMA1_CH4_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(3))
92#define DMA1_CH5_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(4))
93#define DMA1_CH6_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(5))
94#define DMA1_CH7_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(6))
95#define DMA1_CH8_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(7))
96#define DMA2_CH1_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(0 + STM32_DMA1_NUM_CHANNELS))
97#define DMA2_CH2_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(1 + STM32_DMA1_NUM_CHANNELS))
98#define DMA2_CH3_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(2 + STM32_DMA1_NUM_CHANNELS))
99#define DMA2_CH4_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(3 + STM32_DMA1_NUM_CHANNELS))
100#define DMA2_CH5_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(4 + STM32_DMA1_NUM_CHANNELS))
101#define DMA2_CH6_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(5 + STM32_DMA1_NUM_CHANNELS))
102#define DMA2_CH7_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(6 + STM32_DMA1_NUM_CHANNELS))
103#define DMA2_CH8_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(7 + STM32_DMA1_NUM_CHANNELS))
104
105#else /* !(STM32_DMA_SUPPORTS_DMAMUX == TRUE) */
106
107#define DMA1_CH1_VARIANT 0
108#define DMA1_CH2_VARIANT 0
109#define DMA1_CH3_VARIANT 0
110#define DMA1_CH4_VARIANT 0
111#define DMA1_CH5_VARIANT 0
112#define DMA1_CH6_VARIANT 0
113#define DMA1_CH7_VARIANT 0
114#define DMA2_CH1_VARIANT 0
115#define DMA2_CH2_VARIANT 0
116#define DMA2_CH3_VARIANT 0
117#define DMA2_CH4_VARIANT 0
118#define DMA2_CH5_VARIANT 0
119#define DMA2_CH6_VARIANT 0
120#define DMA2_CH7_VARIANT 0
121
122#endif /* !(STM32_DMA_SUPPORTS_DMAMUX == TRUE) */
123
124/*
125 * Default ISR collision masks.
126 */
127#if !defined(STM32_DMA1_CH1_CMASK)
128#define STM32_DMA1_CH1_CMASK (1U << 0U)
129#endif
130
131#if !defined(STM32_DMA1_CH2_CMASK)
132#define STM32_DMA1_CH2_CMASK (1U << 1U)
133#endif
134
135#if !defined(STM32_DMA1_CH3_CMASK)
136#define STM32_DMA1_CH3_CMASK (1U << 2U)
137#endif
138
139#if !defined(STM32_DMA1_CH4_CMASK)
140#define STM32_DMA1_CH4_CMASK (1U << 3U)
141#endif
142
143#if !defined(STM32_DMA1_CH5_CMASK)
144#define STM32_DMA1_CH5_CMASK (1U << 4U)
145#endif
146
147#if !defined(STM32_DMA1_CH6_CMASK)
148#define STM32_DMA1_CH6_CMASK (1U << 5U)
149#endif
150
151#if !defined(STM32_DMA1_CH7_CMASK)
152#define STM32_DMA1_CH7_CMASK (1U << 6U)
153#endif
154
155#if !defined(STM32_DMA1_CH8_CMASK)
156#define STM32_DMA1_CH8_CMASK (1U << 7U)
157#endif
158
159#if !defined(STM32_DMA2_CH1_CMASK)
160#define STM32_DMA2_CH1_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 0U))
161#endif
162
163#if !defined(STM32_DMA2_CH2_CMASK)
164#define STM32_DMA2_CH2_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 1U))
165#endif
166
167#if !defined(STM32_DMA2_CH3_CMASK)
168#define STM32_DMA2_CH3_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 2U))
169#endif
170
171#if !defined(STM32_DMA2_CH4_CMASK)
172#define STM32_DMA2_CH4_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 3U))
173#endif
174
175#if !defined(STM32_DMA2_CH5_CMASK)
176#define STM32_DMA2_CH5_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 4U))
177#endif
178
179#if !defined(STM32_DMA2_CH6_CMASK)
180#define STM32_DMA2_CH6_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 5U))
181#endif
182
183#if !defined(STM32_DMA2_CH7_CMASK)
184#define STM32_DMA2_CH7_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 6U))
185#endif
186
187#if !defined(STM32_DMA2_CH8_CMASK)
188#define STM32_DMA2_CH8_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 7U))
189#endif
190
191/*===========================================================================*/
192/* Driver exported variables. */
193/*===========================================================================*/
194
195/**
196 * @brief DMA streams descriptors.
197 * @details This table keeps the association between an unique stream
198 * identifier and the involved physical registers.
199 * @note Don't use this array directly, use the appropriate wrapper macros
200 * instead: @p STM32_DMA1_STREAM1, @p STM32_DMA1_STREAM2 etc.
201 */
202const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = {
203#if STM32_DMA1_NUM_CHANNELS > 0
204 {DMA1, DMA1_Channel1, STM32_DMA1_CH1_CMASK, DMA1_CH1_VARIANT, 0, 0, STM32_DMA1_CH1_NUMBER},
205#endif
206#if STM32_DMA1_NUM_CHANNELS > 1
207 {DMA1, DMA1_Channel2, STM32_DMA1_CH2_CMASK, DMA1_CH2_VARIANT, 4, 1, STM32_DMA1_CH2_NUMBER},
208#endif
209#if STM32_DMA1_NUM_CHANNELS > 2
210 {DMA1, DMA1_Channel3, STM32_DMA1_CH3_CMASK, DMA1_CH3_VARIANT, 8, 2, STM32_DMA1_CH3_NUMBER},
211#endif
212#if STM32_DMA1_NUM_CHANNELS > 3
213 {DMA1, DMA1_Channel4, STM32_DMA1_CH4_CMASK, DMA1_CH4_VARIANT, 12, 3, STM32_DMA1_CH4_NUMBER},
214#endif
215#if STM32_DMA1_NUM_CHANNELS > 4
216 {DMA1, DMA1_Channel5, STM32_DMA1_CH5_CMASK, DMA1_CH5_VARIANT, 16, 4, STM32_DMA1_CH5_NUMBER},
217#endif
218#if STM32_DMA1_NUM_CHANNELS > 5
219 {DMA1, DMA1_Channel6, STM32_DMA1_CH6_CMASK, DMA1_CH6_VARIANT, 20, 5, STM32_DMA1_CH6_NUMBER},
220#endif
221#if STM32_DMA1_NUM_CHANNELS > 6
222 {DMA1, DMA1_Channel7, STM32_DMA1_CH7_CMASK, DMA1_CH7_VARIANT, 24, 6, STM32_DMA1_CH7_NUMBER},
223#endif
224#if STM32_DMA1_NUM_CHANNELS > 7
225 {DMA1, DMA1_Channel8, STM32_DMA1_CH8_CMASK, DMA1_CH8_VARIANT, 28, 7, STM32_DMA1_CH8_NUMBER},
226#endif
227#if STM32_DMA2_NUM_CHANNELS > 0
228 {DMA2, DMA2_Channel1, STM32_DMA2_CH1_CMASK, DMA2_CH1_VARIANT, 0, 0 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH1_NUMBER},
229#endif
230#if STM32_DMA2_NUM_CHANNELS > 1
231 {DMA2, DMA2_Channel2, STM32_DMA2_CH2_CMASK, DMA2_CH2_VARIANT, 4, 1 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH2_NUMBER},
232#endif
233#if STM32_DMA2_NUM_CHANNELS > 2
234 {DMA2, DMA2_Channel3, STM32_DMA2_CH3_CMASK, DMA2_CH3_VARIANT, 8, 2 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH3_NUMBER},
235#endif
236#if STM32_DMA2_NUM_CHANNELS > 3
237 {DMA2, DMA2_Channel4, STM32_DMA2_CH4_CMASK, DMA2_CH4_VARIANT, 12, 3 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH4_NUMBER},
238#endif
239#if STM32_DMA2_NUM_CHANNELS > 4
240 {DMA2, DMA2_Channel5, STM32_DMA2_CH5_CMASK, DMA2_CH5_VARIANT, 16, 4 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH5_NUMBER},
241#endif
242#if STM32_DMA2_NUM_CHANNELS > 5
243 {DMA2, DMA2_Channel6, STM32_DMA2_CH6_CMASK, DMA2_CH6_VARIANT, 20, 5 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH6_NUMBER},
244#endif
245#if STM32_DMA2_NUM_CHANNELS > 6
246 {DMA2, DMA2_Channel7, STM32_DMA2_CH7_CMASK, DMA2_CH7_VARIANT, 24, 6 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH7_NUMBER},
247#endif
248#if STM32_DMA2_NUM_CHANNELS > 7
249 {DMA2, DMA2_Channel8, STM32_DMA2_CH8_CMASK, DMA2_CH8_VARIANT, 28, 7 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH8_NUMBER},
250#endif
251};
252
253/*===========================================================================*/
254/* Driver local variables and types. */
255/*===========================================================================*/
256
257/**
258 * @brief Global DMA-related data structures.
259 */
260static struct {
261 /**
262 * @brief Mask of the allocated streams.
263 */
264 uint32_t allocated_mask;
265 /**
266 * @brief Mask of the enabled streams ISRs.
267 */
268 uint32_t isr_mask;
269 /**
270 * @brief DMA IRQ redirectors.
271 */
272 struct {
273 /**
274 * @brief DMA callback function.
275 */
276 stm32_dmaisr_t func;
277 /**
278 * @brief DMA callback parameter.
279 */
280 void *param;
281 } streams[STM32_DMA_STREAMS];
282} dma;
283
284/*===========================================================================*/
285/* Driver local functions. */
286/*===========================================================================*/
287
288/*===========================================================================*/
289/* Driver interrupt handlers. */
290/*===========================================================================*/
291
292#if defined(STM32_DMA1_CH1_HANDLER) || defined(__DOXYGEN__)
293/**
294 * @brief DMA1 stream 1 shared ISR.
295 *
296 * @isr
297 */
298OSAL_IRQ_HANDLER(STM32_DMA1_CH1_HANDLER) {
299
300 OSAL_IRQ_PROLOGUE();
301
302 dmaServeInterrupt(STM32_DMA1_STREAM1);
303
304 OSAL_IRQ_EPILOGUE();
305}
306#endif
307
308#if defined(STM32_DMA1_CH2_HANDLER) || defined(__DOXYGEN__)
309/**
310 * @brief DMA1 stream 2 shared ISR.
311 *
312 * @isr
313 */
314OSAL_IRQ_HANDLER(STM32_DMA1_CH2_HANDLER) {
315
316 OSAL_IRQ_PROLOGUE();
317
318 dmaServeInterrupt(STM32_DMA1_STREAM2);
319
320 OSAL_IRQ_EPILOGUE();
321}
322#endif
323
324#if defined(STM32_DMA1_CH3_HANDLER) || defined(__DOXYGEN__)
325/**
326 * @brief DMA1 stream 3 shared ISR.
327 *
328 * @isr
329 */
330OSAL_IRQ_HANDLER(STM32_DMA1_CH3_HANDLER) {
331
332 OSAL_IRQ_PROLOGUE();
333
334 dmaServeInterrupt(STM32_DMA1_STREAM3);
335
336 OSAL_IRQ_EPILOGUE();
337}
338#endif
339
340#if defined(STM32_DMA1_CH4_HANDLER) || defined(__DOXYGEN__)
341/**
342 * @brief DMA1 stream 4 shared ISR.
343 *
344 * @isr
345 */
346OSAL_IRQ_HANDLER(STM32_DMA1_CH4_HANDLER) {
347
348 OSAL_IRQ_PROLOGUE();
349
350 dmaServeInterrupt(STM32_DMA1_STREAM4);
351
352 OSAL_IRQ_EPILOGUE();
353}
354#endif
355
356#if defined(STM32_DMA1_CH5_HANDLER) || defined(__DOXYGEN__)
357/**
358 * @brief DMA1 stream 5 shared ISR.
359 *
360 * @isr
361 */
362OSAL_IRQ_HANDLER(STM32_DMA1_CH5_HANDLER) {
363
364 OSAL_IRQ_PROLOGUE();
365
366 dmaServeInterrupt(STM32_DMA1_STREAM5);
367
368 OSAL_IRQ_EPILOGUE();
369}
370#endif
371
372#if defined(STM32_DMA1_CH6_HANDLER) || defined(__DOXYGEN__)
373/**
374 * @brief DMA1 stream 6 shared ISR.
375 *
376 * @isr
377 */
378OSAL_IRQ_HANDLER(STM32_DMA1_CH6_HANDLER) {
379
380 OSAL_IRQ_PROLOGUE();
381
382 dmaServeInterrupt(STM32_DMA1_STREAM6);
383
384 OSAL_IRQ_EPILOGUE();
385}
386#endif
387
388#if defined(STM32_DMA1_CH7_HANDLER) || defined(__DOXYGEN__)
389/**
390 * @brief DMA1 stream 7 shared ISR.
391 *
392 * @isr
393 */
394OSAL_IRQ_HANDLER(STM32_DMA1_CH7_HANDLER) {
395
396 OSAL_IRQ_PROLOGUE();
397
398 dmaServeInterrupt(STM32_DMA1_STREAM7);
399
400 OSAL_IRQ_EPILOGUE();
401}
402#endif
403
404#if defined(STM32_DMA1_CH8_HANDLER) || defined(__DOXYGEN__)
405/**
406 * @brief DMA1 stream 8 shared ISR.
407 *
408 * @isr
409 */
410OSAL_IRQ_HANDLER(STM32_DMA1_CH8_HANDLER) {
411
412 OSAL_IRQ_PROLOGUE();
413
414 dmaServeInterrupt(STM32_DMA1_STREAM8);
415
416 OSAL_IRQ_EPILOGUE();
417}
418#endif
419
420#if defined(STM32_DMA2_CH1_HANDLER) || defined(__DOXYGEN__)
421/**
422 * @brief DMA2 stream 1 shared ISR.
423 *
424 * @isr
425 */
426OSAL_IRQ_HANDLER(STM32_DMA2_CH1_HANDLER) {
427
428 OSAL_IRQ_PROLOGUE();
429
430 dmaServeInterrupt(STM32_DMA2_STREAM1);
431
432 OSAL_IRQ_EPILOGUE();
433}
434#endif
435
436#if defined(STM32_DMA2_CH2_HANDLER) || defined(__DOXYGEN__)
437/**
438 * @brief DMA2 stream 2 shared ISR.
439 *
440 * @isr
441 */
442OSAL_IRQ_HANDLER(STM32_DMA2_CH2_HANDLER) {
443
444 OSAL_IRQ_PROLOGUE();
445
446 dmaServeInterrupt(STM32_DMA2_STREAM2);
447
448 OSAL_IRQ_EPILOGUE();
449}
450#endif
451
452#if defined(STM32_DMA2_CH3_HANDLER) || defined(__DOXYGEN__)
453/**
454 * @brief DMA2 stream 3 shared ISR.
455 *
456 * @isr
457 */
458OSAL_IRQ_HANDLER(STM32_DMA2_CH3_HANDLER) {
459
460 OSAL_IRQ_PROLOGUE();
461
462 dmaServeInterrupt(STM32_DMA2_STREAM3);
463
464 OSAL_IRQ_EPILOGUE();
465}
466#endif
467
468#if defined(STM32_DMA2_CH4_HANDLER) || defined(__DOXYGEN__)
469/**
470 * @brief DMA2 stream 4 shared ISR.
471 *
472 * @isr
473 */
474OSAL_IRQ_HANDLER(STM32_DMA2_CH4_HANDLER) {
475
476 OSAL_IRQ_PROLOGUE();
477
478 dmaServeInterrupt(STM32_DMA2_STREAM4);
479
480 OSAL_IRQ_EPILOGUE();
481}
482#endif
483
484#if defined(STM32_DMA2_CH5_HANDLER) || defined(__DOXYGEN__)
485/**
486 * @brief DMA2 stream 5 shared ISR.
487 *
488 * @isr
489 */
490OSAL_IRQ_HANDLER(STM32_DMA2_CH5_HANDLER) {
491
492 OSAL_IRQ_PROLOGUE();
493
494 dmaServeInterrupt(STM32_DMA2_STREAM5);
495
496 OSAL_IRQ_EPILOGUE();
497}
498#endif
499
500#if defined(STM32_DMA2_CH6_HANDLER) || defined(__DOXYGEN__)
501/**
502 * @brief DMA2 stream 6 shared ISR.
503 *
504 * @isr
505 */
506OSAL_IRQ_HANDLER(STM32_DMA2_CH6_HANDLER) {
507
508 OSAL_IRQ_PROLOGUE();
509
510 dmaServeInterrupt(STM32_DMA2_STREAM6);
511
512 OSAL_IRQ_EPILOGUE();
513}
514#endif
515
516#if defined(STM32_DMA2_CH7_HANDLER) || defined(__DOXYGEN__)
517/**
518 * @brief DMA2 stream 7 shared ISR.
519 *
520 * @isr
521 */
522OSAL_IRQ_HANDLER(STM32_DMA2_CH7_HANDLER) {
523
524 OSAL_IRQ_PROLOGUE();
525
526 dmaServeInterrupt(STM32_DMA2_STREAM7);
527
528 OSAL_IRQ_EPILOGUE();
529}
530#endif
531
532#if defined(STM32_DMA2_CH8_HANDLER) || defined(__DOXYGEN__)
533/**
534 * @brief DMA2 stream 8 shared ISR.
535 *
536 * @isr
537 */
538OSAL_IRQ_HANDLER(STM32_DMA2_CH8_HANDLER) {
539
540 OSAL_IRQ_PROLOGUE();
541
542 dmaServeInterrupt(STM32_DMA2_STREAM8);
543
544 OSAL_IRQ_EPILOGUE();
545}
546#endif
547
548/*===========================================================================*/
549/* Driver exported functions. */
550/*===========================================================================*/
551
552/**
553 * @brief STM32 DMA helper initialization.
554 *
555 * @init
556 */
557void dmaInit(void) {
558 int i;
559
560 dma.allocated_mask = 0U;
561 dma.isr_mask = 0U;
562 for (i = 0; i < STM32_DMA_STREAMS; i++) {
563 _stm32_dma_streams[i].channel->CCR = STM32_DMA_CCR_RESET_VALUE;
564 dma.streams[i].func = NULL;
565 }
566 DMA1->IFCR = 0xFFFFFFFFU;
567#if STM32_DMA2_NUM_CHANNELS > 0
568 DMA2->IFCR = 0xFFFFFFFFU;
569#endif
570}
571
572/**
573 * @brief Allocates a DMA stream.
574 * @details The stream is allocated and, if required, the DMA clock enabled.
575 * The function also enables the IRQ vector associated to the stream
576 * and initializes its priority.
577 *
578 * @param[in] id numeric identifiers of a specific stream or:
579 * - @p STM32_DMA_STREAM_ID_ANY for any stream.
580 * - @p STM32_DMA_STREAM_ID_ANY_DMA1 for any stream
581 * on DMA1.
582 * - @p STM32_DMA_STREAM_ID_ANY_DMA2 for any stream
583 * on DMA2.
584 * .
585 * @param[in] priority IRQ priority for the DMA stream
586 * @param[in] func handling function pointer, can be @p NULL
587 * @param[in] param a parameter to be passed to the handling function
588 * @return Pointer to the allocated @p stm32_dma_stream_t
589 * structure.
590 * @retval NULL if a/the stream is not available.
591 *
592 * @iclass
593 */
594const stm32_dma_stream_t *dmaStreamAllocI(uint32_t id,
595 uint32_t priority,
596 stm32_dmaisr_t func,
597 void *param) {
598 uint32_t i, startid, endid;
599
600 osalDbgCheckClassI();
601
602 if (id < STM32_DMA_STREAMS) {
603 startid = id;
604 endid = id;
605 }
606#if STM32_DMA_SUPPORTS_DMAMUX == TRUE
607 else if (id == STM32_DMA_STREAM_ID_ANY) {
608 startid = 0U;
609 endid = STM32_DMA_STREAMS - 1U;
610 }
611 else if (id == STM32_DMA_STREAM_ID_ANY_DMA1) {
612 startid = 0U;
613 endid = STM32_DMA1_NUM_CHANNELS - 1U;
614 }
615#if STM32_DMA2_NUM_CHANNELS > 0
616 else if (id == STM32_DMA_STREAM_ID_ANY_DMA2) {
617 startid = STM32_DMA1_NUM_CHANNELS;
618 endid = STM32_DMA_STREAMS - 1U;
619 }
620#endif
621#endif
622 else {
623 osalDbgCheck(false);
624 return NULL;
625 }
626
627 for (i = startid; i <= endid; i++) {
628 uint32_t mask = (1U << i);
629 if ((dma.allocated_mask & mask) == 0U) {
630 const stm32_dma_stream_t *dmastp = STM32_DMA_STREAM(i);
631
632 /* Installs the DMA handler.*/
633 dma.streams[i].func = func;
634 dma.streams[i].param = param;
635 dma.allocated_mask |= mask;
636
637 /* Enabling DMA clocks required by the current streams set.*/
638 if ((STM32_DMA1_STREAMS_MASK & mask) != 0U) {
639 rccEnableDMA1(true);
640 }
641#if STM32_DMA2_NUM_CHANNELS > 0
642 if ((STM32_DMA2_STREAMS_MASK & mask) != 0U) {
643 rccEnableDMA2(true);
644 }
645#endif
646
647#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) && defined(rccEnableDMAMUX)
648 /* Enabling DMAMUX if present.*/
649 if (dma.allocated_mask != 0U) {
650 rccEnableDMAMUX(true);
651 }
652#endif
653
654 /* Enables the associated IRQ vector if not already enabled and if a
655 callback is defined.*/
656 if (func != NULL) {
657 if ((dma.isr_mask & dmastp->cmask) == 0U) {
658 nvicEnableVector(dmastp->vector, priority);
659 }
660 dma.isr_mask |= mask;
661 }
662
663 /* Putting the stream in a known state.*/
664 dmaStreamDisable(dmastp);
665 dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE;
666
667 return dmastp;
668 }
669 }
670
671 return NULL;
672}
673
674/**
675 * @brief Allocates a DMA stream.
676 * @details The stream is allocated and, if required, the DMA clock enabled.
677 * The function also enables the IRQ vector associated to the stream
678 * and initializes its priority.
679 *
680 * @param[in] id numeric identifiers of a specific stream or:
681 * - @p STM32_DMA_STREAM_ID_ANY for any stream.
682 * - @p STM32_DMA_STREAM_ID_ANY_DMA1 for any stream
683 * on DMA1.
684 * - @p STM32_DMA_STREAM_ID_ANY_DMA2 for any stream
685 * on DMA2.
686 * .
687 * @param[in] priority IRQ priority for the DMA stream
688 * @param[in] func handling function pointer, can be @p NULL
689 * @param[in] param a parameter to be passed to the handling function
690 * @return Pointer to the allocated @p stm32_dma_stream_t
691 * structure.
692 * @retval NULL if a/the stream is not available.
693 *
694 * @api
695 */
696const stm32_dma_stream_t *dmaStreamAlloc(uint32_t id,
697 uint32_t priority,
698 stm32_dmaisr_t func,
699 void *param) {
700 const stm32_dma_stream_t *dmastp;
701
702 osalSysLock();
703 dmastp = dmaStreamAllocI(id, priority, func, param);
704 osalSysUnlock();
705
706 return dmastp;
707}
708
709/**
710 * @brief Releases a DMA stream.
711 * @details The stream is freed and, if required, the DMA clock disabled.
712 * Trying to release a unallocated stream is an illegal operation
713 * and is trapped if assertions are enabled.
714 *
715 * @param[in] dmastp pointer to a stm32_dma_stream_t structure
716 *
717 * @iclass
718 */
719void dmaStreamFreeI(const stm32_dma_stream_t *dmastp) {
720 uint32_t selfindex = (uint32_t)dmastp->selfindex;
721
722 osalDbgCheck(dmastp != NULL);
723
724 /* Check if the streams is not taken.*/
725 osalDbgAssert((dma.allocated_mask & (1 << selfindex)) != 0U,
726 "not allocated");
727
728 /* Marks the stream as not allocated.*/
729 dma.allocated_mask &= ~(1U << selfindex);
730 dma.isr_mask &= ~(1U << selfindex);
731
732 /* Disables the associated IRQ vector if it is no more in use.*/
733 if ((dma.isr_mask & dmastp->cmask) == 0U) {
734 nvicDisableVector(dmastp->vector);
735 }
736
737 /* Removes the DMA handler.*/
738 dma.streams[selfindex].func = NULL;
739 dma.streams[selfindex].param = NULL;
740
741 /* Shutting down clocks that are no more required, if any.*/
742 if ((dma.allocated_mask & STM32_DMA1_STREAMS_MASK) == 0U) {
743 rccDisableDMA1();
744 }
745#if STM32_DMA2_NUM_CHANNELS > 0
746 if ((dma.allocated_mask & STM32_DMA2_STREAMS_MASK) == 0U) {
747 rccDisableDMA2();
748 }
749#endif
750
751#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) && defined(rccDisableDMAMUX)
752 /* Shutting down DMAMUX if present.*/
753 if (dma.allocated_mask == 0U) {
754 rccDisableDMAMUX();
755 }
756#endif
757}
758
759/**
760 * @brief Releases a DMA stream.
761 * @details The stream is freed and, if required, the DMA clock disabled.
762 * Trying to release a unallocated stream is an illegal operation
763 * and is trapped if assertions are enabled.
764 *
765 * @param[in] dmastp pointer to a stm32_dma_stream_t structure
766 *
767 * @api
768 */
769void dmaStreamFree(const stm32_dma_stream_t *dmastp) {
770
771 osalSysLock();
772 dmaStreamFreeI(dmastp);
773 osalSysUnlock();
774}
775
776/**
777 * @brief Serves a DMA IRQ.
778 *
779 * @param[in] dmastp pointer to a stm32_dma_stream_t structure
780 *
781 * @special
782 */
783void dmaServeInterrupt(const stm32_dma_stream_t *dmastp) {
784 uint32_t flags;
785 uint32_t selfindex = (uint32_t)dmastp->selfindex;
786
787 flags = (dmastp->dma->ISR >> dmastp->shift) & STM32_DMA_ISR_MASK;
788 if (flags & dmastp->channel->CCR) {
789 dmastp->dma->IFCR = flags << dmastp->shift;
790 if (dma.streams[selfindex].func) {
791 dma.streams[selfindex].func(dma.streams[selfindex].param, flags);
792 }
793 }
794}
795
796#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) || defined(__DOXYGEN__)
797/**
798 * @brief Associates a peripheral request to a DMA stream.
799 * @note This function can be invoked in both ISR or thread context.
800 *
801 * @param[in] dmastp pointer to a @p stm32_dma_stream_t structure
802 * @param[in] per peripheral identifier
803 *
804 * @special
805 */
806void dmaSetRequestSource(const stm32_dma_stream_t *dmastp, uint32_t per) {
807
808 osalDbgCheck(per < 256U);
809
810 dmastp->mux->CCR = per;
811}
812#endif
813
814#endif /* STM32_DMA_REQUIRED */
815
816/** @} */
diff --git a/lib/chibios/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.h b/lib/chibios/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.h
new file mode 100644
index 000000000..a91f5cb5e
--- /dev/null
+++ b/lib/chibios/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.h
@@ -0,0 +1,554 @@
1/*
2 ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/**
18 * @file DMAv1/stm32_dma.h
19 * @brief DMA helper driver header.
20 * @note This driver uses the new naming convention used for the STM32F2xx
21 * so the "DMA channels" are referred as "DMA streams".
22 *
23 * @addtogroup STM32_DMA
24 * @{
25 */
26
27#ifndef STM32_DMA_H
28#define STM32_DMA_H
29
30/*===========================================================================*/
31/* Driver constants. */
32/*===========================================================================*/
33
34/**
35 * @brief DMA capability.
36 * @details if @p TRUE then the DMA is able of burst transfers, FIFOs,
37 * scatter gather and other advanced features.
38 */
39#define STM32_DMA_ADVANCED FALSE
40
41/**
42 * @brief Total number of DMA streams.
43 * @details This is the total number of streams among all the DMA units.
44 */
45#define STM32_DMA_STREAMS (STM32_DMA1_NUM_CHANNELS + \
46 STM32_DMA2_NUM_CHANNELS)
47
48/**
49 * @brief Mask of the ISR bits passed to the DMA callback functions.
50 */
51#define STM32_DMA_ISR_MASK 0x0E
52
53/**
54 * @brief Returns the request line associated to the specified stream.
55 * @note In some STM32 manuals the request line is named confusingly
56 * channel.
57 *
58 * @param[in] id the unique numeric stream identifier
59 * @param[in] c a stream/request association word, one request per
60 * nibble
61 * @return Returns the request associated to the stream.
62 */
63#define STM32_DMA_GETCHANNEL(id, c) \
64 (((uint32_t)(c) >> (((uint32_t)(id) % (uint32_t)STM32_DMA1_NUM_CHANNELS) * 4U)) & 15U)
65
66/**
67 * @brief Checks if a DMA priority is within the valid range.
68 * @param[in] prio DMA priority
69 *
70 * @retval The check result.
71 * @retval false invalid DMA priority.
72 * @retval true correct DMA priority.
73 */
74#define STM32_DMA_IS_VALID_PRIORITY(prio) (((prio) >= 0U) && ((prio) <= 3U))
75
76#if (STM32_DMA_SUPPORTS_DMAMUX == FALSE) || defined(_DOXYGEN__)
77/**
78 * @brief Checks if a DMA stream id is within the valid range.
79 *
80 * @param[in] id DMA stream id
81 * @retval The check result.
82 * @retval false invalid DMA channel.
83 * @retval true correct DMA channel.
84 */
85#define STM32_DMA_IS_VALID_STREAM(id) (((id) >= 0U) && \
86 ((id) < STM32_DMA_STREAMS))
87#else /* STM32_DMA_SUPPORTS_DMAMUX == FALSE */
88#if STM32_DMA2_NUM_CHANNELS > 0
89#define STM32_DMA_IS_VALID_STREAM(id) (((id) >= 0U) && \
90 ((id) <= (STM32_DMA_STREAMS + 2)))
91#else
92#define STM32_DMA_IS_VALID_STREAM(id) (((id) >= 0U) && \
93 ((id) <= (STM32_DMA_STREAMS + 1)))
94#endif
95#endif /* STM32_DMA_SUPPORTS_DMAMUX == FALSE */
96
97/**
98 * @brief Returns an unique numeric identifier for a DMA stream.
99 *
100 * @param[in] dma the DMA unit number
101 * @param[in] stream the stream number
102 * @return An unique numeric stream identifier.
103 */
104#define STM32_DMA_STREAM_ID(dma, stream) \
105 ((((dma) - 1) * STM32_DMA1_NUM_CHANNELS) + ((stream) - 1))
106
107/**
108 * @brief Returns a DMA stream identifier mask.
109 *
110 *
111 * @param[in] dma the DMA unit number
112 * @param[in] stream the stream number
113 * @return A DMA stream identifier mask.
114 */
115#define STM32_DMA_STREAM_ID_MSK(dma, stream) \
116 (1U << STM32_DMA_STREAM_ID(dma, stream))
117
118/**
119 * @brief Checks if a DMA stream unique identifier belongs to a mask.
120 *
121 * @param[in] id the stream numeric identifier
122 * @param[in] mask the stream numeric identifiers mask
123 *
124 * @retval The check result.
125 * @retval false id does not belong to the mask.
126 * @retval true id belongs to the mask.
127 */
128#define STM32_DMA_IS_VALID_ID(id, mask) (((1U << (id)) & (mask)))
129
130#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) || defined(_DOXYGEN__)
131/**
132 * @name Special stream identifiers
133 * @{
134 */
135#define STM32_DMA_STREAM_ID_ANY STM32_DMA_STREAMS
136#define STM32_DMA_STREAM_ID_ANY_DMA1 (STM32_DMA_STREAM_ID_ANY + 1)
137#if STM32_DMA2_NUM_CHANNELS > 0
138#define STM32_DMA_STREAM_ID_ANY_DMA2 (STM32_DMA_STREAM_ID_ANY_DMA1 + 1)
139#endif
140/** @} */
141#endif
142
143/**
144 * @name DMA streams identifiers
145 * @{
146 */
147/**
148 * @brief Returns a pointer to a stm32_dma_stream_t structure.
149 *
150 * @param[in] id the stream numeric identifier
151 * @return A pointer to the stm32_dma_stream_t constant structure
152 * associated to the DMA stream.
153 */
154#define STM32_DMA_STREAM(id) (&_stm32_dma_streams[id])
155
156#if STM32_DMA1_NUM_CHANNELS > 0
157#define STM32_DMA1_STREAM1 STM32_DMA_STREAM(0)
158#endif
159#if STM32_DMA1_NUM_CHANNELS > 1
160#define STM32_DMA1_STREAM2 STM32_DMA_STREAM(1)
161#endif
162#if STM32_DMA1_NUM_CHANNELS > 2
163#define STM32_DMA1_STREAM3 STM32_DMA_STREAM(2)
164#endif
165#if STM32_DMA1_NUM_CHANNELS > 3
166#define STM32_DMA1_STREAM4 STM32_DMA_STREAM(3)
167#endif
168#if STM32_DMA1_NUM_CHANNELS > 4
169#define STM32_DMA1_STREAM5 STM32_DMA_STREAM(4)
170#endif
171#if STM32_DMA1_NUM_CHANNELS > 5
172#define STM32_DMA1_STREAM6 STM32_DMA_STREAM(5)
173#endif
174#if STM32_DMA1_NUM_CHANNELS > 6
175#define STM32_DMA1_STREAM7 STM32_DMA_STREAM(6)
176#endif
177#if STM32_DMA1_NUM_CHANNELS > 7
178#define STM32_DMA1_STREAM8 STM32_DMA_STREAM(7)
179#endif
180#if STM32_DMA2_NUM_CHANNELS > 0
181#define STM32_DMA2_STREAM1 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 0)
182#endif
183#if STM32_DMA2_NUM_CHANNELS > 1
184#define STM32_DMA2_STREAM2 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 1)
185#endif
186#if STM32_DMA2_NUM_CHANNELS > 2
187#define STM32_DMA2_STREAM3 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 2)
188#endif
189#if STM32_DMA2_NUM_CHANNELS > 3
190#define STM32_DMA2_STREAM4 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 3)
191#endif
192#if STM32_DMA2_NUM_CHANNELS > 4
193#define STM32_DMA2_STREAM5 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 4)
194#endif
195#if STM32_DMA2_NUM_CHANNELS > 5
196#define STM32_DMA2_STREAM6 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 5)
197#endif
198#if STM32_DMA2_NUM_CHANNELS > 6
199#define STM32_DMA2_STREAM7 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 6)
200#endif
201#if STM32_DMA2_NUM_CHANNELS > 7
202#define STM32_DMA2_STREAM8 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 7)
203#endif
204/** @} */
205
206/**
207 * @name CR register constants common to all DMA types
208 * @{
209 */
210#define STM32_DMA_CCR_RESET_VALUE 0x00000000U
211#define STM32_DMA_CR_EN DMA_CCR_EN
212#define STM32_DMA_CR_TEIE DMA_CCR_TEIE
213#define STM32_DMA_CR_HTIE DMA_CCR_HTIE
214#define STM32_DMA_CR_TCIE DMA_CCR_TCIE
215#define STM32_DMA_CR_DIR_MASK (DMA_CCR_DIR | DMA_CCR_MEM2MEM)
216#define STM32_DMA_CR_DIR_P2M 0U
217#define STM32_DMA_CR_DIR_M2P DMA_CCR_DIR
218#define STM32_DMA_CR_DIR_M2M DMA_CCR_MEM2MEM
219#define STM32_DMA_CR_CIRC DMA_CCR_CIRC
220#define STM32_DMA_CR_PINC DMA_CCR_PINC
221#define STM32_DMA_CR_MINC DMA_CCR_MINC
222#define STM32_DMA_CR_PSIZE_MASK DMA_CCR_PSIZE
223#define STM32_DMA_CR_PSIZE_BYTE 0U
224#define STM32_DMA_CR_PSIZE_HWORD DMA_CCR_PSIZE_0
225#define STM32_DMA_CR_PSIZE_WORD DMA_CCR_PSIZE_1
226#define STM32_DMA_CR_MSIZE_MASK DMA_CCR_MSIZE
227#define STM32_DMA_CR_MSIZE_BYTE 0U
228#define STM32_DMA_CR_MSIZE_HWORD DMA_CCR_MSIZE_0
229#define STM32_DMA_CR_MSIZE_WORD DMA_CCR_MSIZE_1
230#define STM32_DMA_CR_SIZE_MASK (STM32_DMA_CR_PSIZE_MASK | \
231 STM32_DMA_CR_MSIZE_MASK)
232#define STM32_DMA_CR_PL_MASK DMA_CCR_PL
233#define STM32_DMA_CR_PL(n) ((n) << 12U)
234/** @} */
235
236/**
237 * @name Request line selector macro
238 * @{
239 */
240#if STM32_DMA_SUPPORTS_CSELR || defined(__DOXYGEN__)
241#define STM32_DMA_CR_CHSEL_MASK (15U << 16U)
242#define STM32_DMA_CR_CHSEL(n) ((n) << 16U)
243#else
244#define STM32_DMA_CR_CHSEL_MASK 0U
245#define STM32_DMA_CR_CHSEL(n) 0U
246#endif
247/** @} */
248
249/**
250 * @name CR register constants only found in enhanced DMA
251 * @{
252 */
253#define STM32_DMA_CR_DMEIE 0U /**< @brief Ignored by normal DMA. */
254/** @} */
255
256/**
257 * @name Status flags passed to the ISR callbacks
258 * @{
259 */
260#define STM32_DMA_ISR_FEIF 0U
261#define STM32_DMA_ISR_DMEIF 0U
262#define STM32_DMA_ISR_TEIF DMA_ISR_TEIF1
263#define STM32_DMA_ISR_HTIF DMA_ISR_HTIF1
264#define STM32_DMA_ISR_TCIF DMA_ISR_TCIF1
265/** @} */
266
267/*===========================================================================*/
268/* Driver pre-compile time settings. */
269/*===========================================================================*/
270
271/*===========================================================================*/
272/* Derived constants and error checks. */
273/*===========================================================================*/
274
275#if !defined(STM32_DMA_SUPPORTS_DMAMUX)
276#error "STM32_DMA_SUPPORTS_DMAMUX not defined in registry"
277#endif
278
279#if !defined(STM32_DMA_SUPPORTS_CSELR)
280#error "STM32_DMA_SUPPORTS_CSELR not defined in registry"
281#endif
282
283#if STM32_DMA_SUPPORTS_DMAMUX && STM32_DMA_SUPPORTS_CSELR
284#error "STM32_DMA_SUPPORTS_DMAMUX and STM32_DMA_SUPPORTS_CSELR both TRUE"
285#endif
286
287#if !defined(STM32_DMA1_NUM_CHANNELS)
288#error "STM32_DMA1_NUM_CHANNELS not defined in registry"
289#endif
290
291#if !defined(STM32_DMA2_NUM_CHANNELS)
292#error "STM32_DMA2_NUM_CHANNELS not defined in registry"
293#endif
294
295#if (STM32_DMA1_NUM_CHANNELS < 0) || (STM32_DMA1_NUM_CHANNELS > 8)
296#error "unsupported channels configuration"
297#endif
298
299#if (STM32_DMA2_NUM_CHANNELS < 0) || (STM32_DMA2_NUM_CHANNELS > 8)
300#error "unsupported channels configuration"
301#endif
302
303#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) || defined(__DOXYGEN__)
304#include "stm32_dmamux.h"
305#endif
306
307/*===========================================================================*/
308/* Driver data structures and types. */
309/*===========================================================================*/
310
311/**
312 * @brief Type of a DMA callback.
313 *
314 * @param[in] p parameter for the registered function
315 * @param[in] flags pre-shifted content of the ISR register, the bits
316 * are aligned to bit zero
317 */
318typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags);
319
320/**
321 * @brief STM32 DMA stream descriptor structure.
322 */
323typedef struct {
324 DMA_TypeDef *dma; /**< @brief Associated DMA. */
325 DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */
326 uint32_t cmask; /**< @brief Mask of streams sharing
327 the same ISR. */
328#if (STM32_DMA_SUPPORTS_CSELR == TRUE) || defined(__DOXYGEN__)
329 volatile uint32_t *cselr; /**< @brief Associated CSELR reg. */
330#elif STM32_DMA_SUPPORTS_DMAMUX == TRUE
331 DMAMUX_Channel_TypeDef *mux; /**< @brief Associated DMA mux. */
332#else
333 uint8_t dummy; /**< @brief Filler. */
334#endif
335 uint8_t shift; /**< @brief Bit offset in ISR, IFCR
336 and CSELR registers. */
337 uint8_t selfindex; /**< @brief Index to self in array. */
338 uint8_t vector; /**< @brief Associated IRQ vector. */
339} stm32_dma_stream_t;
340
341/*===========================================================================*/
342/* Driver macros. */
343/*===========================================================================*/
344
345/**
346 * @name Macro Functions
347 * @{
348 */
349/**
350 * @brief Associates a peripheral data register to a DMA stream.
351 * @note This function can be invoked in both ISR or thread context.
352 * @pre The stream must have been allocated using @p dmaStreamAlloc().
353 * @post After use the stream can be released using @p dmaStreamRelease().
354 *
355 * @param[in] dmastp pointer to a stm32_dma_stream_t structure
356 * @param[in] addr value to be written in the CPAR register
357 *
358 * @special
359 */
360#define dmaStreamSetPeripheral(dmastp, addr) { \
361 (dmastp)->channel->CPAR = (uint32_t)(addr); \
362}
363
364/**
365 * @brief Associates a memory destination to a DMA stream.
366 * @note This function can be invoked in both ISR or thread context.
367 * @pre The stream must have been allocated using @p dmaStreamAlloc().
368 * @post After use the stream can be released using @p dmaStreamRelease().
369 *
370 * @param[in] dmastp pointer to a stm32_dma_stream_t structure
371 * @param[in] addr value to be written in the CMAR register
372 *
373 * @special
374 */
375#define dmaStreamSetMemory0(dmastp, addr) { \
376 (dmastp)->channel->CMAR = (uint32_t)(addr); \
377}
378
379/**
380 * @brief Sets the number of transfers to be performed.
381 * @note This function can be invoked in both ISR or thread context.
382 * @pre The stream must have been allocated using @p dmaStreamAlloc().
383 * @post After use the stream can be released using @p dmaStreamRelease().
384 *
385 * @param[in] dmastp pointer to a stm32_dma_stream_t structure
386 * @param[in] size value to be written in the CNDTR register
387 *
388 * @special
389 */
390#define dmaStreamSetTransactionSize(dmastp, size) { \
391 (dmastp)->channel->CNDTR = (uint32_t)(size); \
392}
393
394/**
395 * @brief Returns the number of transfers to be performed.
396 * @note This function can be invoked in both ISR or thread context.
397 * @pre The stream must have been allocated using @p dmaStreamAlloc().
398 * @post After use the stream can be released using @p dmaStreamRelease().
399 *
400 * @param[in] dmastp pointer to a stm32_dma_stream_t structure
401 * @return The number of transfers to be performed.
402 *
403 * @special
404 */
405#define dmaStreamGetTransactionSize(dmastp) ((size_t)((dmastp)->channel->CNDTR))
406
407/**
408 * @brief Programs the stream mode settings.
409 * @note This function can be invoked in both ISR or thread context.
410 * @pre The stream must have been allocated using @p dmaStreamAlloc().
411 * @post After use the stream can be released using @p dmaStreamRelease().
412 *
413 * @param[in] dmastp pointer to a stm32_dma_stream_t structure
414 * @param[in] mode value to be written in the CCR register
415 *
416 * @special
417 */
418#if STM32_DMA_SUPPORTS_CSELR || defined(__DOXYGEN__)
419#define dmaStreamSetMode(dmastp, mode) { \
420 uint32_t cselr = *(dmastp)->cselr; \
421 cselr &= ~(0x0000000FU << (dmastp)->shift); \
422 cselr |= (((uint32_t)(mode) >> 16U) << (dmastp)->shift); \
423 *(dmastp)->cselr = cselr; \
424 (dmastp)->channel->CCR = (uint32_t)(mode); \
425}
426#else
427#define dmaStreamSetMode(dmastp, mode) { \
428 (dmastp)->channel->CCR = (uint32_t)(mode); \
429}
430#endif
431
432/**
433 * @brief DMA stream enable.
434 * @note This function can be invoked in both ISR or thread context.
435 * @pre The stream must have been allocated using @p dmaStreamAlloc().
436 * @post After use the stream can be released using @p dmaStreamRelease().
437 *
438 * @param[in] dmastp pointer to a stm32_dma_stream_t structure
439 *
440 * @special
441 */
442#define dmaStreamEnable(dmastp) { \
443 (dmastp)->channel->CCR |= STM32_DMA_CR_EN; \
444}
445
446/**
447 * @brief DMA stream disable.
448 * @details The function disables the specified stream and then clears any
449 * pending interrupt.
450 * @note This function can be invoked in both ISR or thread context.
451 * @note Interrupts enabling flags are set to zero after this call, see
452 * bug 3607518.
453 * @pre The stream must have been allocated using @p dmaStreamAlloc().
454 * @post After use the stream can be released using @p dmaStreamRelease().
455 *
456 * @param[in] dmastp pointer to a stm32_dma_stream_t structure
457 *
458 * @special
459 */
460#define dmaStreamDisable(dmastp) { \
461 (dmastp)->channel->CCR &= ~(STM32_DMA_CR_TCIE | STM32_DMA_CR_HTIE | \
462 STM32_DMA_CR_TEIE | STM32_DMA_CR_EN); \
463 dmaStreamClearInterrupt(dmastp); \
464}
465
466/**
467 * @brief DMA stream interrupt sources clear.
468 * @note This function can be invoked in both ISR or thread context.
469 * @pre The stream must have been allocated using @p dmaStreamAlloc().
470 * @post After use the stream can be released using @p dmaStreamRelease().
471 *
472 * @param[in] dmastp pointer to a stm32_dma_stream_t structure
473 *
474 * @special
475 */
476#define dmaStreamClearInterrupt(dmastp) { \
477 (dmastp)->dma->IFCR = STM32_DMA_ISR_MASK << (dmastp)->shift; \
478}
479
480/**
481 * @brief Starts a memory to memory operation using the specified stream.
482 * @note The default transfer data mode is "byte to byte" but it can be
483 * changed by specifying extra options in the @p mode parameter.
484 * @pre The stream must have been allocated using @p dmaStreamAlloc().
485 * @post After use the stream can be released using @p dmaStreamRelease().
486 *
487 * @param[in] dmastp pointer to a stm32_dma_stream_t structure
488 * @param[in] mode value to be written in the CCR register, this value
489 * is implicitly ORed with:
490 * - @p STM32_DMA_CR_MINC
491 * - @p STM32_DMA_CR_PINC
492 * - @p STM32_DMA_CR_DIR_M2M
493 * - @p STM32_DMA_CR_EN
494 * .
495 * @param[in] src source address
496 * @param[in] dst destination address
497 * @param[in] n number of data units to copy
498 */
499#define dmaStartMemCopy(dmastp, mode, src, dst, n) { \
500 dmaStreamSetPeripheral(dmastp, src); \
501 dmaStreamSetMemory0(dmastp, dst); \
502 dmaStreamSetTransactionSize(dmastp, n); \
503 dmaStreamSetMode(dmastp, (mode) | \
504 STM32_DMA_CR_MINC | STM32_DMA_CR_PINC | \
505 STM32_DMA_CR_DIR_M2M | STM32_DMA_CR_EN); \
506}
507
508/**
509 * @brief Polled wait for DMA transfer end.
510 * @pre The stream must have been allocated using @p dmaStreamAlloc().
511 * @post After use the stream can be released using @p dmaStreamRelease().
512 *
513 * @param[in] dmastp pointer to a stm32_dma_stream_t structure
514 */
515#define dmaWaitCompletion(dmastp) { \
516 while ((dmastp)->channel->CNDTR > 0U) \
517 ; \
518 dmaStreamDisable(dmastp); \
519}
520/** @} */
521
522/*===========================================================================*/
523/* External declarations. */
524/*===========================================================================*/
525
526#if !defined(__DOXYGEN__)
527extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS];
528#endif
529
530#ifdef __cplusplus
531extern "C" {
532#endif
533 void dmaInit(void);
534 const stm32_dma_stream_t *dmaStreamAllocI(uint32_t id,
535 uint32_t priority,
536 stm32_dmaisr_t func,
537 void *param);
538 const stm32_dma_stream_t *dmaStreamAlloc(uint32_t id,
539 uint32_t priority,
540 stm32_dmaisr_t func,
541 void *param);
542 void dmaStreamFreeI(const stm32_dma_stream_t *dmastp);
543 void dmaStreamFree(const stm32_dma_stream_t *dmastp);
544 void dmaServeInterrupt(const stm32_dma_stream_t *dmastp);
545#if STM32_DMA_SUPPORTS_DMAMUX == TRUE
546 void dmaSetRequestSource(const stm32_dma_stream_t *dmastp, uint32_t per);
547#endif
548#ifdef __cplusplus
549}
550#endif
551
552#endif /* STM32_DMA_H */
553
554/** @} */
diff --git a/lib/chibios/os/hal/ports/STM32/LLD/DMAv1/stm32_dma1_ch23.inc b/lib/chibios/os/hal/ports/STM32/LLD/DMAv1/stm32_dma1_ch23.inc
new file mode 100644
index 000000000..c67f5b470
--- /dev/null
+++ b/lib/chibios/os/hal/ports/STM32/LLD/DMAv1/stm32_dma1_ch23.inc
@@ -0,0 +1,78 @@
1/*
2 ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/**
18 * @file DMAv1/stm32_dma1_ch23.inc
19 * @brief Shared DMA1 Channels 2 and 3 handler.
20 *
21 * @addtogroup STM32_DMA1_CH23_HANDLER
22 * @{
23 */
24
25/*===========================================================================*/
26/* Driver local definitions. */
27/*===========================================================================*/
28
29/*===========================================================================*/
30/* Derived constants and error checks. */
31/*===========================================================================*/
32
33/* Other checks.*/
34#if !defined(STM32_DMA1_CH23_HANDLER)
35#error "STM32_DMA1_CH23_HANDLER not defined in stm32_isr.h"
36#endif
37
38/*===========================================================================*/
39/* Driver exported variables. */
40/*===========================================================================*/
41
42/*===========================================================================*/
43/* Driver local variables. */
44/*===========================================================================*/
45
46/*===========================================================================*/
47/* Driver local functions. */
48/*===========================================================================*/
49
50/*===========================================================================*/
51/* Driver interrupt handlers. */
52/*===========================================================================*/
53
54#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__)
55/**
56 * @brief DMA1 streams 2 and 3 shared ISR.
57 *
58 * @isr
59 */
60OSAL_IRQ_HANDLER(STM32_DMA1_CH23_HANDLER) {
61
62 OSAL_IRQ_PROLOGUE();
63
64 /* Check on channel 2.*/
65 dmaServeInterrupt(STM32_DMA1_STREAM2);
66
67 /* Check on channel 3.*/
68 dmaServeInterrupt(STM32_DMA1_STREAM3);
69
70 OSAL_IRQ_EPILOGUE();
71}
72#endif
73
74/*===========================================================================*/
75/* Driver exported functions. */
76/*===========================================================================*/
77
78/** @} */
diff --git a/lib/chibios/os/hal/ports/STM32/LLD/DMAv1/stm32_dma1_ch4567.inc b/lib/chibios/os/hal/ports/STM32/LLD/DMAv1/stm32_dma1_ch4567.inc
new file mode 100644
index 000000000..7c800b4ad
--- /dev/null
+++ b/lib/chibios/os/hal/ports/STM32/LLD/DMAv1/stm32_dma1_ch4567.inc
@@ -0,0 +1,90 @@
1/*
2 ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/**
18 * @file DMAv1/stm32_dma1_ch4567.inc
19 * @brief Shared DMA1 Channels 4, 5, 6 and 7 handler.
20 *
21 * @addtogroup STM32_DMA1_CH4567_HANDLER
22 * @{
23 */
24
25/*===========================================================================*/
26/* Driver local definitions. */
27/*===========================================================================*/
28
29/*===========================================================================*/
30/* Derived constants and error checks. */
31/*===========================================================================*/
32
33/* Other checks.*/
34#if !defined(STM32_DMA1_CH4567_HANDLER)
35#error "STM32_DMA1_CH4567_HANDLER not defined in stm32_isr.h"
36#endif
37
38/*===========================================================================*/
39/* Driver exported variables. */
40/*===========================================================================*/
41
42/*===========================================================================*/
43/* Driver local variables. */
44/*===========================================================================*/
45
46/*===========================================================================*/
47/* Driver local functions. */
48/*===========================================================================*/
49
50/*===========================================================================*/
51/* Driver interrupt handlers. */
52/*===========================================================================*/
53
54#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__)
55/**
56 * @brief DMA1 streams 4, 5, 6 and 7 shared ISR.
57 *
58 * @isr
59 */
60OSAL_IRQ_HANDLER(STM32_DMA1_CH4567_HANDLER) {
61
62 OSAL_IRQ_PROLOGUE();
63
64 /* Check on channel 4.*/
65 dmaServeInterrupt(STM32_DMA1_STREAM4);
66
67#if STM32_DMA1_NUM_CHANNELS >= 5
68 /* Check on channel 5.*/
69 dmaServeInterrupt(STM32_DMA1_STREAM5);
70#endif
71
72#if STM32_DMA1_NUM_CHANNELS >= 6
73 /* Check on channel 6.*/
74 dmaServeInterrupt(STM32_DMA1_STREAM6);
75#endif
76
77#if STM32_DMA1_NUM_CHANNELS >= 7
78 /* Check on channel 7.*/
79 dmaServeInterrupt(STM32_DMA1_STREAM7);
80#endif
81
82 OSAL_IRQ_EPILOGUE();
83}
84#endif
85
86/*===========================================================================*/
87/* Driver exported functions. */
88/*===========================================================================*/
89
90/** @} */