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)
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/>.
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
;
40 #if defined(STM32H7) || defined(STM32G4)
43 dmaChannelSpec_t channelSpec
[MAX_PERIPHERAL_DMA_OPTIONS
];
45 } dmaPeripheralMapping_t
;
47 typedef struct dmaTimerMapping_s
{
50 #if defined(STM32H7) || defined(STM32G4)
53 dmaChannelSpec_t channelSpec
[MAX_TIMER_DMA_OPTIONS
];
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, also map UART6 requests to LPUART1 requests
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
71 #define DMA_REQUEST_UART9_RX DMA_REQUEST_LPUART1_RX
72 #define DMA_REQUEST_UART9_TX DMA_REQUEST_LPUART1_TX
74 static const dmaPeripheralMapping_t dmaPeripheralMapping
[] = {
76 REQMAP_DIR(SPI
, 1, TX
),
77 REQMAP_DIR(SPI
, 1, RX
),
78 REQMAP_DIR(SPI
, 2, TX
),
79 REQMAP_DIR(SPI
, 2, RX
),
80 REQMAP_DIR(SPI
, 3, TX
),
81 REQMAP_DIR(SPI
, 3, RX
),
82 REQMAP_DIR(SPI
, 4, TX
),
83 REQMAP_DIR(SPI
, 4, RX
),
95 REQMAP_DIR(UART
, 1, TX
),
96 REQMAP_DIR(UART
, 1, RX
),
97 REQMAP_DIR(UART
, 2, TX
),
98 REQMAP_DIR(UART
, 2, RX
),
99 REQMAP_DIR(UART
, 3, TX
),
100 REQMAP_DIR(UART
, 3, RX
),
101 REQMAP_DIR(UART
, 4, TX
),
102 REQMAP_DIR(UART
, 4, RX
),
103 REQMAP_DIR(UART
, 5, TX
),
104 REQMAP_DIR(UART
, 5, RX
),
105 REQMAP_DIR(UART
, 9, TX
),
106 REQMAP_DIR(UART
, 9, RX
),
110 // Pseudo peripheral for TIMx_UP channel
111 REQMAP_TIMUP(TIMUP
, 1),
112 REQMAP_TIMUP(TIMUP
, 2),
113 REQMAP_TIMUP(TIMUP
, 3),
114 REQMAP_TIMUP(TIMUP
, 4),
115 REQMAP_TIMUP(TIMUP
, 5),
116 REQMAP_TIMUP(TIMUP
, 6),
117 REQMAP_TIMUP(TIMUP
, 7),
118 REQMAP_TIMUP(TIMUP
, 8),
119 REQMAP_TIMUP(TIMUP
, 15),
120 REQMAP_TIMUP(TIMUP
, 16),
121 REQMAP_TIMUP(TIMUP
, 17),
122 REQMAP_TIMUP(TIMUP
, 20),
131 #define TC(chan) DEF_TIM_CHANNEL(CH_ ## chan)
133 #define REQMAP_TIM(tim, chan) { tim, TC(chan), DMA_REQUEST_ ## tim ## _ ## chan }
135 static const dmaTimerMapping_t dmaTimerMapping
[] = {
136 REQMAP_TIM(TIM1
, CH1
),
137 REQMAP_TIM(TIM1
, CH2
),
138 REQMAP_TIM(TIM1
, CH3
),
139 REQMAP_TIM(TIM1
, CH4
),
140 REQMAP_TIM(TIM2
, CH1
),
141 REQMAP_TIM(TIM2
, CH2
),
142 REQMAP_TIM(TIM2
, CH3
),
143 REQMAP_TIM(TIM2
, CH4
),
144 REQMAP_TIM(TIM3
, CH1
),
145 REQMAP_TIM(TIM3
, CH2
),
146 REQMAP_TIM(TIM3
, CH3
),
147 REQMAP_TIM(TIM3
, CH4
),
148 REQMAP_TIM(TIM4
, CH1
),
149 REQMAP_TIM(TIM4
, CH2
),
150 REQMAP_TIM(TIM4
, CH3
),
151 REQMAP_TIM(TIM5
, CH1
),
152 REQMAP_TIM(TIM5
, CH2
),
153 REQMAP_TIM(TIM5
, CH3
),
154 REQMAP_TIM(TIM5
, CH4
),
155 REQMAP_TIM(TIM8
, CH1
),
156 REQMAP_TIM(TIM8
, CH2
),
157 REQMAP_TIM(TIM8
, CH3
),
158 REQMAP_TIM(TIM8
, CH4
),
159 REQMAP_TIM(TIM15
, CH1
),
160 REQMAP_TIM(TIM16
, CH1
),
161 REQMAP_TIM(TIM17
, CH1
),
162 REQMAP_TIM(TIM20
, CH1
),
163 REQMAP_TIM(TIM20
, CH2
),
164 REQMAP_TIM(TIM20
, CH3
),
165 REQMAP_TIM(TIM20
, CH4
),
166 // XXX Check non-CH1 for TIM15,16,17 and 20
172 #define DMA(d, c) { DMA_CODE(d, c, 0), (dmaResource_t *)DMA ## d ## _Channel ## c, 0 }
174 static dmaChannelSpec_t dmaChannelSpec
[MAX_PERIPHERAL_DMA_OPTIONS
] = {
195 #elif defined(STM32H7)
197 #define REQMAP_SGL(periph) { DMA_PERIPH_ ## periph, 0, DMA_REQUEST_ ## periph }
198 #define REQMAP(periph, device) { DMA_PERIPH_ ## periph, periph ## DEV_ ## device, DMA_REQUEST_ ## periph ## device }
199 #define REQMAP_DIR(periph, device, dir) { DMA_PERIPH_ ## periph ## _ ## dir, periph ## DEV_ ## device, DMA_REQUEST_ ## periph ## device ## _ ## dir }
200 #define REQMAP_TIMUP(periph, timno) { DMA_PERIPH_TIMUP, timno - 1, DMA_REQUEST_ ## TIM ## timno ## _UP }
202 // Resolve UART/USART mess
203 #define DMA_REQUEST_UART1_RX DMA_REQUEST_USART1_RX
204 #define DMA_REQUEST_UART1_TX DMA_REQUEST_USART1_TX
205 #define DMA_REQUEST_UART2_RX DMA_REQUEST_USART2_RX
206 #define DMA_REQUEST_UART2_TX DMA_REQUEST_USART2_TX
207 #define DMA_REQUEST_UART3_RX DMA_REQUEST_USART3_RX
208 #define DMA_REQUEST_UART3_TX DMA_REQUEST_USART3_TX
209 #define DMA_REQUEST_UART6_RX DMA_REQUEST_USART6_RX
210 #define DMA_REQUEST_UART6_TX DMA_REQUEST_USART6_TX
212 static const dmaPeripheralMapping_t dmaPeripheralMapping
[] = {
214 REQMAP_DIR(SPI
, 1, TX
),
215 REQMAP_DIR(SPI
, 1, RX
),
216 REQMAP_DIR(SPI
, 2, TX
),
217 REQMAP_DIR(SPI
, 2, RX
),
218 REQMAP_DIR(SPI
, 3, TX
),
219 REQMAP_DIR(SPI
, 3, RX
),
220 REQMAP_DIR(SPI
, 4, TX
),
221 REQMAP_DIR(SPI
, 4, RX
),
222 REQMAP_DIR(SPI
, 5, TX
), // Not available in smaller packages
223 REQMAP_DIR(SPI
, 5, RX
), // ditto
224 // REQMAP_DIR(SPI, 6, TX), // SPI6 is on BDMA (todo)
225 // REQMAP_DIR(SPI, 6, TX), // ditto
231 #if defined(STM32H743xx) || defined(STM32H750xx) || defined(STM32H723xx) || defined(STM32H725xx)
237 REQMAP_DIR(UART
, 1, TX
),
238 REQMAP_DIR(UART
, 1, RX
),
239 REQMAP_DIR(UART
, 2, TX
),
240 REQMAP_DIR(UART
, 2, RX
),
241 REQMAP_DIR(UART
, 3, TX
),
242 REQMAP_DIR(UART
, 3, RX
),
243 REQMAP_DIR(UART
, 4, TX
),
244 REQMAP_DIR(UART
, 4, RX
),
245 REQMAP_DIR(UART
, 5, TX
),
246 REQMAP_DIR(UART
, 5, RX
),
247 REQMAP_DIR(UART
, 6, TX
),
248 REQMAP_DIR(UART
, 6, RX
),
249 REQMAP_DIR(UART
, 7, TX
),
250 REQMAP_DIR(UART
, 7, RX
),
251 REQMAP_DIR(UART
, 8, TX
),
252 REQMAP_DIR(UART
, 8, RX
),
256 // Pseudo peripheral for TIMx_UP channel
257 REQMAP_TIMUP(TIMUP
, 1),
258 REQMAP_TIMUP(TIMUP
, 2),
259 REQMAP_TIMUP(TIMUP
, 3),
260 REQMAP_TIMUP(TIMUP
, 4),
261 REQMAP_TIMUP(TIMUP
, 5),
262 REQMAP_TIMUP(TIMUP
, 6),
263 REQMAP_TIMUP(TIMUP
, 7),
264 REQMAP_TIMUP(TIMUP
, 8),
265 REQMAP_TIMUP(TIMUP
, 15),
266 REQMAP_TIMUP(TIMUP
, 16),
267 REQMAP_TIMUP(TIMUP
, 17),
276 #define TC(chan) DEF_TIM_CHANNEL(CH_ ## chan)
278 #define REQMAP_TIM(tim, chan) { tim, TC(chan), DMA_REQUEST_ ## tim ## _ ## chan }
280 static const dmaTimerMapping_t dmaTimerMapping
[] = {
281 REQMAP_TIM(TIM1
, CH1
),
282 REQMAP_TIM(TIM1
, CH2
),
283 REQMAP_TIM(TIM1
, CH3
),
284 REQMAP_TIM(TIM1
, CH4
),
285 REQMAP_TIM(TIM2
, CH1
),
286 REQMAP_TIM(TIM2
, CH2
),
287 REQMAP_TIM(TIM2
, CH3
),
288 REQMAP_TIM(TIM2
, CH4
),
289 REQMAP_TIM(TIM3
, CH1
),
290 REQMAP_TIM(TIM3
, CH2
),
291 REQMAP_TIM(TIM3
, CH3
),
292 REQMAP_TIM(TIM3
, CH4
),
293 REQMAP_TIM(TIM4
, CH1
),
294 REQMAP_TIM(TIM4
, CH2
),
295 REQMAP_TIM(TIM4
, CH3
),
296 REQMAP_TIM(TIM5
, CH1
),
297 REQMAP_TIM(TIM5
, CH2
),
298 REQMAP_TIM(TIM5
, CH3
),
299 REQMAP_TIM(TIM5
, CH4
),
300 REQMAP_TIM(TIM8
, CH1
),
301 REQMAP_TIM(TIM8
, CH2
),
302 REQMAP_TIM(TIM8
, CH3
),
303 REQMAP_TIM(TIM8
, CH4
),
304 REQMAP_TIM(TIM15
, CH1
),
305 REQMAP_TIM(TIM16
, CH1
),
306 REQMAP_TIM(TIM17
, CH1
),
312 #define DMA(d, s) { DMA_CODE(d, s, 0), (dmaResource_t *)DMA ## d ## _Stream ## s, 0 }
314 static dmaChannelSpec_t dmaChannelSpec
[MAX_PERIPHERAL_DMA_OPTIONS
] = {
335 #elif defined(STM32F4) || defined(STM32F7)
338 #define DMA(d, s, c) { DMA_CODE(d, s, c), (dmaResource_t *)DMA ## d ## _Stream ## s, DMA_Channel_ ## c }
339 #elif defined(STM32F7)
340 #define DMA(d, s, c) { DMA_CODE(d, s, c), (dmaResource_t *)DMA ## d ## _Stream ## s, DMA_CHANNEL_ ## c }
343 static const dmaPeripheralMapping_t dmaPeripheralMapping
[] = {
345 // Everything including F405 and F446
346 { DMA_PERIPH_SPI_TX
, SPIDEV_1
, { DMA(2, 3, 3), DMA(2, 5, 3) } },
347 { DMA_PERIPH_SPI_RX
, SPIDEV_1
, { DMA(2, 0, 3), DMA(2, 2, 3) } },
348 { DMA_PERIPH_SPI_TX
, SPIDEV_2
, { DMA(1, 4, 0) } },
349 { DMA_PERIPH_SPI_RX
, SPIDEV_2
, { DMA(1, 3, 0) } },
350 { DMA_PERIPH_SPI_TX
, SPIDEV_3
, { DMA(1, 5, 0), DMA(1, 7, 0) } },
351 { DMA_PERIPH_SPI_RX
, SPIDEV_3
, { DMA(1, 0, 0), DMA(1, 2, 0) } },
353 #if defined(STM32F411xE) || defined(STM32F745xx) || defined(STM32F746xx) || defined(STM32F765xx) || defined(STM32F722xx)
354 { DMA_PERIPH_SPI_TX
, SPIDEV_4
, { DMA(2, 1, 4) } },
355 { DMA_PERIPH_SPI_RX
, SPIDEV_4
, { DMA(2, 0, 4) } },
357 #ifdef USE_EXTENDED_SPI_DEVICE
358 { DMA_PERIPH_SPI_TX
, SPIDEV_5
, { DMA(2, 6, 7) } },
359 { DMA_PERIPH_SPI_RX
, SPIDEV_5
, { DMA(2, 5, 7) } },
361 #if !defined(STM32F722xx)
362 { DMA_PERIPH_SPI_TX
, SPIDEV_6
, { DMA(2, 5, 1) } },
363 { DMA_PERIPH_SPI_RX
, SPIDEV_6
, { DMA(2, 6, 1) } },
365 #endif // USE_EXTENDED_SPI_DEVICE
370 { DMA_PERIPH_ADC
, ADCDEV_1
, { DMA(2, 0, 0), DMA(2, 4, 0) } },
371 { DMA_PERIPH_ADC
, ADCDEV_2
, { DMA(2, 2, 1), DMA(2, 3, 1) } },
372 { DMA_PERIPH_ADC
, ADCDEV_3
, { DMA(2, 0, 2), DMA(2, 1, 2) } },
375 #ifdef USE_SDCARD_SDIO
376 { DMA_PERIPH_SDIO
, 0, { DMA(2, 3, 4), DMA(2, 6, 4) } },
380 { DMA_PERIPH_UART_TX
, UARTDEV_1
, { DMA(2, 7, 4) } },
381 { DMA_PERIPH_UART_RX
, UARTDEV_1
, { DMA(2, 5, 4), DMA(2, 2, 4) } },
382 { DMA_PERIPH_UART_TX
, UARTDEV_2
, { DMA(1, 6, 4) } },
383 { DMA_PERIPH_UART_RX
, UARTDEV_2
, { DMA(1, 5, 4) } },
384 { DMA_PERIPH_UART_TX
, UARTDEV_3
, { DMA(1, 3, 4) } },
385 { DMA_PERIPH_UART_RX
, UARTDEV_3
, { DMA(1, 1, 4) } },
386 { DMA_PERIPH_UART_TX
, UARTDEV_4
, { DMA(1, 4, 4) } },
387 { DMA_PERIPH_UART_RX
, UARTDEV_4
, { DMA(1, 2, 4) } },
388 { DMA_PERIPH_UART_TX
, UARTDEV_5
, { DMA(1, 7, 4) } },
389 { DMA_PERIPH_UART_RX
, UARTDEV_5
, { DMA(1, 0, 4) } },
390 { DMA_PERIPH_UART_TX
, UARTDEV_6
, { DMA(2, 6, 5), DMA(2, 7, 5) } },
391 { DMA_PERIPH_UART_RX
, UARTDEV_6
, { DMA(2, 1, 5), DMA(2, 2, 5) } },
395 #define TC(chan) DEF_TIM_CHANNEL(CH_ ## chan)
397 static const dmaTimerMapping_t dmaTimerMapping
[] = {
398 // Generated from 'timer_def.h'
399 { TIM1
, TC(CH1
), { DMA(2, 6, 0), DMA(2, 1, 6), DMA(2, 3, 6) } },
400 { TIM1
, TC(CH2
), { DMA(2, 6, 0), DMA(2, 2, 6) } },
401 { TIM1
, TC(CH3
), { DMA(2, 6, 0), DMA(2, 6, 6) } },
402 { TIM1
, TC(CH4
), { DMA(2, 4, 6) } },
404 { TIM2
, TC(CH1
), { DMA(1, 5, 3) } },
405 { TIM2
, TC(CH2
), { DMA(1, 6, 3) } },
406 { TIM2
, TC(CH3
), { DMA(1, 1, 3) } },
407 { TIM2
, TC(CH4
), { DMA(1, 7, 3), DMA(1, 6, 3) } },
409 { TIM3
, TC(CH1
), { DMA(1, 4, 5) } },
410 { TIM3
, TC(CH2
), { DMA(1, 5, 5) } },
411 { TIM3
, TC(CH3
), { DMA(1, 7, 5) } },
412 { TIM3
, TC(CH4
), { DMA(1, 2, 5) } },
414 { TIM4
, TC(CH1
), { DMA(1, 0, 2) } },
415 { TIM4
, TC(CH2
), { DMA(1, 3, 2) } },
416 { TIM4
, TC(CH3
), { DMA(1, 7, 2) } },
418 { TIM5
, TC(CH1
), { DMA(1, 2, 6) } },
419 { TIM5
, TC(CH2
), { DMA(1, 4, 6) } },
420 { TIM5
, TC(CH3
), { DMA(1, 0, 6) } },
421 { TIM5
, TC(CH4
), { DMA(1, 1, 6), DMA(1, 3, 6) } },
423 { TIM8
, TC(CH1
), { DMA(2, 2, 0), DMA(2, 2, 7) } },
424 { TIM8
, TC(CH2
), { DMA(2, 2, 0), DMA(2, 3, 7) } },
425 { TIM8
, TC(CH3
), { DMA(2, 2, 0), DMA(2, 4, 7) } },
426 { TIM8
, TC(CH4
), { DMA(2, 7, 7) } },
432 // The embedded ADC24_DMA_REMAP conditional should be removed
433 // when (and if) F3 is going generic.
434 #define DMA(d, c) { DMA_CODE(d, 0, c), (dmaResource_t *)DMA ## d ## _Channel ## c }
435 static const dmaPeripheralMapping_t dmaPeripheralMapping
[18] = {
437 { DMA_PERIPH_SPI_TX
, SPIDEV_1
, { DMA(1, 3) } },
438 { DMA_PERIPH_SPI_RX
, SPIDEV_1
, { DMA(1, 2) } },
439 { DMA_PERIPH_SPI_TX
, SPIDEV_2
, { DMA(1, 5) } },
440 { DMA_PERIPH_SPI_RX
, SPIDEV_2
, { DMA(1, 4) } },
441 { DMA_PERIPH_SPI_TX
, SPIDEV_3
, { DMA(2, 2) } },
442 { DMA_PERIPH_SPI_RX
, SPIDEV_3
, { DMA(2, 1) } },
446 { DMA_PERIPH_ADC
, ADCDEV_1
, { DMA(1, 1) } },
447 #ifdef ADC24_DMA_REMAP
448 { DMA_PERIPH_ADC
, ADCDEV_2
, { DMA(2, 3) } },
450 { DMA_PERIPH_ADC
, ADCDEV_2
, { DMA(2, 1) } },
452 { DMA_PERIPH_ADC
, ADCDEV_3
, { DMA(2, 5) } },
453 #ifdef ADC24_DMA_REMAP
454 { DMA_PERIPH_ADC
, ADCDEV_4
, { DMA(2, 4) } },
456 { DMA_PERIPH_ADC
, ADCDEV_4
, { DMA(2, 2) } },
461 { DMA_PERIPH_UART_TX
, UARTDEV_1
, { DMA(1, 4) } },
462 { DMA_PERIPH_UART_RX
, UARTDEV_1
, { DMA(1, 5) } },
464 { DMA_PERIPH_UART_TX
, UARTDEV_2
, { DMA(1, 7) } },
465 { DMA_PERIPH_UART_RX
, UARTDEV_2
, { DMA(1, 6) } },
466 { DMA_PERIPH_UART_TX
, UARTDEV_3
, { DMA(1, 2) } },
467 { DMA_PERIPH_UART_RX
, UARTDEV_3
, { DMA(1, 3) } },
468 { DMA_PERIPH_UART_TX
, UARTDEV_4
, { DMA(2, 5) } },
469 { DMA_PERIPH_UART_RX
, UARTDEV_4
, { DMA(2, 3) } },
473 #define TC(chan) DEF_TIM_CHANNEL(CH_ ## chan)
475 static const dmaTimerMapping_t dmaTimerMapping
[] = {
476 // Generated from 'timer_def.h'
477 { TIM1
, TC(CH1
), { DMA(1, 2) } },
478 { TIM1
, TC(CH2
), { DMA(1, 3) } },
479 { TIM1
, TC(CH3
), { DMA(1, 6) } },
480 { TIM1
, TC(CH4
), { DMA(1, 4) } },
482 { TIM2
, TC(CH1
), { DMA(1, 5) } },
483 { TIM2
, TC(CH2
), { DMA(1, 7) } },
484 { TIM2
, TC(CH3
), { DMA(1, 1) } },
485 { TIM2
, TC(CH4
), { DMA(1, 7) } },
487 { TIM3
, TC(CH1
), { DMA(1, 6) } },
488 { TIM3
, TC(CH3
), { DMA(1, 2) } },
489 { TIM3
, TC(CH4
), { DMA(1, 3) } },
491 { TIM4
, TC(CH1
), { DMA(1, 1) } },
492 { TIM4
, TC(CH2
), { DMA(1, 4) } },
493 { TIM4
, TC(CH3
), { DMA(1, 5) } },
495 { TIM8
, TC(CH1
), { DMA(2, 3) } },
496 { TIM8
, TC(CH2
), { DMA(2, 5) } },
497 { TIM8
, TC(CH3
), { DMA(2, 1) } },
498 { TIM8
, TC(CH4
), { DMA(2, 2) } },
500 { TIM15
, TC(CH1
), { DMA(1, 5) } },
502 #ifdef REMAP_TIM16_DMA
503 { TIM16
, TC(CH1
), { DMA(1, 6) } },
505 { TIM16
, TC(CH1
), { DMA(1, 3) } },
508 #ifdef REMAP_TIM17_DMA
509 { TIM17
, TC(CH1
), { DMA(1, 7) } },
511 { TIM17
, TC(CH1
), { DMA(1, 1) } },
519 #if defined(STM32H7) || defined(STM32G4)
520 static void dmaSetupRequest(dmaChannelSpec_t
*dmaSpec
, uint8_t request
)
522 // Setup request as channel
523 dmaSpec
->channel
= request
;
525 // Insert DMA request into code
526 dmaCode_t code
= dmaSpec
->code
;
527 dmaSpec
->code
= DMA_CODE(DMA_CODE_CONTROLLER(code
), DMA_CODE_STREAM(code
), dmaSpec
->channel
);
531 const dmaChannelSpec_t
*dmaGetChannelSpecByPeripheral(dmaPeripheral_e device
, uint8_t index
, int8_t opt
)
533 if (opt
< 0 || opt
>= MAX_PERIPHERAL_DMA_OPTIONS
) {
537 for (unsigned i
= 0 ; i
< ARRAYLEN(dmaPeripheralMapping
) ; i
++) {
538 const dmaPeripheralMapping_t
*periph
= &dmaPeripheralMapping
[i
];
539 #if defined(STM32H7) || defined(STM32G4)
540 if (periph
->device
== device
&& periph
->index
== index
) {
541 dmaChannelSpec_t
*dmaSpec
= &dmaChannelSpec
[opt
];
542 dmaSetupRequest(dmaSpec
, periph
->dmaRequest
);
546 if (periph
->device
== device
&& periph
->index
== index
&& periph
->channelSpec
[opt
].ref
) {
547 return &periph
->channelSpec
[opt
];
555 dmaoptValue_t
dmaoptByTag(ioTag_t ioTag
)
557 #ifdef USE_TIMER_MGMT
558 for (unsigned i
= 0; i
< MAX_TIMER_PINMAP_COUNT
; i
++) {
559 if (timerIOConfig(i
)->ioTag
== ioTag
) {
560 return timerIOConfig(i
)->dmaopt
;
567 return DMA_OPT_UNUSED
;
570 const dmaChannelSpec_t
*dmaGetChannelSpecByTimerValue(TIM_TypeDef
*tim
, uint8_t channel
, dmaoptValue_t dmaopt
)
572 if (dmaopt
< 0 || dmaopt
>= MAX_TIMER_DMA_OPTIONS
) {
576 for (unsigned i
= 0 ; i
< ARRAYLEN(dmaTimerMapping
) ; i
++) {
577 const dmaTimerMapping_t
*timerMapping
= &dmaTimerMapping
[i
];
578 #if defined(STM32H7) || defined(STM32G4)
579 if (timerMapping
->tim
== tim
&& timerMapping
->channel
== channel
) {
580 dmaChannelSpec_t
*dmaSpec
= &dmaChannelSpec
[dmaopt
];
581 dmaSetupRequest(dmaSpec
, timerMapping
->dmaRequest
);
585 if (timerMapping
->tim
== tim
&& timerMapping
->channel
== channel
&& timerMapping
->channelSpec
[dmaopt
].ref
) {
586 return &timerMapping
->channelSpec
[dmaopt
];
594 const dmaChannelSpec_t
*dmaGetChannelSpecByTimer(const timerHardware_t
*timer
)
600 dmaoptValue_t dmaopt
= dmaoptByTag(timer
->tag
);
601 return dmaGetChannelSpecByTimerValue(timer
->tim
, timer
->channel
, dmaopt
);
604 // dmaGetOptionByTimer is called by pgResetFn_timerIOConfig to find out dmaopt for pre-configured timer.
606 dmaoptValue_t
dmaGetOptionByTimer(const timerHardware_t
*timer
)
608 #if defined(STM32H7) || defined(STM32G4)
609 for (unsigned opt
= 0; opt
< ARRAYLEN(dmaChannelSpec
); opt
++) {
610 if (timer
->dmaRefConfigured
== dmaChannelSpec
[opt
].ref
) {
611 return (dmaoptValue_t
)opt
;
615 for (unsigned i
= 0 ; i
< ARRAYLEN(dmaTimerMapping
); i
++) {
616 const dmaTimerMapping_t
*timerMapping
= &dmaTimerMapping
[i
];
617 if (timerMapping
->tim
== timer
->tim
&& timerMapping
->channel
== timer
->channel
) {
618 for (unsigned j
= 0; j
< MAX_TIMER_DMA_OPTIONS
; j
++) {
619 const dmaChannelSpec_t
*dma
= &timerMapping
->channelSpec
[j
];
620 if (dma
->ref
== timer
->dmaRefConfigured
621 #if defined(STM32F4) || defined(STM32F7)
622 && dma
->channel
== timer
->dmaChannelConfigured
632 return DMA_OPT_UNUSED
;
635 #if defined(STM32H7) || defined(STM32G4)
636 // A variant of dmaGetOptionByTimer that looks for matching dmaTimUPRef
637 dmaoptValue_t
dmaGetUpOptionByTimer(const timerHardware_t
*timer
)
639 for (unsigned opt
= 0; opt
< ARRAYLEN(dmaChannelSpec
); opt
++) {
640 if (timer
->dmaTimUPRef
== dmaChannelSpec
[opt
].ref
) {
641 return (dmaoptValue_t
)opt
;
645 return DMA_OPT_UNUSED
;
649 #endif // USE_DMA_SPEC