Fix function brace style
[betaflight.git] / src / main / drivers / dma_reqmap.c
blob41f62a7a53adbe9fb69d36117339e273f92d9996
1 /*
2 * This file is part of Cleanflight and Betaflight.
4 * Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
8 * any later version.
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
21 #include <stdint.h>
23 #include "platform.h"
25 #ifdef USE_DMA_SPEC
27 #include "drivers/adc.h"
28 #include "drivers/bus_spi.h"
29 #include "drivers/serial.h"
30 #include "drivers/serial_uart.h"
31 #include "drivers/timer_def.h"
33 #include "pg/timerio.h"
35 #include "dma_reqmap.h"
37 typedef struct dmaPeripheralMapping_s {
38 dmaPeripheral_e device;
39 uint8_t index;
40 #if defined(STM32H7) || defined(STM32G4)
41 uint8_t dmaRequest;
42 #else
43 dmaChannelSpec_t channelSpec[MAX_PERIPHERAL_DMA_OPTIONS];
44 #endif
45 } dmaPeripheralMapping_t;
47 typedef struct dmaTimerMapping_s {
48 TIM_TypeDef *tim;
49 uint8_t channel;
50 #if defined(STM32H7) || defined(STM32G4)
51 uint8_t dmaRequest;
52 #else
53 dmaChannelSpec_t channelSpec[MAX_TIMER_DMA_OPTIONS];
54 #endif
55 } dmaTimerMapping_t;
57 #if defined(STM32G4)
59 #define REQMAP_SGL(periph) { DMA_PERIPH_ ## periph, 0, DMA_REQUEST_ ## periph }
60 #define REQMAP(periph, device) { DMA_PERIPH_ ## periph, periph ## DEV_ ## device, DMA_REQUEST_ ## periph ## device }
61 #define REQMAP_DIR(periph, device, dir) { DMA_PERIPH_ ## periph ## _ ## dir, periph ## DEV_ ## device, DMA_REQUEST_ ## periph ## device ## _ ## dir }
62 #define REQMAP_TIMUP(periph, timno) { DMA_PERIPH_TIMUP, timno - 1, DMA_REQUEST_ ## TIM ## timno ## _UP }
64 // Resolve UART/USART mess
65 #define DMA_REQUEST_UART1_RX DMA_REQUEST_USART1_RX
66 #define DMA_REQUEST_UART1_TX DMA_REQUEST_USART1_TX
67 #define DMA_REQUEST_UART2_RX DMA_REQUEST_USART2_RX
68 #define DMA_REQUEST_UART2_TX DMA_REQUEST_USART2_TX
69 #define DMA_REQUEST_UART3_RX DMA_REQUEST_USART3_RX
70 #define DMA_REQUEST_UART3_TX DMA_REQUEST_USART3_TX
72 // Resolve our preference for MOSI/MISO rather than TX/RX
73 #define DMA_REQUEST_SPI1_MOSI DMA_REQUEST_SPI1_TX
74 #define DMA_REQUEST_SPI1_MISO DMA_REQUEST_SPI1_RX
75 #define DMA_REQUEST_SPI2_MOSI DMA_REQUEST_SPI2_TX
76 #define DMA_REQUEST_SPI2_MISO DMA_REQUEST_SPI2_RX
77 #define DMA_REQUEST_SPI3_MOSI DMA_REQUEST_SPI3_TX
78 #define DMA_REQUEST_SPI3_MISO DMA_REQUEST_SPI3_RX
79 #define DMA_REQUEST_SPI4_MOSI DMA_REQUEST_SPI4_TX
80 #define DMA_REQUEST_SPI4_MISO DMA_REQUEST_SPI4_RX
82 static const dmaPeripheralMapping_t dmaPeripheralMapping[] = {
83 #ifdef USE_SPI
84 REQMAP_DIR(SPI, 1, MOSI),
85 REQMAP_DIR(SPI, 1, MISO),
86 REQMAP_DIR(SPI, 2, MOSI),
87 REQMAP_DIR(SPI, 2, MISO),
88 REQMAP_DIR(SPI, 3, MOSI),
89 REQMAP_DIR(SPI, 3, MISO),
90 REQMAP_DIR(SPI, 4, MOSI),
91 REQMAP_DIR(SPI, 4, MISO),
92 #endif // USE_SPI
94 #ifdef USE_ADC
95 REQMAP(ADC, 1),
96 REQMAP(ADC, 2),
97 REQMAP(ADC, 3),
98 REQMAP(ADC, 4),
99 REQMAP(ADC, 5),
100 #endif
102 #ifdef USE_UART
103 REQMAP_DIR(UART, 1, TX),
104 REQMAP_DIR(UART, 1, RX),
105 REQMAP_DIR(UART, 2, TX),
106 REQMAP_DIR(UART, 2, RX),
107 REQMAP_DIR(UART, 3, TX),
108 REQMAP_DIR(UART, 3, RX),
109 REQMAP_DIR(UART, 4, TX),
110 REQMAP_DIR(UART, 4, RX),
111 REQMAP_DIR(UART, 5, TX),
112 REQMAP_DIR(UART, 5, RX),
113 #ifdef USE_LPUART1
114 { DMA_PERIPH_UART_TX, LPUARTDEV_1, DMA_REQUEST_LPUART1_TX },
115 { DMA_PERIPH_UART_RX, LPUARTDEV_1, DMA_REQUEST_LPUART1_RX },
116 #endif
117 #endif
119 #ifdef USE_TIMER
120 // Pseudo peripheral for TIMx_UP channel
121 REQMAP_TIMUP(TIMUP, 1),
122 REQMAP_TIMUP(TIMUP, 2),
123 REQMAP_TIMUP(TIMUP, 3),
124 REQMAP_TIMUP(TIMUP, 4),
125 REQMAP_TIMUP(TIMUP, 5),
126 REQMAP_TIMUP(TIMUP, 6),
127 REQMAP_TIMUP(TIMUP, 7),
128 REQMAP_TIMUP(TIMUP, 8),
129 REQMAP_TIMUP(TIMUP, 15),
130 REQMAP_TIMUP(TIMUP, 16),
131 REQMAP_TIMUP(TIMUP, 17),
132 REQMAP_TIMUP(TIMUP, 20),
133 #endif
136 #undef REQMAP_TIMUP
137 #undef REQMAP
138 #undef REQMAP_SGL
139 #undef REQMAP_DIR
141 #define TC(chan) DEF_TIM_CHANNEL(CH_ ## chan)
143 #define REQMAP_TIM(tim, chan) { tim, TC(chan), DMA_REQUEST_ ## tim ## _ ## chan }
145 static const dmaTimerMapping_t dmaTimerMapping[] = {
146 REQMAP_TIM(TIM1, CH1),
147 REQMAP_TIM(TIM1, CH2),
148 REQMAP_TIM(TIM1, CH3),
149 REQMAP_TIM(TIM1, CH4),
150 REQMAP_TIM(TIM2, CH1),
151 REQMAP_TIM(TIM2, CH2),
152 REQMAP_TIM(TIM2, CH3),
153 REQMAP_TIM(TIM2, CH4),
154 REQMAP_TIM(TIM3, CH1),
155 REQMAP_TIM(TIM3, CH2),
156 REQMAP_TIM(TIM3, CH3),
157 REQMAP_TIM(TIM3, CH4),
158 REQMAP_TIM(TIM4, CH1),
159 REQMAP_TIM(TIM4, CH2),
160 REQMAP_TIM(TIM4, CH3),
161 REQMAP_TIM(TIM5, CH1),
162 REQMAP_TIM(TIM5, CH2),
163 REQMAP_TIM(TIM5, CH3),
164 REQMAP_TIM(TIM5, CH4),
165 REQMAP_TIM(TIM8, CH1),
166 REQMAP_TIM(TIM8, CH2),
167 REQMAP_TIM(TIM8, CH3),
168 REQMAP_TIM(TIM8, CH4),
169 REQMAP_TIM(TIM15, CH1),
170 REQMAP_TIM(TIM16, CH1),
171 REQMAP_TIM(TIM17, CH1),
172 REQMAP_TIM(TIM20, CH1),
173 REQMAP_TIM(TIM20, CH2),
174 REQMAP_TIM(TIM20, CH3),
175 REQMAP_TIM(TIM20, CH4),
176 // XXX Check non-CH1 for TIM15,16,17 and 20
179 #undef TC
180 #undef REQMAP_TIM
182 #define DMA(d, c) { DMA_CODE(d, c, 0), (dmaResource_t *)DMA ## d ## _Channel ## c, 0 }
184 static dmaChannelSpec_t dmaChannelSpec[MAX_PERIPHERAL_DMA_OPTIONS] = {
185 DMA(1, 1),
186 DMA(1, 2),
187 DMA(1, 3),
188 DMA(1, 4),
189 DMA(1, 5),
190 DMA(1, 6),
191 DMA(1, 7),
192 DMA(1, 8),
193 DMA(2, 1),
194 DMA(2, 2),
195 DMA(2, 3),
196 DMA(2, 4),
197 DMA(2, 5),
198 DMA(2, 6),
199 DMA(2, 7),
200 DMA(2, 8),
203 #undef DMA
205 #elif defined(STM32H7)
207 #define REQMAP_SGL(periph) { DMA_PERIPH_ ## periph, 0, DMA_REQUEST_ ## periph }
208 #define REQMAP(periph, device) { DMA_PERIPH_ ## periph, periph ## DEV_ ## device, DMA_REQUEST_ ## periph ## device }
209 #define REQMAP_DIR(periph, device, dir) { DMA_PERIPH_ ## periph ## _ ## dir, periph ## DEV_ ## device, DMA_REQUEST_ ## periph ## device ## _ ## dir }
210 #define REQMAP_TIMUP(periph, timno) { DMA_PERIPH_TIMUP, timno - 1, DMA_REQUEST_ ## TIM ## timno ## _UP }
212 // Resolve UART/USART mess
213 #define DMA_REQUEST_UART1_RX DMA_REQUEST_USART1_RX
214 #define DMA_REQUEST_UART1_TX DMA_REQUEST_USART1_TX
215 #define DMA_REQUEST_UART2_RX DMA_REQUEST_USART2_RX
216 #define DMA_REQUEST_UART2_TX DMA_REQUEST_USART2_TX
217 #define DMA_REQUEST_UART3_RX DMA_REQUEST_USART3_RX
218 #define DMA_REQUEST_UART3_TX DMA_REQUEST_USART3_TX
219 #define DMA_REQUEST_UART6_RX DMA_REQUEST_USART6_RX
220 #define DMA_REQUEST_UART6_TX DMA_REQUEST_USART6_TX
221 #define DMA_REQUEST_UART10_RX DMA_REQUEST_USART10_RX
222 #define DMA_REQUEST_UART10_TX DMA_REQUEST_USART10_TX
224 // Resolve our preference for MOSI/MISO rather than TX/RX
225 #define DMA_REQUEST_SPI1_MOSI DMA_REQUEST_SPI1_TX
226 #define DMA_REQUEST_SPI1_MISO DMA_REQUEST_SPI1_RX
227 #define DMA_REQUEST_SPI2_MOSI DMA_REQUEST_SPI2_TX
228 #define DMA_REQUEST_SPI2_MISO DMA_REQUEST_SPI2_RX
229 #define DMA_REQUEST_SPI3_MOSI DMA_REQUEST_SPI3_TX
230 #define DMA_REQUEST_SPI3_MISO DMA_REQUEST_SPI3_RX
231 #define DMA_REQUEST_SPI4_MOSI DMA_REQUEST_SPI4_TX
232 #define DMA_REQUEST_SPI4_MISO DMA_REQUEST_SPI4_RX
233 #define DMA_REQUEST_SPI5_MOSI DMA_REQUEST_SPI5_TX
234 #define DMA_REQUEST_SPI5_MISO DMA_REQUEST_SPI5_RX
236 static const dmaPeripheralMapping_t dmaPeripheralMapping[] = {
237 #ifdef USE_SPI
238 REQMAP_DIR(SPI, 1, MOSI),
239 REQMAP_DIR(SPI, 1, MISO),
240 REQMAP_DIR(SPI, 2, MOSI),
241 REQMAP_DIR(SPI, 2, MISO),
242 REQMAP_DIR(SPI, 3, MOSI),
243 REQMAP_DIR(SPI, 3, MISO),
244 REQMAP_DIR(SPI, 4, MOSI),
245 REQMAP_DIR(SPI, 4, MISO),
246 REQMAP_DIR(SPI, 5, MOSI), // Not available in smaller packages
247 REQMAP_DIR(SPI, 5, MISO), // ditto
248 // REQMAP_DIR(SPI, 6, MOSI), // SPI6 is on BDMA (todo)
249 // REQMAP_DIR(SPI, 6, MOSI), // ditto
250 #endif // USE_SPI
252 #ifdef USE_ADC
253 REQMAP(ADC, 1),
254 REQMAP(ADC, 2),
255 #if defined(STM32H743xx) || defined(STM32H750xx) || defined(STM32H723xx) || defined(STM32H725xx) || defined(STM32H730xx)
256 REQMAP(ADC, 3),
257 #endif
258 #endif
260 #ifdef USE_UART
261 REQMAP_DIR(UART, 1, TX),
262 REQMAP_DIR(UART, 1, RX),
263 REQMAP_DIR(UART, 2, TX),
264 REQMAP_DIR(UART, 2, RX),
265 REQMAP_DIR(UART, 3, TX),
266 REQMAP_DIR(UART, 3, RX),
267 REQMAP_DIR(UART, 4, TX),
268 REQMAP_DIR(UART, 4, RX),
269 REQMAP_DIR(UART, 5, TX),
270 REQMAP_DIR(UART, 5, RX),
271 REQMAP_DIR(UART, 6, TX),
272 REQMAP_DIR(UART, 6, RX),
273 REQMAP_DIR(UART, 7, TX),
274 REQMAP_DIR(UART, 7, RX),
275 REQMAP_DIR(UART, 8, TX),
276 REQMAP_DIR(UART, 8, RX),
277 #if defined(STM32H7A3xxQ)
278 REQMAP_DIR(UART, 9, TX),
279 REQMAP_DIR(UART, 9, RX),
280 REQMAP_DIR(UART, 10, TX),
281 REQMAP_DIR(UART, 10, RX),
282 #endif
283 #ifdef USE_LPUART1
284 { DMA_PERIPH_UART_TX, LPUARTDEV_1, BDMA_REQUEST_LPUART1_TX },
285 { DMA_PERIPH_UART_RX, LPUARTDEV_1, BDMA_REQUEST_LPUART1_RX },
286 #endif
287 #endif
289 #ifdef USE_TIMER
290 // Pseudo peripheral for TIMx_UP channel
291 REQMAP_TIMUP(TIMUP, 1),
292 REQMAP_TIMUP(TIMUP, 2),
293 REQMAP_TIMUP(TIMUP, 3),
294 REQMAP_TIMUP(TIMUP, 4),
295 REQMAP_TIMUP(TIMUP, 5),
296 REQMAP_TIMUP(TIMUP, 6),
297 REQMAP_TIMUP(TIMUP, 7),
298 REQMAP_TIMUP(TIMUP, 8),
299 REQMAP_TIMUP(TIMUP, 15),
300 REQMAP_TIMUP(TIMUP, 16),
301 REQMAP_TIMUP(TIMUP, 17),
302 #endif
305 #undef REQMAP_TIMUP
306 #undef REQMAP
307 #undef REQMAP_SGL
308 #undef REQMAP_DIR
310 #define TC(chan) DEF_TIM_CHANNEL(CH_ ## chan)
312 #define REQMAP_TIM(tim, chan) { tim, TC(chan), DMA_REQUEST_ ## tim ## _ ## chan }
314 static const dmaTimerMapping_t dmaTimerMapping[] = {
315 REQMAP_TIM(TIM1, CH1),
316 REQMAP_TIM(TIM1, CH2),
317 REQMAP_TIM(TIM1, CH3),
318 REQMAP_TIM(TIM1, CH4),
319 REQMAP_TIM(TIM2, CH1),
320 REQMAP_TIM(TIM2, CH2),
321 REQMAP_TIM(TIM2, CH3),
322 REQMAP_TIM(TIM2, CH4),
323 REQMAP_TIM(TIM3, CH1),
324 REQMAP_TIM(TIM3, CH2),
325 REQMAP_TIM(TIM3, CH3),
326 REQMAP_TIM(TIM3, CH4),
327 REQMAP_TIM(TIM4, CH1),
328 REQMAP_TIM(TIM4, CH2),
329 REQMAP_TIM(TIM4, CH3),
330 REQMAP_TIM(TIM5, CH1),
331 REQMAP_TIM(TIM5, CH2),
332 REQMAP_TIM(TIM5, CH3),
333 REQMAP_TIM(TIM5, CH4),
334 REQMAP_TIM(TIM8, CH1),
335 REQMAP_TIM(TIM8, CH2),
336 REQMAP_TIM(TIM8, CH3),
337 REQMAP_TIM(TIM8, CH4),
338 REQMAP_TIM(TIM15, CH1),
339 REQMAP_TIM(TIM16, CH1),
340 REQMAP_TIM(TIM17, CH1),
343 #undef TC
344 #undef REQMAP_TIM
346 #define DMA(d, s) { DMA_CODE(d, s, 0), (dmaResource_t *)DMA ## d ## _Stream ## s, 0 }
348 static dmaChannelSpec_t dmaChannelSpec[MAX_PERIPHERAL_DMA_OPTIONS] = {
349 DMA(1, 0),
350 DMA(1, 1),
351 DMA(1, 2),
352 DMA(1, 3),
353 DMA(1, 4),
354 DMA(1, 5),
355 DMA(1, 6),
356 DMA(1, 7),
357 DMA(2, 0),
358 DMA(2, 1),
359 DMA(2, 2),
360 DMA(2, 3),
361 DMA(2, 4),
362 DMA(2, 5),
363 DMA(2, 6),
364 DMA(2, 7),
367 #undef DMA
369 #elif defined(STM32F4) || defined(STM32F7)
371 #if defined(STM32F4)
372 #define DMA(d, s, c) { DMA_CODE(d, s, c), (dmaResource_t *)DMA ## d ## _Stream ## s, DMA_Channel_ ## c }
373 #elif defined(STM32F7)
374 #define DMA(d, s, c) { DMA_CODE(d, s, c), (dmaResource_t *)DMA ## d ## _Stream ## s, DMA_CHANNEL_ ## c }
375 #endif
377 static const dmaPeripheralMapping_t dmaPeripheralMapping[] = {
378 #ifdef USE_SPI
379 // Everything including F405 and F446
380 #if defined(STM32F745xx) || defined(STM32F746xx) || defined(STM32F765xx)
381 { DMA_PERIPH_SPI_MOSI, SPIDEV_1, { DMA(2, 5, 3), DMA(2, 3, 3) } },
382 { DMA_PERIPH_SPI_MISO, SPIDEV_1, { DMA(2, 2, 3), DMA(2, 0, 3) } },
383 #else
384 { DMA_PERIPH_SPI_MOSI, SPIDEV_1, { DMA(2, 3, 3), DMA(2, 5, 3) } },
385 { DMA_PERIPH_SPI_MISO, SPIDEV_1, { DMA(2, 0, 3), DMA(2, 2, 3) } },
386 #endif
387 { DMA_PERIPH_SPI_MOSI, SPIDEV_2, { DMA(1, 4, 0) } },
388 { DMA_PERIPH_SPI_MISO, SPIDEV_2, { DMA(1, 3, 0) } },
389 { DMA_PERIPH_SPI_MOSI, SPIDEV_3, { DMA(1, 5, 0), DMA(1, 7, 0) } },
390 { DMA_PERIPH_SPI_MISO, SPIDEV_3, { DMA(1, 0, 0), DMA(1, 2, 0) } },
392 #if defined(STM32F411xE) || defined(STM32F745xx) || defined(STM32F746xx) || defined(STM32F765xx) || defined(STM32F722xx)
393 { DMA_PERIPH_SPI_MOSI, SPIDEV_4, { DMA(2, 1, 4), DMA(2, 4, 5) } },
394 { DMA_PERIPH_SPI_MISO, SPIDEV_4, { DMA(2, 0, 4), DMA(2, 3, 5) } },
396 #ifdef USE_EXTENDED_SPI_DEVICE
397 { DMA_PERIPH_SPI_MOSI, SPIDEV_5, { DMA(2, 6, 7) } },
398 { DMA_PERIPH_SPI_MISO, SPIDEV_5, { DMA(2, 5, 7) } },
400 #if !defined(STM32F722xx)
401 { DMA_PERIPH_SPI_MOSI, SPIDEV_6, { DMA(2, 5, 1) } },
402 { DMA_PERIPH_SPI_MISO, SPIDEV_6, { DMA(2, 6, 1) } },
403 #endif
404 #endif // USE_EXTENDED_SPI_DEVICE
405 #endif
406 #endif // USE_SPI
408 #ifdef USE_ADC
409 { DMA_PERIPH_ADC, ADCDEV_1, { DMA(2, 0, 0), DMA(2, 4, 0) } },
410 { DMA_PERIPH_ADC, ADCDEV_2, { DMA(2, 2, 1), DMA(2, 3, 1) } },
411 { DMA_PERIPH_ADC, ADCDEV_3, { DMA(2, 0, 2), DMA(2, 1, 2) } },
412 #endif
414 #ifdef USE_SDCARD_SDIO
415 { DMA_PERIPH_SDIO, 0, { DMA(2, 3, 4), DMA(2, 6, 4) } },
416 #endif
418 #ifdef USE_UART
419 { DMA_PERIPH_UART_TX, UARTDEV_1, { DMA(2, 7, 4) } },
420 { DMA_PERIPH_UART_RX, UARTDEV_1, { DMA(2, 5, 4), DMA(2, 2, 4) } },
421 { DMA_PERIPH_UART_TX, UARTDEV_2, { DMA(1, 6, 4) } },
422 { DMA_PERIPH_UART_RX, UARTDEV_2, { DMA(1, 5, 4) } },
423 { DMA_PERIPH_UART_TX, UARTDEV_3, { DMA(1, 3, 4) } },
424 { DMA_PERIPH_UART_RX, UARTDEV_3, { DMA(1, 1, 4) } },
425 { DMA_PERIPH_UART_TX, UARTDEV_4, { DMA(1, 4, 4) } },
426 { DMA_PERIPH_UART_RX, UARTDEV_4, { DMA(1, 2, 4) } },
427 { DMA_PERIPH_UART_TX, UARTDEV_5, { DMA(1, 7, 4) } },
428 { DMA_PERIPH_UART_RX, UARTDEV_5, { DMA(1, 0, 4) } },
429 { DMA_PERIPH_UART_TX, UARTDEV_6, { DMA(2, 6, 5), DMA(2, 7, 5) } },
430 { DMA_PERIPH_UART_RX, UARTDEV_6, { DMA(2, 1, 5), DMA(2, 2, 5) } },
431 #endif
434 #define TC(chan) DEF_TIM_CHANNEL(CH_ ## chan)
436 static const dmaTimerMapping_t dmaTimerMapping[] = {
437 // Generated from 'timer_def.h'
438 { TIM1, TC(CH1), { DMA(2, 6, 0), DMA(2, 1, 6), DMA(2, 3, 6) } },
439 { TIM1, TC(CH2), { DMA(2, 6, 0), DMA(2, 2, 6) } },
440 { TIM1, TC(CH3), { DMA(2, 6, 0), DMA(2, 6, 6) } },
441 { TIM1, TC(CH4), { DMA(2, 4, 6) } },
443 { TIM2, TC(CH1), { DMA(1, 5, 3) } },
444 { TIM2, TC(CH2), { DMA(1, 6, 3) } },
445 { TIM2, TC(CH3), { DMA(1, 1, 3) } },
446 { TIM2, TC(CH4), { DMA(1, 7, 3), DMA(1, 6, 3) } },
448 { TIM3, TC(CH1), { DMA(1, 4, 5) } },
449 { TIM3, TC(CH2), { DMA(1, 5, 5) } },
450 { TIM3, TC(CH3), { DMA(1, 7, 5) } },
451 { TIM3, TC(CH4), { DMA(1, 2, 5) } },
453 { TIM4, TC(CH1), { DMA(1, 0, 2) } },
454 { TIM4, TC(CH2), { DMA(1, 3, 2) } },
455 { TIM4, TC(CH3), { DMA(1, 7, 2) } },
457 { TIM5, TC(CH1), { DMA(1, 2, 6) } },
458 { TIM5, TC(CH2), { DMA(1, 4, 6) } },
459 { TIM5, TC(CH3), { DMA(1, 0, 6) } },
460 { TIM5, TC(CH4), { DMA(1, 1, 6), DMA(1, 3, 6) } },
462 { TIM8, TC(CH1), { DMA(2, 2, 0), DMA(2, 2, 7) } },
463 { TIM8, TC(CH2), { DMA(2, 2, 0), DMA(2, 3, 7) } },
464 { TIM8, TC(CH3), { DMA(2, 2, 0), DMA(2, 4, 7) } },
465 { TIM8, TC(CH4), { DMA(2, 7, 7) } },
467 #undef TC
468 #undef DMA
469 #endif
471 #if defined(STM32H7) || defined(STM32G4)
472 static void dmaSetupRequest(dmaChannelSpec_t *dmaSpec, uint8_t request)
474 // Setup request as channel
475 dmaSpec->channel = request;
477 // Insert DMA request into code
478 dmaCode_t code = dmaSpec->code;
479 dmaSpec->code = DMA_CODE(DMA_CODE_CONTROLLER(code), DMA_CODE_STREAM(code), dmaSpec->channel);
481 #endif
483 const dmaChannelSpec_t *dmaGetChannelSpecByPeripheral(dmaPeripheral_e device, uint8_t index, int8_t opt)
485 if (opt < 0 || opt >= MAX_PERIPHERAL_DMA_OPTIONS) {
486 return NULL;
489 for (unsigned i = 0 ; i < ARRAYLEN(dmaPeripheralMapping) ; i++) {
490 const dmaPeripheralMapping_t *periph = &dmaPeripheralMapping[i];
491 #if defined(STM32H7) || defined(STM32G4)
492 if (periph->device == device && periph->index == index) {
493 dmaChannelSpec_t *dmaSpec = &dmaChannelSpec[opt];
494 dmaSetupRequest(dmaSpec, periph->dmaRequest);
495 return dmaSpec;
497 #else
498 if (periph->device == device && periph->index == index && periph->channelSpec[opt].ref) {
499 return &periph->channelSpec[opt];
501 #endif
504 return NULL;
507 dmaoptValue_t dmaoptByTag(ioTag_t ioTag)
509 #ifdef USE_TIMER_MGMT
510 for (unsigned i = 0; i < MAX_TIMER_PINMAP_COUNT; i++) {
511 if (timerIOConfig(i)->ioTag == ioTag) {
512 return timerIOConfig(i)->dmaopt;
515 #else
516 UNUSED(ioTag);
517 #endif
519 return DMA_OPT_UNUSED;
522 const dmaChannelSpec_t *dmaGetChannelSpecByTimerValue(TIM_TypeDef *tim, uint8_t channel, dmaoptValue_t dmaopt)
524 if (dmaopt < 0 || dmaopt >= MAX_TIMER_DMA_OPTIONS) {
525 return NULL;
528 for (unsigned i = 0 ; i < ARRAYLEN(dmaTimerMapping) ; i++) {
529 const dmaTimerMapping_t *timerMapping = &dmaTimerMapping[i];
530 #if defined(STM32H7) || defined(STM32G4)
531 if (timerMapping->tim == tim && timerMapping->channel == channel) {
532 dmaChannelSpec_t *dmaSpec = &dmaChannelSpec[dmaopt];
533 dmaSetupRequest(dmaSpec, timerMapping->dmaRequest);
534 return dmaSpec;
536 #else
537 if (timerMapping->tim == tim && timerMapping->channel == channel && timerMapping->channelSpec[dmaopt].ref) {
538 return &timerMapping->channelSpec[dmaopt];
540 #endif
543 return NULL;
546 const dmaChannelSpec_t *dmaGetChannelSpecByTimer(const timerHardware_t *timer)
548 if (!timer) {
549 return NULL;
552 dmaoptValue_t dmaopt = dmaoptByTag(timer->tag);
553 return dmaGetChannelSpecByTimerValue(timer->tim, timer->channel, dmaopt);
556 // dmaGetOptionByTimer is called by pgResetFn_timerIOConfig to find out dmaopt for pre-configured timer.
558 dmaoptValue_t dmaGetOptionByTimer(const timerHardware_t *timer)
560 #if defined(STM32H7) || defined(STM32G4)
561 for (unsigned opt = 0; opt < ARRAYLEN(dmaChannelSpec); opt++) {
562 if (timer->dmaRefConfigured == dmaChannelSpec[opt].ref) {
563 return (dmaoptValue_t)opt;
566 #else
567 for (unsigned i = 0 ; i < ARRAYLEN(dmaTimerMapping); i++) {
568 const dmaTimerMapping_t *timerMapping = &dmaTimerMapping[i];
569 if (timerMapping->tim == timer->tim && timerMapping->channel == timer->channel) {
570 for (unsigned j = 0; j < MAX_TIMER_DMA_OPTIONS; j++) {
571 const dmaChannelSpec_t *dma = &timerMapping->channelSpec[j];
572 if (dma->ref == timer->dmaRefConfigured
573 #if defined(STM32F4) || defined(STM32F7)
574 && dma->channel == timer->dmaChannelConfigured
575 #endif
577 return j;
582 #endif
584 return DMA_OPT_UNUSED;
587 #if defined(STM32H7) || defined(STM32G4)
588 // A variant of dmaGetOptionByTimer that looks for matching dmaTimUPRef
589 dmaoptValue_t dmaGetUpOptionByTimer(const timerHardware_t *timer)
591 for (unsigned opt = 0; opt < ARRAYLEN(dmaChannelSpec); opt++) {
592 if (timer->dmaTimUPRef == dmaChannelSpec[opt].ref) {
593 return (dmaoptValue_t)opt;
597 return DMA_OPT_UNUSED;
599 #endif
601 #endif // USE_DMA_SPEC