diff options
Diffstat (limited to 'lib/chibios/os/hal/ports/STM32/LLD/DMAv1')
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 @@ | |||
1 | PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c | ||
2 | PLATFORMINC += $(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 @@ | |||
1 | STM32 DMAv1 driver. | ||
2 | |||
3 | Driver 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 | |||
15 | The file registry must export: | ||
16 | |||
17 | STM32_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. | ||
21 | STM32_DMA_SUPPORTS_CSELR - TRUE if the DMA have a CSELR register. | ||
22 | STM32_DMA_SUPPORTS_DMAMUX - TRUE if the DMA is riven by a DMAMUX. | ||
23 | STM32_DMAn_NUM_CHANNELS - Number of channels in DMAs "n" (1..2). | ||
24 | STM32_DMAn_CHx_HANDLER - Vector name for IRQ "x" (1..7). If the macro | ||
25 | is not exported then the ISR is not declared. | ||
26 | STM32_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 | */ | ||
202 | const 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 | */ | ||
260 | static 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 | */ | ||
298 | OSAL_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 | */ | ||
314 | OSAL_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 | */ | ||
330 | OSAL_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 | */ | ||
346 | OSAL_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 | */ | ||
362 | OSAL_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 | */ | ||
378 | OSAL_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 | */ | ||
394 | OSAL_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 | */ | ||
410 | OSAL_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 | */ | ||
426 | OSAL_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 | */ | ||
442 | OSAL_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 | */ | ||
458 | OSAL_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 | */ | ||
474 | OSAL_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 | */ | ||
490 | OSAL_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 | */ | ||
506 | OSAL_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 | */ | ||
522 | OSAL_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 | */ | ||
538 | OSAL_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 | */ | ||
557 | void 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 | */ | ||
594 | const 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 | */ | ||
696 | const 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 | */ | ||
719 | void 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 | */ | ||
769 | void 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 | */ | ||
783 | void 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 | */ | ||
806 | void 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 | */ | ||
318 | typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); | ||
319 | |||
320 | /** | ||
321 | * @brief STM32 DMA stream descriptor structure. | ||
322 | */ | ||
323 | typedef 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__) | ||
527 | extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS]; | ||
528 | #endif | ||
529 | |||
530 | #ifdef __cplusplus | ||
531 | extern "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 | */ | ||
60 | OSAL_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 | */ | ||
60 | OSAL_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 | /** @} */ | ||